github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/policy/policy_test.go (about)

     1  /*
     2  Copyright hechain. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package policy
     8  
     9  import (
    10  	"testing"
    11  
    12  	"github.com/hechain20/hechain/common/policies"
    13  	"github.com/hechain20/hechain/core/policy/mocks"
    14  	"github.com/hechain20/hechain/protoutil"
    15  	"github.com/hyperledger/fabric-protos-go/peer"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestCheckPolicyInvalidArgs(t *testing.T) {
    20  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
    21  		Managers: map[string]policies.Manager{
    22  			"A": &mocks.MockChannelPolicyManager{
    23  				MockPolicy: &mocks.MockPolicy{
    24  					Deserializer: &mocks.MockIdentityDeserializer{
    25  						Identity: []byte("Alice"),
    26  						Msg:      []byte("msg1"),
    27  					},
    28  				},
    29  			},
    30  		},
    31  	}
    32  	pc := &policyChecker{channelPolicyManagerGetter: policyManagerGetter}
    33  
    34  	err := pc.CheckPolicy("B", "admin", &peer.SignedProposal{})
    35  	require.Error(t, err)
    36  	require.Contains(t, err.Error(), "Failed to get policy manager for channel [B]")
    37  }
    38  
    39  func TestCheckPolicyBySignedDataInvalidArgs(t *testing.T) {
    40  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
    41  		Managers: map[string]policies.Manager{
    42  			"A": &mocks.MockChannelPolicyManager{
    43  				MockPolicy: &mocks.MockPolicy{
    44  					Deserializer: &mocks.MockIdentityDeserializer{
    45  						Identity: []byte("Alice"),
    46  						Msg:      []byte("msg1"),
    47  					},
    48  				},
    49  			},
    50  		},
    51  	}
    52  	pc := &policyChecker{channelPolicyManagerGetter: policyManagerGetter}
    53  
    54  	err := pc.CheckPolicyBySignedData("", "admin", []*protoutil.SignedData{{}})
    55  	require.Error(t, err)
    56  	require.Contains(t, err.Error(), "Invalid channel ID name during check policy on signed data. Name must be different from nil.")
    57  
    58  	err = pc.CheckPolicyBySignedData("A", "", []*protoutil.SignedData{{}})
    59  	require.Error(t, err)
    60  	require.Contains(t, err.Error(), "Invalid policy name during check policy on signed data on channel [A]. Name must be different from nil.")
    61  
    62  	err = pc.CheckPolicyBySignedData("A", "admin", nil)
    63  	require.Error(t, err)
    64  	require.Contains(t, err.Error(), "Invalid signed data during check policy on channel [A] with policy [admin]")
    65  
    66  	err = pc.CheckPolicyBySignedData("B", "admin", []*protoutil.SignedData{{}})
    67  	require.Error(t, err)
    68  	require.Contains(t, err.Error(), "Failed to get policy manager for channel [B]")
    69  
    70  	err = pc.CheckPolicyBySignedData("A", "admin", []*protoutil.SignedData{{}})
    71  	require.Error(t, err)
    72  	require.Contains(t, err.Error(), "Failed evaluating policy on signed data during check policy on channel [A] with policy [admin]")
    73  }
    74  
    75  func TestPolicyCheckerInvalidArgs(t *testing.T) {
    76  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
    77  		Managers: map[string]policies.Manager{
    78  			"A": &mocks.MockChannelPolicyManager{
    79  				MockPolicy: &mocks.MockPolicy{Deserializer: &mocks.MockIdentityDeserializer{
    80  					Identity: []byte("Alice"),
    81  					Msg:      []byte("msg1"),
    82  				}},
    83  			},
    84  			"B": &mocks.MockChannelPolicyManager{
    85  				MockPolicy: &mocks.MockPolicy{Deserializer: &mocks.MockIdentityDeserializer{
    86  					Identity: []byte("Bob"),
    87  					Msg:      []byte("msg2"),
    88  				}},
    89  			},
    90  			"C": &mocks.MockChannelPolicyManager{
    91  				MockPolicy: &mocks.MockPolicy{Deserializer: &mocks.MockIdentityDeserializer{
    92  					Identity: []byte("Alice"),
    93  					Msg:      []byte("msg3"),
    94  				}},
    95  			},
    96  		},
    97  	}
    98  	identityDeserializer := &mocks.MockIdentityDeserializer{
    99  		Identity: []byte("Alice"),
   100  		Msg:      []byte("msg1"),
   101  	}
   102  	pc := &policyChecker{
   103  		channelPolicyManagerGetter: policyManagerGetter,
   104  		localMSP:                   identityDeserializer,
   105  		principalGetter:            &mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
   106  	}
   107  
   108  	// Check that (non-empty channel, empty policy) fails
   109  	err := pc.CheckPolicy("A", "", nil)
   110  	require.Error(t, err)
   111  	require.Contains(t, err.Error(), "Invalid policy name during check policy on channel [A]. Name must be different from nil.")
   112  
   113  	// Check that (empty channel, empty policy) fails
   114  	err = pc.CheckPolicy("", "", nil)
   115  	require.Error(t, err)
   116  	require.Contains(t, err.Error(), "Invalid policy name during channelless check policy. Name must be different from nil.")
   117  
   118  	// Check that (non-empty channel, non-empty policy, nil proposal) fails
   119  	err = pc.CheckPolicy("A", "A", nil)
   120  	require.Error(t, err)
   121  	require.Contains(t, err.Error(), "Invalid signed proposal during check policy on channel [A] with policy [A]")
   122  
   123  	// Check that (empty channel, non-empty policy, nil proposal) fails
   124  	err = pc.CheckPolicy("", "A", nil)
   125  	require.Error(t, err)
   126  	require.Contains(t, err.Error(), "Invalid signed proposal during channelless check policy with policy [A]")
   127  }
   128  
   129  func TestPolicyChecker(t *testing.T) {
   130  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
   131  		Managers: map[string]policies.Manager{
   132  			"A": &mocks.MockChannelPolicyManager{
   133  				MockPolicy: &mocks.MockPolicy{
   134  					Deserializer: &mocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")},
   135  				},
   136  			},
   137  			"B": &mocks.MockChannelPolicyManager{
   138  				MockPolicy: &mocks.MockPolicy{
   139  					Deserializer: &mocks.MockIdentityDeserializer{
   140  						Identity: []byte("Bob"),
   141  						Msg:      []byte("msg2"),
   142  					},
   143  				},
   144  			},
   145  			"C": &mocks.MockChannelPolicyManager{
   146  				MockPolicy: &mocks.MockPolicy{
   147  					Deserializer: &mocks.MockIdentityDeserializer{
   148  						Identity: []byte("Alice"),
   149  						Msg:      []byte("msg3"),
   150  					},
   151  				},
   152  			},
   153  		},
   154  	}
   155  	identityDeserializer := &mocks.MockIdentityDeserializer{
   156  		Identity: []byte("Alice"),
   157  		Msg:      []byte("msg1"),
   158  	}
   159  	pc := &policyChecker{
   160  		channelPolicyManagerGetter: policyManagerGetter,
   161  		localMSP:                   identityDeserializer,
   162  		principalGetter:            &mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
   163  	}
   164  
   165  	t.Run("CheckPolicy", func(t *testing.T) {
   166  		// Validate Alice signatures against channel A's readers
   167  		sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
   168  		policyManagerGetter.Managers["A"].(*mocks.MockChannelPolicyManager).MockPolicy.(*mocks.MockPolicy).Deserializer.(*mocks.MockIdentityDeserializer).Msg = sProp.ProposalBytes
   169  		sProp.Signature = sProp.ProposalBytes
   170  		err := pc.CheckPolicy("A", "readers", sProp)
   171  		require.NoError(t, err)
   172  
   173  		// Proposal from Alice for channel A should fail against channel B, where Alice is not involved
   174  		err = pc.CheckPolicy("B", "readers", sProp)
   175  		require.Error(t, err)
   176  		require.Contains(t, err.Error(), "Failed evaluating policy on signed data during check policy on channel [B] with policy [readers]: [Invalid Identity]")
   177  
   178  		// Proposal from Alice for channel A should fail against channel C, where Alice is involved but signature is not valid
   179  		err = pc.CheckPolicy("C", "readers", sProp)
   180  		require.Error(t, err)
   181  		require.Contains(t, err.Error(), "Failed evaluating policy on signed data during check policy on channel [C] with policy [readers]: [Invalid Signature]")
   182  	})
   183  
   184  	t.Run("CheckPolicyNoChannel", func(t *testing.T) {
   185  		sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
   186  		sProp.Signature = sProp.ProposalBytes
   187  
   188  		// Alice is a member of the local MSP, policy check must succeed
   189  		identityDeserializer.Msg = sProp.ProposalBytes
   190  		err := pc.CheckPolicyNoChannel(Members, sProp)
   191  		require.NoError(t, err)
   192  
   193  		sProp, _ = protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Bob"), []byte("msg2"))
   194  		// Bob is not a member of the local MSP, policy check must fail
   195  		err = pc.CheckPolicyNoChannel(Members, sProp)
   196  		require.Error(t, err)
   197  		require.Contains(t, err.Error(), "Failed deserializing proposal creator during channelless check policy with policy [Members]: [Invalid Identity]")
   198  	})
   199  
   200  	t.Run("CheckPolicyNoChannel", func(t *testing.T) {
   201  		signedData := &protoutil.SignedData{
   202  			Identity:  []byte("Alice"),
   203  			Data:      []byte("msg1"),
   204  			Signature: []byte("msg1"), // for testing only, signature is same as data to pass MockIdentity.Verify
   205  		}
   206  
   207  		// Alice is a member of the local MSP, policy check must succeed
   208  		identityDeserializer.Msg = signedData.Data
   209  		err := pc.CheckPolicyNoChannelBySignedData(Admins, []*protoutil.SignedData{signedData})
   210  		require.NoError(t, err)
   211  
   212  		// CheckPolicyNoChannelBySignedData iterates each signed data and returns an error if any data is invalid
   213  		// Bob is not a member of the local MSP, policy check must fail when deserializing the identity
   214  		signedData2 := &protoutil.SignedData{
   215  			Identity:  []byte("Bob"),
   216  			Data:      []byte("msg2"),
   217  			Signature: []byte("msg2"),
   218  		}
   219  		err = pc.CheckPolicyNoChannelBySignedData(Admins, []*protoutil.SignedData{signedData, signedData2})
   220  		require.Error(t, err)
   221  		require.Contains(t, err.Error(), "failed deserializing signed data identity during channelless check policy with policy [Admins]: [Invalid Identity]")
   222  
   223  		// policy name cannot be empty
   224  		err = pc.CheckPolicyNoChannelBySignedData("", []*protoutil.SignedData{signedData})
   225  		require.EqualError(t, err, "invalid policy name during channelless check policy. Name must be different from nil.")
   226  
   227  		// signed data cannot be nil or empty
   228  		err = pc.CheckPolicyNoChannelBySignedData(Admins, nil)
   229  		require.EqualError(t, err, "no signed data during channelless check policy with policy [Admins]")
   230  		err = pc.CheckPolicyNoChannelBySignedData(Admins, []*protoutil.SignedData{})
   231  		require.EqualError(t, err, "no signed data during channelless check policy with policy [Admins]")
   232  	})
   233  }