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