github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/common/policydsl/policydslgo_builder.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  /*
     7  Notice: This file has been modified for Hyperledger Fabric SDK Go usage.
     8  Please review third_party pinning scripts and patches for more details.
     9  */
    10  
    11  package policydsl
    12  
    13  import (
    14  	"sort"
    15  
    16  	"github.com/golang/protobuf/proto"
    17  	cb "github.com/hyperledger/fabric-protos-go/common"
    18  	mb "github.com/hyperledger/fabric-protos-go/msp"
    19  )
    20  
    21  // AcceptAllPolicy always evaluates to true
    22  var AcceptAllPolicy *cb.SignaturePolicyEnvelope
    23  
    24  // MarshaledAcceptAllPolicy is the Marshaled version of AcceptAllPolicy
    25  var MarshaledAcceptAllPolicy []byte
    26  
    27  // RejectAllPolicy always evaluates to false
    28  var RejectAllPolicy *cb.SignaturePolicyEnvelope
    29  
    30  // MarshaledRejectAllPolicy is the Marshaled version of RejectAllPolicy
    31  var MarshaledRejectAllPolicy []byte
    32  
    33  func init() {
    34  	AcceptAllPolicy = Envelope(NOutOf(0, []*cb.SignaturePolicy{}), [][]byte{})
    35  	MarshaledAcceptAllPolicy = protoMarshalOrPanic(AcceptAllPolicy)
    36  
    37  	RejectAllPolicy = Envelope(NOutOf(1, []*cb.SignaturePolicy{}), [][]byte{})
    38  	MarshaledRejectAllPolicy = protoMarshalOrPanic(RejectAllPolicy)
    39  }
    40  
    41  // Envelope builds an envelope message embedding a SignaturePolicy
    42  func Envelope(policy *cb.SignaturePolicy, identities [][]byte) *cb.SignaturePolicyEnvelope {
    43  	ids := make([]*mb.MSPPrincipal, len(identities))
    44  	for i := range ids {
    45  		ids[i] = &mb.MSPPrincipal{PrincipalClassification: mb.MSPPrincipal_IDENTITY, Principal: identities[i]}
    46  	}
    47  
    48  	return &cb.SignaturePolicyEnvelope{
    49  		Version:    0,
    50  		Rule:       policy,
    51  		Identities: ids,
    52  	}
    53  }
    54  
    55  // SignedBy creates a SignaturePolicy requiring a given signer's signature
    56  func SignedBy(index int32) *cb.SignaturePolicy {
    57  	return &cb.SignaturePolicy{
    58  		Type: &cb.SignaturePolicy_SignedBy{
    59  			SignedBy: index,
    60  		},
    61  	}
    62  }
    63  
    64  // SignedByMspMember creates a SignaturePolicyEnvelope
    65  // requiring 1 signature from any member of the specified MSP
    66  func SignedByMspMember(mspId string) *cb.SignaturePolicyEnvelope {
    67  	return signedByFabricEntity(mspId, mb.MSPRole_MEMBER)
    68  }
    69  
    70  // SignedByMspClient creates a SignaturePolicyEnvelope
    71  // requiring 1 signature from any client of the specified MSP
    72  func SignedByMspClient(mspId string) *cb.SignaturePolicyEnvelope {
    73  	return signedByFabricEntity(mspId, mb.MSPRole_CLIENT)
    74  }
    75  
    76  // SignedByMspPeer creates a SignaturePolicyEnvelope
    77  // requiring 1 signature from any peer of the specified MSP
    78  func SignedByMspPeer(mspId string) *cb.SignaturePolicyEnvelope {
    79  	return signedByFabricEntity(mspId, mb.MSPRole_PEER)
    80  }
    81  
    82  // SignedByFabricEntity creates a SignaturePolicyEnvelope
    83  // requiring 1 signature from any fabric entity, having the passed role, of the specified MSP
    84  func signedByFabricEntity(mspId string, role mb.MSPRole_MSPRoleType) *cb.SignaturePolicyEnvelope {
    85  	// specify the principal: it's a member of the msp we just found
    86  	principal := &mb.MSPPrincipal{
    87  		PrincipalClassification: mb.MSPPrincipal_ROLE,
    88  		Principal:               protoMarshalOrPanic(&mb.MSPRole{Role: role, MspIdentifier: mspId})}
    89  
    90  	// create the policy: it requires exactly 1 signature from the first (and only) principal
    91  	p := &cb.SignaturePolicyEnvelope{
    92  		Version:    0,
    93  		Rule:       NOutOf(1, []*cb.SignaturePolicy{SignedBy(0)}),
    94  		Identities: []*mb.MSPPrincipal{principal},
    95  	}
    96  
    97  	return p
    98  }
    99  
   100  // SignedByMspAdmin creates a SignaturePolicyEnvelope
   101  // requiring 1 signature from any admin of the specified MSP
   102  func SignedByMspAdmin(mspId string) *cb.SignaturePolicyEnvelope {
   103  	// specify the principal: it's a member of the msp we just found
   104  	principal := &mb.MSPPrincipal{
   105  		PrincipalClassification: mb.MSPPrincipal_ROLE,
   106  		Principal:               protoMarshalOrPanic(&mb.MSPRole{Role: mb.MSPRole_ADMIN, MspIdentifier: mspId})}
   107  
   108  	// create the policy: it requires exactly 1 signature from the first (and only) principal
   109  	p := &cb.SignaturePolicyEnvelope{
   110  		Version:    0,
   111  		Rule:       NOutOf(1, []*cb.SignaturePolicy{SignedBy(0)}),
   112  		Identities: []*mb.MSPPrincipal{principal},
   113  	}
   114  
   115  	return p
   116  }
   117  
   118  //wrapper for generating "any of a given role" type policies
   119  func signedByAnyOfGivenRole(role mb.MSPRole_MSPRoleType, ids []string) *cb.SignaturePolicyEnvelope {
   120  	return SignedByNOutOfGivenRole(1, role, ids)
   121  }
   122  
   123  func SignedByNOutOfGivenRole(n int32, role mb.MSPRole_MSPRoleType, ids []string) *cb.SignaturePolicyEnvelope {
   124  	// we create an array of principals, one principal
   125  	// per application MSP defined on this chain
   126  	sort.Strings(ids)
   127  	principals := make([]*mb.MSPPrincipal, len(ids))
   128  	sigspolicy := make([]*cb.SignaturePolicy, len(ids))
   129  
   130  	for i, id := range ids {
   131  		principals[i] = &mb.MSPPrincipal{
   132  			PrincipalClassification: mb.MSPPrincipal_ROLE,
   133  			Principal:               protoMarshalOrPanic(&mb.MSPRole{Role: role, MspIdentifier: id})}
   134  		sigspolicy[i] = SignedBy(int32(i))
   135  	}
   136  
   137  	// create the policy: it requires exactly 1 signature from any of the principals
   138  	p := &cb.SignaturePolicyEnvelope{
   139  		Version:    0,
   140  		Rule:       NOutOf(n, sigspolicy),
   141  		Identities: principals,
   142  	}
   143  
   144  	return p
   145  }
   146  
   147  // SignedByAnyMember returns a policy that requires one valid
   148  // signature from a member of any of the orgs whose ids are
   149  // listed in the supplied string array
   150  func SignedByAnyMember(ids []string) *cb.SignaturePolicyEnvelope {
   151  	return signedByAnyOfGivenRole(mb.MSPRole_MEMBER, ids)
   152  }
   153  
   154  // SignedByAnyClient returns a policy that requires one valid
   155  // signature from a client of any of the orgs whose ids are
   156  // listed in the supplied string array
   157  func SignedByAnyClient(ids []string) *cb.SignaturePolicyEnvelope {
   158  	return signedByAnyOfGivenRole(mb.MSPRole_CLIENT, ids)
   159  }
   160  
   161  // SignedByAnyPeer returns a policy that requires one valid
   162  // signature from an orderer of any of the orgs whose ids are
   163  // listed in the supplied string array
   164  func SignedByAnyPeer(ids []string) *cb.SignaturePolicyEnvelope {
   165  	return signedByAnyOfGivenRole(mb.MSPRole_PEER, ids)
   166  }
   167  
   168  // SignedByAnyAdmin returns a policy that requires one valid
   169  // signature from a admin of any of the orgs whose ids are
   170  // listed in the supplied string array
   171  func SignedByAnyAdmin(ids []string) *cb.SignaturePolicyEnvelope {
   172  	return signedByAnyOfGivenRole(mb.MSPRole_ADMIN, ids)
   173  }
   174  
   175  // And is a convenience method which utilizes NOutOf to produce And equivalent behavior
   176  func And(lhs, rhs *cb.SignaturePolicy) *cb.SignaturePolicy {
   177  	return NOutOf(2, []*cb.SignaturePolicy{lhs, rhs})
   178  }
   179  
   180  // Or is a convenience method which utilizes NOutOf to produce Or equivalent behavior
   181  func Or(lhs, rhs *cb.SignaturePolicy) *cb.SignaturePolicy {
   182  	return NOutOf(1, []*cb.SignaturePolicy{lhs, rhs})
   183  }
   184  
   185  // NOutOf creates a policy which requires N out of the slice of policies to evaluate to true
   186  func NOutOf(n int32, policies []*cb.SignaturePolicy) *cb.SignaturePolicy {
   187  	return &cb.SignaturePolicy{
   188  		Type: &cb.SignaturePolicy_NOutOf_{
   189  			NOutOf: &cb.SignaturePolicy_NOutOf{
   190  				N:     n,
   191  				Rules: policies,
   192  			},
   193  		},
   194  	}
   195  }
   196  
   197  // protoMarshalOrPanic serializes a protobuf message and panics if this
   198  // operation fails
   199  func protoMarshalOrPanic(pb proto.Message) []byte {
   200  	data, err := proto.Marshal(pb)
   201  	if err != nil {
   202  		panic(err)
   203  	}
   204  
   205  	return data
   206  }