github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/discovery/endorsement/collection.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package endorsement 8 9 import ( 10 "github.com/hechain20/hechain/common/policies" 11 "github.com/hechain20/hechain/gossip/api" 12 "github.com/hyperledger/fabric-protos-go/peer" 13 "github.com/pkg/errors" 14 ) 15 16 func principalsFromCollectionConfig(ccp *peer.CollectionConfigPackage) (principalSetsByCollectionName, error) { 17 principalSetsByCollections := make(principalSetsByCollectionName) 18 if ccp == nil { 19 return principalSetsByCollections, nil 20 } 21 for _, colConfig := range ccp.Config { 22 staticCol := colConfig.GetStaticCollectionConfig() 23 if staticCol == nil { 24 // Right now we only support static collections, so if we got something else 25 // we should refuse to process further 26 return nil, errors.Errorf("expected a static collection but got %v instead", colConfig) 27 } 28 if staticCol.MemberOrgsPolicy == nil { 29 return nil, errors.Errorf("MemberOrgsPolicy of %s is nil", staticCol.Name) 30 } 31 pol := staticCol.MemberOrgsPolicy.GetSignaturePolicy() 32 if pol == nil { 33 return nil, errors.Errorf("policy of %s is nil", staticCol.Name) 34 } 35 var principals policies.PrincipalSet 36 // We now extract all principals from the policy 37 for _, principal := range pol.Identities { 38 principals = append(principals, principal) 39 } 40 principalSetsByCollections[staticCol.Name] = principals 41 } 42 return principalSetsByCollections, nil 43 } 44 45 type principalSetsByCollectionName map[string]policies.PrincipalSet 46 47 // toIdentityFilter converts this principalSetsByCollectionName mapping to a filter 48 // which accepts or rejects identities of peers. 49 func (psbc principalSetsByCollectionName) toIdentityFilter(channel string, evaluator principalEvaluator, cc *peer.ChaincodeCall) (identityFilter, error) { 50 var principalSets policies.PrincipalSets 51 for _, col := range cc.CollectionNames { 52 // Each collection we're interested in should exist in the principalSetsByCollectionName mapping. 53 // Otherwise, we have no way of computing a filter because we can't locate the principals the peer identities 54 // need to satisfy. 55 principalSet, exists := psbc[col] 56 if !exists { 57 return nil, errors.Errorf("collection %s doesn't exist in collection config for chaincode %s", col, cc.Name) 58 } 59 principalSets = append(principalSets, principalSet) 60 } 61 return filterForPrincipalSets(channel, evaluator, principalSets), nil 62 } 63 64 // filterForPrincipalSets creates a filter of peer identities out of the given PrincipalSets 65 func filterForPrincipalSets(channel string, evaluator principalEvaluator, sets policies.PrincipalSets) identityFilter { 66 return func(identity api.PeerIdentityType) bool { 67 // Iterate over all principal sets and ensure each principal set 68 // authorizes the identity. 69 for _, principalSet := range sets { 70 if !isIdentityAuthorizedByPrincipalSet(channel, evaluator, principalSet, identity) { 71 return false 72 } 73 } 74 return true 75 } 76 } 77 78 // isIdentityAuthorizedByPrincipalSet returns whether the given identity satisfies some principal out of the given PrincipalSet 79 func isIdentityAuthorizedByPrincipalSet(channel string, evaluator principalEvaluator, principalSet policies.PrincipalSet, identity api.PeerIdentityType) bool { 80 // We look for a principal which authorizes the identity 81 // among all principals in the principalSet 82 for _, principal := range principalSet { 83 err := evaluator.SatisfiesPrincipal(channel, identity, principal) 84 if err != nil { 85 continue 86 } 87 // Else, err is nil, so we found a principal which authorized 88 // the given identity. 89 return true 90 } 91 return false 92 }