Skip to content

Commit 33e3fb6

Browse files
author
Jason Yellick
committed
[FAB-6567] Move ACL resources deeper in tree
The ACL work preliminarily put all of the policy references and polici at the root level of the config tree. Because the peer resources tree is now intended to support more than ACLs, keeping these at the root level does not make sense. Instead, these need to be moved down into the tree. This CR moves the old resource policy references from /Resources to /Resources/APIs It also creates /Resources/PeerPolicies as a global location to declare policies which may be referenced both for API ACL purposes, as well as later by other parts of the resources tree. Change-Id: I5c8eeba0472f480ac88ddbf02a0a1a3d90092463 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent 20b5503 commit 33e3fb6

File tree

8 files changed

+169
-89
lines changed

8 files changed

+169
-89
lines changed

common/resourcesconfig/apis.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright IBM Corp. 2017 All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package resourcesconfig
8+
9+
import (
10+
cb "github.com/hyperledger/fabric/protos/common"
11+
pb "github.com/hyperledger/fabric/protos/peer"
12+
13+
"github.com/golang/protobuf/proto"
14+
"github.com/pkg/errors"
15+
)
16+
17+
// apisGroup represents the ConfigGroup names APIs off the resources group
18+
type apisGroup struct {
19+
apiPolicyRefs map[string]string
20+
}
21+
22+
func (ag *apisGroup) PolicyRefForAPI(apiName string) string {
23+
return ag.apiPolicyRefs[apiName]
24+
}
25+
26+
func newAPIsGroup(group *cb.ConfigGroup) (*apisGroup, error) {
27+
if len(group.Groups) > 0 {
28+
return nil, errors.New("apis group does not support sub-groups")
29+
}
30+
31+
apiPolicyRefs := make(map[string]string)
32+
33+
for key, value := range group.Values {
34+
api := &pb.Resource{}
35+
if err := proto.Unmarshal(value.Value, api); err != nil {
36+
return nil, err
37+
}
38+
39+
// If the policy is fully qualified, ie to /Channel/Application/Readers leave it alone
40+
// otherwise, make it fully qualified referring to /Resources/APIs/policyName
41+
if '/' != api.PolicyRef[0] {
42+
apiPolicyRefs[key] = "/" + RootGroupKey + "/" + APIsGroupKey + "/" + api.PolicyRef
43+
} else {
44+
apiPolicyRefs[key] = api.PolicyRef
45+
}
46+
}
47+
48+
return &apisGroup{
49+
apiPolicyRefs: apiPolicyRefs,
50+
}, nil
51+
}

common/resourcesconfig/bundle.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ var logger = flogging.MustGetLogger("common/config/resource")
2525

2626
// PolicyMapper is an interface for
2727
type PolicyMapper interface {
28-
// PolicyRefForResource takes the name of a resource, and returns the policy name for a resource
29-
// or the empty string is the resource is not found
30-
PolicyRefForResource(resourceName string) string
28+
// PolicyRefForAPI takes the name of an API, and returns the policy name
29+
// or the empty string if the API is not found
30+
PolicyRefForAPI(apiName string) string
3131
}
3232

3333
type Bundle struct {
@@ -107,6 +107,6 @@ func (b *Bundle) PolicyManager() policies.Manager {
107107
return b.pm
108108
}
109109

110-
func (b *Bundle) ResourcePolicyMapper() PolicyMapper {
111-
return b.rg
110+
func (b *Bundle) APIPolicyMapper() PolicyMapper {
111+
return b.rg.apisGroup
112112
}

common/resourcesconfig/bundle_test.go

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,32 @@ func TestBundleGreenPath(t *testing.T) {
3333
env, err := utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, "foo", nil, &cb.ConfigEnvelope{
3434
Config: &cb.Config{
3535
ChannelGroup: &cb.ConfigGroup{
36-
Values: map[string]*cb.ConfigValue{
37-
"Foo": &cb.ConfigValue{
38-
Value: utils.MarshalOrPanic(&pb.Resource{
39-
PolicyRef: "foo",
40-
}),
41-
},
42-
"Bar": &cb.ConfigValue{
43-
Value: utils.MarshalOrPanic(&pb.Resource{
44-
PolicyRef: "/Channel/foo",
45-
}),
46-
},
47-
},
48-
Policies: map[string]*cb.ConfigPolicy{
49-
"foo": dummyPolicy,
50-
"bar": dummyPolicy,
51-
},
5236
Groups: map[string]*cb.ConfigGroup{
53-
"subGroup": &cb.ConfigGroup{
37+
APIsGroupKey: &cb.ConfigGroup{
38+
Values: map[string]*cb.ConfigValue{
39+
"Foo": &cb.ConfigValue{
40+
Value: utils.MarshalOrPanic(&pb.Resource{
41+
PolicyRef: "foo",
42+
}),
43+
},
44+
"Bar": &cb.ConfigValue{
45+
Value: utils.MarshalOrPanic(&pb.Resource{
46+
PolicyRef: "/Channel/foo",
47+
}),
48+
},
49+
},
50+
},
51+
PeerPoliciesGroupKey: &cb.ConfigGroup{
5452
Policies: map[string]*cb.ConfigPolicy{
55-
"other": dummyPolicy,
53+
"foo": dummyPolicy,
54+
"bar": dummyPolicy,
55+
},
56+
Groups: map[string]*cb.ConfigGroup{
57+
"subGroup": &cb.ConfigGroup{
58+
Policies: map[string]*cb.ConfigPolicy{
59+
"other": dummyPolicy,
60+
},
61+
},
5662
},
5763
},
5864
},
@@ -64,8 +70,8 @@ func TestBundleGreenPath(t *testing.T) {
6470
b, err := New(env, nil, nil)
6571
assert.NoError(t, err)
6672
assert.NotNil(t, b)
67-
assert.Equal(t, "/Resources/foo", b.ResourcePolicyMapper().PolicyRefForResource("Foo"))
68-
assert.Equal(t, "/Channel/foo", b.ResourcePolicyMapper().PolicyRefForResource("Bar"))
73+
assert.Equal(t, "/Resources/APIs/foo", b.APIPolicyMapper().PolicyRefForAPI("Foo"))
74+
assert.Equal(t, "/Channel/foo", b.APIPolicyMapper().PolicyRefForAPI("Bar"))
6975

7076
t.Run("Code coverage nits", func(t *testing.T) {
7177
assert.Equal(t, b.RootGroupKey(), RootGroupKey)
@@ -79,7 +85,7 @@ func TestBundleBadSubGroup(t *testing.T) {
7985
Config: &cb.Config{
8086
ChannelGroup: &cb.ConfigGroup{
8187
Groups: map[string]*cb.ConfigGroup{
82-
"subGroup": &cb.ConfigGroup{
88+
PeerPoliciesGroupKey: &cb.ConfigGroup{
8389
Values: map[string]*cb.ConfigValue{
8490
"Foo": &cb.ConfigValue{
8591
Value: utils.MarshalOrPanic(&pb.Resource{
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright IBM Corp. 2017 All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package resourcesconfig
8+
9+
import (
10+
cb "github.com/hyperledger/fabric/protos/common"
11+
12+
"github.com/pkg/errors"
13+
)
14+
15+
// peerPoliciesGroup is a free-form group, which supports only policies
16+
type peerPoliciesGroup struct{}
17+
18+
func newPeerPoliciesGroup(group *cb.ConfigGroup) (*peerPoliciesGroup, error) {
19+
return &peerPoliciesGroup{}, verifyNoMoreValues(group)
20+
}
21+
22+
func verifyNoMoreValues(subGroup *cb.ConfigGroup) error {
23+
if len(subGroup.Values) > 0 {
24+
return errors.Errorf("sub-groups not allowed to have values")
25+
}
26+
for _, subGroup := range subGroup.Groups {
27+
if err := verifyNoMoreValues(subGroup); err != nil {
28+
return err
29+
}
30+
}
31+
return nil
32+
}

common/resourcesconfig/resources.go

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,60 +7,47 @@ SPDX-License-Identifier: Apache-2.0
77
package resourcesconfig
88

99
import (
10-
"fmt"
11-
1210
cb "github.com/hyperledger/fabric/protos/common"
13-
pb "github.com/hyperledger/fabric/protos/peer"
1411

15-
"github.com/golang/protobuf/proto"
12+
"github.com/pkg/errors"
1613
)
1714

18-
// ResourceGroup represents the ConfigGroup at the base of the resource configuration
19-
type resourceGroup struct {
20-
resourcePolicyRefs map[string]string
21-
}
15+
const (
16+
PeerPoliciesGroupKey = "PeerPolicies"
17+
APIsGroupKey = "APIs"
18+
)
2219

23-
func (rg *resourceGroup) PolicyRefForResource(resourceName string) string {
24-
return rg.resourcePolicyRefs[resourceName]
20+
// resourceGroup represents the ConfigGroup at the base of the resource configuration.
21+
type resourceGroup struct {
22+
apisGroup *apisGroup
23+
peerPoliciesGroup *peerPoliciesGroup
2524
}
2625

2726
func newResourceGroup(root *cb.ConfigGroup) (*resourceGroup, error) {
28-
resourcePolicyRefs := make(map[string]string)
29-
30-
for key, value := range root.Values {
31-
resource := &pb.Resource{}
32-
if err := proto.Unmarshal(value.Value, resource); err != nil {
33-
return nil, err
34-
}
35-
36-
// If the policy is fully qualified, ie to /Channel/Application/Readers leave it alone
37-
// otherwise, make it fully qualified referring to /Resources/policyName
38-
if '/' != resource.PolicyRef[0] {
39-
resourcePolicyRefs[key] = "/" + RootGroupKey + "/" + resource.PolicyRef
40-
} else {
41-
resourcePolicyRefs[key] = resource.PolicyRef
42-
}
27+
if len(root.Values) > 0 {
28+
return nil, errors.New("/Resources group does not support any values")
4329
}
4430

45-
for _, subGroup := range root.Groups {
46-
if err := verifyNoMoreValues(subGroup); err != nil {
47-
return nil, err
48-
}
31+
// initialize the elements with empty implementations, override if actually set
32+
rg := &resourceGroup{
33+
apisGroup: &apisGroup{},
34+
peerPoliciesGroup: &peerPoliciesGroup{},
4935
}
5036

51-
return &resourceGroup{
52-
resourcePolicyRefs: resourcePolicyRefs,
53-
}, nil
54-
}
55-
56-
func verifyNoMoreValues(subGroup *cb.ConfigGroup) error {
57-
if len(subGroup.Values) > 0 {
58-
return fmt.Errorf("sub-groups not allowed to have values")
59-
}
60-
for _, subGroup := range subGroup.Groups {
61-
if err := verifyNoMoreValues(subGroup); err != nil {
62-
return err
37+
for subGroupName, subGroup := range root.Groups {
38+
var err error
39+
switch subGroupName {
40+
case APIsGroupKey:
41+
rg.apisGroup, err = newAPIsGroup(subGroup)
42+
case PeerPoliciesGroupKey:
43+
rg.peerPoliciesGroup, err = newPeerPoliciesGroup(subGroup)
44+
default:
45+
err = errors.New("unknown sub-group")
46+
}
47+
if err != nil {
48+
return nil, errors.Wrapf(err, "error processing group %s", subGroupName)
6349
}
6450
}
65-
return nil
51+
52+
return rg, nil
6653
}

core/scc/rscc/rscc_test.go

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,26 @@ func createConfig() []byte {
9191
b := utils.MarshalOrPanic(&common.Config{
9292
Type: int32(common.ConfigType_RESOURCE),
9393
ChannelGroup: &common.ConfigGroup{
94-
// All of the default seed data values would inside this ConfigGroup
95-
Values: map[string]*common.ConfigValue{
96-
"res": &common.ConfigValue{
97-
Value: utils.MarshalOrPanic(&pb.Resource{
98-
PolicyRef: "respol",
99-
}),
100-
ModPolicy: "resmodpol",
101-
},
102-
},
103-
Policies: map[string]*common.ConfigPolicy{
104-
"respol": &common.ConfigPolicy{
105-
Policy: &common.Policy{
106-
Type: int32(common.Policy_SIGNATURE),
107-
Value: utils.MarshalOrPanic(cauthdsl.AcceptAllPolicy),
94+
Groups: map[string]*common.ConfigGroup{
95+
"APIs": &common.ConfigGroup{
96+
// All of the default seed data values would inside this ConfigGroup
97+
Values: map[string]*common.ConfigValue{
98+
"res": &common.ConfigValue{
99+
Value: utils.MarshalOrPanic(&pb.Resource{
100+
PolicyRef: "respol",
101+
}),
102+
ModPolicy: "resmodpol",
103+
},
104+
},
105+
Policies: map[string]*common.ConfigPolicy{
106+
"respol": &common.ConfigPolicy{
107+
Policy: &common.Policy{
108+
Type: int32(common.Policy_SIGNATURE),
109+
Value: utils.MarshalOrPanic(cauthdsl.AcceptAllPolicy),
110+
},
111+
ModPolicy: "Example",
112+
},
108113
},
109-
ModPolicy: "Example",
110114
},
111115
},
112116
ModPolicy: "adminpol",

core/scc/rscc/rsccpolicy.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func (e InvalidIdInfo) Error() string {
3535

3636
//policyEvalutor interface provides the interfaces for policy evaluation
3737
type policyEvaluator interface {
38-
PolicyRefForResource(resName string) string
38+
PolicyRefForAPI(resName string) string
3939
Evaluate(polName string, id []*common.SignedData) error
4040
}
4141

@@ -44,13 +44,13 @@ type policyEvaluatorImpl struct {
4444
bundle *resourcesconfig.Bundle
4545
}
4646

47-
func (pe *policyEvaluatorImpl) PolicyRefForResource(resName string) string {
48-
pm := pe.bundle.ResourcePolicyMapper()
47+
func (pe *policyEvaluatorImpl) PolicyRefForAPI(resName string) string {
48+
pm := pe.bundle.APIPolicyMapper()
4949
if pm == nil {
5050
return ""
5151
}
5252

53-
return pm.PolicyRefForResource(resName)
53+
return pm.PolicyRefForAPI(resName)
5454
}
5555

5656
func (pe *policyEvaluatorImpl) Evaluate(polName string, sd []*common.SignedData) error {
@@ -80,7 +80,7 @@ type rsccPolicyProviderImpl struct {
8080

8181
//GetPolicyName returns the policy name given the resource string
8282
func (rp *rsccPolicyProviderImpl) GetPolicyName(resName string) string {
83-
return rp.pEvaluator.PolicyRefForResource(resName)
83+
return rp.pEvaluator.PolicyRefForAPI(resName)
8484
}
8585

8686
func newRsccPolicyProvider(channel string, pEvaluator policyEvaluator) rsccPolicyProvider {

core/scc/rscc/rsccpolicy_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type mockPolicyEvaluatorImpl struct {
3333
peval map[string]error
3434
}
3535

36-
func (pe *mockPolicyEvaluatorImpl) PolicyRefForResource(resName string) string {
36+
func (pe *mockPolicyEvaluatorImpl) PolicyRefForAPI(resName string) string {
3737
return pe.pmap[resName]
3838
}
3939

0 commit comments

Comments
 (0)