Exemplo de caminhada embora usando a biblioteca de controle de acesso refinada

Este tópico fornece alguns exemplos de como essa biblioteca e esse chaincode podem ser usados. Tudo isso assumindo que Init() foi chamado para criar as entidades de bootstrap e o chamador de Init() e invoke() é "%CN%frank.thomas@example.com". O fluxo normal em um aplicativo será criar algumas listas iniciais de controle de acesso que serão usadas para conceder ou negar acesso às outras entidades.

Inicialização

Chame Initialization() para criar entidades de bootstrap ao instanciar chaincode. Por exemplo:

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

Criar um novo 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)

}

Agora que temos uma nova ACL, podemos usá-la para modificar quem pode executar determinadas operações. Então, primeiro adicionaremos 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 inicial de bootstrap. Assim, isso garante que Frank Thomas ainda possa executar operações em .Groups, pois a ACL que concede permissão a ele é a primeira na lista. Mas agora qualquer pessoa que corresponda à ACL AllowAdmins pode executar operações CREATE, READ, UPDATE ou DELETE (agora eles podem criar novos grupos).

Criar um novo grupo

Os administradores agora podem criar um novo 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 - a de Bob Garcia (usando seu certificado) - para tentar criar um novo 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. Essa chamada criará um novo grupo chamado "AdminGrp" com os membros iniciais do grupo sendo jill.muller@example.com e ivan.novak@example.com ou qualquer pessoa com a atribuição de atributo (ABAC)=admin.

Criar um novo 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 admins

  }

  **resourceMgr**  :=  **chaincodeACL**.NewResourceManager(nil, stub)  // Not specify identity, use caller's identity as default.
  err :=  **resourceMgr**.Create(resourceMgr, nil)   // Using caller's certificate

  ...
}

Isso criaria um novo recurso chamado transferMarble que o aplicativo poderia usar para controlar o acesso à função de chaincode transferMarble. No momento, o acesso é limitado pela lista de controle de acesso AllowAdmins.

Verificar acesso a um recurso

Podemos usar esse novo recurso em nosso chaincode para permitir apenas que os administradores transfiram um mármore modificando o método invoke() do chaincode Marbles da seguinte forma:

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
    …

    }

}