Exemple d'utilisation de la bibliothèque de contrôle d'accès de niveau fin

Cette rubrique fournit des exemples d'utilisation de cette bibliothèque et de ce code chaîne. Tous ces éléments supposent que Init() a été appelé pour créer les entités d'initialisation et que l'appelant de Init() et invoke() est "%CN%frank.thomas@example.com". Dans une application, le flux normal consiste à créer des listes de contrôle d'accès initiales qui seront utilisées pour accorder ou refuser l'accès aux autres entités.

Initialisation

Appelez Initialization() pour créer des entités d'initialisation lors de l'instanciation du code chaîne. Exemple :

import "chaincodeACL"
func (t \*SimpleChaincode) Init(nil, stub shim.ChaincodeStubInterface) pb.Response
{
         err := chaincodeACL.Initialization(stub)
}

Créer une ACL

import "chaincodeACL"
...
{

**ACLMgr**  := chaincodeACL.NewACLManager(nil, stub) // Not specify identity, use caller's identity as default.

// Define a new ACL
**newACL**  := chaincodeACL.ACL{

    "AllowAdmins",   // ACL name
    "Allow admins full access",  // Description
    []string{"CREATE","READ","UPDATE","DELETE"},    // Accesses allowed or not
    true, // Allowed
    []string{"%CN%bob.dole@example.com","%OU%example.com,"%GRP%admins"}, // Initial identity patterns
    ".ACLs.acl", // Start with bootstrap ACL

}

// Add this ACL with default identity (caller's identify here)
err :=  **ACLMgr**.Create( **newACL** , nil)

}

Maintenant que nous avons une nouvelle ACL, nous pouvons l'utiliser pour modifier qui peut effectuer certaines opérations. Nous allons donc d'abord ajouter cette nouvelle ACL au groupe de démarrage .Groups pour permettre à tout administrateur de créer un groupe.

Ajouter une ACL à un groupe

import "chaincodeACL"
…
{

  **groupMgr**  := chaincodeACL.NewGroupManager(nil, stub) // Not specify identity, use caller's identity as default.
  err :=  **groupMgr**.AddAfterACL(

    ".Groups",     // Bootstrap group name
    ".Groups.ACL", // Which ACL to add after
    "AllowAdmins", // The new ACL to add
    nil            // with default identity that's frank.thomas

)

}

Cette opération ajoute l'ACL AllowAdmins au groupe d'amorce .Groups après l'ACL d'amorce initiale. Ainsi, cela garantit que Frank Thomas peut toujours effectuer des opérations sur .Groups car l'ACL lui accordant l'autorisation est la première dans la liste. Mais à présent, toute personne qui correspond à la liste de contrôle d'accès AllowAdmins peut effectuer des opérations CREATE, READ, UPDATE ou DELETE (elle peut désormais créer de nouveaux groupes).

Créer un groupe

Les administrateurs peuvent désormais créer un groupe :

import "chaincodeACL"
...
{

...
  // Define a new group.
  **newGroup**  := chaincodeACL.Group{

      "AdminGrp",   // Name of the group
      "Administrators of the app",   // Description of the group
      {"%CN%jill.muller@example.com","%CN%ivan.novak@example.com","%ATTR%role=admin"},
      []string{"AllowAdmins"},   // The ACL for the group

    }

  **groupMgr**  := chaincodeACL.NewGroupManager(nil, stub)   // Not specify identity, use caller's identity as default.
  err :=  **groupMgr**.Create( **newGroup** , bob\_garcia\_certificate)   // Using a specific certificate

...
}

Cet appel utilise une identité explicite - celle de Bob Garcia (en utilisant son certificat) - pour essayer de créer un nouveau groupe. Comme Bob Garcia correspond à un modèle dans l'ACL AllowAdmins et que les membres de cette ACL peuvent effectuer des opérations CREATE sur le groupe d'amorce .Groups, cet appel réussira. Si Jim Silva - qui n'était pas dans l'unité d'organisation example.com ni dans le groupe AdminGrp (qui n'existe toujours pas) - avait passé son certificat comme dernier argument, l'appel échouerait car il n'a pas les autorisations appropriées. Cet appel va créer un nouveau groupe appelé "AdminGrp" avec les membres initiaux du groupe étant jill.muller@example.com et ivan.novak@example.com ou toute personne avec l'attribut (ABAC) role=admin.

Créer une ressource

import "chaincodeACL"
...
{

  ...
  **newResource**  :=  **chaincodeACL**.Resource{

      "transferMarble", // Name of resource to create

      "The transferMarble chaincode function", // Description of the resource

      []string{"AllowAdmins"}, // Single ACL for now allowing admins

  }

  **resourceMgr**  :=  **chaincodeACL**.NewResourceManager(nil, stub)  // Not specify identity, use caller's identity as default.
  err :=  **resourceMgr**.Create(resourceMgr, nil)   // Using caller's certificate

  ...
}

Cette opération créerait une ressource nommée transferMarble que l'application pourrait utiliser pour contrôler l'accès à la fonction de code chaîne transferMarble. L'accès est actuellement limité par la liste de contrôle d'accès AllowAdmins.

Vérifier l'accès à une ressource

Nous pouvons utiliser cette nouvelle ressource dans notre code chaîne pour autoriser uniquement les administrateurs à transférer une bille en modifiant la méthode invoke() du code chaîne Marbles comme suit :

import "chaincodeACL"
…
func (t \*SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {

  **resourceMgr**  :=  **chaincodeACL**.NewResourceManager(nil, stub)   // Not specify identity, use caller's identity as default.

  function, args := stub.GetFunctionAndParameters()

  fmt.Println("invoke is running " + function)        // Handle different functions

  if function == "initMarble" {   //create a new marble

      return t.initMarble(stub, args)}

  else if function == " **transferMarble**" { //change owner of a specific marble

    **allowed** , err : =  **resourceMgr**. **CheckAccess** ("transferMarble", "UPDATE", nil)
    if  **allowed**  == true {

      return t.transferMarble(stub, args)

    else {

      return NOACCESS

    }

    } else if function == "transferMarblesBasedOnColor" { //transfer all marbles of a certain color
    …

    }

}