Ejemplo de revisión mediante la biblioteca de control de acceso detallado

En este tema, se proporcionan algunos ejemplos de cómo se pueden utilizar la biblioteca y el código de cadena. Todos estos ejemplos suponen que se ha llamado a la función Init() para crear las entidades de inicialización de datos y que el emisor de llamada de Init() y invoke() es "%CN%frank.thomas@example.com". El flujo normal de una aplicación consiste en crear algunas listas de control de acceso inicial que se utilizarán para otorgar o denegar el acceso a las otras entidades.

Inicialización

Llame a la función Initialization() para crear entidades de inicialización de datos al desplegar códigos de cadenas. Por ejemplo:

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

Crear una 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)

}

Puede utilizar la nueva ACL para modificar quién puede realizar determinadas operaciones. En primer lugar, agregue esta nueva ACL al grupo de inicialización de datos .Groups para permitir que cualquier administrador cree un grupo.

Agregar una ACL a un 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

)

}

Esto agrega la ACL AllowAdmins al grupo de inicialización de datos .Groups después de la ACL de inicialización de datos inicial. Por lo tanto, esto garantiza que Frank Thomas pueda completar las operaciones en el grupo .Groups porque la ACL que otorga el permiso Frank es la primera en la lista. Ahora, cualquier persona que coincida con la ACL AllowAdmins puede completar las operaciones CREATE, READ, UPDATE o DELETE (ahora pueden crear grupos).

Crear un grupo

Los administradores ahora pueden crear un 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 llamada utiliza una identidad explícita (Bob García, mediante su certificado) para intentar crear un grupo. Debido a que Bob Garcia coincide con un patrón en la ACL AllowAdmins y los miembros de esa ACL pueden realizar operaciones CREATE en el grupo de inicialización de datos .Groups, esta llamada se realizará correctamente. Si Jim Silva, que no estaba en la unidad de organización example.com ni en el grupo AdminGrp (que aún no existe), tuviera su certificado aprobado como último argumento, la llamada fallaría ya que no tiene los permisos adecuados. Esta llamada crea un grupo denominado "AdminGrp" con los miembros iniciales del grupo que son jill.muller@example.com y ivan.novak@example.com o cualquier persona con el atributo (ABAC) role=admin.

Crear 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

  ...
}
Esto crea un recurso denominado transferMarble que la aplicación puede utilizar para controlar el acceso a la función de código de cadena transferMarble. El acceso está actualmente limitado por la lista de control de acceso AllowAdmins.

Comprobación del acceso a un recurso

Puede utilizar este nuevo recurso en el código de cadena para permitir que solo los administradores transfieran un mármol, modificando el método invoke() del código de cadena de mármoles como se muestra en el siguiente 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
    …

    }

}