Esempio di utilizzo della libreria di controllo dell'accesso con filtro
In questo argomento vengono forniti alcuni esempi di utilizzo di questa libreria e di questo codice concatenato. Tutti questi presuppongono che Init() sia stato chiamato per creare le entità bootstrap e il chiamante di Init() e invoke() è "%CN%frank.thomas@example.com". Il flusso normale in un'applicazione prevede la creazione di 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 bootstrap .Groups per consentire a qualsiasi amministratore di creare un gruppo.
Aggiungere 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
)
}
In questo modo l'ACL AllowAdmins viene aggiunta al gruppo bootstrap .Groups dopo l'ACL bootstrap iniziale. Ciò garantisce che Frank Thomas possa ancora eseguire operazioni su .Groups poiché l'ACL che gli concede l'autorizzazione è il primo nella lista. Ma ora chiunque corrisponda all'ACL AllowAdmins può eseguire operazioni CREATE, READ, UPDATE o DELETE (ora possono creare nuovi gruppi).
Creare un nuovo gruppo
Gli amministratori ora possono 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 provare a 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 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 non sarebbe riuscita 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 il ruolo 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
...
}
In questo modo verrà creata una nuova risorsa denominata transferMarble che l'applicazione potrebbe utilizzare per controllare l'accesso alla funzione chaincode 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 a catena solo per consentire agli amministratori di trasferire un marmo modificando il metodo invoke() del codice a catena 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
…
}
}