@@ -18,15 +18,25 @@ package policies
18
18
19
19
import (
20
20
"fmt"
21
+ "strings"
21
22
22
23
cb "github.com/hyperledger/fabric/protos/common"
23
24
24
25
logging "github.com/op/go-logging"
25
26
)
26
27
27
28
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
+
28
38
// ChannelApplicationReaders is the label for the channel's application readers policy
29
- ChannelApplicationReaders = "/channel/Application /Readers"
39
+ ChannelApplicationReaders = "/" + ChannelPrefix + "/" + ApplicationPrefix + " /Readers"
30
40
)
31
41
32
42
var logger = logging .MustGetLogger ("common/policies" )
@@ -45,7 +55,7 @@ type Manager interface {
45
55
// Manager returns the sub-policy manager for a given path and whether it exists
46
56
Manager (path []string ) (Manager , bool )
47
57
48
- // Basepath returns the basePath the manager was instnatiated with
58
+ // Basepath returns the basePath the manager was instantiated with
49
59
BasePath () string
50
60
51
61
// Policies returns all policy names defined in the manager
@@ -78,7 +88,9 @@ type policyConfig struct {
78
88
// ManagerImpl is an implementation of Manager and configtx.ConfigHandler
79
89
// In general, it should only be referenced as an Impl for the configtx.ConfigManager
80
90
type ManagerImpl struct {
91
+ parent * ManagerImpl
81
92
basePath string
93
+ fqPrefix string
82
94
providers map [int32 ]Provider
83
95
config * policyConfig
84
96
pendingConfig * policyConfig
@@ -93,6 +105,7 @@ func NewManagerImpl(basePath string, providers map[int32]Provider) *ManagerImpl
93
105
94
106
return & ManagerImpl {
95
107
basePath : basePath ,
108
+ fqPrefix : PathSeparator + basePath + PathSeparator ,
96
109
providers : providers ,
97
110
config : & policyConfig {
98
111
policies : make (map [string ]Policy ),
@@ -138,15 +151,36 @@ func (pm *ManagerImpl) Manager(path []string) (Manager, bool) {
138
151
139
152
// GetPolicy returns a policy and true if it was the policy requested, or false if it is the default reject policy
140
153
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 ]
142
176
if ! ok {
143
177
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 )
145
179
}
146
- return rejectPolicy (id ), false
180
+ return rejectPolicy (relpath ), false
147
181
}
148
182
if logger .IsEnabledFor (logging .DEBUG ) {
149
- logger .Debugf ("Returning policy %s for evaluation" , id )
183
+ logger .Debugf ("Returning policy %s for evaluation" , relpath )
150
184
}
151
185
return policy , true
152
186
}
@@ -165,6 +199,7 @@ func (pm *ManagerImpl) BeginPolicyProposals(groups []string) ([]Proposer, error)
165
199
managers := make ([]Proposer , len (groups ))
166
200
for i , group := range groups {
167
201
newManager := NewManagerImpl (group , pm .providers )
202
+ newManager .parent = pm
168
203
pm .pendingConfig .managers [group ] = newManager
169
204
managers [i ] = newManager
170
205
}
@@ -184,7 +219,7 @@ func (pm *ManagerImpl) CommitProposals() {
184
219
185
220
for managerPath , m := range pm .pendingConfig .managers {
186
221
for _ , policyName := range m .PolicyNames () {
187
- fqKey := managerPath + "/" + policyName
222
+ fqKey := managerPath + PathSeparator + policyName
188
223
pm .pendingConfig .policies [fqKey ], _ = m .GetPolicy (policyName )
189
224
logger .Debugf ("In commit adding relative sub-policy %s to %s" , fqKey , pm .basePath )
190
225
}
@@ -197,6 +232,20 @@ func (pm *ManagerImpl) CommitProposals() {
197
232
198
233
pm .config = pm .pendingConfig
199
234
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
+ }
200
249
}
201
250
202
251
// ProposePolicy takes key, path, and ConfigPolicy and registers it in the proposed PolicyManager, or errors
0 commit comments