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
    …

    }

}