@@ -24,8 +24,10 @@ import (
24
24
"github.com/hyperledger/fabric/core/peer"
25
25
"github.com/hyperledger/fabric/core/policy"
26
26
"github.com/hyperledger/fabric/core/policyprovider"
27
+ "github.com/hyperledger/fabric/msp"
27
28
"github.com/hyperledger/fabric/msp/mgmt"
28
29
"github.com/hyperledger/fabric/protos/common"
30
+ mb "github.com/hyperledger/fabric/protos/msp"
29
31
pb "github.com/hyperledger/fabric/protos/peer"
30
32
"github.com/hyperledger/fabric/protos/utils"
31
33
"github.com/pkg/errors"
@@ -142,6 +144,87 @@ func (lscc *lifeCycleSysCC) putChaincodeData(stub shim.ChaincodeStubInterface, c
142
144
return err
143
145
}
144
146
147
+ // checkCollectionMemberPolicy checks whether the supplied collection configuration
148
+ // complies to the given msp configuration
149
+ func checkCollectionMemberPolicy (collectionConfig * common.CollectionConfig , mspmgr msp.MSPManager ) error {
150
+ if mspmgr == nil {
151
+ return fmt .Errorf ("msp manager not set" )
152
+ }
153
+ msps , err := mspmgr .GetMSPs ()
154
+ if err != nil {
155
+ return errors .Wrapf (err , "error getting channel msp" )
156
+ }
157
+ if collectionConfig == nil {
158
+ return fmt .Errorf ("collection configuration is not set" )
159
+ }
160
+ coll := collectionConfig .GetStaticCollectionConfig ()
161
+ if coll == nil {
162
+ return fmt .Errorf ("collection configuration is empty" )
163
+ }
164
+ if coll .MemberOrgsPolicy == nil {
165
+ return fmt .Errorf ("collection member policy is not set" )
166
+ }
167
+ if coll .MemberOrgsPolicy .GetSignaturePolicy () == nil {
168
+ return fmt .Errorf ("collection member org policy is empty" )
169
+ }
170
+ // make sure that the orgs listed are actually part of the channel
171
+ // check all principals in the signature policy
172
+ for _ , principal := range coll .MemberOrgsPolicy .GetSignaturePolicy ().Identities {
173
+ found := false
174
+ var orgID string
175
+ // the member org policy only supports certain principal types
176
+ switch principal .PrincipalClassification {
177
+
178
+ case mb .MSPPrincipal_ROLE :
179
+ msprole := & mb.MSPRole {}
180
+ err := proto .Unmarshal (principal .Principal , msprole )
181
+ if err != nil {
182
+ return errors .Wrapf (err , "collection-name: %s -- cannot unmarshal identities" , coll .GetName ())
183
+ }
184
+ orgID = msprole .MspIdentifier
185
+ // the msp map is indexed using msp IDs - this behavior is implementation specific, making the following check a bit of a hack
186
+ for mspid := range msps {
187
+ if mspid == orgID {
188
+ found = true
189
+ break
190
+ }
191
+ }
192
+
193
+ case mb .MSPPrincipal_ORGANIZATION_UNIT :
194
+ mspou := & mb.OrganizationUnit {}
195
+ err := proto .Unmarshal (principal .Principal , mspou )
196
+ if err != nil {
197
+ return errors .Wrapf (err , "collection-name: %s -- cannot unmarshal identities" , coll .GetName ())
198
+ }
199
+ orgID = mspou .MspIdentifier
200
+ // the msp map is indexed using msp IDs - this behavior is implementation specific, making the following check a bit of a hack
201
+ for mspid := range msps {
202
+ if mspid == orgID {
203
+ found = true
204
+ break
205
+ }
206
+ }
207
+
208
+ case mb .MSPPrincipal_IDENTITY :
209
+ orgID = "identity principal"
210
+ for _ , msp := range msps {
211
+ _ , err := msp .DeserializeIdentity (principal .Principal )
212
+ if err == nil {
213
+ found = true
214
+ break
215
+ }
216
+ }
217
+ default :
218
+ return fmt .Errorf ("collection-name: %s -- principal type %v is not supported" , coll .GetName (), principal .PrincipalClassification )
219
+ }
220
+ if ! found {
221
+ logger .Warningf ("collection-name: %s collection member %s is not part of the channel" , coll .GetName (), orgID )
222
+ }
223
+ }
224
+
225
+ return nil
226
+ }
227
+
145
228
// putChaincodeCollectionData adds collection data for the chaincode
146
229
func (lscc * lifeCycleSysCC ) putChaincodeCollectionData (stub shim.ChaincodeStubInterface , cd * ccprovider.ChaincodeData , collectionConfigBytes []byte ) error {
147
230
if cd == nil {
@@ -159,7 +242,16 @@ func (lscc *lifeCycleSysCC) putChaincodeCollectionData(stub shim.ChaincodeStubIn
159
242
return errors .Errorf ("invalid collection configuration supplied for chaincode %s:%s" , cd .Name , cd .Version )
160
243
}
161
244
162
- // TODO: FAB-6526 - to add validation of the collections object
245
+ mspmgr := mgmt .GetManagerForChain (stub .GetChannelID ())
246
+ if mspmgr == nil {
247
+ return fmt .Errorf ("could not get MSP manager for channel %s" , stub .GetChannelID ())
248
+ }
249
+ for _ , collectionConfig := range collections .Config {
250
+ err = checkCollectionMemberPolicy (collectionConfig , mspmgr )
251
+ if err != nil {
252
+ return errors .Wrapf (err , "collection member policy check failed" )
253
+ }
254
+ }
163
255
164
256
key := privdata .BuildCollectionKVSKey (cd .Name )
165
257
0 commit comments