github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/policydsl/policydsl_builder.go (about) 1 /* 2 Copyright hechain. 2022 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 87 // create the policy: it requires exactly 1 signature from the first (and only) principal 88 p := &cb.SignaturePolicyEnvelope{ 89 Version: 0, 90 Rule: NOutOf(1, []*cb.SignaturePolicy{SignedBy(0)}), 91 Identities: []*mb.MSPPrincipal{principal}, 92 } 93 94 return p 95 } 96 97 // SignedByMspAdmin creates a SignaturePolicyEnvelope 98 // requiring 1 signature from any admin of the specified MSP 99 func SignedByMspAdmin(mspId string) *cb.SignaturePolicyEnvelope { 100 // specify the principal: it's a member of the msp we just found 101 principal := &mb.MSPPrincipal{ 102 PrincipalClassification: mb.MSPPrincipal_ROLE, 103 Principal: protoMarshalOrPanic(&mb.MSPRole{Role: mb.MSPRole_ADMIN, MspIdentifier: mspId}), 104 } 105 106 // create the policy: it requires exactly 1 signature from the first (and only) principal 107 p := &cb.SignaturePolicyEnvelope{ 108 Version: 0, 109 Rule: NOutOf(1, []*cb.SignaturePolicy{SignedBy(0)}), 110 Identities: []*mb.MSPPrincipal{principal}, 111 } 112 113 return p 114 } 115 116 // wrapper for generating "any of a given role" type policies 117 func signedByAnyOfGivenRole(role mb.MSPRole_MSPRoleType, ids []string) *cb.SignaturePolicyEnvelope { 118 return SignedByNOutOfGivenRole(1, role, ids) 119 } 120 121 func SignedByNOutOfGivenRole(n int32, role mb.MSPRole_MSPRoleType, ids []string) *cb.SignaturePolicyEnvelope { 122 // we create an array of principals, one principal 123 // per application MSP defined on this chain 124 sort.Strings(ids) 125 principals := make([]*mb.MSPPrincipal, len(ids)) 126 sigspolicy := make([]*cb.SignaturePolicy, len(ids)) 127 128 for i, id := range ids { 129 principals[i] = &mb.MSPPrincipal{ 130 PrincipalClassification: mb.MSPPrincipal_ROLE, 131 Principal: protoMarshalOrPanic(&mb.MSPRole{Role: role, MspIdentifier: id}), 132 } 133 sigspolicy[i] = SignedBy(int32(i)) 134 } 135 136 // create the policy: it requires exactly 1 signature from any of the principals 137 p := &cb.SignaturePolicyEnvelope{ 138 Version: 0, 139 Rule: NOutOf(n, sigspolicy), 140 Identities: principals, 141 } 142 143 return p 144 } 145 146 // SignedByAnyMember returns a policy that requires one valid 147 // signature from a member of any of the orgs whose ids are 148 // listed in the supplied string array 149 func SignedByAnyMember(ids []string) *cb.SignaturePolicyEnvelope { 150 return signedByAnyOfGivenRole(mb.MSPRole_MEMBER, ids) 151 } 152 153 // SignedByAnyClient returns a policy that requires one valid 154 // signature from a client of any of the orgs whose ids are 155 // listed in the supplied string array 156 func SignedByAnyClient(ids []string) *cb.SignaturePolicyEnvelope { 157 return signedByAnyOfGivenRole(mb.MSPRole_CLIENT, ids) 158 } 159 160 // SignedByAnyPeer returns a policy that requires one valid 161 // signature from an orderer of any of the orgs whose ids are 162 // listed in the supplied string array 163 func SignedByAnyPeer(ids []string) *cb.SignaturePolicyEnvelope { 164 return signedByAnyOfGivenRole(mb.MSPRole_PEER, ids) 165 } 166 167 // SignedByAnyAdmin returns a policy that requires one valid 168 // signature from a admin of any of the orgs whose ids are 169 // listed in the supplied string array 170 func SignedByAnyAdmin(ids []string) *cb.SignaturePolicyEnvelope { 171 return signedByAnyOfGivenRole(mb.MSPRole_ADMIN, ids) 172 } 173 174 // And is a convenience method which utilizes NOutOf to produce And equivalent behavior 175 func And(lhs, rhs *cb.SignaturePolicy) *cb.SignaturePolicy { 176 return NOutOf(2, []*cb.SignaturePolicy{lhs, rhs}) 177 } 178 179 // Or is a convenience method which utilizes NOutOf to produce Or equivalent behavior 180 func Or(lhs, rhs *cb.SignaturePolicy) *cb.SignaturePolicy { 181 return NOutOf(1, []*cb.SignaturePolicy{lhs, rhs}) 182 } 183 184 // NOutOf creates a policy which requires N out of the slice of policies to evaluate to true 185 func NOutOf(n int32, policies []*cb.SignaturePolicy) *cb.SignaturePolicy { 186 return &cb.SignaturePolicy{ 187 Type: &cb.SignaturePolicy_NOutOf_{ 188 NOutOf: &cb.SignaturePolicy_NOutOf{ 189 N: n, 190 Rules: policies, 191 }, 192 }, 193 } 194 } 195 196 // protoMarshalOrPanic serializes a protobuf message and panics if this 197 // operation fails 198 func protoMarshalOrPanic(pb proto.Message) []byte { 199 data, err := proto.Marshal(pb) 200 if err != nil { 201 panic(err) 202 } 203 204 return data 205 }