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  }