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 }