github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/policies/implicitmeta.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package policies 8 9 import ( 10 "bytes" 11 "fmt" 12 13 "github.com/golang/protobuf/proto" 14 cb "github.com/hyperledger/fabric-protos-go/common" 15 "github.com/hyperledger/fabric/msp" 16 "github.com/hyperledger/fabric/protoutil" 17 "go.uber.org/zap/zapcore" 18 ) 19 20 type ImplicitMetaPolicy struct { 21 Threshold int 22 SubPolicies []Policy 23 24 // Only used for logging 25 managers map[string]*ManagerImpl 26 SubPolicyName string 27 } 28 29 // NewPolicy creates a new policy based on the policy bytes 30 func NewImplicitMetaPolicy(data []byte, managers map[string]*ManagerImpl) (*ImplicitMetaPolicy, error) { 31 definition := &cb.ImplicitMetaPolicy{} 32 if err := proto.Unmarshal(data, definition); err != nil { 33 return nil, fmt.Errorf("Error unmarshaling to ImplicitMetaPolicy: %s", err) 34 } 35 36 subPolicies := make([]Policy, len(managers)) 37 38 i := 0 39 for _, manager := range managers { 40 subPolicies[i], _ = manager.GetPolicy(definition.SubPolicy) 41 i++ 42 } 43 44 var threshold int 45 46 switch definition.Rule { 47 case cb.ImplicitMetaPolicy_ANY: 48 threshold = 1 49 case cb.ImplicitMetaPolicy_ALL: 50 threshold = len(subPolicies) 51 case cb.ImplicitMetaPolicy_MAJORITY: 52 threshold = len(subPolicies)/2 + 1 53 } 54 55 // In the special case that there are no policies, consider 0 to be a majority or any 56 if len(subPolicies) == 0 { 57 threshold = 0 58 } 59 60 return &ImplicitMetaPolicy{ 61 SubPolicies: subPolicies, 62 Threshold: threshold, 63 managers: managers, 64 SubPolicyName: definition.SubPolicy, 65 }, nil 66 } 67 68 // EvaluateSignedData takes a set of SignedData and evaluates whether this set of signatures satisfies the policy 69 func (imp *ImplicitMetaPolicy) EvaluateSignedData(signatureSet []*protoutil.SignedData) error { 70 logger.Debugf("This is an implicit meta policy, it will trigger other policy evaluations, whose failures may be benign") 71 remaining := imp.Threshold 72 73 defer func() { 74 if remaining != 0 { 75 // This log message may be large and expensive to construct, so worth checking the log level 76 if logger.IsEnabledFor(zapcore.DebugLevel) { 77 var b bytes.Buffer 78 b.WriteString(fmt.Sprintf("Evaluation Failed: Only %d policies were satisfied, but needed %d of [ ", imp.Threshold-remaining, imp.Threshold)) 79 for m := range imp.managers { 80 b.WriteString(m) 81 b.WriteString("/") 82 b.WriteString(imp.SubPolicyName) 83 b.WriteString(" ") 84 } 85 b.WriteString("]") 86 logger.Debugf(b.String()) 87 } 88 } 89 }() 90 91 for _, policy := range imp.SubPolicies { 92 if policy.EvaluateSignedData(signatureSet) == nil { 93 remaining-- 94 if remaining == 0 { 95 return nil 96 } 97 } 98 } 99 if remaining == 0 { 100 return nil 101 } 102 return fmt.Errorf("implicit policy evaluation failed - %d sub-policies were satisfied, but this policy requires %d of the '%s' sub-policies to be satisfied", (imp.Threshold - remaining), imp.Threshold, imp.SubPolicyName) 103 } 104 105 // EvaluateIdentities takes an array of identities and evaluates whether 106 // they satisfy the policy 107 func (imp *ImplicitMetaPolicy) EvaluateIdentities(identities []msp.Identity) error { 108 logger.Debugf("This is an implicit meta policy, it will trigger other policy evaluations, whose failures may be benign") 109 remaining := imp.Threshold 110 111 defer func() { 112 // This log message may be large and expensive to construct, so worth checking the log level 113 if remaining == 0 { 114 return 115 } 116 if !logger.IsEnabledFor(zapcore.DebugLevel) { 117 return 118 } 119 120 var b bytes.Buffer 121 b.WriteString(fmt.Sprintf("Evaluation Failed: Only %d policies were satisfied, but needed %d of [ ", imp.Threshold-remaining, imp.Threshold)) 122 for m := range imp.managers { 123 b.WriteString(m) 124 b.WriteString("/") 125 b.WriteString(imp.SubPolicyName) 126 b.WriteString(" ") 127 } 128 b.WriteString("]") 129 logger.Debugf(b.String()) 130 }() 131 132 for _, policy := range imp.SubPolicies { 133 if policy.EvaluateIdentities(identities) == nil { 134 remaining-- 135 if remaining == 0 { 136 return nil 137 } 138 } 139 } 140 if remaining == 0 { 141 return nil 142 } 143 return fmt.Errorf("implicit policy evaluation failed - %d sub-policies were satisfied, but this policy requires %d of the '%s' sub-policies to be satisfied", (imp.Threshold - remaining), imp.Threshold, imp.SubPolicyName) 144 }