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 }