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  }