Skip to content

Commit

Permalink
[FAB-10466] Function test for syscc ACL via query
Browse files Browse the repository at this point in the history
This CR adds function tests for system chaincode ACL policies
by querying. It also modifies a few of the returned error
messages to make them consistent with the other system chaincode
ACL error messages.

Change-Id: I7c58ae779e531c7e98078e21796165df102abeb6
Signed-off-by: Will Lahti <[email protected]>
  • Loading branch information
wlahti committed Jun 11, 2018
1 parent bfb4b0f commit 469dd2f
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 64 deletions.
11 changes: 5 additions & 6 deletions core/scc/cscc/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,7 @@ func (e *PeerConfiger) InvokeNoShim(args [][]byte, sp *pb.SignedProposal) pb.Res
// 2. check local MSP Admins policy
// TODO: move to ACLProvider once it will support chainless ACLs
if err = e.policyChecker.CheckPolicyNoChannel(mgmt.Admins, sp); err != nil {
return shim.Error(fmt.Sprintf("\"JoinChain\" request failed authorization check "+
"for channel [%s]: [%s]", cid, err))
return shim.Error(fmt.Sprintf("access denied for [%s][%s]: [%s]", fname, cid, err))
}

// Initialize txsFilter if it does not yet exist. We can do this safely since
Expand All @@ -159,28 +158,28 @@ func (e *PeerConfiger) InvokeNoShim(args [][]byte, sp *pb.SignedProposal) pb.Res
case GetConfigBlock:
// 2. check policy
if err = e.aclProvider.CheckACL(resources.Cscc_GetConfigBlock, string(args[1]), sp); err != nil {
return shim.Error(fmt.Sprintf("\"GetConfigBlock\" request failed authorization check for channel [%s]: [%s]", args[1], err))
return shim.Error(fmt.Sprintf("access denied for [%s][%s]: %s", fname, args[1], err))
}

return getConfigBlock(args[1])
case GetConfigTree:
// 2. check policy
if err = e.aclProvider.CheckACL(resources.Cscc_GetConfigTree, string(args[1]), sp); err != nil {
return shim.Error(fmt.Sprintf("\"GetConfigTree\" request failed authorization check for channel [%s]: [%s]", args[1], err))
return shim.Error(fmt.Sprintf("access denied for [%s][%s]: %s", fname, args[1], err))
}

return e.getConfigTree(args[1])
case SimulateConfigTreeUpdate:
// Check policy
if err = e.aclProvider.CheckACL(resources.Cscc_SimulateConfigTreeUpdate, string(args[1]), sp); err != nil {
return shim.Error(fmt.Sprintf("\"SimulateConfigTreeUpdate\" request failed authorization check for channel [%s]: [%s]", args[1], err))
return shim.Error(fmt.Sprintf("access denied for [%s][%s]: %s", fname, args[1], err))
}
return e.simulateConfigTreeUpdate(args[1], args[2])
case GetChannels:
// 2. check local MSP Members policy
// TODO: move to ACLProvider once it will support chainless ACLs
if err = e.policyChecker.CheckPolicyNoChannel(mgmt.Members, sp); err != nil {
return shim.Error(fmt.Sprintf("\"GetChannels\" request failed authorization check: [%s]", err))
return shim.Error(fmt.Sprintf("access denied for [%s]: %s", fname, err))
}

return getChannels()
Expand Down
10 changes: 5 additions & 5 deletions core/scc/cscc/configure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func TestConfigerInvokeInvalidParameters(t *testing.T) {
args := [][]byte{[]byte("GetChannels")}
res = stub.MockInvokeWithSignedProposal("3", args, nil)
assert.Equal(t, res.Status, int32(shim.ERROR), "CSCC invoke expected to fail no signed proposal provided")
assert.Contains(t, res.Message, "failed authorization check")
assert.Contains(t, res.Message, "access denied for [GetChannels]")

args = [][]byte{[]byte("fooFunction"), []byte("testChainID")}
res = stub.MockInvoke("5", args)
Expand Down Expand Up @@ -301,7 +301,7 @@ func TestConfigerInvokeJoinChainCorrectParams(t *testing.T) {
if res.Status == shim.OK {
t.Fatalf("cscc invoke JoinChain must fail : %v", res.Message)
}
assert.Contains(t, res.Message, "\"JoinChain\" request failed authorization check for channel")
assert.Contains(t, res.Message, "access denied for [JoinChain][mytestchainid]")
sProp.Signature = sProp.ProposalBytes

// Query the configuration block
Expand All @@ -317,7 +317,7 @@ func TestConfigerInvokeJoinChainCorrectParams(t *testing.T) {
args = [][]byte{[]byte("GetConfigBlock"), []byte(chainID)}
res = stub.MockInvokeWithSignedProposal("2", args, sProp)
if res.Status == shim.OK {
t.Fatalf("cscc invoke GetConfigBlock shoulda have failed: %v", res.Message)
t.Fatalf("cscc invoke GetConfigBlock should have failed: %v", res.Message)
}
assert.Contains(t, res.Message, "Failed authorization")
mockAclProvider.AssertExpectations(t)
Expand Down Expand Up @@ -399,7 +399,7 @@ func TestGetConfigTree(t *testing.T) {
aclProvider.CheckACLReturns(fmt.Errorf("fake-error"))
res := pc.InvokeNoShim(args, nil)
assert.NotEqual(t, int32(shim.OK), res.Status)
assert.Equal(t, "\"GetConfigTree\" request failed authorization check for channel [testchan]: [fake-error]", res.Message)
assert.Equal(t, "access denied for [GetConfigTree][testchan]: fake-error", res.Message)
})
}

Expand Down Expand Up @@ -481,7 +481,7 @@ func TestSimulateConfigTreeUpdate(t *testing.T) {
aclProvider.CheckACLReturns(fmt.Errorf("fake-error"))
res := pc.InvokeNoShim(args, nil)
assert.NotEqual(t, int32(shim.OK), res.Status)
assert.Equal(t, "\"SimulateConfigTreeUpdate\" request failed authorization check for channel [testchan]: [fake-error]", res.Message)
assert.Equal(t, "access denied for [SimulateConfigTreeUpdate][testchan]: fake-error", res.Message)
})
}

Expand Down
10 changes: 5 additions & 5 deletions core/scc/lscc/lscc.go
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ func (lscc *lifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response

// 2. check local MSP Admins policy
if err = lscc.policyChecker.CheckPolicyNoChannel(mgmt.Admins, sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization for INSTALL has been denied (error-%s)", err))
return shim.Error(fmt.Sprintf("access denied for [%s]: %s", function, err))
}

depSpec := args[1]
Expand Down Expand Up @@ -849,12 +849,12 @@ func (lscc *lifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response
resource = resources.Lscc_GetChaincodeData
}
if err = lscc.aclProvider.CheckACL(resource, channel, sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization request failed %s: %s", channel, err))
return shim.Error(fmt.Sprintf("access denied for [%s][%s]: %s", function, channel, err))
}

cdbytes, err := lscc.getCCInstance(stub, ccname)
if err != nil {
logger.Errorf("error getting chaincode %s on channel: %s(err:%s)", ccname, channel, err)
logger.Errorf("error getting chaincode %s on channel [%s]: %s", ccname, channel, err)
return shim.Error(err.Error())
}

Expand All @@ -880,7 +880,7 @@ func (lscc *lifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response
}

if err = lscc.aclProvider.CheckACL(resources.Lscc_GetInstantiatedChaincodes, stub.GetChannelID(), sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization for GETCHAINCODES on channel %s has been denied with error %s", args[0], err))
return shim.Error(fmt.Sprintf("access denied for [%s][%s]: %s", function, stub.GetChannelID(), err))
}

return lscc.getChaincodes(stub)
Expand All @@ -891,7 +891,7 @@ func (lscc *lifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response

// 2. check local MSP Admins policy
if err = lscc.policyChecker.CheckPolicyNoChannel(mgmt.Admins, sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization for GETINSTALLEDCHAINCODES on channel %s has been denied with error %s", args[0], err))
return shim.Error(fmt.Sprintf("access denied for [%s]: %s", function, err))
}

return lscc.getInstalledChaincodes()
Expand Down
34 changes: 18 additions & 16 deletions core/scc/lscc/lscc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func TestInstall(t *testing.T) {
testInstall(t, "", "0", path, false, EmptyChaincodeNameErr("").Error(), "Alice", scc, stub)
testInstall(t, "example02", "1{}0", path, false, InvalidVersionErr("1{}0").Error(), "Alice", scc, stub)
testInstall(t, "example02", "0", path, true, InvalidStatedbArtifactsErr("").Error(), "Alice", scc, stub)
testInstall(t, "example02", "0", path, false, "Authorization for INSTALL has been denied", "Bob", scc, stub)
testInstall(t, "example02", "0", path, false, "access denied for [install]", "Bob", scc, stub)
testInstall(t, "example02-2", "1.0-alpha+001", path, false, "", "Alice", scc, stub)
testInstall(t, "example02-2", "1.0+sha.c0ffee", path, false, "", "Alice", scc, stub)

Expand Down Expand Up @@ -640,21 +640,23 @@ func TestFunctionsWithAliases(t *testing.T) {
sProp.Signature = sProp.ProposalBytes

testInvoke := func(function, resource string) {
res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1")}, nil)
assert.NotEqual(t, int32(shim.OK), res.Status)
assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message)
t.Run(function, func(t *testing.T) {
res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1")}, nil)
assert.NotEqual(t, int32(shim.OK), res.Status)
assert.Equal(t, "invalid number of arguments to lscc: 2", res.Message)

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(errors.New("bonanza"))
res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("chaincode")}, sProp)
assert.NotEqual(t, int32(shim.OK), res.Status, res.Message)
assert.Contains(t, res.Message, "Authorization request failed testchannel1: bonanza")
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(errors.New("bonanza"))
res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("chaincode")}, sProp)
assert.NotEqual(t, int32(shim.OK), res.Status, res.Message)
assert.Equal(t, fmt.Sprintf("access denied for [%s][testchannel1]: bonanza", function), res.Message)

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(nil)
res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("nonexistentchaincode")}, sProp)
assert.NotEqual(t, int32(shim.OK), res.Status, res.Message)
assert.Equal(t, res.Message, "could not find chaincode with name 'nonexistentchaincode'")
mockAclProvider.Reset()
mockAclProvider.On("CheckACL", resource, "testchannel1", sProp).Return(nil)
res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function), []byte("testchannel1"), []byte("nonexistentchaincode")}, sProp)
assert.NotEqual(t, int32(shim.OK), res.Status, res.Message)
assert.Equal(t, res.Message, "could not find chaincode with name 'nonexistentchaincode'")
})
}

testInvoke("getid", "lscc/ChaincodeExists")
Expand Down Expand Up @@ -686,7 +688,7 @@ func TestGetChaincodes(t *testing.T) {
mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, "test", sProp).Return(errors.New("coyote"))
res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
assert.NotEqual(t, int32(shim.OK), res.Status)
assert.Regexp(t, "Authorization for GETCHAINCODES on channel(.*)coyote", res.Message)
assert.Regexp(t, `access denied for \[`+function+`\]\[test\](.*)coyote`, res.Message)

mockAclProvider.Reset()
mockAclProvider.On("CheckACL", resources.Lscc_GetInstantiatedChaincodes, "test", sProp).Return(nil)
Expand Down Expand Up @@ -726,7 +728,7 @@ func TestGetInstalledChaincodes(t *testing.T) {

res = stub.MockInvokeWithSignedProposal("1", [][]byte{[]byte(function)}, sProp)
assert.NotEqual(t, int32(shim.OK), res.Status)
assert.Contains(t, res.Message, "Authorization for GETINSTALLEDCHAINCODES")
assert.Contains(t, res.Message, "access denied for ["+function+"]")

sProp, _ = utils.MockSignedEndorserProposalOrPanic("", &pb.ChaincodeSpec{}, []byte("Alice"), []byte("msg1"))
identityDeserializer.Msg = sProp.ProposalBytes
Expand Down
2 changes: 1 addition & 1 deletion core/scc/qscc/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func (e *LedgerQuerier) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
// 2. check the channel reader policy
res := getACLResource(fname)
if err = e.aclProvider.CheckACL(res, cid, sp); err != nil {
return shim.Error(fmt.Sprintf("Authorization request for [%s][%s] failed: [%s]", fname, cid, err))
return shim.Error(fmt.Sprintf("access denied for [%s][%s]: [%s]", fname, cid, err))
}

switch fname {
Expand Down
Loading

0 comments on commit 469dd2f

Please sign in to comment.