Exemplo de Passo a Passo Usando a Biblioteca de Controle de Acesso Detalhado

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 acesso para 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
    …

    }

}