github.com/true-sqn/fabric@v2.1.1+incompatible/core/policy/application.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package policy 8 9 import ( 10 "github.com/golang/protobuf/proto" 11 "github.com/hyperledger/fabric-protos-go/common" 12 "github.com/hyperledger/fabric-protos-go/peer" 13 "github.com/hyperledger/fabric/common/cauthdsl" 14 "github.com/hyperledger/fabric/common/policies" 15 "github.com/hyperledger/fabric/msp" 16 "github.com/hyperledger/fabric/protoutil" 17 "github.com/pkg/errors" 18 ) 19 20 //go:generate mockery -dir . -name Policy -case underscore -output mocks/ 21 22 // Policy is the local interface that used to generate mocks for foreign interface. 23 type Policy interface { 24 policies.Policy 25 } 26 27 //go:generate mockery -dir . -name ChannelPolicyManagerGetter -case underscore -output mocks/ 28 29 // ChannelPolicyManagerGetter is the local interface that used to generate mocks for foreign interface. 30 type ChannelPolicyManagerGetter interface { 31 policies.ChannelPolicyManagerGetter 32 } 33 34 //go:generate mockery -dir . -name PolicyManager -case underscore -output mocks/ 35 36 // PolicyManager is the local interface that used to generate mocks for foreign interface. 37 type PolicyManager interface { 38 policies.Manager 39 } 40 41 //go:generate mockery -dir . -name IdentityDeserializer -case underscore -output mocks/ 42 43 // IdentityDeserializer is the local interface that used to generate mocks for foreign interface. 44 type IdentityDeserializer interface { 45 msp.IdentityDeserializer 46 } 47 48 //go:generate mockery -dir . -name Identity -case underscore -output mocks/ 49 50 // Identity is the local interface that used to generate mocks for foreign interface. 51 type Identity interface { 52 msp.Identity 53 } 54 55 //go:generate mockery -dir . -name ChannelPolicyReferenceProvider -case underscore -output mocks/ 56 //go:generate mockery -dir . -name SignaturePolicyProvider -case underscore -output mocks/ 57 58 // SignaturePolicyProvider provides the backing implementation of a policy. 59 type SignaturePolicyProvider interface { 60 // NewPolicy creates a new policy based on the policy bytes. 61 NewPolicy(signaturePolicy *common.SignaturePolicyEnvelope) (policies.Policy, error) 62 } 63 64 // ChannelPolicyReferenceProvider is used to determine if a set of signature is valid and complies with a policy. 65 type ChannelPolicyReferenceProvider interface { 66 // NewPolicy creates a new policy based on the policy bytes. 67 NewPolicy(channelConfigPolicyReference string) (policies.Policy, error) 68 } 69 70 type ApplicationPolicyEvaluator struct { 71 signaturePolicyProvider SignaturePolicyProvider 72 channelPolicyReferenceProvider ChannelPolicyReferenceProvider 73 } 74 75 // Manager defines functions to interface with the policy manager of a channel 76 type Manager interface { 77 // GetPolicy returns a policy and true if it was the policy requested, or false if it is the default policy 78 GetPolicy(id string) (policies.Policy, bool) 79 } 80 81 type ChannelPolicyReferenceProviderImpl struct { 82 Manager 83 } 84 85 func (c *ChannelPolicyReferenceProviderImpl) NewPolicy(channelConfigPolicyReference string) (policies.Policy, error) { 86 p, ok := c.GetPolicy(channelConfigPolicyReference) 87 if !ok { 88 return nil, errors.Errorf("failed to retrieve policy for reference %s", channelConfigPolicyReference) 89 } 90 91 return p, nil 92 } 93 94 // dynamicPolicyManager implements a policy manager that 95 // always acts on the latest config for this channel 96 type dynamicPolicyManager struct { 97 channelPolicyManagerGetter policies.ChannelPolicyManagerGetter 98 channelID string 99 } 100 101 func (d *dynamicPolicyManager) GetPolicy(id string) (policies.Policy, bool) { 102 mgr := d.channelPolicyManagerGetter.Manager(d.channelID) 103 if mgr == nil { 104 // this will never happen - if we are here we 105 // managed to retrieve the policy manager for 106 // this channel once, and so by the way the 107 // channel config is managed, we cannot fail. 108 panic("programming error") 109 } 110 111 return mgr.GetPolicy(id) 112 } 113 114 // New returns an evaluator for application policies 115 func New(deserializer msp.IdentityDeserializer, channel string, channelPolicyManagerGetter policies.ChannelPolicyManagerGetter) (*ApplicationPolicyEvaluator, error) { 116 mgr := channelPolicyManagerGetter.Manager(channel) 117 if mgr == nil { 118 return nil, errors.Errorf("failed to retrieve policy manager for channel %s", channel) 119 } 120 121 return &ApplicationPolicyEvaluator{ 122 signaturePolicyProvider: &cauthdsl.EnvelopeBasedPolicyProvider{Deserializer: deserializer}, 123 channelPolicyReferenceProvider: &ChannelPolicyReferenceProviderImpl{Manager: &dynamicPolicyManager{ 124 channelID: channel, 125 channelPolicyManagerGetter: channelPolicyManagerGetter, 126 }}, 127 }, nil 128 } 129 130 func (a *ApplicationPolicyEvaluator) evaluateSignaturePolicy(signaturePolicy *common.SignaturePolicyEnvelope, signatureSet []*protoutil.SignedData) error { 131 p, err := a.signaturePolicyProvider.NewPolicy(signaturePolicy) 132 if err != nil { 133 return errors.WithMessage(err, "could not create evaluator for signature policy") 134 } 135 136 return p.EvaluateSignedData(signatureSet) 137 } 138 139 func (a *ApplicationPolicyEvaluator) evaluateChannelConfigPolicyReference(channelConfigPolicyReference string, signatureSet []*protoutil.SignedData) error { 140 p, err := a.channelPolicyReferenceProvider.NewPolicy(channelConfigPolicyReference) 141 if err != nil { 142 return errors.WithMessage(err, "could not create evaluator for channel reference policy") 143 } 144 145 return p.EvaluateSignedData(signatureSet) 146 } 147 148 func (a *ApplicationPolicyEvaluator) Evaluate(policyBytes []byte, signatureSet []*protoutil.SignedData) error { 149 p := &peer.ApplicationPolicy{} 150 err := proto.Unmarshal(policyBytes, p) 151 if err != nil { 152 return errors.Wrap(err, "failed to unmarshal ApplicationPolicy bytes") 153 } 154 155 switch policy := p.Type.(type) { 156 case *peer.ApplicationPolicy_SignaturePolicy: 157 return a.evaluateSignaturePolicy(policy.SignaturePolicy, signatureSet) 158 case *peer.ApplicationPolicy_ChannelConfigPolicyReference: 159 return a.evaluateChannelConfigPolicyReference(policy.ChannelConfigPolicyReference, signatureSet) 160 default: 161 return errors.Errorf("unsupported policy type %T", policy) 162 } 163 }