github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/common/policydsl/policyparser_test.go (about) 1 /* 2 Copyright hechain. 2017 All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package policydsl 8 9 import ( 10 "reflect" 11 "testing" 12 13 "github.com/hechain20/hechain/protoutil" 14 "github.com/hyperledger/fabric-protos-go/common" 15 "github.com/hyperledger/fabric-protos-go/msp" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestOutOf1(t *testing.T) { 20 p1, err := FromString("OutOf(1, 'A.member', 'B.member')") 21 require.NoError(t, err) 22 23 principals := make([]*msp.MSPPrincipal, 0) 24 25 principals = append(principals, &msp.MSPPrincipal{ 26 PrincipalClassification: msp.MSPPrincipal_ROLE, 27 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 28 }) 29 30 principals = append(principals, &msp.MSPPrincipal{ 31 PrincipalClassification: msp.MSPPrincipal_ROLE, 32 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 33 }) 34 35 p2 := &common.SignaturePolicyEnvelope{ 36 Version: 0, 37 Rule: NOutOf(1, []*common.SignaturePolicy{SignedBy(0), SignedBy(1)}), 38 Identities: principals, 39 } 40 41 require.Equal(t, p1, p2) 42 } 43 44 func TestOutOf2(t *testing.T) { 45 p1, err := FromString("OutOf(2, 'A.member', 'B.member')") 46 require.NoError(t, err) 47 48 principals := make([]*msp.MSPPrincipal, 0) 49 50 principals = append(principals, &msp.MSPPrincipal{ 51 PrincipalClassification: msp.MSPPrincipal_ROLE, 52 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 53 }) 54 55 principals = append(principals, &msp.MSPPrincipal{ 56 PrincipalClassification: msp.MSPPrincipal_ROLE, 57 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 58 }) 59 60 p2 := &common.SignaturePolicyEnvelope{ 61 Version: 0, 62 Rule: NOutOf(2, []*common.SignaturePolicy{SignedBy(0), SignedBy(1)}), 63 Identities: principals, 64 } 65 66 require.Equal(t, p1, p2) 67 } 68 69 func TestAnd(t *testing.T) { 70 p1, err := FromString("AND('A.member', 'B.member')") 71 require.NoError(t, err) 72 73 principals := make([]*msp.MSPPrincipal, 0) 74 75 principals = append(principals, &msp.MSPPrincipal{ 76 PrincipalClassification: msp.MSPPrincipal_ROLE, 77 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 78 }) 79 80 principals = append(principals, &msp.MSPPrincipal{ 81 PrincipalClassification: msp.MSPPrincipal_ROLE, 82 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 83 }) 84 85 p2 := &common.SignaturePolicyEnvelope{ 86 Version: 0, 87 Rule: And(SignedBy(0), SignedBy(1)), 88 Identities: principals, 89 } 90 91 require.Equal(t, p1, p2) 92 } 93 94 func TestAndClientPeerOrderer(t *testing.T) { 95 p1, err := FromString("AND('A.client', 'B.peer')") 96 require.NoError(t, err) 97 98 principals := make([]*msp.MSPPrincipal, 0) 99 100 principals = append(principals, &msp.MSPPrincipal{ 101 PrincipalClassification: msp.MSPPrincipal_ROLE, 102 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_CLIENT, MspIdentifier: "A"}), 103 }) 104 105 principals = append(principals, &msp.MSPPrincipal{ 106 PrincipalClassification: msp.MSPPrincipal_ROLE, 107 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_PEER, MspIdentifier: "B"}), 108 }) 109 110 p2 := &common.SignaturePolicyEnvelope{ 111 Version: 0, 112 Rule: And(SignedBy(0), SignedBy(1)), 113 Identities: principals, 114 } 115 116 require.True(t, reflect.DeepEqual(p1, p2)) 117 } 118 119 func TestOr(t *testing.T) { 120 p1, err := FromString("OR('A.member', 'B.member')") 121 require.NoError(t, err) 122 123 principals := make([]*msp.MSPPrincipal, 0) 124 125 principals = append(principals, &msp.MSPPrincipal{ 126 PrincipalClassification: msp.MSPPrincipal_ROLE, 127 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 128 }) 129 130 principals = append(principals, &msp.MSPPrincipal{ 131 PrincipalClassification: msp.MSPPrincipal_ROLE, 132 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 133 }) 134 135 p2 := &common.SignaturePolicyEnvelope{ 136 Version: 0, 137 Rule: Or(SignedBy(0), SignedBy(1)), 138 Identities: principals, 139 } 140 141 require.Equal(t, p1, p2) 142 } 143 144 func TestComplex1(t *testing.T) { 145 p1, err := FromString("OR('A.member', AND('B.member', 'C.member'))") 146 require.NoError(t, err) 147 148 principals := make([]*msp.MSPPrincipal, 0) 149 150 principals = append(principals, &msp.MSPPrincipal{ 151 PrincipalClassification: msp.MSPPrincipal_ROLE, 152 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 153 }) 154 155 principals = append(principals, &msp.MSPPrincipal{ 156 PrincipalClassification: msp.MSPPrincipal_ROLE, 157 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "C"}), 158 }) 159 160 principals = append(principals, &msp.MSPPrincipal{ 161 PrincipalClassification: msp.MSPPrincipal_ROLE, 162 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 163 }) 164 165 p2 := &common.SignaturePolicyEnvelope{ 166 Version: 0, 167 Rule: Or(SignedBy(2), And(SignedBy(0), SignedBy(1))), 168 Identities: principals, 169 } 170 171 require.Equal(t, p1, p2) 172 } 173 174 func TestComplex2(t *testing.T) { 175 p1, err := FromString("OR(AND('A.member', 'B.member'), OR('C.admin', 'D.member'))") 176 require.NoError(t, err) 177 178 principals := make([]*msp.MSPPrincipal, 0) 179 180 principals = append(principals, &msp.MSPPrincipal{ 181 PrincipalClassification: msp.MSPPrincipal_ROLE, 182 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 183 }) 184 185 principals = append(principals, &msp.MSPPrincipal{ 186 PrincipalClassification: msp.MSPPrincipal_ROLE, 187 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 188 }) 189 190 principals = append(principals, &msp.MSPPrincipal{ 191 PrincipalClassification: msp.MSPPrincipal_ROLE, 192 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: "C"}), 193 }) 194 195 principals = append(principals, &msp.MSPPrincipal{ 196 PrincipalClassification: msp.MSPPrincipal_ROLE, 197 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "D"}), 198 }) 199 200 p2 := &common.SignaturePolicyEnvelope{ 201 Version: 0, 202 Rule: Or(And(SignedBy(0), SignedBy(1)), Or(SignedBy(2), SignedBy(3))), 203 Identities: principals, 204 } 205 206 require.Equal(t, p1, p2) 207 } 208 209 func TestMSPIDWIthSpecialChars(t *testing.T) { 210 p1, err := FromString("OR('MSP.member', 'MSP.WITH.DOTS.member', 'MSP-WITH-DASHES.member')") 211 require.NoError(t, err) 212 213 principals := make([]*msp.MSPPrincipal, 0) 214 215 principals = append(principals, &msp.MSPPrincipal{ 216 PrincipalClassification: msp.MSPPrincipal_ROLE, 217 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "MSP"}), 218 }) 219 220 principals = append(principals, &msp.MSPPrincipal{ 221 PrincipalClassification: msp.MSPPrincipal_ROLE, 222 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "MSP.WITH.DOTS"}), 223 }) 224 225 principals = append(principals, &msp.MSPPrincipal{ 226 PrincipalClassification: msp.MSPPrincipal_ROLE, 227 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "MSP-WITH-DASHES"}), 228 }) 229 230 p2 := &common.SignaturePolicyEnvelope{ 231 Version: 0, 232 Rule: NOutOf(1, []*common.SignaturePolicy{SignedBy(0), SignedBy(1), SignedBy(2)}), 233 Identities: principals, 234 } 235 236 require.Equal(t, p1, p2) 237 } 238 239 func TestBadStringsNoPanic(t *testing.T) { 240 _, err := FromString("OR('A.member', Bmember)") // error after 1st Evaluate() 241 require.EqualError(t, err, "unrecognized token 'Bmember' in policy string") 242 243 _, err = FromString("OR('A.member', 'Bmember')") // error after 2nd Evalute() 244 require.EqualError(t, err, "unrecognized token 'Bmember' in policy string") 245 246 _, err = FromString(`OR('A.member', '\'Bmember\'')`) // error after 3rd Evalute() 247 require.EqualError(t, err, "unrecognized token 'Bmember' in policy string") 248 } 249 250 func TestNodeOUs(t *testing.T) { 251 p1, err := FromString("OR('A.peer', 'B.admin', 'C.orderer', 'D.client')") 252 require.NoError(t, err) 253 254 principals := make([]*msp.MSPPrincipal, 0) 255 256 principals = append(principals, &msp.MSPPrincipal{ 257 PrincipalClassification: msp.MSPPrincipal_ROLE, 258 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_PEER, MspIdentifier: "A"}), 259 }) 260 261 principals = append(principals, &msp.MSPPrincipal{ 262 PrincipalClassification: msp.MSPPrincipal_ROLE, 263 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: "B"}), 264 }) 265 266 principals = append(principals, &msp.MSPPrincipal{ 267 PrincipalClassification: msp.MSPPrincipal_ROLE, 268 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_ORDERER, MspIdentifier: "C"}), 269 }) 270 271 principals = append(principals, &msp.MSPPrincipal{ 272 PrincipalClassification: msp.MSPPrincipal_ROLE, 273 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_CLIENT, MspIdentifier: "D"}), 274 }) 275 276 p2 := &common.SignaturePolicyEnvelope{ 277 Version: 0, 278 Rule: NOutOf(1, []*common.SignaturePolicy{SignedBy(0), SignedBy(1), SignedBy(2), SignedBy(3)}), 279 Identities: principals, 280 } 281 282 require.Equal(t, p1, p2) 283 } 284 285 func TestOutOfNumIsString(t *testing.T) { 286 p1, err := FromString("OutOf('1', 'A.member', 'B.member')") 287 require.NoError(t, err) 288 289 principals := make([]*msp.MSPPrincipal, 0) 290 291 principals = append(principals, &msp.MSPPrincipal{ 292 PrincipalClassification: msp.MSPPrincipal_ROLE, 293 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 294 }) 295 296 principals = append(principals, &msp.MSPPrincipal{ 297 PrincipalClassification: msp.MSPPrincipal_ROLE, 298 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 299 }) 300 301 p2 := &common.SignaturePolicyEnvelope{ 302 Version: 0, 303 Rule: NOutOf(1, []*common.SignaturePolicy{SignedBy(0), SignedBy(1)}), 304 Identities: principals, 305 } 306 307 require.Equal(t, p1, p2) 308 } 309 310 func TestOutOfErrorCase(t *testing.T) { 311 p1, err1 := FromString("") // 1st NewEvaluableExpressionWithFunctions() returns an error 312 require.Nil(t, p1) 313 require.EqualError(t, err1, "Unexpected end of expression") 314 315 p2, err2 := FromString("OutOf(1)") // outof() if len(args)<2 316 require.Nil(t, p2) 317 require.EqualError(t, err2, "expected at least two arguments to NOutOf. Given 1") 318 319 p3, err3 := FromString("OutOf(true, 'A.member')") // outof() }else{. 1st arg is non of float, int, string 320 require.Nil(t, p3) 321 require.EqualError(t, err3, "unexpected type bool") 322 323 p4, err4 := FromString("OutOf(1, 2)") // oufof() switch default. 2nd arg is not string. 324 require.Nil(t, p4) 325 require.EqualError(t, err4, "unexpected type float64") 326 327 p5, err5 := FromString("OutOf(1, 'true')") // firstPass() switch default 328 require.Nil(t, p5) 329 require.EqualError(t, err5, "unexpected type bool") 330 331 p6, err6 := FromString(`OutOf('\'\\\'A\\\'\'', 'B.member')`) // secondPass() switch args[1].(type) default 332 require.Nil(t, p6) 333 require.EqualError(t, err6, "unrecognized type, expected a number, got string") 334 335 p7, err7 := FromString(`OutOf(1, '\'1\'')`) // secondPass() switch args[1].(type) default 336 require.Nil(t, p7) 337 require.EqualError(t, err7, "unrecognized type, expected a principal or a policy, got float64") 338 339 p8, err8 := FromString(`''`) // 2nd NewEvaluateExpressionWithFunction() returns an error 340 require.Nil(t, p8) 341 require.EqualError(t, err8, "Unexpected end of expression") 342 343 p9, err9 := FromString(`'\'\''`) // 3rd NewEvaluateExpressionWithFunction() returns an error 344 require.Nil(t, p9) 345 require.EqualError(t, err9, "Unexpected end of expression") 346 } 347 348 func TestBadStringBeforeFAB11404_ThisCanDeleteAfterFAB11404HasMerged(t *testing.T) { 349 s1 := "1" // ineger in string 350 p1, err1 := FromString(s1) 351 require.Nil(t, p1) 352 require.EqualError(t, err1, `invalid policy string '1'`) 353 354 s2 := "'1'" // quoted ineger in string 355 p2, err2 := FromString(s2) 356 require.Nil(t, p2) 357 require.EqualError(t, err2, `invalid policy string ''1''`) 358 359 s3 := `'\'1\''` // nested quoted ineger in string 360 p3, err3 := FromString(s3) 361 require.Nil(t, p3) 362 require.EqualError(t, err3, `invalid policy string ''\'1\'''`) 363 } 364 365 func TestSecondPassBoundaryCheck(t *testing.T) { 366 // Check lower boundary 367 // Prohibit t<0 368 p0, err0 := FromString("OutOf(-1, 'A.member', 'B.member')") 369 require.Nil(t, p0) 370 require.EqualError(t, err0, "invalid t-out-of-n predicate, t -1, n 2") 371 372 // Permit t==0 : always satisfied policy 373 // There is no clear usecase of t=0, but somebody may already use it, so we don't treat as an error. 374 p1, err1 := FromString("OutOf(0, 'A.member', 'B.member')") 375 require.NoError(t, err1) 376 principals := make([]*msp.MSPPrincipal, 0) 377 principals = append(principals, &msp.MSPPrincipal{ 378 PrincipalClassification: msp.MSPPrincipal_ROLE, 379 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "A"}), 380 }) 381 principals = append(principals, &msp.MSPPrincipal{ 382 PrincipalClassification: msp.MSPPrincipal_ROLE, 383 Principal: protoutil.MarshalOrPanic(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: "B"}), 384 }) 385 expected1 := &common.SignaturePolicyEnvelope{ 386 Version: 0, 387 Rule: NOutOf(0, []*common.SignaturePolicy{SignedBy(0), SignedBy(1)}), 388 Identities: principals, 389 } 390 require.Equal(t, expected1, p1) 391 392 // Check upper boundary 393 // Permit t==n+1 : never satisfied policy 394 // Usecase: To create immutable ledger key 395 p2, err2 := FromString("OutOf(3, 'A.member', 'B.member')") 396 require.NoError(t, err2) 397 expected2 := &common.SignaturePolicyEnvelope{ 398 Version: 0, 399 Rule: NOutOf(3, []*common.SignaturePolicy{SignedBy(0), SignedBy(1)}), 400 Identities: principals, 401 } 402 require.Equal(t, expected2, p2) 403 404 // Prohibit t>n + 1 405 p3, err3 := FromString("OutOf(4, 'A.member', 'B.member')") 406 require.Nil(t, p3) 407 require.EqualError(t, err3, "invalid t-out-of-n predicate, t 4, n 2") 408 }