github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/common/policydsl/policyparserjava.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  	"regexp"
    11  	"sort"
    12  	"strconv"
    13  	"strings"
    14  )
    15  
    16  const (
    17  	Name   = "name"
    18  	MspID  = "mspid"
    19  	MspID2 = "mspId"
    20  	Role   = "role"
    21  
    22  	SBy = "signed-by"
    23  )
    24  
    25  type mspInfo struct {
    26  	mspPrincipal *mb.MSPPrincipal
    27  	mspNum       int32
    28  }
    29  
    30  type stringArray []string
    31  
    32  func (l stringArray) Len() int {
    33  	return len(l)
    34  }
    35  
    36  func (l stringArray) Less(i, j int) bool {
    37  	switch {
    38  	case l[i] > l[j]:
    39  		return false
    40  	case l[i] < l[j]:
    41  		return true
    42  	default:
    43  		return false
    44  	}
    45  }
    46  
    47  func (l stringArray) Swap(i, j int) {
    48  	l[i], l[j] = l[j], l[i]
    49  }
    50  
    51  func sortMapKeys(sortedMap map[string]interface{}) []string {
    52  	sortKeys := make(stringArray, len(sortedMap))
    53  	var keyIndex int
    54  	for k, _ := range sortedMap {
    55  		sortKeys[keyIndex] = k
    56  		keyIndex++
    57  	}
    58  	sort.Sort(sortKeys)
    59  	return sortKeys
    60  }
    61  
    62  func sortMapArray(sortedMapArray []interface{}) ([]interface{}, error) {
    63  	sortKeys := make(stringArray, len(sortedMapArray))
    64  	newMap := make(map[string]interface{})
    65  	for i, sortedMap := range sortedMapArray {
    66  		nlo, ok := sortedMap.(map[interface{}]interface{})
    67  		if !ok {
    68  			return nil, errors.Errorf("expect map[interface]interface got %v", sortedMap)
    69  		}
    70  		toMapString, err := mapInterfaceToMapString(nlo)
    71  		if err != nil {
    72  			return nil, err
    73  		}
    74  		sortKeys[i] = toMapString[SBy].(string)
    75  		newMap[sortKeys[i]] = sortedMap
    76  	}
    77  	sort.Sort(sortKeys)
    78  	ret := make([]interface{}, sortKeys.Len())
    79  	for i, key := range sortKeys {
    80  		ret[i] = newMap[key]
    81  	}
    82  	return ret, nil
    83  }
    84  
    85  func parseIdentitiesForJava(identities map[string]interface{}) (map[string]*mspInfo, []*mb.MSPPrincipal, error) {
    86  	sortIdentitiesMapKeys := sortMapKeys(identities)
    87  	ret := make(map[string]*mspInfo)
    88  	mspPrincipals := make([]*mb.MSPPrincipal, len(identities))
    89  	for i, k := range sortIdentitiesMapKeys {
    90  		if ret[k] != nil {
    91  			return nil, nil, errors.Errorf("In identities with key %v is listed more than once", k)
    92  		}
    93  		v := identities[k]
    94  		vMap, ok := v.(map[string]interface{})
    95  		if !ok {
    96  			return nil, nil, errors.Errorf("In identities with key %v value expected map got %v", k, v)
    97  		}
    98  
    99  		roleObj := vMap[Role]
   100  		if roleObj == nil {
   101  			return nil, nil, errors.Errorf("In identities with key %v value must be not nil for role", k)
   102  		}
   103  		roleMap, ok := roleObj.(map[string]interface{})
   104  		if !ok {
   105  			return nil, nil, errors.Errorf("In identities with key %v value expected map for role got %v", k, roleObj)
   106  		}
   107  
   108  		nameObj := roleMap[Name]
   109  		if nameObj == nil {
   110  			return nil, nil, errors.Errorf("In identities with key %v name must be not nil in role", k)
   111  		}
   112  		name, ok := nameObj.(string)
   113  		if !ok {
   114  			return nil, nil, errors.Errorf("In identities with key %v name expected string in role got %v", k, nameObj)
   115  		}
   116  		name = strings.TrimSpace(name)
   117  
   118  		mspIdObj := roleMap[MspID]
   119  		if mspIdObj == nil {
   120  			return nil, nil, errors.Errorf("In identities with key %v mspId must be not nil in role", k)
   121  		}
   122  		mspId, ok := mspIdObj.(string)
   123  		if !ok {
   124  			return nil, nil, errors.Errorf("In identities with key %v mspId expected string in role got %v", k, mspIdObj)
   125  		}
   126  
   127  		if mspId == "" {
   128  			return nil, nil, errors.Errorf("In identities with key %v mspId must be not empty in role", k)
   129  		}
   130  		var r mb.MSPRole_MSPRoleType
   131  		switch name {
   132  		case RoleClient:
   133  			r = mb.MSPRole_CLIENT
   134  		case RoleMember:
   135  			r = mb.MSPRole_MEMBER
   136  		case RoleAdmin:
   137  			r = mb.MSPRole_ADMIN
   138  		case RolePeer:
   139  			r = mb.MSPRole_PEER
   140  		case RoleOrderer:
   141  			r = mb.MSPRole_ORDERER
   142  		}
   143  
   144  		/* build the principal we've been told */
   145  		mspRole, err := proto.Marshal(&mb.MSPRole{MspIdentifier: mspId, Role: r})
   146  		if err != nil {
   147  			return nil, nil, errors.Errorf("error marshalling msp role: %s", err)
   148  		}
   149  
   150  		p := &mspInfo{
   151  			mspPrincipal: &mb.MSPPrincipal{
   152  				PrincipalClassification: mb.MSPPrincipal_ROLE,
   153  				Principal:               mspRole,
   154  			},
   155  			mspNum: int32(i),
   156  		}
   157  		mspPrincipals[i] = p.mspPrincipal
   158  		ret[k] = p
   159  	}
   160  
   161  	if len(ret) == 0 {
   162  		return nil, nil, errors.New("No identities were found in the policy specification")
   163  	}
   164  	return ret, mspPrincipals, nil
   165  }
   166  
   167  func parsePolicyForJava(identitiesMap map[string]*mspInfo, policy map[string]interface{}) (*cb.SignaturePolicy, error) {
   168  	if policy == nil {
   169  		return nil, errors.New("No policy section was found in the document")
   170  	}
   171  	for k, v := range policy {
   172  		if k == SBy {
   173  			vo, ok := v.(string)
   174  			if !ok {
   175  				return nil, errors.New("signed-by expecting a string value")
   176  			}
   177  			mspInfos, ok := identitiesMap[vo]
   178  			if !ok {
   179  				return nil, errors.Errorf("No Identities found by name %v in signed-by.", vo)
   180  			}
   181  			return SignedBy(mspInfos.mspNum), nil
   182  		} else {
   183  			if noofPattern.MatchString(k) {
   184  				subm := noofPattern.FindStringSubmatch(k)
   185  				if len(subm) == 2 {
   186  					matchNo, err := strconv.Atoi(subm[1])
   187  					if err != nil {
   188  						return nil, err
   189  					}
   190  					vStringLists, ok := v.([]interface{})
   191  					if !ok {
   192  						return nil, errors.Errorf("%v expected to have array but found %v", k, v)
   193  					}
   194  					mapArray, err := sortMapArray(vStringLists)
   195  					if err != nil {
   196  						return nil, err
   197  					}
   198  					strLen := len(mapArray)
   199  					if strLen < matchNo {
   200  						return nil, errors.Errorf("%v expected to have at least %v items to match but only found %v", k, matchNo, strLen)
   201  					}
   202  					sps := make([]*cb.SignaturePolicy, strLen)
   203  					for i, vStringList := range mapArray {
   204  						nlo, ok := vStringList.(map[interface{}]interface{})
   205  						if !ok {
   206  							return nil, errors.Errorf("expect map[interface]interface got %v", vStringList)
   207  						}
   208  						toMapString, err := mapInterfaceToMapString(nlo)
   209  						if err != nil {
   210  							return nil, err
   211  						}
   212  						signaturePolicy, err := parsePolicyForJava(identitiesMap, toMapString)
   213  						if err != nil {
   214  							return nil, err
   215  						}
   216  						sps[i] = signaturePolicy
   217  					}
   218  					return NOutOf(int32(matchNo), sps), nil
   219  				}
   220  			} else {
   221  				return nil, errors.Errorf("Unsupported policy type %v", k)
   222  			}
   223  		}
   224  	}
   225  	return nil, errors.New("No values found for policy")
   226  }
   227  
   228  func mapInterfaceToMapString(mapInterface map[interface{}]interface{}) (map[string]interface{}, error) {
   229  	mapString := make(map[string]interface{})
   230  	for k, v := range mapInterface {
   231  		key, ok := k.(string)
   232  		if !ok {
   233  			return nil, errors.Errorf("expecting a string value got %v", k)
   234  		}
   235  		mapString[key] = v
   236  	}
   237  	return mapString, nil
   238  }
   239  
   240  var noofPattern = regexp.MustCompile("^(\\d+)-of$")
   241  
   242  func PolicyParseJava(yamlString string) (*cb.SignaturePolicyEnvelope, error) {
   243  	newViper := viper.New()
   244  	newViper.SetConfigType("yaml")
   245  	blockReader := bytes.NewBufferString(yamlString)
   246  	defer blockReader.Reset()
   247  	err := newViper.ReadConfig(blockReader)
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	identities, mspPrincipals, err := parseIdentitiesForJava(newViper.GetStringMap("identities"))
   252  	if err != nil {
   253  		return nil, err
   254  	}
   255  
   256  	rule, err := parsePolicyForJava(identities, newViper.GetStringMap("policy"))
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	p := &cb.SignaturePolicyEnvelope{
   262  		Identities: mspPrincipals,
   263  		Version:    0,
   264  		Rule:       rule,
   265  	}
   266  
   267  	return p, nil
   268  
   269  }