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  }