go_study/fabric-main/core/aclmgmt/resourceprovider_test.go

157 lines
4.9 KiB
Go

/*
Copyright IBM Corp. 2016 All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package aclmgmt
import (
"fmt"
"os"
"testing"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/core/aclmgmt/mocks"
"github.com/hyperledger/fabric/core/policy"
"github.com/hyperledger/fabric/internal/pkg/identity"
msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/require"
)
func newPolicyProvider(pEvaluator policyEvaluator) aclmgmtPolicyProvider {
return &aclmgmtPolicyProviderImpl{pEvaluator}
}
// ------- mocks ---------
// mockPolicyEvaluatorImpl implements policyEvaluator
type mockPolicyEvaluatorImpl struct {
pmap map[string]string
peval map[string]error
}
func (pe *mockPolicyEvaluatorImpl) PolicyRefForAPI(resName string) string {
return pe.pmap[resName]
}
func (pe *mockPolicyEvaluatorImpl) Evaluate(polName string, sd []*protoutil.SignedData) error {
err, ok := pe.peval[polName]
if !ok {
return PolicyNotFound(polName)
}
// this could be non nil or some error
return err
}
//go:generate counterfeiter -o mocks/signer_serializer.go --fake-name SignerSerializer . signerSerializer
type signerSerializer interface {
identity.SignerSerializer
}
//go:generate counterfeiter -o mocks/defaultaclprovider.go --fake-name DefaultACLProvider . defaultACLProvider
func TestPolicyBase(t *testing.T) {
evaluator := &mockPolicyEvaluatorImpl{pmap: map[string]string{"res": "pol"}, peval: map[string]error{"pol": nil}}
provider := newPolicyProvider(evaluator)
t.Run("SignedProposal", func(t *testing.T) {
proposal, _ := protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
err := provider.CheckACL("pol", proposal)
require.NoError(t, err)
})
t.Run("Envelope", func(t *testing.T) {
signer := &mocks.SignerSerializer{}
envelope, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, "myc", signer, &common.ConfigEnvelope{}, 0, 0)
require.NoError(t, err)
err = provider.CheckACL("pol", envelope)
require.NoError(t, err)
})
t.Run("SignedData", func(t *testing.T) {
data := &protoutil.SignedData{
Data: []byte("DATA"),
Identity: []byte("IDENTITY"),
Signature: []byte("SIGNATURE"),
}
err := provider.CheckACL("pol", data)
require.NoError(t, err)
})
}
func TestPolicyBad(t *testing.T) {
peval := &mockPolicyEvaluatorImpl{pmap: map[string]string{"res": "pol"}, peval: map[string]error{"pol": nil}}
pprov := newPolicyProvider(peval)
// bad policy
err := pprov.CheckACL("pol", []byte("not a signed proposal"))
require.Error(t, err, InvalidIdInfo("pol").Error())
sProp, _ := protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
err = pprov.CheckACL("badpolicy", sProp)
require.Error(t, err)
sProp, _ = protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
sProp.ProposalBytes = []byte("bad proposal bytes")
err = pprov.CheckACL("res", sProp)
require.Error(t, err)
sProp, _ = protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
prop := &peer.Proposal{}
if proto.Unmarshal(sProp.ProposalBytes, prop) != nil {
t.FailNow()
}
prop.Header = []byte("bad hdr")
sProp.ProposalBytes = protoutil.MarshalOrPanic(prop)
err = pprov.CheckACL("res", sProp)
require.Error(t, err)
}
// test to ensure ptypes are processed by default provider
func TestForceDefaultsForPType(t *testing.T) {
defAclProvider := &mocks.DefaultACLProvider{}
defAclProvider.CheckACLReturns(nil)
defAclProvider.IsPtypePolicyReturns(true)
rp := &resourceProvider{defaultProvider: defAclProvider}
err := rp.CheckACL("aptype", "somechannel", struct{}{})
require.NoError(t, err)
}
func TestCheckACLNoChannel(t *testing.T) {
// use mocked objects to test good path
mockDefAclProvider := &mocks.DefaultACLProvider{}
mockDefAclProvider.CheckACLNoChannelReturns(nil)
mockDefAclProvider.IsPtypePolicyReturns(true)
rp := &resourceProvider{defaultProvider: mockDefAclProvider}
err := rp.CheckACLNoChannel("aptype", struct{}{})
require.NoError(t, err)
// error paths
defAclProvider := &defaultACLProviderImpl{
pResourcePolicyMap: map[string]string{"aptype": policy.Admins},
}
rp = &resourceProvider{defaultProvider: defAclProvider}
err = rp.CheckACLNoChannel("nontype", struct{}{})
require.Error(t, err, "cannot override peer type policy for channeless ACL check")
rp = &resourceProvider{defaultProvider: defAclProvider}
err = rp.CheckACLNoChannel("aptype", struct{}{})
require.EqualError(t, err, "Unknown id on channelless checkACL aptype")
}
func init() {
// setup the MSP manager so that we can sign/verify
err := msptesttools.LoadMSPSetupForTesting()
if err != nil {
fmt.Printf("Could not load msp config, err %s", err)
os.Exit(-1)
return
}
}