Skip to content

Commit f777ba7

Browse files
author
Jason Yellick
committed
[FAB-2408] Fix policies absolute paths
https://jira.hyperledger.org/browse/FAB-2408 While the policy manager was still in development, the absolute path resolution for policies was handled in the configuration manager. This worked fine for config updates, but for other components of the system such as those depending on the 'ChannelApplicationReaders', the absolute paths did not work. This CR pushes the absolute policy path resolution back into the policy manager where it belongs. Change-Id: Idcfa2ca030115b3ff9e3034f8c54767af1c2ea49 Signed-off-by: Jason Yellick <[email protected]>
1 parent 2419383 commit f777ba7

File tree

4 files changed

+79
-21
lines changed

4 files changed

+79
-21
lines changed

common/configtx/update.go

-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package configtx
1818

1919
import (
2020
"fmt"
21-
"strings"
2221

2322
"github.com/hyperledger/fabric/common/policies"
2423
cb "github.com/hyperledger/fabric/protos/common"
@@ -123,10 +122,6 @@ func (cm *configManager) authorizeUpdate(configUpdateEnv *cb.ConfigUpdateEnvelop
123122
}
124123

125124
func (cm *configManager) policyForItem(item comparable) (policies.Policy, bool) {
126-
if strings.HasPrefix(item.modPolicy(), PathSeparator) {
127-
return cm.PolicyManager().GetPolicy(item.modPolicy()[1:])
128-
}
129-
130125
// path is always at least of length 1
131126
manager, ok := cm.PolicyManager().Manager(item.path[1:])
132127
if !ok {

common/configtx/update_test.go

-9
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,4 @@ func TestPolicyForItem(t *testing.T) {
7272
})
7373
assert.True(t, ok)
7474
assert.Equal(t, policy, fooPolicy, "Should not have found relative foo policy the foo manager")
75-
76-
policy, ok = cm.policyForItem(comparable{
77-
path: []string{"root", "foo"},
78-
ConfigValue: &cb.ConfigValue{
79-
ModPolicy: "/rootPolicy",
80-
},
81-
})
82-
assert.True(t, ok)
83-
assert.Equal(t, policy, rootPolicy, "Should not have found absolute root policy from the foo path position")
8475
}

common/policies/policy.go

+56-7
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,25 @@ package policies
1818

1919
import (
2020
"fmt"
21+
"strings"
2122

2223
cb "github.com/hyperledger/fabric/protos/common"
2324

2425
logging "github.com/op/go-logging"
2526
)
2627

2728
const (
29+
// Path separator is used to separate policy names in paths
30+
PathSeparator = "/"
31+
32+
// ChannelPrefix is used in the path of standard channel policy managers
33+
ChannelPrefix = "Channel"
34+
35+
// ApplicationPrefix is used in the path of standard application policy paths
36+
ApplicationPrefix = "Application"
37+
2838
// ChannelApplicationReaders is the label for the channel's application readers policy
29-
ChannelApplicationReaders = "/channel/Application/Readers"
39+
ChannelApplicationReaders = "/" + ChannelPrefix + "/" + ApplicationPrefix + "/Readers"
3040
)
3141

3242
var logger = logging.MustGetLogger("common/policies")
@@ -45,7 +55,7 @@ type Manager interface {
4555
// Manager returns the sub-policy manager for a given path and whether it exists
4656
Manager(path []string) (Manager, bool)
4757

48-
// Basepath returns the basePath the manager was instnatiated with
58+
// Basepath returns the basePath the manager was instantiated with
4959
BasePath() string
5060

5161
// Policies returns all policy names defined in the manager
@@ -78,7 +88,9 @@ type policyConfig struct {
7888
// ManagerImpl is an implementation of Manager and configtx.ConfigHandler
7989
// In general, it should only be referenced as an Impl for the configtx.ConfigManager
8090
type ManagerImpl struct {
91+
parent *ManagerImpl
8192
basePath string
93+
fqPrefix string
8294
providers map[int32]Provider
8395
config *policyConfig
8496
pendingConfig *policyConfig
@@ -93,6 +105,7 @@ func NewManagerImpl(basePath string, providers map[int32]Provider) *ManagerImpl
93105

94106
return &ManagerImpl{
95107
basePath: basePath,
108+
fqPrefix: PathSeparator + basePath + PathSeparator,
96109
providers: providers,
97110
config: &policyConfig{
98111
policies: make(map[string]Policy),
@@ -138,15 +151,36 @@ func (pm *ManagerImpl) Manager(path []string) (Manager, bool) {
138151

139152
// GetPolicy returns a policy and true if it was the policy requested, or false if it is the default reject policy
140153
func (pm *ManagerImpl) GetPolicy(id string) (Policy, bool) {
141-
policy, ok := pm.config.policies[id]
154+
if id == "" {
155+
logger.Errorf("Returning dummy reject all policy because no policy ID supplied")
156+
return rejectPolicy(id), false
157+
}
158+
var relpath string
159+
160+
if strings.HasPrefix(id, PathSeparator) {
161+
if pm.parent != nil {
162+
return pm.parent.GetPolicy(id)
163+
}
164+
if !strings.HasPrefix(id, pm.fqPrefix) {
165+
if logger.IsEnabledFor(logging.DEBUG) {
166+
logger.Debugf("Requested policy from root manager with wrong basePath: %s, returning rejectAll", id)
167+
}
168+
return rejectPolicy(id), false
169+
}
170+
relpath = id[len(pm.fqPrefix):]
171+
} else {
172+
relpath = id
173+
}
174+
175+
policy, ok := pm.config.policies[relpath]
142176
if !ok {
143177
if logger.IsEnabledFor(logging.DEBUG) {
144-
logger.Debugf("Returning dummy reject all policy because %s could not be found in %s", id, pm.basePath)
178+
logger.Debugf("Returning dummy reject all policy because %s could not be found in /%s/%s", id, pm.basePath, relpath)
145179
}
146-
return rejectPolicy(id), false
180+
return rejectPolicy(relpath), false
147181
}
148182
if logger.IsEnabledFor(logging.DEBUG) {
149-
logger.Debugf("Returning policy %s for evaluation", id)
183+
logger.Debugf("Returning policy %s for evaluation", relpath)
150184
}
151185
return policy, true
152186
}
@@ -165,6 +199,7 @@ func (pm *ManagerImpl) BeginPolicyProposals(groups []string) ([]Proposer, error)
165199
managers := make([]Proposer, len(groups))
166200
for i, group := range groups {
167201
newManager := NewManagerImpl(group, pm.providers)
202+
newManager.parent = pm
168203
pm.pendingConfig.managers[group] = newManager
169204
managers[i] = newManager
170205
}
@@ -184,7 +219,7 @@ func (pm *ManagerImpl) CommitProposals() {
184219

185220
for managerPath, m := range pm.pendingConfig.managers {
186221
for _, policyName := range m.PolicyNames() {
187-
fqKey := managerPath + "/" + policyName
222+
fqKey := managerPath + PathSeparator + policyName
188223
pm.pendingConfig.policies[fqKey], _ = m.GetPolicy(policyName)
189224
logger.Debugf("In commit adding relative sub-policy %s to %s", fqKey, pm.basePath)
190225
}
@@ -197,6 +232,20 @@ func (pm *ManagerImpl) CommitProposals() {
197232

198233
pm.config = pm.pendingConfig
199234
pm.pendingConfig = nil
235+
236+
if pm.parent == nil && pm.basePath == ChannelPrefix {
237+
if _, ok := pm.config.managers[ApplicationPrefix]; ok {
238+
// Check for default application policies if the application component is defined
239+
for _, policyName := range []string{ChannelApplicationReaders} {
240+
_, ok := pm.GetPolicy(policyName)
241+
if !ok {
242+
logger.Warningf("Current configuration has no policy '%s', this will likely cause problems in production systems", policyName)
243+
} else {
244+
logger.Debugf("As expected, current configuration has policy '%s'", policyName)
245+
}
246+
}
247+
}
248+
}
200249
}
201250

202251
// ProposePolicy takes key, path, and ConfigPolicy and registers it in the proposed PolicyManager, or errors

common/policies/policy_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ func TestUnnestedManager(t *testing.T) {
7474

7575
func TestNestedManager(t *testing.T) {
7676
m := NewManagerImpl("test", defaultProviders())
77+
absPrefix := "/test/"
7778
nesting1, err := m.BeginPolicyProposals([]string{"nest1"})
7879
assert.NoError(t, err)
7980
assert.Len(t, nesting1, 1, "Should not have returned exactly one additional manager")
@@ -137,6 +138,10 @@ func TestNestedManager(t *testing.T) {
137138
for _, policyName := range policyNames {
138139
_, ok := m.GetPolicy(policyName)
139140
assert.True(t, ok, "Should have found policy %s", policyName)
141+
142+
absName := absPrefix + policyName
143+
_, ok = m.GetPolicy(absName)
144+
assert.True(t, ok, "Should have found absolute policy %s", absName)
140145
}
141146

142147
for _, policyName := range n1PolicyNames {
@@ -145,6 +150,12 @@ func TestNestedManager(t *testing.T) {
145150

146151
_, ok = m.GetPolicy(n1.BasePath() + "/" + policyName)
147152
assert.True(t, ok, "Should have found policy %s", policyName)
153+
154+
for i, abs := range []Manager{n1, m} {
155+
absName := absPrefix + n1.BasePath() + "/" + policyName
156+
_, ok = abs.GetPolicy(absName)
157+
assert.True(t, ok, "Should have found absolutely policy for manager %d", i)
158+
}
148159
}
149160

150161
for _, policyName := range n2aPolicyNames {
@@ -156,6 +167,12 @@ func TestNestedManager(t *testing.T) {
156167

157168
_, ok = m.GetPolicy(n1.BasePath() + "/" + n2a.BasePath() + "/" + policyName)
158169
assert.True(t, ok, "Should have found policy %s", policyName)
170+
171+
for i, abs := range []Manager{n2a, n1, m} {
172+
absName := absPrefix + n1.BasePath() + "/" + n2a.BasePath() + "/" + policyName
173+
_, ok = abs.GetPolicy(absName)
174+
assert.True(t, ok, "Should have found absolutely policy for manager %d", i)
175+
}
159176
}
160177

161178
for _, policyName := range n2bPolicyNames {
@@ -167,5 +184,11 @@ func TestNestedManager(t *testing.T) {
167184

168185
_, ok = m.GetPolicy(n1.BasePath() + "/" + n2b.BasePath() + "/" + policyName)
169186
assert.True(t, ok, "Should have found policy %s", policyName)
187+
188+
for i, abs := range []Manager{n2b, n1, m} {
189+
absName := absPrefix + n1.BasePath() + "/" + n2b.BasePath() + "/" + policyName
190+
_, ok = abs.GetPolicy(absName)
191+
assert.True(t, ok, "Should have found absolutely policy for manager %d", i)
192+
}
170193
}
171194
}

0 commit comments

Comments
 (0)