Ejemplo de uso de la biblioteca de control de acceso detallado

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

Inicialización

Llame a Initialization() para crear entidades de inicialización al instanciar el código de cadena. Por ejemplo:

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

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

}

Ahora que tenemos una nueva ACL, podemos utilizarla para modificar quién puede realizar determinadas operaciones. Por lo tanto, primero agregaremos esta nueva ACL al grupo de inicialización de datos .Groups para permitir que cualquier administrador cree un grupo.

Adición de 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 realizar operaciones en .Groups, ya que la ACL que le otorga permiso es la primera en la lista. Pero ahora cualquier persona que coincida con la ACL AllowAdmins puede realizar las operaciones CREATE, READ, UPDATE o DELETE (ahora pueden crear nuevos grupos).

Crear un nuevo grupo

Los administradores ahora pueden crear un nuevo 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 está usando una identidad explícita - la de Bob García (usando su certificado) - para tratar de crear un nuevo grupo. Puesto que Bob García coincide con un patrón de la ACL AllowAdmins y los miembros de esa ACL pueden realizar operaciones CREATE en el grupo de inicialización .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), hubiera aprobado su certificado como último argumento, la llamada fallaría porque no tiene los permisos adecuados. Esta llamada creará un nuevo grupo denominado "AdminGrp" con los miembros iniciales del grupo jill.muller@example.com y ivan.novak@example.com o cualquier persona con el atributo (ABAC) role=admin.

Crear nuevo 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

  ...
}

Esto crearía un nuevo recurso denominado transferMarble que la aplicación podría utilizar para controlar el acceso a la función de código de cadenas transferMarble. El acceso está actualmente limitado por la lista de control de acceso AllowAdmins.

Compruebe el acceso a un recurso

Podemos utilizar este nuevo recurso en nuestro código de cadenas para permitir solo a los administradores transferir un mármol modificando el método invoke() del código de cadenas Marbles de la siguiente manera:

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
    …

    }

}