Esempio di procedura guidata utilizzando la libreria di controllo dell'accesso con filtro

In questo argomento vengono forniti alcuni esempi di utilizzo di questa libreria e del codice concatenato. Tutti questi presupponendo che Init() sia stato chiamato per creare le entità di bootstrap e il chiamante di Init() e invoke() è "%CN%frank.thomas@example.com". Il flusso normale in un'applicazione consisterà nel creare alcune liste di controllo dell'accesso iniziali che verranno utilizzate per concedere o negare l'accesso alle altre entità.

Inizializzazione

Chiamare Initialization() per creare entità di bootstrap durante la creazione di un'istanza del codice concatenato. Ad esempio:

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

Crea una nuova 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)

}

Ora che abbiamo una nuova ACL, possiamo usarla per modificare chi può eseguire determinate operazioni. Quindi aggiungeremo prima questa nuova ACL al gruppo di bootstrap .Groups per consentire a qualsiasi amministratore di creare un gruppo.

Aggiungi un'ACL a un gruppo

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

)

}

Questa operazione aggiunge l'ACL AllowAdmins al gruppo di bootstrap .Groups dopo l'ACL di bootstrap iniziale. Ciò assicura che Frank Thomas possa ancora eseguire operazioni su .Groups poiché l'ACL che gli concede l'autorizzazione è la prima nell'elenco. Ma ora chiunque corrisponda all'ACL AllowAdmins può eseguire operazioni CREATE, READ, UPDATE o DELETE (ora può creare nuovi gruppi).

Creare un nuovo gruppo

Gli amministratori possono ora creare un nuovo gruppo:

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

...
}

Questa chiamata sta usando un'identità esplicita - quella di Bob Garcia (usando il suo certificato) - per cercare di creare un nuovo gruppo. Poiché Bob Garcia corrisponde a un pattern nell'ACL AllowAdmins e i membri di tale ACL possono eseguire operazioni CREATE sul gruppo di bootstrap .Groups, questa chiamata avrà esito positivo. Se Jim Silva - che non era nell'unità organizzativa example.com né nel gruppo AdminGrp (che ancora non esiste) - avesse il suo certificato passato come ultimo argomento, la chiamata fallirebbe in quanto non dispone delle autorizzazioni appropriate. Questa chiamata creerà un nuovo gruppo denominato "AdminGrp" con i membri iniziali del gruppo che sono jill.muller@example.com e ivan.novak@example.com o chiunque abbia l'attributo (ABAC) role=admin.

Crea una nuova risorsa

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

  ...
}

Questa operazione creerebbe una nuova risorsa denominata transferMarble che l'applicazione potrebbe utilizzare per controllare l'accesso alla funzione codice concatenato transferMarble. L'accesso è attualmente limitato dalla lista di controllo dell'accesso AllowAdmins.

Controllare l'accesso per una risorsa

Possiamo utilizzare questa nuova risorsa nel nostro codice concatenato solo per consentire agli amministratori di trasferire un marmo modificando il metodo invoke() del codice concatenato Marmi come segue:

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
    …

    }

}