github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/policies/inquire/inquire.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package inquire 8 9 import ( 10 "fmt" 11 12 "github.com/hyperledger/fabric-protos-go/common" 13 "github.com/hyperledger/fabric/common/flogging" 14 "github.com/hyperledger/fabric/common/graph" 15 "github.com/hyperledger/fabric/common/policies" 16 ) 17 18 var logger = flogging.MustGetLogger("policies.inquire") 19 20 const ( 21 combinationsUpperBound = 10000 22 ) 23 24 type inquireableSignaturePolicy struct { 25 sigPol *common.SignaturePolicyEnvelope 26 } 27 28 // NewInquireableSignaturePolicy creates a signature policy that can be inquired, 29 // from a policy and a signature policy. 30 func NewInquireableSignaturePolicy(sigPol *common.SignaturePolicyEnvelope) policies.InquireablePolicy { 31 return &inquireableSignaturePolicy{ 32 sigPol: sigPol, 33 } 34 } 35 36 // SatisfiedBy returns a slice of PrincipalSets that each of them 37 // satisfies the policy. 38 func (isp *inquireableSignaturePolicy) SatisfiedBy() []policies.PrincipalSet { 39 rootId := fmt.Sprintf("%d", 0) 40 root := graph.NewTreeVertex(rootId, isp.sigPol.Rule) 41 computePolicyTree(root) 42 var res []policies.PrincipalSet 43 for _, perm := range root.ToTree().Permute(combinationsUpperBound) { 44 principalSet := principalsOfTree(perm, isp.sigPol.Identities) 45 if len(principalSet) == 0 { 46 return nil 47 } 48 res = append(res, principalSet) 49 } 50 return res 51 } 52 53 func principalsOfTree(tree *graph.Tree, principals policies.PrincipalSet) policies.PrincipalSet { 54 var principalSet policies.PrincipalSet 55 i := tree.BFS() 56 for { 57 v := i.Next() 58 if v == nil { 59 break 60 } 61 if !v.IsLeaf() { 62 continue 63 } 64 pol := v.Data.(*common.SignaturePolicy) 65 switch principalIndex := pol.Type.(type) { 66 case *common.SignaturePolicy_SignedBy: 67 if len(principals) <= int(principalIndex.SignedBy) { 68 logger.Warning("Failed computing principalsOfTree, index out of bounds") 69 return nil 70 } 71 principal := principals[principalIndex.SignedBy] 72 principalSet = append(principalSet, principal) 73 default: 74 // Leaf vertex is not of type SignedBy 75 logger.Warning("Leaf vertex", v.Id, "is of type", pol.GetType()) 76 return nil 77 } 78 } 79 return principalSet 80 } 81 82 func computePolicyTree(v *graph.TreeVertex) { 83 sigPol := v.Data.(*common.SignaturePolicy) 84 if p := sigPol.GetNOutOf(); p != nil { 85 v.Threshold = int(p.N) 86 for i, rule := range p.Rules { 87 id := fmt.Sprintf("%s.%d", v.Id, i) 88 u := v.AddDescendant(graph.NewTreeVertex(id, rule)) 89 computePolicyTree(u) 90 } 91 } 92 }