github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/core/common/privdata/simplecollection.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package privdata 8 9 import ( 10 "fmt" 11 12 "github.com/golang/protobuf/proto" 13 m "github.com/hyperledger/fabric-protos-go/msp" 14 "github.com/hyperledger/fabric-protos-go/peer" 15 "github.com/hyperledger/fabric/common/policies" 16 "github.com/hyperledger/fabric/msp" 17 "github.com/hyperledger/fabric/protoutil" 18 "github.com/pkg/errors" 19 ) 20 21 // SimpleCollection implements a collection with static properties 22 // and a public member set 23 type SimpleCollection struct { 24 name string 25 accessPolicy policies.Policy 26 memberOrgs []string 27 conf peer.StaticCollectionConfig 28 } 29 30 type SimpleCollectionPersistenceConfigs struct { 31 blockToLive uint64 32 } 33 34 // NewSimpleCollection returns a simple collection object based on a given 35 // StaticCollectionConfig proto that has all the necessary information 36 func NewSimpleCollection(collectionConfig *peer.StaticCollectionConfig, deserializer msp.IdentityDeserializer) (*SimpleCollection, error) { 37 sc := &SimpleCollection{} 38 err := sc.Setup(collectionConfig, deserializer) 39 return sc, err 40 } 41 42 // CollectionID returns the collection's ID 43 func (sc *SimpleCollection) CollectionID() string { 44 return sc.name 45 } 46 47 // MemberOrgs returns the MSP IDs that are part of this collection 48 func (sc *SimpleCollection) MemberOrgs() []string { 49 return sc.memberOrgs 50 } 51 52 // RequiredPeerCount returns the minimum number of peers 53 // required to send private data to 54 func (sc *SimpleCollection) RequiredPeerCount() int { 55 return int(sc.conf.RequiredPeerCount) 56 } 57 58 // MaximumPeerCount returns the maximum number of peers 59 // to which the private data will be sent 60 func (sc *SimpleCollection) MaximumPeerCount() int { 61 return int(sc.conf.MaximumPeerCount) 62 } 63 64 // AccessFilter returns the member filter function that evaluates signed data 65 // against the member access policy of this collection 66 func (sc *SimpleCollection) AccessFilter() Filter { 67 return func(sd protoutil.SignedData) bool { 68 if err := sc.accessPolicy.EvaluateSignedData([]*protoutil.SignedData{&sd}); err != nil { 69 return false 70 } 71 return true 72 } 73 } 74 75 // IsMemberOnlyRead returns whether only collection member 76 // has the read permission 77 func (sc *SimpleCollection) IsMemberOnlyRead() bool { 78 return sc.conf.MemberOnlyRead 79 } 80 81 // IsMemberOnlyWrite returns whether only collection member 82 // has the write permission 83 func (sc *SimpleCollection) IsMemberOnlyWrite() bool { 84 return sc.conf.MemberOnlyWrite 85 } 86 87 // Setup configures a simple collection object based on a given 88 // StaticCollectionConfig proto that has all the necessary information 89 func (sc *SimpleCollection) Setup(collectionConfig *peer.StaticCollectionConfig, deserializer msp.IdentityDeserializer) error { 90 if collectionConfig == nil { 91 return errors.New("Nil config passed to collection setup") 92 } 93 sc.conf = *collectionConfig 94 sc.name = collectionConfig.GetName() 95 96 // get the access signature policy envelope 97 collectionPolicyConfig := collectionConfig.GetMemberOrgsPolicy() 98 if collectionPolicyConfig == nil { 99 return errors.New("Collection config policy is nil") 100 } 101 accessPolicyEnvelope := collectionPolicyConfig.GetSignaturePolicy() 102 if accessPolicyEnvelope == nil { 103 return errors.New("Collection config access policy is nil") 104 } 105 106 err := sc.setupAccessPolicy(collectionPolicyConfig, deserializer) 107 if err != nil { 108 return err 109 } 110 111 // get member org MSP IDs from the envelope 112 for _, principal := range accessPolicyEnvelope.Identities { 113 switch principal.PrincipalClassification { 114 case m.MSPPrincipal_ROLE: 115 // Principal contains the msp role 116 mspRole := &m.MSPRole{} 117 err := proto.Unmarshal(principal.Principal, mspRole) 118 if err != nil { 119 return errors.Wrap(err, "Could not unmarshal MSPRole from principal") 120 } 121 sc.memberOrgs = append(sc.memberOrgs, mspRole.MspIdentifier) 122 case m.MSPPrincipal_IDENTITY: 123 principalId, err := deserializer.DeserializeIdentity(principal.Principal) 124 if err != nil { 125 return errors.Wrap(err, "Invalid identity principal, not a certificate") 126 } 127 sc.memberOrgs = append(sc.memberOrgs, principalId.GetMSPIdentifier()) 128 case m.MSPPrincipal_ORGANIZATION_UNIT: 129 OU := &m.OrganizationUnit{} 130 err := proto.Unmarshal(principal.Principal, OU) 131 if err != nil { 132 return errors.Wrap(err, "Could not unmarshal OrganizationUnit from principal") 133 } 134 sc.memberOrgs = append(sc.memberOrgs, OU.MspIdentifier) 135 default: 136 return errors.New(fmt.Sprintf("Invalid principal type %d", int32(principal.PrincipalClassification))) 137 } 138 } 139 140 return nil 141 } 142 143 // setupAccessPolicy configures a simple collection object based on a given 144 // StaticCollectionConfig proto that has all the necessary information 145 func (sc *SimpleCollection) setupAccessPolicy(collectionPolicyConfig *peer.CollectionPolicyConfig, deserializer msp.IdentityDeserializer) error { 146 var err error 147 sc.accessPolicy, err = getPolicy(collectionPolicyConfig, deserializer) 148 return err 149 } 150 151 // BlockToLive return collection's block to live configuration 152 func (s *SimpleCollectionPersistenceConfigs) BlockToLive() uint64 { 153 return s.blockToLive 154 }