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