Skip to content

Commit

Permalink
[FAB-17639] Add/Remove ACLs from channel config.
Browse files Browse the repository at this point in the history
* Implemented Add/Remove ACLs functionalities for channel configuration.

Signed-off-by: Chongxin Luo <[email protected]>
  • Loading branch information
DereckLuo authored and sykesm committed Mar 27, 2020
1 parent 4d515e0 commit 222f99a
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 16 deletions.
59 changes: 59 additions & 0 deletions pkg/config/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,65 @@ func (c *ConfigTx) RemoveAnchorPeer(orgName string, anchorPeerToRemove Address)
return nil
}

// AddACLs adds ACLS to an existing channel config application.
func (c *ConfigTx) AddACLs(acls map[string]string) error {
configACLs, err := getACLs(c.updated)
if err != nil {
return err
}

for apiResource, policyRef := range configACLs {
acls[apiResource] = policyRef
}

err = addValue(c.updated.ChannelGroup.Groups[ApplicationGroupKey], aclValues(acls), AdminsPolicyKey)
if err != nil {
return err
}

return nil
}

// RemoveACLs a list of ACLs from given channel config application.
func (c *ConfigTx) RemoveACLs(acls []string) error {
configACLs, err := getACLs(c.updated)
if err != nil {
return err
}

for _, acl := range acls {
delete(configACLs, acl)
}

err = addValue(c.updated.ChannelGroup.Groups[ApplicationGroupKey], aclValues(configACLs), AdminsPolicyKey)
if err != nil {
return err
}

return nil
}

// getACLs returns a map of ACLS for given config application.
func getACLs(config *cb.Config) (map[string]string, error) {
applicationGroup, ok := config.ChannelGroup.Groups[ApplicationGroupKey]
if !ok {
return nil, fmt.Errorf("application does not exist in channel config")
}

ACLProtos := &pb.ACLs{}

err := unmarshalConfigValueAtKey(applicationGroup, ACLsKey, ACLProtos)
if err != nil {
return nil, err
}

retACLs := map[string]string{}
for apiResource, policyRef := range ACLProtos.Acls {
retACLs[apiResource] = policyRef.PolicyRef
}
return retACLs, nil
}

// GetAnchorPeers retrieves existing anchor peers from a application organization.
func (c *ConfigTx) GetAnchorPeers(orgName string) ([]Address, error) {
applicationOrgGroup, ok := c.base.ChannelGroup.Groups[ApplicationGroupKey].Groups[orgName]
Expand Down
169 changes: 153 additions & 16 deletions pkg/config/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -664,28 +664,141 @@ func TestGetAnchorPeerFailures(t *testing.T) {
}
}

func baseApplication(t *testing.T) Application {
return Application{
Policies: standardPolicies(),
Organizations: []Organization{
{
Name: "Org1",
Policies: applicationOrgStandardPolicies(),
MSP: baseMSP(t),
func TestAddACL(t *testing.T) {
t.Parallel()

tests := []struct {
testName string
configMod func(*cb.Config)
newACL map[string]string
expectedACL map[string]string
expectedErr string
}{
{
testName: "success",
newACL: map[string]string{"acl2": "newACL"},
expectedACL: map[string]string{
"acl1": "hi",
"acl2": "newACL",
},
{
Name: "Org2",
Policies: applicationOrgStandardPolicies(),
MSP: baseMSP(t),
expectedErr: "",
},
{
testName: "configuration missing application config group",
configMod: func(config *cb.Config) {
delete(config.ChannelGroup.Groups, ApplicationGroupKey)
},
expectedErr: "application does not exist in channel config",
},
Capabilities: map[string]bool{
"V1_3": true,
}

for _, tt := range tests {
tt := tt
t.Run(tt.testName, func(t *testing.T) {
t.Parallel()
gt := NewGomegaWithT(t)

channelGroup := newConfigGroup()
baseApplication := baseApplication(t)
applicationGroup, err := newApplicationGroup(baseApplication)

channelGroup.Groups[ApplicationGroupKey] = applicationGroup
config := &cb.Config{
ChannelGroup: channelGroup,
}
if tt.configMod != nil {
tt.configMod(config)
}
c := ConfigTx{
base: config,
updated: config,
}

err = c.AddACLs(tt.newACL)
if tt.expectedErr != "" {
gt.Expect(err).To(MatchError(tt.expectedErr))
} else {
gt.Expect(err).NotTo(HaveOccurred())
acls, err := getACLs(config)
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(acls).To(Equal(tt.expectedACL))
}
})
}
}

func TestRemoveACL(t *testing.T) {
t.Parallel()

tests := []struct {
testName string
configMod func(*cb.Config)
removeACL []string
expectedACL map[string]string
expectedErr string
}{
{
testName: "success",
removeACL: []string{"acl1", "acl2"},
expectedACL: map[string]string{
"acl3": "acl3Value",
},
expectedErr: "",
},
ACLs: map[string]string{
"acl1": "hi",
{
testName: "remove non-existing acls",
removeACL: []string{"bad-acl1", "bad-acl2"},
expectedACL: map[string]string{
"acl1": "hi",
"acl2": "acl2Value",
"acl3": "acl3Value",
},
expectedErr: "",
},
{
testName: "configuration missing application config group",
configMod: func(config *cb.Config) {
delete(config.ChannelGroup.Groups, ApplicationGroupKey)
},
expectedErr: "application does not exist in channel config",
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.testName, func(t *testing.T) {
t.Parallel()
gt := NewGomegaWithT(t)

channelGroup := newConfigGroup()
baseApplication := baseApplication(t)
baseApplication.ACLs["acl2"] = "acl2Value"
baseApplication.ACLs["acl3"] = "acl3Value"
applicationGroup, err := newApplicationGroup(baseApplication)

channelGroup.Groups[ApplicationGroupKey] = applicationGroup
config := &cb.Config{
ChannelGroup: channelGroup,
}
if tt.configMod != nil {
tt.configMod(config)
}
c := &ConfigTx{
base: config,
updated: config,
}

err = c.RemoveACLs(tt.removeACL)
if tt.expectedErr != "" {
gt.Expect(err).To(MatchError(tt.expectedErr))
} else {
gt.Expect(err).NotTo(HaveOccurred())
acls, err := getACLs(config)
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(acls).To(Equal(tt.expectedACL))
}
})
}
}

func TestAddApplicationOrg(t *testing.T) {
Expand Down Expand Up @@ -903,3 +1016,27 @@ func TestAddApplicationOrgFailures(t *testing.T) {
err = c.AddApplicationOrg(org)
gt.Expect(err).To(MatchError("failed to create application org Org3: no policies defined"))
}

func baseApplication(t *testing.T) Application {
return Application{
Policies: standardPolicies(),
Organizations: []Organization{
{
Name: "Org1",
Policies: applicationOrgStandardPolicies(),
MSP: baseMSP(t),
},
{
Name: "Org2",
Policies: applicationOrgStandardPolicies(),
MSP: baseMSP(t),
},
},
Capabilities: map[string]bool{
"V1_3": true,
},
ACLs: map[string]string{
"acl1": "hi",
},
}
}

0 comments on commit 222f99a

Please sign in to comment.