Skip to content

Commit b4dc9fc

Browse files
author
Jason Yellick
committed
FAB-13517 Add ACLs for _lifecycle chaincode
This CR wires the standard ACL checking stuff into the new _lifecycle chaincode. Change-Id: Ie16018fb8e6b7b9904f345cd60b231e7af5326f9 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent fd1d654 commit b4dc9fc

File tree

9 files changed

+175
-1
lines changed

9 files changed

+175
-1
lines changed

core/aclmgmt/defaultaclprovider.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ func (d *defaultACLProviderImpl) initialize() {
5858
d.pResourcePolicyMap = make(map[string]string)
5959
d.cResourcePolicyMap = make(map[string]string)
6060

61+
//-------------- _lifecycle --------------
62+
d.pResourcePolicyMap[resources.Lifecycle_InstallChaincode] = mgmt.Admins
63+
d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincode] = mgmt.Admins
64+
d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincodes] = mgmt.Admins
65+
d.pResourcePolicyMap[resources.Lifecycle_ApproveChaincodeDefinitionForMyOrg] = mgmt.Admins
66+
67+
d.cResourcePolicyMap[resources.Lifecycle_CommitChaincodeDefinition] = CHANNELWRITERS
68+
d.cResourcePolicyMap[resources.Lifecycle_QueryChaincodeDefinition] = CHANNELWRITERS
69+
d.cResourcePolicyMap[resources.Lifecycle_QueryNamespaceDefinitions] = CHANNELWRITERS
70+
6171
//-------------- LSCC --------------
6272
//p resources (implemented by the chaincode currently)
6373
d.pResourcePolicyMap[resources.Lscc_Install] = mgmt.Admins

core/aclmgmt/resources/resources.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ package resources
1111
//based on local MSP). These are not currently covered by resource or default
1212
//ACLProviders
1313
const (
14+
// _lifecycle resources
15+
Lifecycle_InstallChaincode = "_lifecycle/InstallChaincode"
16+
Lifecycle_QueryInstalledChaincode = "_lifecycle/QueryInstalledChaincode"
17+
Lifecycle_QueryInstalledChaincodes = "_lifecycle/QueryInstalledChaincodes"
18+
Lifecycle_ApproveChaincodeDefinitionForMyOrg = "_lifecycle/ApproveChaincodeDefinitionForMyOrg"
19+
Lifecycle_CommitChaincodeDefinition = "_lifecycle/CommitChaincodeDefinition"
20+
Lifecycle_QueryChaincodeDefinition = "_lifecycle/QueryChaincodeDefinition"
21+
Lifecycle_QueryNamespaceDefinitions = "_lifecycle/QueryNamespaceDefinitions"
22+
1423
//Lscc resources
1524
Lscc_Install = "lscc/Install"
1625
Lscc_Deploy = "lscc/Deploy"

core/chaincode/lifecycle/integration_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ var _ = Describe("Integration", func() {
3535
fakeCapabilities *mock.ApplicationCapabilities
3636
fakeOrgConfig *mock.ApplicationOrgConfig
3737
fakeStub *mock.ChaincodeStub
38+
fakeACLProvider *mock.ACLProvider
3839

3940
fakeOrgKVStore map[string][]byte
4041
fakePublicKVStore map[string][]byte
@@ -53,6 +54,7 @@ var _ = Describe("Integration", func() {
5354
fakeCapabilities = &mock.ApplicationCapabilities{}
5455
fakeCapabilities.LifecycleV20Returns(true)
5556
fakeApplicationConfig.CapabilitiesReturns(fakeCapabilities)
57+
fakeACLProvider = &mock.ACLProvider{}
5658

5759
fakeOrgConfig = &mock.ApplicationOrgConfig{}
5860
fakeOrgConfig.MSPIDReturns("fake-mspid")
@@ -68,6 +70,7 @@ var _ = Describe("Integration", func() {
6870
Functions: l,
6971
OrgMSPID: "fake-mspid",
7072
ChannelConfigSource: fakeChannelConfigSource,
73+
ACLProvider: fakeACLProvider,
7174
}
7275

7376
fakePublicKVStore = map[string][]byte{}

core/chaincode/lifecycle/lifecycle_suite_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
commonledger "github.com/hyperledger/fabric/common/ledger"
1515
"github.com/hyperledger/fabric/common/policies"
1616
"github.com/hyperledger/fabric/common/util"
17+
"github.com/hyperledger/fabric/core/aclmgmt"
1718
"github.com/hyperledger/fabric/core/chaincode/lifecycle"
1819
"github.com/hyperledger/fabric/core/chaincode/shim"
1920
"github.com/hyperledger/fabric/core/handlers/validation/api/state"
@@ -22,6 +23,11 @@ import (
2223
. "github.com/onsi/gomega"
2324
)
2425

26+
//go:generate counterfeiter -o mock/aclprovider.go --fake-name ACLProvider . aclProvider
27+
type aclProvider interface {
28+
aclmgmt.ACLProvider
29+
}
30+
2531
//go:generate counterfeiter -o mock/chaincode_stub.go --fake-name ChaincodeStub . chaincodeStub
2632
type chaincodeStub interface {
2733
shim.ChaincodeStubInterface

core/chaincode/lifecycle/mock/aclprovider.go

Lines changed: 98 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/chaincode/lifecycle/scc.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/hyperledger/fabric/common/chaincode"
1313
"github.com/hyperledger/fabric/common/channelconfig"
14+
"github.com/hyperledger/fabric/core/aclmgmt"
1415
"github.com/hyperledger/fabric/core/chaincode/shim"
1516
"github.com/hyperledger/fabric/core/dispatcher"
1617
pb "github.com/hyperledger/fabric/protos/peer"
@@ -91,6 +92,8 @@ type ChannelConfigSource interface {
9192
type SCC struct {
9293
OrgMSPID string
9394

95+
ACLProvider aclmgmt.ACLProvider
96+
9497
ChannelConfigSource ChannelConfigSource
9598

9699
// Functions provides the backing implementation of lifecycle.
@@ -170,7 +173,16 @@ func (scc *SCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
170173
}
171174
}
172175

173-
// TODO add ACLs
176+
// Handle ACL:
177+
sp, err := stub.GetSignedProposal()
178+
if err != nil {
179+
return shim.Error(fmt.Sprintf("Failed getting signed proposal from stub: [%s]", err))
180+
}
181+
182+
err = scc.ACLProvider.CheckACL(fmt.Sprintf("%s/%s", LifecycleNamespace, args[0]), stub.GetChannelID(), sp)
183+
if err != nil {
184+
return shim.Error(fmt.Sprintf("Failed to authorize invocation due to failed ACL check: %s", err))
185+
}
174186

175187
outputBytes, err := scc.Dispatcher.Dispatch(
176188
args[1],

core/chaincode/lifecycle/scc_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var _ = Describe("SCC", func() {
3131
fakeChannelConfig *mock.ChannelConfig
3232
fakeApplicationConfig *mock.ApplicationConfig
3333
fakeCapabilities *mock.ApplicationCapabilities
34+
fakeACLProvider *mock.ACLProvider
3435
)
3536

3637
BeforeEach(func() {
@@ -43,13 +44,15 @@ var _ = Describe("SCC", func() {
4344
fakeCapabilities = &mock.ApplicationCapabilities{}
4445
fakeCapabilities.LifecycleV20Returns(true)
4546
fakeApplicationConfig.CapabilitiesReturns(fakeCapabilities)
47+
fakeACLProvider = &mock.ACLProvider{}
4648
scc = &lifecycle.SCC{
4749
Dispatcher: &dispatcher.Dispatcher{
4850
Protobuf: &dispatcher.ProtobufImpl{},
4951
},
5052
Functions: fakeSCCFuncs,
5153
OrgMSPID: "fake-mspid",
5254
ChannelConfigSource: fakeChannelConfigSource,
55+
ACLProvider: fakeACLProvider,
5356
}
5457
})
5558

@@ -137,6 +140,27 @@ var _ = Describe("SCC", func() {
137140
})
138141
})
139142

143+
Context("when the ACL provider disapproves of the function", func() {
144+
BeforeEach(func() {
145+
fakeStub.GetArgsReturns([][]byte{[]byte("any-function"), nil})
146+
fakeACLProvider.CheckACLReturns(fmt.Errorf("acl-error"))
147+
})
148+
149+
It("returns an error", func() {
150+
Expect(scc.Invoke(fakeStub)).To(Equal(shim.Error("Failed to authorize invocation due to failed ACL check: acl-error")))
151+
})
152+
153+
Context("when the signed data for the tx cannot be retrieved", func() {
154+
BeforeEach(func() {
155+
fakeStub.GetSignedProposalReturns(nil, fmt.Errorf("shim-error"))
156+
})
157+
158+
It("returns an error", func() {
159+
Expect(scc.Invoke(fakeStub)).To(Equal(shim.Error("Failed getting signed proposal from stub: [shim-error]")))
160+
})
161+
})
162+
})
163+
140164
Describe("InstallChaincode", func() {
141165
var (
142166
arg *lb.InstallChaincodeArgs

peer/node/start.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ func serve(args []string) error {
314314
Functions: lifecycleImpl,
315315
OrgMSPID: mspID,
316316
ChannelConfigSource: peer.Default,
317+
ACLProvider: aclProvider,
317318
}
318319

319320
dockerProvider := dockercontroller.NewProvider(

sampleconfig/configtx.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ Application: &ApplicationDefaults
145145
# User's can override these defaults with their own policy mapping by defining the
146146
# mapping under ACLs in their channel definition
147147

148+
#---New Lifecycle System Chaincode (_lifecycle) function to policy mapping for access control--#
149+
150+
# ACL policy for _lifecycle's "CommitChaincodeDefinition" function
151+
_lifecycle/CommitChaincodeDefinition: /Channel/Application/Writers
152+
153+
# ACL policy for _lifecycle's "QueryChaincodeDefinition" function
154+
_lifecycle/QueryChaincodeDefinition: /Channel/Application/Readers
155+
156+
# ACL policy for _lifecycle's "QueryNamespaceDefinitions" function
157+
_lifecycle/QueryNamespaceDefinitions: /Channel/Application/Readers
158+
148159
#---Lifecycle System Chaincode (lscc) function to policy mapping for access control---#
149160

150161
# ACL policy for lscc's "getid" function

0 commit comments

Comments
 (0)