Skip to content

Commit

Permalink
Refactor assets package and tidy dependency versions
Browse files Browse the repository at this point in the history
  • Loading branch information
bandreghetti committed Jul 25, 2020
1 parent 816118e commit 71c9373
Show file tree
Hide file tree
Showing 16 changed files with 960 additions and 509 deletions.
488 changes: 3 additions & 485 deletions assets/asset.go

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions assets/checkWriters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package assets

import (
"fmt"
"regexp"

"github.com/goledgerdev/cc-tools/errors"
"github.com/hyperledger/fabric/core/chaincode/lib/cid"
"github.com/hyperledger/fabric/core/chaincode/shim"
)

// CheckGlobalWriters checks if tx creator is allowed to write asset
func (a Asset) CheckGlobalWriters(stub shim.ChaincodeStubInterface) error {
// Fetch asset properties
assetTypeDef := a.Type()
if assetTypeDef == nil {
return errors.NewCCError(fmt.Sprintf("asset type named %s does not exist", a.TypeTag()), 400)
}

// Get tx creator MSP ID
txCreator, err := cid.GetMSPID(stub)
if err != nil {
return errors.WrapErrorWithStatus(err, "error getting tx creator", 500)
}

// Check full asset write permission
if assetTypeDef.Writers != nil {
writePermission := false
for _, w := range assetTypeDef.Writers {
match, err := regexp.MatchString(w, txCreator)
if err != nil {
return errors.NewCCError("failed to check if writer matches regexp", 500)
}
if match {
writePermission = true
}
}
if !writePermission {
return errors.NewCCError(fmt.Sprintf("%s cannot write to this asset", txCreator), 403)
}
}

return nil
}

// CheckWriters checks if tx creator is allowed to write asset
func (a Asset) CheckWriters(stub shim.ChaincodeStubInterface) error {
// Check full asset write permission
err := a.CheckGlobalWriters(stub)
if err != nil {
return errors.WrapError(err, "failed writers check")
}

// Fetch asset properties
assetTypeDef := a.Type()
if assetTypeDef == nil {
return errors.NewCCError(fmt.Sprintf("asset type named %s does not exist", a.TypeTag()), 400)
}

// Get tx creator MSP ID
txCreator, err := cid.GetMSPID(stub)
if err != nil {
return errors.WrapErrorWithStatus(err, "error getting tx creator", 500)
}

// Check attributes write permission
for _, prop := range assetTypeDef.Props {
if _, exists := a[prop.Tag]; exists && prop.Writers != nil {
writePermission := false
for _, w := range prop.Writers {
match, err := regexp.MatchString(w, txCreator)
if err != nil {
return errors.NewCCError("failed to check if writer matches regexp", 500)
}
if match {
writePermission = true
}
}
if !writePermission {
return errors.NewCCError(fmt.Sprintf("%s cannot write to this asset property", txCreator), 403)
}
}
}

return nil
}
51 changes: 51 additions & 0 deletions assets/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package assets

import (
"encoding/json"

"github.com/goledgerdev/cc-tools/errors"
"github.com/hyperledger/fabric/core/chaincode/shim"
)

// Delete erases asset from world state
func (a *Asset) Delete(stub shim.ChaincodeStubInterface) ([]byte, error) {
isReferenced, err := a.IsReferenced(stub)
if err != nil {
return nil, errors.WrapError(err, "failed to check if asset if being referenced")
}
if isReferenced {
return nil, errors.NewCCError("another asset holds a reference to this one", 400)
}

err = a.DelRefs(stub)
if err != nil {
return nil, errors.WrapError(err, "failed cleaning reference index")
}

var assetJSON []byte
if !a.IsPrivate() {
err = stub.DelState(a.Key())
if err != nil {
return nil, errors.WrapError(err, "failed to delete state from ledger")
}
assetJSON, err = json.Marshal(a)
if err != nil {
return nil, errors.WrapError(err, "failed to marshal asset")
}
} else {
err = stub.DelPrivateData(a.TypeTag(), a.Key())
if err != nil {
return nil, errors.WrapError(err, "failed to delete state from private collection")
}
assetKeyOnly := map[string]interface{}{
"@key": a.Key(),
"@assetType": a.TypeTag(),
}
assetJSON, err = json.Marshal(assetKeyOnly)
if err != nil {
return nil, errors.WrapError(err, "failed to marshal private asset key")
}
}

return assetJSON, nil
}
25 changes: 25 additions & 0 deletions assets/existsInLedger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package assets

import (
"github.com/goledgerdev/cc-tools/errors"
"github.com/hyperledger/fabric/core/chaincode/shim"
)

// ExistsInLedger checks if asset already exists
func (a *Asset) ExistsInLedger(stub shim.ChaincodeStubInterface) (bool, errors.ICCError) {
var assetBytes []byte
var err error
if a.IsPrivate() {
assetBytes, err = stub.GetPrivateData(a.TypeTag(), a.Key())
} else {
assetBytes, err = stub.GetState(a.Key())
}
if err != nil {
return false, errors.WrapErrorWithStatus(err, "unable to check asset existence", 400)
}
if assetBytes != nil {
return true, nil
}

return false, nil
}
33 changes: 33 additions & 0 deletions assets/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package assets

import (
"encoding/json"

"github.com/goledgerdev/cc-tools/errors"
"github.com/hyperledger/fabric/core/chaincode/shim"
)

// Get reads asset from ledger
func (a *Asset) Get(stub shim.ChaincodeStubInterface) (*Asset, errors.ICCError) {
var assetBytes []byte
var err error
if a.IsPrivate() {
assetBytes, err = stub.GetPrivateData(a.TypeTag(), a.Key())
} else {
assetBytes, err = stub.GetState(a.Key())
}
if err != nil {
return nil, errors.WrapErrorWithStatus(err, "unable to get asset", 400)
}
if assetBytes == nil {
return nil, errors.NewCCError("asset not found", 404)
}

var response Asset
err = json.Unmarshal(assetBytes, &response)
if err != nil {
return nil, errors.WrapErrorWithStatus(err, "failed to unmarshal asset from ledger", 500)
}

return &response, nil
}
2 changes: 1 addition & 1 deletion assets/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strings"

"github.com/goledgerdev/cc-tools/errors"
"github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger/fabric/core/chaincode/shim"
)

/*
Expand Down
62 changes: 62 additions & 0 deletions assets/put.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package assets

import (
"encoding/json"

"github.com/goledgerdev/cc-tools/errors"
"github.com/hyperledger/fabric/core/chaincode/shim"
)

// Put inserts asset in blockchain
func (a *Asset) Put(stub shim.ChaincodeStubInterface) (map[string]interface{}, errors.ICCError) {
// Write index of references this asset points to
err := a.PutRefs(stub)
if err != nil {
return nil, errors.WrapError(err, "failed writing reference index")
}

// Marshal asset back to JSON format
assetJSON, err := json.Marshal(a)
if err != nil {
return nil, errors.WrapError(err, "failed to encode asset to JSON format")
}

// Write asset to blockchain
if a.IsPrivate() {
err = stub.PutPrivateData(a.TypeTag(), a.Key(), assetJSON)
if err != nil {
return nil, errors.WrapError(err, "failed to write asset to ledger")
}
assetKeyOnly := map[string]interface{}{
"@key": a.Key(),
"@assetType": a.TypeTag(),
}
return assetKeyOnly, nil
}

err = stub.PutState(a.Key(), assetJSON)
if err != nil {
return nil, errors.WrapError(err, "failed to write asset to ledger")
}
return *a, nil
}

// PutNew inserts asset in blockchain and returns error if asset exists
func (a *Asset) PutNew(stub shim.ChaincodeStubInterface) (map[string]interface{}, errors.ICCError) {
// Check if asset already exists
exists, err := a.ExistsInLedger(stub)
if err != nil {
return nil, errors.WrapError(err, "failed to verify if asset already exists")
}
if exists {
return nil, errors.NewCCError("asset already exists", 409)
}

// Marshal asset back to JSON format
res, err := a.Put(stub)
if err != nil {
return nil, errors.WrapError(err, "failed to write asset to ledger")
}

return res, nil
}
Loading

0 comments on commit 71c9373

Please sign in to comment.