Exemplo de Utilização da Biblioteca de Controle de Acesso Detalhada
Este tópico fornece alguns exemplos de como a biblioteca e o chaincode podem ser usados. Todos esses exemplos pressupõem que a função Init()
foi chamada para criar as entidades de bootstrap e que o chamador de Init()
e invoke()
é "%CN%frank.thomas@example.com"
. O fluxo normal em um aplicativo é criar algumas listas de controle de acesso iniciais que serão usadas para conceder ou negar acesso às outras entidades.
Inicialização
Chame a função Initialization()
para criar entidades de bootstrap ao implantar chaincodes. Por exemplo:
import "chaincodeACL"
func (t \*SimpleChaincode) Init(nil, stub shim.ChaincodeStubInterface) pb.Response
{
err := chaincodeACL.Initialization(stub)
}
Criar uma 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 administrators 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)
}
Você pode usar a nova ACL para modificar quem pode executar determinadas operações. Primeiro, adicione essa nova ACL ao grupo de bootstrap .Groups
para permitir que qualquer administrador crie um grupo.
Adicionar uma ACL a um grupo
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
)
}
Isso adiciona a ACL AllowAdmins
ao grupo de bootstrap .Groups
após a ACL de bootstrap inicial. Assim, isso garante que Frank Thomas ainda possa concluir operações no grupo .Groups
porque o ACL que concede a permissão Frank está primeiro na lista. Agora, qualquer pessoa que corresponda à ACL AllowAdmins
pode concluir as operações CREATE, READ, UPDATE ou DELETE (agora eles podem criar grupos).
Criar um grupo
Os administradores agora podem criar um grupo.
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
...
}
Esta chamada está usando uma identidade explícita (Bob Garcia, usando seu certificado) para tentar criar um grupo. Como Bob Garcia corresponde a um padrão na ACL AllowAdmins
e os membros dessa ACL podem executar operações CREATE no grupo de bootstrap .Groups
, essa chamada será bem-sucedida. Se Jim Silva, que não estava na unidade organizacional example.com
nem no grupo AdminGrp
(que ainda não existe), tivesse seu certificado passado como o último argumento, a chamada falharia, pois ele não tem as permissões apropriadas. Esta chamada cria um grupo chamado "AdminGrp
", com os membros iniciais do grupo sendo jill.muller@example.com e ivan.novak@example.com ou qualquer pessoa com o atributo (ABAC) role=admin.
Criar um recurso
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 administrators
}
**resourceMgr** := **chaincodeACL**.NewResourceManager(nil, stub) // Not specify identity, use caller's identity as default.
err := **resourceMgr**.Create(resourceMgr, nil) // Using caller's certificate
...
}
Isso cria um recurso chamado transferMarble
que o aplicativo pode usar para controlar o acesso à função chaincode transferMarble
. No momento, o acesso é limitado pela lista de controle de acesso AllowAdmins
.
Verificar o acesso de um recurso
Você pode usar esse novo recurso em seu chaincode para permitir que apenas os administradores transfiram um mármore, modificando o método invoke()
do chaincode do Marbles, conforme mostrado no seguinte código:
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 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
…
}
}