Skip to content

Commit

Permalink
[FAB-5721] ACLProvider at LSCC
Browse files Browse the repository at this point in the history
This change-set does following:
- It modifed the LSCC to use ACLProvider
for access control.

Tests have been updated to validate the changes.

Use RegsiterACLProvider instead of SetACLProvider

. use MockACLProvider (basically its Reset) to work
  the ACL system

Change-Id: I09ff832730b22d64bf67416c9db9a3acab34ff4c
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
Signed-off-by: Srinivasan Muralidharan <srinivasan.muralidharan99@gmail.com>
  • Loading branch information
adecaro authored and muralisrini committed Sep 29, 2017
1 parent ca1cb92 commit 65cb5b2
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 11 deletions.
17 changes: 12 additions & 5 deletions core/scc/lscc/lscc.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/cauthdsl"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/core/aclmgmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/hyperledger/fabric/core/common/sysccprovider"
Expand Down Expand Up @@ -849,10 +849,17 @@ func (lscc *LifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response
ccname := string(args[2])

// 2. check local Channel Readers policy
// Notice that this information are already available on the ledger
// therefore we enforce here that the caller is reader of the channel.
if err = lscc.policyChecker.CheckPolicy(chain, policies.ChannelApplicationReaders, sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization for %s on channel %s has been denied with error %s", function, args[1], err))
var resource string
switch function {
case GETCCINFO:
resource = aclmgmt.LSCC_GETCCINFO
case GETDEPSPEC:
resource = aclmgmt.LSCC_GETDEPSPEC
case GETCCDATA:
resource = aclmgmt.LSCC_GETCCDATA
}
if err = aclmgmt.GetACLProvider().CheckACL(resource, chain, sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization request failed %s: %s", chain, err))
}

cdbytes, err := lscc.getCCInstance(stub, ccname)
Expand Down
58 changes: 52 additions & 6 deletions core/scc/lscc/lscc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"archive/tar"
"bytes"
"compress/gzip"
"errors"
"fmt"
"io/ioutil"
"os"
Expand All @@ -30,6 +31,8 @@ import (
"github.com/hyperledger/fabric/common/mocks/scc"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/aclmgmt"
"github.com/hyperledger/fabric/core/aclmgmt/mocks"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/core/common/ccpackage"
"github.com/hyperledger/fabric/core/common/ccprovider"
Expand Down Expand Up @@ -139,6 +142,8 @@ func testInstall(t *testing.T, ccname string, version string, path string, expec
}
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETINSTALLEDCHAINCODES, "test", sProp).Return(nil)
args = [][]byte{[]byte(GETINSTALLEDCHAINCODES)}
sProp, _ = utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
identityDeserializer.Msg = sProp.ProposalBytes
Expand Down Expand Up @@ -323,6 +328,8 @@ func testDeploy(t *testing.T, ccname string, version string, path string, forceB
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, "test", sProp).Return(nil)
args = [][]byte{[]byte(GETCCINFO), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK {
t.FailNow()
Expand Down Expand Up @@ -414,6 +421,8 @@ func TestMultipleDeploy(t *testing.T) {
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, "test", sProp).Return(nil)
args = [][]byte{[]byte(GETCCINFO), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK {
t.FailNow()
Expand All @@ -429,11 +438,15 @@ func TestMultipleDeploy(t *testing.T) {
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, "test", sProp2).Return(nil)
args = [][]byte{[]byte(DEPLOY), []byte("test"), b}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp2); res.Status != shim.OK {
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, "test", sProp).Return(nil)
args = [][]byte{[]byte(GETCCINFO), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK {
t.FailNow()
Expand Down Expand Up @@ -508,12 +521,16 @@ func TestRetryFailedDeploy(t *testing.T) {
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETDEPSPEC, "test", sProp2).Return(nil)
//deploy correctly now
args = [][]byte{[]byte(DEPLOY), []byte("test"), b}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp2); res.Status != shim.OK {
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETDEPSPEC, "test", sProp).Return(nil)
//get the deploymentspec
args = [][]byte{[]byte(GETDEPSPEC), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK || res.Payload == nil {
Expand Down Expand Up @@ -605,6 +622,8 @@ func TestTamperChaincode(t *testing.T) {
}

//get the deploymentspec
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETDEPSPEC, "test", sProp).Return(nil)
args = [][]byte{[]byte(GETDEPSPEC), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res = stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status == shim.OK {
t.Logf("Expected error on tampering files but succeeded")
Expand Down Expand Up @@ -724,6 +743,8 @@ func testIPolDeploy(t *testing.T, iPol string, successExpected bool) {
}
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, chainid, sProp).Return(nil)
args = [][]byte{[]byte(GETCCINFO), []byte(chainid), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK {
if successExpected {
Expand Down Expand Up @@ -867,6 +888,8 @@ func testIPolUpgrade(t *testing.T, iPol string, successExpected bool) {
if res := stub.MockInvokeWithSignedProposal("1", args, sProp2); res.Status != shim.OK {
t.Fatalf("Deploy failed %s", res)
}
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, chainid, sProp).Return(nil)
args = [][]byte{[]byte(GETCCINFO), []byte(chainid), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK {
t.Fatalf("GetCCInfo after deploy failed %s", res)
Expand Down Expand Up @@ -950,18 +973,24 @@ func TestGetAPIsWithoutInstall(t *testing.T) {
//Force remove CC
os.Remove(lscctestpath + "/example02.0")

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, "test", sProp).Return(nil)
//GETCCINFO should still work
args = [][]byte{[]byte(GETCCINFO), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK {
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCDATA, "test", sProp).Return(nil)
//GETCCDATA should still work
args = [][]byte{[]byte(GETCCDATA), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status != shim.OK {
t.FailNow()
}

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETDEPSPEC, "test", sProp).Return(nil)
//GETDEPSPEC should not work
args = [][]byte{[]byte(GETDEPSPEC), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
if res := stub.MockInvokeWithSignedProposal("1", args, sProp); res.Status == shim.OK {
Expand Down Expand Up @@ -1140,6 +1169,8 @@ func TestGetCCAccessRights(t *testing.T) {
// Should pass
args = [][]byte{[]byte(GETCCINFO), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
sProp, _ := utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, "test", sProp).Return(nil)
identityDeserializer.Msg = sProp.ProposalBytes
sProp.Signature = sProp.ProposalBytes
res := stub.MockInvokeWithSignedProposal("1", args, sProp)
Expand All @@ -1150,20 +1181,24 @@ func TestGetCCAccessRights(t *testing.T) {

// Should fail
sProp, _ = utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1"))
identityDeserializer.Msg = sProp.ProposalBytes
sProp.Signature = sProp.ProposalBytes
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCINFO, "test", sProp).Return(errors.New("Failed access control"))
res = stub.MockInvokeWithSignedProposal("1", args, sProp)
if res.Status == shim.OK {
t.Logf("This should fail [%s]", res.Message)
t.FailNow()
}
assert.Contains(t, res.Message, "Failed access control")
mockAclProvider.AssertExpectations(t)

// GETDEPSPEC
// Should pass
args = [][]byte{[]byte(GETDEPSPEC), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
sProp, _ = utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
identityDeserializer.Msg = sProp.ProposalBytes
sProp.Signature = sProp.ProposalBytes
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETDEPSPEC, "test", sProp).Return(nil)
res = stub.MockInvokeWithSignedProposal("1", args, sProp)
if res.Status != shim.OK {
t.Logf("This should pass [%s]", res.Message)
Expand All @@ -1172,20 +1207,24 @@ func TestGetCCAccessRights(t *testing.T) {

// Should fail
sProp, _ = utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1"))
identityDeserializer.Msg = sProp.ProposalBytes
sProp.Signature = sProp.ProposalBytes
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETDEPSPEC, "test", sProp).Return(errors.New("Failed access control"))
res = stub.MockInvokeWithSignedProposal("1", args, sProp)
if res.Status == shim.OK {
t.Logf("This should fail [%s]", res.Message)
t.FailNow()
}
assert.Contains(t, res.Message, "Failed access control")
mockAclProvider.AssertExpectations(t)

// GETCCDATA
// Should pass
args = [][]byte{[]byte(GETCCDATA), []byte("test"), []byte(cds.ChaincodeSpec.ChaincodeId.Name)}
sProp, _ = utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
identityDeserializer.Msg = sProp.ProposalBytes
sProp.Signature = sProp.ProposalBytes
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCDATA, "test", sProp).Return(nil)
res = stub.MockInvokeWithSignedProposal("1", args, sProp)
if res.Status != shim.OK {
t.Logf("This should pass [%s]", res.Message)
Expand All @@ -1194,19 +1233,22 @@ func TestGetCCAccessRights(t *testing.T) {

// Should fail
sProp, _ = utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Bob"), []byte("msg1"))
identityDeserializer.Msg = sProp.ProposalBytes
sProp.Signature = sProp.ProposalBytes
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCDATA, "test", sProp).Return(errors.New("Failed access control"))
res = stub.MockInvokeWithSignedProposal("1", args, sProp)
if res.Status == shim.OK {
t.Logf("This should fail [%s]", res.Message)
t.FailNow()
}
assert.Contains(t, res.Message, "Failed access control")
mockAclProvider.AssertExpectations(t)
}

var id msp.SigningIdentity
var sid []byte
var mspid string
var chainid string = util.GetTestChainID()
var mockAclProvider *mocks.MockACLProvider

func TestMain(m *testing.M) {
ccprovider.SetChaincodesPath(lscctestpath)
Expand Down Expand Up @@ -1260,5 +1302,9 @@ func TestMain(m *testing.M) {
// also set the MSP for the "test" chain
mspmgmt.XXXSetMSPManager("test", mspmgmt.GetManagerForChain(util.GetTestChainID()))

mockAclProvider = &mocks.MockACLProvider{}
mockAclProvider.Reset()

aclmgmt.RegisterACLProvider(mockAclProvider)
os.Exit(m.Run())
}

0 comments on commit 65cb5b2

Please sign in to comment.