Search code examples
access-controlhyperledgerhyperledger-composer

Participant does not have create access to resource


I am making a business model using hyperledger composer wherein i have a bank as a participant and a customer as an asset. The bank is as defined below:

participant Bank identified by bankId {
o String bankId
o String name
o String code
}

and the customer looks like this:

asset Customer identified by aadhaarId {
o String aadhaarId
o String panId
o String firstName
o String lastName
o String contactNo
o String residence
o String accountNumber
o AccountType accountType
o String creationDate  
--> Bank bank
}

I want that a participant (bank) can update only those customers that belong to it and i want to create a transaction to do this. So i created the following transaction:

transaction updateCustomer identified by transactionId {
o String transactionId  
--> Customer customer
o Customer newDetails
}

and defined a rule in the .acl file as follows:

rule bankCanUpdateItsCutomersViaTransaction {
description: "Allow a participant to update it's own resources"
participant(p): "org.acme.sample.Bank"
operation: UPDATE
resource(r): "org.acme.sample.updateCustomer"
condition: (p.getIdentifier() == r.customer.bank.getIdentifier())
action: ALLOW
}

To test this, i created a participant(besides the already provided admin) and created a customer linked with that participant.I have a transaction processor function behind this that simply updates the customer asset registry. But when i try to execute the updateCustomer transaction, i get an error saying that the participant does not have CREATE access to resource. The problem persists even if i change the operation to CREATE in the .acl file. I think that the problem lies in the condition part but i am not able to correct it.

I have a similar transaction for creating Customer as follows:

transaction createCustomer identified by transactionId {
o String transactionId
o Customer newCustomer 
}

and the rule for it is as below:

rule bankCanCreateItsCutomersViaTransaction {    
description: "Allow a participant to create it's own resources"
participant(p): "org.acme.sample.Bank"
operation: CREATE
resource(r): "org.acme.sample.createCustomer"
condition: (p.getIdentifier() == r.newCustomer.bank.getIdentifier())
action: ALLOW
}

there is a simple transaction processor function behind this createCustomer transaction that just adds the newCustomer in the customer asset registry. This works totally fine but the updateCustomer transaction is not working. Any help would be much appreciated. Thanks :)


Solution

  • I took some other path and instead of checking whether the customer belongs to that bank in the rules, i checked that in the transaction processor function. So my rule for updateCustomer looks like this:

    rule bankCanInvokeUpdateCustomer {
    description: "Allow a bank to invoke updateCustomer transaction"
    participant: "org.acme.sample.Bank"
    operation: CREATE
    resource: "org.acme.sample.updateCustomer"
    action: ALLOW 
    }
    

    and i checked the bank as follows:

    var currentParticipant = getCurrentParticipant();
    var currentBank = currentParticipant["$identifier"];
    var actualBank = tx.customer.bank.bankId;
    if( actualBank != currentBank) 
       throw new Error('You can not update someone else\'s customer');
    

    The above code gets the current participant by using the getCurrentParticipant() function and then matches the bank identifier with the bank that the customer has account in. If they are not the same, then in throws an error