github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/core/policy/policy_test.go (about)

     1  /*
     2  Copyright IBM Corp. 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/hyperledger/fabric-protos-go/peer"
    13  	"github.com/hyperledger/fabric/common/policies"
    14  	"github.com/hyperledger/fabric/core/policy/mocks"
    15  	"github.com/hyperledger/fabric/msp/mgmt"
    16  	"github.com/hyperledger/fabric/protoutil"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/mock"
    19  )
    20  
    21  func TestCheckPolicyInvalidArgs(t *testing.T) {
    22  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
    23  		Managers: map[string]policies.Manager{
    24  			"A": &mocks.MockChannelPolicyManager{
    25  				MockPolicy: &mocks.MockPolicy{
    26  					Deserializer: &mocks.MockIdentityDeserializer{
    27  						Identity: []byte("Alice"),
    28  						Msg:      []byte("msg1"),
    29  					},
    30  				},
    31  			},
    32  		},
    33  	}
    34  	pc := &policyChecker{channelPolicyManagerGetter: policyManagerGetter}
    35  
    36  	err := pc.CheckPolicy("B", "admin", &peer.SignedProposal{})
    37  	assert.Error(t, err)
    38  	assert.Contains(t, err.Error(), "Failed to get policy manager for channel [B]")
    39  }
    40  
    41  func TestCheckPolicyBySignedDataInvalidArgs(t *testing.T) {
    42  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
    43  		Managers: map[string]policies.Manager{
    44  			"A": &mocks.MockChannelPolicyManager{
    45  				MockPolicy: &mocks.MockPolicy{
    46  					Deserializer: &mocks.MockIdentityDeserializer{
    47  						Identity: []byte("Alice"),
    48  						Msg:      []byte("msg1"),
    49  					}},
    50  			},
    51  		},
    52  	}
    53  	pc := &policyChecker{channelPolicyManagerGetter: policyManagerGetter}
    54  
    55  	err := pc.CheckPolicyBySignedData("", "admin", []*protoutil.SignedData{{}})
    56  	assert.Error(t, err)
    57  	assert.Contains(t, err.Error(), "Invalid channel ID name during check policy on signed data. Name must be different from nil.")
    58  
    59  	err = pc.CheckPolicyBySignedData("A", "", []*protoutil.SignedData{{}})
    60  	assert.Error(t, err)
    61  	assert.Contains(t, err.Error(), "Invalid policy name during check policy on signed data on channel [A]. Name must be different from nil.")
    62  
    63  	err = pc.CheckPolicyBySignedData("A", "admin", nil)
    64  	assert.Error(t, err)
    65  	assert.Contains(t, err.Error(), "Invalid signed data during check policy on channel [A] with policy [admin]")
    66  
    67  	err = pc.CheckPolicyBySignedData("B", "admin", []*protoutil.SignedData{{}})
    68  	assert.Error(t, err)
    69  	assert.Contains(t, err.Error(), "Failed to get policy manager for channel [B]")
    70  
    71  	err = pc.CheckPolicyBySignedData("A", "admin", []*protoutil.SignedData{{}})
    72  	assert.Error(t, err)
    73  	assert.Contains(t, err.Error(), "Failed evaluating policy on signed data during check policy on channel [A] with policy [admin]")
    74  }
    75  
    76  func TestPolicyCheckerInvalidArgs(t *testing.T) {
    77  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
    78  		Managers: map[string]policies.Manager{
    79  			"A": &mocks.MockChannelPolicyManager{
    80  				MockPolicy: &mocks.MockPolicy{Deserializer: &mocks.MockIdentityDeserializer{
    81  					Identity: []byte("Alice"),
    82  					Msg:      []byte("msg1"),
    83  				}},
    84  			},
    85  			"B": &mocks.MockChannelPolicyManager{
    86  				MockPolicy: &mocks.MockPolicy{Deserializer: &mocks.MockIdentityDeserializer{
    87  					Identity: []byte("Bob"),
    88  					Msg:      []byte("msg2"),
    89  				}},
    90  			},
    91  			"C": &mocks.MockChannelPolicyManager{
    92  				MockPolicy: &mocks.MockPolicy{Deserializer: &mocks.MockIdentityDeserializer{
    93  					Identity: []byte("Alice"),
    94  					Msg:      []byte("msg3"),
    95  				}},
    96  			},
    97  		},
    98  	}
    99  	identityDeserializer := &mocks.MockIdentityDeserializer{
   100  		Identity: []byte("Alice"),
   101  		Msg:      []byte("msg1"),
   102  	}
   103  	pc := NewPolicyChecker(
   104  		policyManagerGetter,
   105  		identityDeserializer,
   106  		&mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
   107  	)
   108  
   109  	// Check that (non-empty channel, empty policy) fails
   110  	err := pc.CheckPolicy("A", "", nil)
   111  	assert.Error(t, err)
   112  	assert.Contains(t, err.Error(), "Invalid policy name during check policy on channel [A]. Name must be different from nil.")
   113  
   114  	// Check that (empty channel, empty policy) fails
   115  	err = pc.CheckPolicy("", "", nil)
   116  	assert.Error(t, err)
   117  	assert.Contains(t, err.Error(), "Invalid policy name during channelless check policy. Name must be different from nil.")
   118  
   119  	// Check that (non-empty channel, non-empty policy, nil proposal) fails
   120  	err = pc.CheckPolicy("A", "A", nil)
   121  	assert.Error(t, err)
   122  	assert.Contains(t, err.Error(), "Invalid signed proposal during check policy on channel [A] with policy [A]")
   123  
   124  	// Check that (empty channel, non-empty policy, nil proposal) fails
   125  	err = pc.CheckPolicy("", "A", nil)
   126  	assert.Error(t, err)
   127  	assert.Contains(t, err.Error(), "Invalid signed proposal during channelless check policy with policy [A]")
   128  }
   129  
   130  func TestPolicyChecker(t *testing.T) {
   131  	policyManagerGetter := &mocks.MockChannelPolicyManagerGetter{
   132  		Managers: map[string]policies.Manager{
   133  			"A": &mocks.MockChannelPolicyManager{
   134  				MockPolicy: &mocks.MockPolicy{
   135  					Deserializer: &mocks.MockIdentityDeserializer{Identity: []byte("Alice"), Msg: []byte("msg1")},
   136  				},
   137  			},
   138  			"B": &mocks.MockChannelPolicyManager{
   139  				MockPolicy: &mocks.MockPolicy{
   140  					Deserializer: &mocks.MockIdentityDeserializer{
   141  						Identity: []byte("Bob"),
   142  						Msg:      []byte("msg2"),
   143  					},
   144  				},
   145  			},
   146  			"C": &mocks.MockChannelPolicyManager{
   147  				MockPolicy: &mocks.MockPolicy{
   148  					Deserializer: &mocks.MockIdentityDeserializer{
   149  						Identity: []byte("Alice"),
   150  						Msg:      []byte("msg3"),
   151  					},
   152  				},
   153  			},
   154  		},
   155  	}
   156  	identityDeserializer := &mocks.MockIdentityDeserializer{
   157  		Identity: []byte("Alice"),
   158  		Msg:      []byte("msg1"),
   159  	}
   160  	pc := NewPolicyChecker(
   161  		policyManagerGetter,
   162  		identityDeserializer,
   163  		&mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
   164  	)
   165  
   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  	assert.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  	assert.Error(t, err)
   176  	assert.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  	assert.Error(t, err)
   181  	assert.Contains(t, err.Error(), "Failed evaluating policy on signed data during check policy on channel [C] with policy [readers]: [Invalid Signature]")
   182  
   183  	// Alice is a member of the local MSP, policy check must succeed
   184  	identityDeserializer.Msg = sProp.ProposalBytes
   185  	err = pc.CheckPolicyNoChannel(mgmt.Members, sProp)
   186  	assert.NoError(t, err)
   187  
   188  	sProp, _ = protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Bob"), []byte("msg2"))
   189  	// Bob is not a member of the local MSP, policy check must fail
   190  	err = pc.CheckPolicyNoChannel(mgmt.Members, sProp)
   191  	assert.Error(t, err)
   192  	assert.Contains(t, err.Error(), "Failed deserializing proposal creator during channelless check policy with policy [Members]: [Invalid Identity]")
   193  }
   194  
   195  type MockPolicyCheckerFactory struct {
   196  	mock.Mock
   197  }
   198  
   199  func (m *MockPolicyCheckerFactory) NewPolicyChecker() PolicyChecker {
   200  	args := m.Called()
   201  	return args.Get(0).(PolicyChecker)
   202  }