Skip to content

Commit

Permalink
Finish GetRecursive implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
bandreghetti committed Jan 14, 2021
1 parent b8b954e commit ee276db
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 2 deletions.
5 changes: 5 additions & 0 deletions assets/assets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ var testAssetList = []AssetType{
DataType: "number",
Writers: []string{`$org\dMSP`},
},
{
Tag: "secrets",
Label: "Secrets",
DataType: "[]->sampleSecret",
},
{
Tag: "active",
Label: "Active",
Expand Down
42 changes: 40 additions & 2 deletions assets/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,26 @@ func (k *Key) Get(stub shim.ChaincodeStubInterface) (*Asset, errors.ICCError) {
return get(stub, pvtCollection, k.Key())
}

/* GetRecursive-related code */

func getRecursive(stub shim.ChaincodeStubInterface, pvtCollection, key string) (*Asset, errors.ICCError) {
var assetBytes []byte
var err error
if pvtCollection != "" {
assetBytes, err = stub.GetPrivateData(pvtCollection, key)
// If org cannot get private data it might be because it has no permission, so we fetch the data hash
if err != nil {
hash, err := stub.GetPrivateDataHash(pvtCollection, key)
if err != nil {
return nil, errors.WrapErrorWithStatus(err, "unable to get asset", 400)
}
response := Asset{
"@key": key,
"@assetType": pvtCollection,
"@hash": hash,
}
return &response, nil
}
} else {
assetBytes, err = stub.GetState(key)
}
Expand All @@ -73,6 +88,7 @@ func getRecursive(stub shim.ChaincodeStubInterface, pvtCollection, key string) (
}

for k, v := range response {
var fullValue interface{}
switch prop := v.(type) {
case map[string]interface{}:
propKey, err := NewKey(prop)
Expand All @@ -90,11 +106,33 @@ func getRecursive(stub shim.ChaincodeStubInterface, pvtCollection, key string) (
return nil, errors.WrapErrorWithStatus(err, "failed to get subasset", 500)
}

response[k] = *subAsset

fullValue = *subAsset
case []interface{}:
for idx, elem := range prop {
if elemMap, ok := elem.(map[string]interface{}); ok {
elemKey, err := NewKey(elemMap)
if err != nil {
return nil, errors.WrapErrorWithStatus(err, "failed to resolve asset references", 500)
}

var subAsset *Asset
if elemKey.IsPrivate() {
subAsset, err = getRecursive(stub, elemKey.TypeTag(), elemKey.Key())
} else {
subAsset, err = getRecursive(stub, "", elemKey.Key())
}
if err != nil {
return nil, errors.WrapErrorWithStatus(err, "failed to get subasset", 500)
}

prop[idx] = *subAsset
}
}
fullValue = prop
default:
continue
}
response[k] = fullValue
}

return &response, nil
Expand Down
58 changes: 58 additions & 0 deletions assets/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,61 @@ func TestGetRecursiveWithPvtData(t *testing.T) {
t.FailNow()
}
}

func TestGetRecursiveWithListOfPvtData(t *testing.T) {
stub := shim.NewMockStub("testcc", new(testCC))

stub.MockTransactionStart("TestGetRecursiveWithListOfPvtData")
var a Asset
assetJSON := []byte("{\"@assetType\": \"sampleSecret\",\"secretName\": \"mySecret\",\"secret\": \"VERYVERYSECRET\"}")
err := json.Unmarshal(assetJSON, &a)
if err != nil {
fmt.Println(err)
t.FailNow()
}
_, err = a.put(stub)
if err != nil {
fmt.Println(err)
t.FailNow()
}
stub.MockTransactionEnd("TestGetRecursiveWithListOfPvtData")

stub.MockTransactionStart("TestGetRecursiveWithListOfPvtData")
var b Asset
assetJSON = []byte("{\"@assetType\": \"samplePerson\",\"name\": \"Maria\",\"cpf\": \"318.207.920-48\",\"readerScore\": 70,\"secrets\":[{\"@assetType\": \"sampleSecret\",\"secretName\": \"mySecret\",\"secret\": \"VERYVERYSECRET\"}]}")
err = json.Unmarshal(assetJSON, &b)
if err != nil {
fmt.Println(err)
t.FailNow()
}
_, err = b.put(stub)
if err != nil {
fmt.Println(err)
t.FailNow()
}
stub.MockTransactionEnd("TestGetRecursiveWithListOfPvtData")

gotAsset, err := b.GetRecursive(stub)
if err != nil {
fmt.Println(err)
t.FailNow()
}

secretProp := gotAsset.GetProp("secrets")
secretList, ok := secretProp.([]interface{})
if !ok {
fmt.Println("secretList should be of type []interface{}")
t.FailNow()
}

if len(secretList) != 1 {
fmt.Println("secretList should have length equal to 1")
}

if !reflect.DeepEqual(secretList[0], a) {
fmt.Println("these should be deeply equal")
fmt.Println(a)
fmt.Println(secretList[0])
t.FailNow()
}
}

0 comments on commit ee276db

Please sign in to comment.