Skip to content
This repository has been archived by the owner on Feb 1, 2022. It is now read-only.

Commit

Permalink
added update service functionalities, upadate docs, logging and error…
Browse files Browse the repository at this point in the history
… managing (#27)

Signed-off-by: Maria Teresa Nieto <mariateresa.nietogalan@telefonica.com>
  • Loading branch information
mtnieto committed Jan 15, 2021
1 parent 5139ec3 commit f1dac16
Show file tree
Hide file tree
Showing 41 changed files with 1,006 additions and 1,051 deletions.
19 changes: 0 additions & 19 deletions fabric-chaincode/Dockerfile

This file was deleted.

95 changes: 36 additions & 59 deletions fabric-chaincode/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# IDENTITY CHAINCODE (coren-identitycc)
# TRUSTID CHAINCODE

A chaincode or smart contract, with all the functionalities allowing developers to create, manage, and export digital assets on the Hyperledger Fabric network

Expand All @@ -24,16 +24,15 @@ Identity for services is represented with the following structure:




## Chaincode internal functionalities

### Init
Initializes the chaincode with the first controller identity that will be the issuer of identities. This identity is created with the following args:

```js
{
did: "did:vtn:trustos:telefonica:0",
controller: "did:vtn:trustos:telefonica:0",
did: "did:vtn:trustos:company:0",
controller: "did:vtn:trustos:company:0",
publicKey: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7NBDzVMESXU/yuARe7YU\nGrkgNMZh5eA5w3PgxgYZf/isDLPHvmSM2Q9cTauDroriGInikQxtZ/CI4+9Qi4Rd\nJCHjeWhzw0hTIXhHoohyo9QTbUVetb4RBDJEcNqFrpztAojn8Ib5EF2soBFtBLyT\nguxlizcWwTZvv+KxHGBg/tUE7JIqw3YzmEK31faR2HhkPPqxTQ9F+h4SOnY9e6Cf\nh75PpjouzarpntSVkAqv/Ot5kV3O4TcWhB0vUr/HZwx2iX+LEyYock8Sx4Op20/g\n7k3J3rYhMGTHfkKMhZjX9QoZ8uBRiSxieAaia0yZSIcycgE6Aqu6KT+WaQn4bCnh\nwQIDAQAB\n-----END PUBLIC KEY-----"
}

Expand All @@ -50,7 +49,7 @@ All invokes are called via the proxy function. The proxy function args are:

```js
{
did: "did:vtn:trustos:telefonica:0",
did: "did:vtn:trustos:company:0",
payload: "eyJhbGdvcml0aG0iOiJQUzI1NiIsImFsZyI6IlBTMjU2In0.eyJmdW5jdGlvbiI6ImNyZWF0ZVNlbGZJZGVudGl0eSIsInBhcmFtcyI6eyJkaWQiOiJkaWQ6dnRuOnRydXN0b3M6dGVsZWZvbmljYToyIiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdTA0ZTlWTE5uMUpIZ1lOSU1SclVcblE0SkhoSG4wd1p4UENEOWtjUHo2M1NNQmlZbkN0Uk0yNHBLODZnQWFUdU00RDhWMkxqckE2ZHZCV3dCT2YydUZcbi80aXJJUlhNT2FJNTh1dFhFQ3NBMHI2Q3cyU3BDWVNWOEJLMXk4aHBuc3cwMi9UMHhZUkRiRnFmaHZxYQ",

}
Expand All @@ -66,7 +65,7 @@ The payload is signed in jws format. The content of the payload has the followin
{
function: "createSelfIdentity",
params: {
did: "did:vtn:trustos:telefonica:2",
did: "did:vtn:trustos:company:2",
publicKey: publick.toString()

}
Expand All @@ -90,7 +89,7 @@ The params in the payload has the following form:

```js
{
did: "did:vtn:trustos:telefonica:2",
did: "did:vtn:trustos:company:2",
publicKey: publick.toString()
}

Expand All @@ -101,7 +100,7 @@ The params in the payload has the following form:
Gets an identity using the DID.The params to sign in the payload are:
```js
{
did: "did:vtn:trustos:telefonica:2",
did: "did:vtn:trustos:company:2",
}

```
Expand All @@ -110,7 +109,7 @@ Gets an identity using the DID.The params to sign in the payload are:
The controller verifies the identity. The params in the signed payload are
```js
{
did: "did:vtn:trustos:telefonica:2",
did: "did:vtn:trustos:company:2",
}

```
Expand All @@ -119,32 +118,46 @@ The controller verifies the identity. The params in the signed payload are
Revokes an identity. THhe params in the signed payload are:
```js
{
did: "did:vtn:trustos:telefonica:2",
did: "did:vtn:trustos:company:2",
}

```

- **`createServiceIdentity()`** <br>
Creates a service identity.
```js
{
did: "vtn:trustos:service:1",
name: "chaincode_example02",
isPublic: true
{
"serviceID": "coren-trackscc",
"name": "coren-trackscc",
"access": {
"policy": "SAME_CONTROLLER"
},
"channel": "channel1"
}
```

- **`updateServiceAccess()`** <br>
Update the access for a users DID.
Update the service access.
```js
{
did: "vtn:trustos:service:1",
access: {
did: "did:vtn:trustos:telefonica:1",
type: 2

},
isPublic: true
policy: "FINE_GRAINED",
threshold: 0,
access: {
"did:vtn:trustid:c0fd6b4749329c4acec7f4ac273d46c2b755736e9f5cae6fc62acec8d04549c6": 2
}
}

}
```
- **`updateService()`** <br>
Update the information from a Service.
```js
{
did: "vtn:trustos:service:1",
name: "chaincodeName",
channel: "channelName"
}
```

Expand All @@ -162,7 +175,7 @@ Invokes a chaincode deployed as a service in the vtn platform. Args are the func
{
did: "vtn:trustos:service:1",
args: ["invoke", "a", "b", "1"],
channel: "telefonicachannel"
channel: "companychannel"
}
```

Expand All @@ -183,17 +196,8 @@ Invokes a chaincode deployed as a service in the vtn platform. Args are the func

</details>

## Architecture of the chaincode
```
coren-trackscc
├── src
└── chaincode
├── go files with the logic and tests
├── postman
├── collection.json // postman collection
└── environment.json // postman environment
└── README.md
```



## Project configuration
This project has to be stored in the following route
Expand Down Expand Up @@ -231,30 +235,3 @@ go test
````



<!-- ## Run the test and generate report
To run the test used for continuous integration, it is necessary to follow the steps below:
First it is necessary to run the sonar server
```
cd $GOPATH/src/name_of_the_project/src/chaincode/miscelanea
docker-compose up -d
```
Once the server is up, it is necessary to execute the test and the code coverage
````
cd $GOPATH/src/coren-trackscc/src/chaincode
mkdir -p bin
go test -short -coverprofile=bin/cov.out `go list ./... | grep -v vendor/`
go tool cover -func=bin/cov.out
````
The next step is to execute the sonnar scanner
````
sonar-scanner
```` -->

60 changes: 42 additions & 18 deletions fabric-chaincode/chaincode.gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ SPDX-License-Identifier: Apache-2.0
package main

import (
log "coren-identitycc/src/chaincode/log"
log "TrustID/fabric-chaincode/log"
"encoding/json"
"errors"
"fmt"

Expand All @@ -26,34 +27,34 @@ func toChaincodeArgs(args ...string) [][]byte {
}

func (cc *Chaincode) invoke(stub shim.ChaincodeStubInterface, userDID string, args interface{}) (string, error) {
log.Infof("[%s][invoke] Invoke chaincode", proxyGateway)
log.Infof("[%s][%s][invoke] Invoke chaincode", CHANNEL_ENV, proxyGateway)

interact := make(map[string]interface{})
interact = args.(map[string]interface{})

if interact["did"] == nil {
log.Errorf("[%s][invoke]*** Error calling service, no service DID Specified", proxyGateway)
return "", errors.New("Error calling service, no service DID Specified")
log.Errorf("[%s][%s][invoke] %s", CHANNEL_ENV, ERRORDidMissing, proxyGateway)
return "", errors.New(ERRORDidMissing)
}

log.Debugf("[%s][invoke] Check access to interact for did: %s and service: %s", proxyGateway, userDID, interact["did"].(string))
log.Debugf("[%s][%s][invoke] Check access to interact for did: %s and service: %s", CHANNEL_ENV, proxyGateway, userDID, interact["did"].(string))
service, err := cc.getServiceRegistry(stub, interact["did"].(string))
if err != nil {
log.Errorf("[%s][invoke]*** Error calling service: ", err.Error())
log.Errorf("[%s][%s][invoke] Error calling service: ", CHANNEL_ENV, err.Error())
return "", err
}
ccName := service.Name
channel := service.Channel

log.Debugf("[%s][invoke] Access for did: %s and service: %s", proxyGateway, userDID, interact["did"].(string))
log.Debugf("[%s][%s][invoke] Access for did: %s and service: %s", CHANNEL_ENV, proxyGateway, userDID, interact["did"].(string))
if err != nil {
log.Errorf("[%s][invoke]*** Error calling service, problem getting service", err.Error())
log.Errorf("[%s][%s][invoke] Error calling service, problem getting service %v", CHANNEL_ENV, proxyGateway, err.Error())
return "", err
}

if cc.hasAccess(stub, service, userDID) {
log.Debugf("[%s][invoke] Did: %s has access to service %s, invoking cc", proxyGateway, userDID, interact["did"].(string))
log.Debugf("[%s][invoke] Interact for chaincode %s args are %v", proxyGateway, ccName, interact["args"])
log.Debugf("[%s][%s][invoke] Did: %s has access to service %s, invoking cc", CHANNEL_ENV, proxyGateway, userDID, interact["did"].(string))
log.Debugf("[%s][%s][invoke] Interact for chaincode %s args are %v", CHANNEL_ENV, proxyGateway, ccName, interact["args"])
s := make([]string, len(interact["args"].([]interface{})))
for i, v := range interact["args"].([]interface{}) {
s[i] = fmt.Sprint(v)
Expand All @@ -62,17 +63,40 @@ func (cc *Chaincode) invoke(stub shim.ChaincodeStubInterface, userDID string, ar
argBytes := toChaincodeArgs(s...)
response := stub.InvokeChaincode(ccName, argBytes, channel)
if response.Status != shim.OK {
log.Debugf("[%s][invoke] Error invoking chaincode %s", proxyGateway, response.Message)
log.Debugf("[%s][%s][invoke] Error invoking chaincode %s", CHANNEL_ENV, proxyGateway, response.Message)
return "", errors.New(response.Message)
}
log.Debugf("[%s][invoke] Invoke OK, returning result", proxyGateway)
log.Infof("%v", response.Payload)

return string(response.Payload), nil
log.Debugf("[%s][%s][invoke] Invoke OK, returning result", CHANNEL_ENV, proxyGateway)
log.Infof("[%s][%s][invoke] Invoke received result: %v", CHANNEL_ENV, proxyGateway, string(response.Payload))
event := Event{}
payload := map[string]interface{}{}
_ = json.Unmarshal(response.Payload, &payload)
if payload["event"] != nil {
eventBytes, _ := json.Marshal(payload["event"])
err := json.Unmarshal(eventBytes, &event)
log.Debugf("event: %v \n", event)

// Here we insert the payload along with the serviceDID & transaction ID
eventPayload := map[string]interface{}{}
err = json.Unmarshal(event.Payload, &eventPayload)
eventBis := map[string]interface{}{"message": eventPayload, "did": interact["did"], "txId": stub.GetTxID()}
eventBytesBis, _ := json.Marshal(eventBis)

// Emit the event
err = stub.SetEvent(event.EventName, []byte(eventBytesBis))
if err != nil {
log.Errorf(" ERROR Fail to set event" + err.Error())
}

responseBytes, _ := json.Marshal(payload["response"])
return string(responseBytes), nil
} else {
return string(response.Payload), nil
}
}

log.Errorf("[%s][invoke] User %s has not access to this resources", proxyGateway, userDID)
err = errors.New("User has not access")
log.Errorf("[%s][%s][invoke] User %s has not access to this resources", CHANNEL_ENV, proxyGateway, userDID)
err = errors.New(ERRORUserAccess)
return "", err

}
Expand All @@ -82,7 +106,7 @@ func (cc *Chaincode) invoke(stub shim.ChaincodeStubInterface, userDID string, ar
func (cc *Chaincode) hasAccess(stub shim.ChaincodeStubInterface, service *Service, userDid string) bool {
idReturn, err := cc.getIDRegistry(stub, userDid)
if err != nil {
log.Errorf("[%s][checkAccess] Error getting access policy %s ", proxyGateway, userDid)
log.Errorf("[%s][%s][checkAccess] Error getting access policy %s ", CHANNEL_ENV, proxyGateway, userDid)
return false
}
switch service.Access.Policy {
Expand Down
4 changes: 2 additions & 2 deletions fabric-chaincode/chaincode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestServices(t *testing.T) {
})

t.Run("Create Service", func(t *testing.T) {
servicePayload := "eyJhbGdvcml0aG0iOiJQUzI1NiIsImFsZyI6IlBTMjU2In0.eyJmdW5jdGlvbiI6ImNyZWF0ZVNlcnZpY2VJZGVudGl0eSIsInBhcmFtcyI6eyJkaWQiOiJ2dG46dHJ1c3RvczpzZXJ2aWNlOjEiLCJuYW1lIjoiY2hhaW5jb2RlX2V4YW1wbGUwMiIsImlzUHVibGljIjp0cnVlfX0.ZD09jbF7YbNbCAlvZhQAS3e76ziwqD-2v3Z-A9abVRPGpuqF4KR4YOkb3lyzLeiiZJo240tDPzfFessG93yCxY3KOcREXZ5hAFqhxk25Eyw9Cx_vngj8_ON7bfh7DBc5J05c4K2-QET9PV1MMWBqeS3TjiCq2zBfHxsWBRsTeOA5e32X6xyqAZq6Cj2NXA4kLXSd4zhRu_B5xtG4HobwhOFqLnliSP74tvBM_disK3Yk08qfrsr9o5u5xOofdbcigEUpaZVpFVdT79VFkFHvrX-ACoadeMMCq87sraE3riEAGaqnXPuIZurE50APyUJAWTYbTHOSYlW9bRB21C8smA"
servicePayload := "eyJhbGdvcml0aG0iOiJQUzI1NiIsImFsZyI6IlBTMjU2In0.eyJmdW5jdGlvbiI6ImNyZWF0ZVNlcnZpY2VJZGVudGl0eSIsInBhcmFtcyI6eyJkaWQiOiJ2dG46dHJ1c3RvczpzZXJ2aWNlOjEiLCJuYW1lIjoiY2hhaW5jb2RlX2V4YW1wbGUwMiIsImlzUHVibGljIjp0cnVlLCJjaGFubmVsIjoidGVsZWZvbmljYWNoYW5uZWwifX0.Zr-Vqp2hGRTmwzXdKAyzBe8MdiqUjpshwR_gtP931TEgwNYwX8jQdZlP_yEIbthepWUwgcP0wZSoMgsssamVJ-U9yf2Ts2TjMJkUOiehXz2gzkzJ-nKWYuDKhF-IAM1nadkejb3442R5iPetlb8IzpwiJkVuc1TorpcciE38fEO81hhI_iUsdWCWrcNSNMYEecFsEui12VbBJKy3Ab9u6h1q0jhMMxg3qutwNaJzoOD2kE2afQidzQ1vyze5xXlsciqd35xtL3bzVPNIxcjkVNx1L2ST0ugY1N1NQcET3tyfTpO8AtyHRrscPjC0IDyjFthkmcRsdPwun3v5scRtEw"
service := Request{Did: "did:vtn:trustos:telefonica:2", Payload: servicePayload}
CreateService(t, stub, service)
})
Expand Down Expand Up @@ -110,7 +110,7 @@ func CreateUnverifiedIdentity(t *testing.T, stub *testcc.MockStub, invokeReq Ide
if res.Status != shim.OK {
t.Error("Invoke failed", res.Status, res.Message)
}
expectedRes := ""
expectedRes := "The identity has been stored in DLT successfully"
assert.Equal(t, expectedRes, string(res.Payload), "Should be the same")

}
Expand Down
8 changes: 1 addition & 7 deletions fabric-chaincode/go.mod
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
module coren-identitycc/src/chaincode
module TrustID/fabric-chaincode/

go 1.12

require (
github.com/fsouza/go-dockerclient v1.6.5 // indirect
github.com/go-logfmt/logfmt v0.4.0 // indirect
github.com/hyperledger/fabric-amcl v0.0.0-20200424173818-327c9e2cf77a // indirect
github.com/hyperledger/fabric-chaincode-go v0.0.0-20200511190512-bcfeb58dd83a
github.com/hyperledger/fabric-lib-go v1.0.0 // indirect
github.com/hyperledger/fabric-protos-go v0.0.0-20200506201313-25f6564b9ac4
github.com/pierrec/lz4 v2.0.5+incompatible // indirect
github.com/s7techlab/cckit v0.6.14 // indirect
github.com/sirupsen/logrus v1.6.0
github.com/spf13/viper v1.4.0 // indirect
github.com/stretchr/testify v1.5.1
github.com/sykesm/zap-logfmt v0.0.3 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
gopkg.in/square/go-jose.v2 v2.5.1
)
Loading

0 comments on commit f1dac16

Please sign in to comment.