github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/common/cauthdsl/cauthdsl_builder.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cauthdsl
    18  
    19  import (
    20  	cb "github.com/hyperledger/fabric/protos/common"
    21  	"github.com/hyperledger/fabric/protos/msp"
    22  
    23  	"sort"
    24  
    25  	"github.com/golang/protobuf/proto"
    26  	"github.com/hyperledger/fabric/protos/utils"
    27  )
    28  
    29  // AcceptAllPolicy always evaluates to true
    30  var AcceptAllPolicy *cb.SignaturePolicyEnvelope
    31  
    32  // MarshaledAcceptAllPolicy is the Marshaled version of AcceptAllPolicy
    33  var MarshaledAcceptAllPolicy []byte
    34  
    35  // RejectAllPolicy always evaluates to false
    36  var RejectAllPolicy *cb.SignaturePolicyEnvelope
    37  
    38  // MarshaledRejectAllPolicy is the Marshaled version of RejectAllPolicy
    39  var MarshaledRejectAllPolicy []byte
    40  
    41  func init() {
    42  	var err error
    43  
    44  	AcceptAllPolicy = Envelope(NOutOf(0, []*cb.SignaturePolicy{}), [][]byte{})
    45  	MarshaledAcceptAllPolicy, err = proto.Marshal(AcceptAllPolicy)
    46  	if err != nil {
    47  		panic("Error marshaling trueEnvelope")
    48  	}
    49  
    50  	RejectAllPolicy = Envelope(NOutOf(1, []*cb.SignaturePolicy{}), [][]byte{})
    51  	MarshaledRejectAllPolicy, err = proto.Marshal(RejectAllPolicy)
    52  	if err != nil {
    53  		panic("Error marshaling falseEnvelope")
    54  	}
    55  }
    56  
    57  // Envelope builds an envelope message embedding a SignaturePolicy
    58  func Envelope(policy *cb.SignaturePolicy, identities [][]byte) *cb.SignaturePolicyEnvelope {
    59  	ids := make([]*msp.MSPPrincipal, len(identities))
    60  	for i, _ := range ids {
    61  		ids[i] = &msp.MSPPrincipal{PrincipalClassification: msp.MSPPrincipal_IDENTITY, Principal: identities[i]}
    62  	}
    63  
    64  	return &cb.SignaturePolicyEnvelope{
    65  		Version:    0,
    66  		Policy:     policy,
    67  		Identities: ids,
    68  	}
    69  }
    70  
    71  // SignedBy creates a SignaturePolicy requiring a given signer's signature
    72  func SignedBy(index int32) *cb.SignaturePolicy {
    73  	return &cb.SignaturePolicy{
    74  		Type: &cb.SignaturePolicy_SignedBy{
    75  			SignedBy: index,
    76  		},
    77  	}
    78  }
    79  
    80  // SignedByMspMember creates a SignaturePolicyEnvelope
    81  // requiring 1 signature from any member of the specified MSP
    82  func SignedByMspMember(mspId string) *cb.SignaturePolicyEnvelope {
    83  	// specify the principal: it's a member of the msp we just found
    84  	principal := &msp.MSPPrincipal{
    85  		PrincipalClassification: msp.MSPPrincipal_ROLE,
    86  		Principal:               utils.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: mspId})}
    87  
    88  	// create the policy: it requires exactly 1 signature from the first (and only) principal
    89  	p := &cb.SignaturePolicyEnvelope{
    90  		Version:    0,
    91  		Policy:     NOutOf(1, []*cb.SignaturePolicy{SignedBy(0)}),
    92  		Identities: []*msp.MSPPrincipal{principal},
    93  	}
    94  
    95  	return p
    96  }
    97  
    98  // SignedByMspAdmin creates a SignaturePolicyEnvelope
    99  // requiring 1 signature from any admin of the specified MSP
   100  func SignedByMspAdmin(mspId string) *cb.SignaturePolicyEnvelope {
   101  	// specify the principal: it's a member of the msp we just found
   102  	principal := &msp.MSPPrincipal{
   103  		PrincipalClassification: msp.MSPPrincipal_ROLE,
   104  		Principal:               utils.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: mspId})}
   105  
   106  	// create the policy: it requires exactly 1 signature from the first (and only) principal
   107  	p := &cb.SignaturePolicyEnvelope{
   108  		Version:    0,
   109  		Policy:     NOutOf(1, []*cb.SignaturePolicy{SignedBy(0)}),
   110  		Identities: []*msp.MSPPrincipal{principal},
   111  	}
   112  
   113  	return p
   114  }
   115  
   116  // SignedByAnyMember returns a policy that requires one valid
   117  // signature from a member of any of the orgs whose ids are
   118  // listed in the supplied string array
   119  func SignedByAnyMember(ids []string) []byte {
   120  	// we create an array of principals, one principal
   121  	// per application MSP defined on this chain
   122  	sort.Strings(ids)
   123  	principals := make([]*msp.MSPPrincipal, len(ids))
   124  	sigspolicy := make([]*cb.SignaturePolicy, len(ids))
   125  	for i, id := range ids {
   126  		principals[i] = &msp.MSPPrincipal{
   127  			PrincipalClassification: msp.MSPPrincipal_ROLE,
   128  			Principal:               utils.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: id})}
   129  		sigspolicy[i] = SignedBy(int32(i))
   130  	}
   131  
   132  	// create the policy: it requires exactly 1 signature from any of the principals
   133  	p := &cb.SignaturePolicyEnvelope{
   134  		Version:    0,
   135  		Policy:     NOutOf(1, sigspolicy),
   136  		Identities: principals,
   137  	}
   138  
   139  	return utils.MarshalOrPanic(p)
   140  }
   141  
   142  // And is a convenience method which utilizes NOutOf to produce And equivalent behavior
   143  func And(lhs, rhs *cb.SignaturePolicy) *cb.SignaturePolicy {
   144  	return NOutOf(2, []*cb.SignaturePolicy{lhs, rhs})
   145  }
   146  
   147  // Or is a convenience method which utilizes NOutOf to produce Or equivalent behavior
   148  func Or(lhs, rhs *cb.SignaturePolicy) *cb.SignaturePolicy {
   149  	return NOutOf(1, []*cb.SignaturePolicy{lhs, rhs})
   150  }
   151  
   152  // NOutOf creates a policy which requires N out of the slice of policies to evaluate to true
   153  func NOutOf(n int32, policies []*cb.SignaturePolicy) *cb.SignaturePolicy {
   154  	return &cb.SignaturePolicy{
   155  		Type: &cb.SignaturePolicy_NOutOf_{
   156  			NOutOf: &cb.SignaturePolicy_NOutOf{
   157  				N:        n,
   158  				Policies: policies,
   159  			},
   160  		},
   161  	}
   162  }