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  }