github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/common/policydsl/policyparsernode.go (about)

     1  package policydsl
     2  
     3  import (
     4  	"bytes"
     5  	"github.com/golang/protobuf/proto"
     6  	cb "github.com/hyperledger/fabric-protos-go/common"
     7  	mb "github.com/hyperledger/fabric-protos-go/msp"
     8  	"github.com/pkg/errors"
     9  	"github.com/spf13/viper"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  func parseIdentitiesForNode(identities []interface{}) ([]*mb.MSPPrincipal, error) {
    15  	mspPrincipals := make([]*mb.MSPPrincipal, len(identities))
    16  	for i, v := range identities {
    17  		if mspPrincipals[i] != nil {
    18  			return nil, errors.Errorf("In identities with key %v is listed more than once", i)
    19  		}
    20  
    21  		vMap, ok := v.(map[interface{}]interface{})
    22  		if !ok {
    23  			return nil, errors.Errorf("In identities with key %v value expected map got %v", i, v)
    24  		}
    25  
    26  		roleObj := vMap[Role]
    27  		if roleObj == nil {
    28  			return nil, errors.Errorf("In identities with key %v value must be not nil for role", i)
    29  		}
    30  		roleMap, ok := roleObj.(map[interface{}]interface{})
    31  		if !ok {
    32  			return nil, errors.Errorf("In identities with key %v value expected map for role got %v", i, roleObj)
    33  		}
    34  
    35  		nameObj := roleMap[Name]
    36  		if nameObj == nil {
    37  			return nil, errors.Errorf("In identities with key %v name must be not nil in role", i)
    38  		}
    39  		name, ok := nameObj.(string)
    40  		if !ok {
    41  			return nil, errors.Errorf("In identities with key %v name expected string in role got %v", i, nameObj)
    42  		}
    43  		name = strings.TrimSpace(name)
    44  
    45  		mspIdObj := roleMap[MspID2]
    46  		if mspIdObj == nil {
    47  			return nil, errors.Errorf("In identities with key %v mspId must be not nil in role", i)
    48  		}
    49  		mspId, ok := mspIdObj.(string)
    50  		if !ok {
    51  			return nil, errors.Errorf("In identities with key %v mspId expected string in role got %v", i, mspIdObj)
    52  		}
    53  
    54  		if mspId == "" {
    55  			return nil, errors.Errorf("In identities with key %v mspId must be not empty in role", i)
    56  		}
    57  		var r mb.MSPRole_MSPRoleType
    58  		switch name {
    59  		case RoleClient:
    60  			r = mb.MSPRole_CLIENT
    61  		case RoleMember:
    62  			r = mb.MSPRole_MEMBER
    63  		case RoleAdmin:
    64  			r = mb.MSPRole_ADMIN
    65  		case RolePeer:
    66  			r = mb.MSPRole_PEER
    67  		case RoleOrderer:
    68  			r = mb.MSPRole_ORDERER
    69  		}
    70  
    71  		/* build the principal we've been told */
    72  		mspRole, err := proto.Marshal(&mb.MSPRole{MspIdentifier: mspId, Role: r})
    73  		if err != nil {
    74  			return nil, errors.Errorf("error marshalling msp role: %s", err)
    75  		}
    76  
    77  		mspPrincipals[i] = &mb.MSPPrincipal{
    78  			PrincipalClassification: mb.MSPPrincipal_ROLE,
    79  			Principal:               mspRole,
    80  		}
    81  	}
    82  
    83  	if len(mspPrincipals) == 0 {
    84  		return nil, errors.New("No identities were found in the policy specification")
    85  	}
    86  	return mspPrincipals, nil
    87  }
    88  
    89  func parsePolicyForNode(identitiesMap []*mb.MSPPrincipal, policy map[string]interface{}) (*cb.SignaturePolicy, error) {
    90  	if policy == nil {
    91  		return nil, errors.New("No policy section was found in the document")
    92  	}
    93  	for k, v := range policy {
    94  		if k == SBy {
    95  			vo, ok := v.(int)
    96  			if !ok {
    97  				return nil, errors.New("signed-by expecting a int value")
    98  			}
    99  			if vo >= len(identitiesMap) {
   100  				return nil, errors.Errorf("No Identities found by index %v in signed-by.", vo)
   101  			}
   102  			mspInfos := identitiesMap[vo]
   103  			if mspInfos == nil {
   104  				return nil, errors.Errorf("No Identities found by index %v in signed-by.", vo)
   105  			}
   106  			return SignedBy(int32(vo)), nil
   107  		} else {
   108  			if noofPattern.MatchString(k) {
   109  				subm := noofPattern.FindStringSubmatch(k)
   110  				if len(subm) == 2 {
   111  					matchNo, err := strconv.Atoi(subm[1])
   112  					if err != nil {
   113  						return nil, err
   114  					}
   115  					vStringLists, ok := v.([]interface{})
   116  					if !ok {
   117  						return nil, errors.Errorf("%v expected to have array but found %v", k, v)
   118  					}
   119  					strLen := len(vStringLists)
   120  					if strLen < matchNo {
   121  						return nil, errors.Errorf("%v expected to have at least %v items to match but only found %v", k, matchNo, strLen)
   122  					}
   123  					sps := make([]*cb.SignaturePolicy, strLen)
   124  					for i, vStringList := range vStringLists {
   125  						nlo, ok := vStringList.(map[interface{}]interface{})
   126  						if !ok {
   127  							return nil, errors.Errorf("expect map[interface]interface got %v", vStringList)
   128  						}
   129  						toMapString, err := mapInterfaceToMapString(nlo)
   130  						if err != nil {
   131  							return nil, err
   132  						}
   133  						signaturePolicy, err := parsePolicyForNode(identitiesMap, toMapString)
   134  						if err != nil {
   135  							return nil, err
   136  						}
   137  						sps[i] = signaturePolicy
   138  					}
   139  					return NOutOf(int32(matchNo), sps), nil
   140  				}
   141  			} else {
   142  				return nil, errors.Errorf("Unsupported policy type %v", k)
   143  			}
   144  		}
   145  	}
   146  	return nil, errors.New("No values found for policy")
   147  }
   148  
   149  func PolicyParseNode(yamlString string) (*cb.SignaturePolicyEnvelope, error) {
   150  	newViper := viper.New()
   151  	newViper.SetConfigType("yaml")
   152  	blockReader := bytes.NewBufferString(yamlString)
   153  	defer blockReader.Reset()
   154  	err := newViper.ReadConfig(blockReader)
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  	identitiesValue := newViper.Get("identities")
   159  	if identitiesValue == nil {
   160  		return nil, errors.New("no find identities")
   161  	}
   162  	identities, ok := identitiesValue.([]interface{})
   163  	if !ok {
   164  		return nil, errors.New("find identities but identities is not []interface{}")
   165  	}
   166  	mspPrincipals, err := parseIdentitiesForNode(identities)
   167  	if err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	rule, err := parsePolicyForNode(mspPrincipals, newViper.GetStringMap("policy"))
   172  	if err != nil {
   173  		return nil, err
   174  	}
   175  
   176  	p := &cb.SignaturePolicyEnvelope{
   177  		Identities: mspPrincipals,
   178  		Version:    0,
   179  		Rule:       rule,
   180  	}
   181  
   182  	return p, nil
   183  
   184  }