github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-config/configtx/policies.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package configtx 8 9 import ( 10 "errors" 11 "fmt" 12 "github.com/hellobchain/third_party/hyperledger/fabric-config/configtx/internal/policydsl" 13 "strconv" 14 "strings" 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 // getPolicies returns a map of Policy from given map of ConfigPolicy in organization config group. 22 func getPolicies(policies map[string]*cb.ConfigPolicy) (map[string]Policy, error) { 23 p := map[string]Policy{} 24 25 for name, policy := range policies { 26 switch cb.Policy_PolicyType(policy.Policy.Type) { 27 case cb.Policy_IMPLICIT_META: 28 imp := &cb.ImplicitMetaPolicy{} 29 err := proto.Unmarshal(policy.Policy.Value, imp) 30 if err != nil { 31 return nil, err 32 } 33 34 rule, err := implicitMetaToString(imp) 35 if err != nil { 36 return nil, err 37 } 38 39 p[name] = Policy{ 40 Type: ImplicitMetaPolicyType, 41 Rule: rule, 42 ModPolicy: policy.GetModPolicy(), 43 } 44 case cb.Policy_SIGNATURE: 45 sp := &cb.SignaturePolicyEnvelope{} 46 err := proto.Unmarshal(policy.Policy.Value, sp) 47 if err != nil { 48 return nil, err 49 } 50 51 rule, err := signatureMetaToString(sp) 52 if err != nil { 53 return nil, err 54 } 55 56 p[name] = Policy{ 57 Type: SignaturePolicyType, 58 Rule: rule, 59 ModPolicy: policy.GetModPolicy(), 60 } 61 default: 62 return nil, fmt.Errorf("unknown policy type: %v", policy.Policy.Type) 63 } 64 } 65 66 return p, nil 67 } 68 69 // implicitMetaToString converts a *cb.ImplicitMetaPolicy to a string representation. 70 func implicitMetaToString(imp *cb.ImplicitMetaPolicy) (string, error) { 71 var args string 72 73 switch imp.Rule { 74 case cb.ImplicitMetaPolicy_ANY: 75 args += cb.ImplicitMetaPolicy_ANY.String() 76 case cb.ImplicitMetaPolicy_ALL: 77 args += cb.ImplicitMetaPolicy_ALL.String() 78 case cb.ImplicitMetaPolicy_MAJORITY: 79 args += cb.ImplicitMetaPolicy_MAJORITY.String() 80 default: 81 return "", fmt.Errorf("unknown implicit meta policy rule type %v", imp.Rule) 82 } 83 84 args = args + " " + imp.SubPolicy 85 86 return args, nil 87 } 88 89 // signatureMetaToString converts a *cb.SignaturePolicyEnvelope to a string representation. 90 func signatureMetaToString(sig *cb.SignaturePolicyEnvelope) (string, error) { 91 var roles []string 92 93 for _, id := range sig.Identities { 94 role, err := mspPrincipalToString(id) 95 if err != nil { 96 return "", err 97 } 98 99 roles = append(roles, role) 100 } 101 102 return signaturePolicyToString(sig.Rule, roles) 103 } 104 105 // mspPrincipalToString converts a *mb.MSPPrincipal to a string representation. 106 func mspPrincipalToString(principal *mb.MSPPrincipal) (string, error) { 107 switch principal.PrincipalClassification { 108 case mb.MSPPrincipal_ROLE: 109 var res strings.Builder 110 111 role := &mb.MSPRole{} 112 113 err := proto.Unmarshal(principal.Principal, role) 114 if err != nil { 115 return "", err 116 } 117 118 res.WriteString("'") 119 res.WriteString(role.MspIdentifier) 120 res.WriteString(".") 121 res.WriteString(strings.ToLower(role.Role.String())) 122 res.WriteString("'") 123 124 return res.String(), nil 125 // TODO: currently fabric only support string to principle convertion for 126 // type ROLE. Implement MSPPrinciple to String for types ORGANIZATION_UNIT, 127 // IDENTITY, ANONYMITY, and GOMBINED once we have support from fabric. 128 case mb.MSPPrincipal_ORGANIZATION_UNIT: 129 return "", nil 130 case mb.MSPPrincipal_IDENTITY: 131 return "", nil 132 case mb.MSPPrincipal_ANONYMITY: 133 return "", nil 134 case mb.MSPPrincipal_COMBINED: 135 return "", nil 136 default: 137 return "", fmt.Errorf("unknown MSP principal classiciation %v", principal.PrincipalClassification) 138 } 139 } 140 141 // signaturePolicyToString recursively converts a *cb.SignaturePolicy to a 142 // string representation. 143 func signaturePolicyToString(sig *cb.SignaturePolicy, IDs []string) (string, error) { 144 switch sig.Type.(type) { 145 case *cb.SignaturePolicy_NOutOf_: 146 nOutOf := sig.GetNOutOf() 147 148 var policies []string 149 150 var res strings.Builder 151 152 // get gate values 153 gate := policydsl.GateOutOf 154 if nOutOf.N == 1 { 155 gate = policydsl.GateOr 156 } 157 158 if nOutOf.N == int32(len(nOutOf.Rules)) { 159 gate = policydsl.GateAnd 160 } 161 162 if gate == policydsl.GateOutOf { 163 policies = append(policies, strconv.Itoa(int(nOutOf.N))) 164 } 165 166 // get subpolicies recursively 167 for _, rule := range nOutOf.Rules { 168 subPolicy, err := signaturePolicyToString(rule, IDs) 169 if err != nil { 170 return "", err 171 } 172 173 policies = append(policies, subPolicy) 174 } 175 176 res.WriteString(strings.ToUpper(gate)) 177 res.WriteString("(") 178 res.WriteString(strings.Join(policies, ", ")) 179 res.WriteString(")") 180 181 return res.String(), nil 182 case *cb.SignaturePolicy_SignedBy: 183 return IDs[sig.GetSignedBy()], nil 184 default: 185 return "", fmt.Errorf("unknown signature policy type %v", sig.Type) 186 } 187 } 188 189 func setPolicies(cg *cb.ConfigGroup, policyMap map[string]Policy) error { 190 if policyMap == nil { 191 return errors.New("no policies defined") 192 } 193 194 if _, ok := policyMap[AdminsPolicyKey]; !ok { 195 return errors.New("no Admins policy defined") 196 } 197 198 if _, ok := policyMap[ReadersPolicyKey]; !ok { 199 return errors.New("no Readers policy defined") 200 } 201 202 if _, ok := policyMap[WritersPolicyKey]; !ok { 203 return errors.New("no Writers policy defined") 204 } 205 206 cg.Policies = make(map[string]*cb.ConfigPolicy) 207 for policyName, policy := range policyMap { 208 err := setPolicy(cg, policyName, policy) 209 if err != nil { 210 return err 211 } 212 } 213 214 return nil 215 } 216 217 func setPolicy(cg *cb.ConfigGroup, policyName string, policy Policy) error { 218 if cg.Policies == nil { 219 cg.Policies = make(map[string]*cb.ConfigPolicy) 220 } 221 222 switch policy.Type { 223 case ImplicitMetaPolicyType: 224 imp, err := implicitMetaFromString(policy.Rule) 225 if err != nil { 226 return fmt.Errorf("invalid implicit meta policy rule: '%s': %v", policy.Rule, err) 227 } 228 229 implicitMetaPolicy, err := proto.Marshal(imp) 230 if err != nil { 231 return fmt.Errorf("marshaling implicit meta policy: %v", err) 232 } 233 234 if policy.ModPolicy == "" { 235 policy.ModPolicy = AdminsPolicyKey 236 } 237 238 cg.Policies[policyName] = &cb.ConfigPolicy{ 239 ModPolicy: policy.ModPolicy, 240 Policy: &cb.Policy{ 241 Type: int32(cb.Policy_IMPLICIT_META), 242 Value: implicitMetaPolicy, 243 }, 244 } 245 case SignaturePolicyType: 246 sp, err := policydsl.FromString(policy.Rule) 247 if err != nil { 248 return fmt.Errorf("invalid signature policy rule: '%s': %v", policy.Rule, err) 249 } 250 251 signaturePolicy, err := proto.Marshal(sp) 252 if err != nil { 253 return fmt.Errorf("marshaling signature policy: %v", err) 254 } 255 256 if policy.ModPolicy == "" { 257 policy.ModPolicy = AdminsPolicyKey 258 } 259 260 cg.Policies[policyName] = &cb.ConfigPolicy{ 261 ModPolicy: policy.ModPolicy, 262 Policy: &cb.Policy{ 263 Type: int32(cb.Policy_SIGNATURE), 264 Value: signaturePolicy, 265 }, 266 } 267 default: 268 return fmt.Errorf("unknown policy type: %s", policy.Type) 269 } 270 271 return nil 272 } 273 274 // removePolicy removes an existing policy from an group key organization. 275 func removePolicy(configGroup *cb.ConfigGroup, policyName string, policies map[string]Policy) { 276 delete(configGroup.Policies, policyName) 277 }