Skip to content

Commit 2369857

Browse files
committed
(#2209) Extract authorization into a external callable
Signed-off-by: R.I.Pienaar <[email protected]>
1 parent 2daf759 commit 2369857

File tree

8 files changed

+117
-102
lines changed

8 files changed

+117
-102
lines changed

providers/agent/mcorpc/agent.go

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020-2022, R.I. Pienaar and the Choria Project contributors
1+
// Copyright (c) 2020-2025, R.I. Pienaar and the Choria Project contributors
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

@@ -30,7 +30,7 @@ type ActivationChecker func() bool
3030
type Agent struct {
3131
Log *logrus.Entry
3232
Config *config.Config
33-
Choria ChoriaFramework
33+
Choria inter.Framework
3434
ServerInfoSource agents.ServerInfoSource
3535

3636
activationCheck ActivationChecker
@@ -39,7 +39,7 @@ type Agent struct {
3939
}
4040

4141
// New creates a new MCollective SimpleRPC compatible agent
42-
func New(name string, metadata *agents.Metadata, fw ChoriaFramework, log *logrus.Entry) *Agent {
42+
func New(name string, metadata *agents.Metadata, fw inter.Framework, log *logrus.Entry) *Agent {
4343
a := &Agent{
4444
meta: metadata,
4545
Log: log.WithFields(logrus.Fields{"agent": name}),
@@ -218,34 +218,60 @@ func (a *Agent) parseIncomingMessage(msg []byte, request protocol.Request) (*Req
218218
}
219219

220220
func (a *Agent) authorize(req *Request) bool {
221-
if !a.Config.RPCAuthorization {
221+
if req.Agent != a.Name() {
222+
a.Log.Errorf("Could not process authorization for request for a different agent")
223+
return false
224+
}
225+
226+
return AuthorizeRequest(a.Choria, req, a.Config, a.ServerInfoSource, a.Log)
227+
}
228+
229+
// AuthorizeRequest authorizes a request using the configured authorizer
230+
func AuthorizeRequest(fw inter.Framework, req *Request, cfg *config.Config, si agents.ServerInfoSource, log *logrus.Entry) bool {
231+
if cfg == nil {
232+
log.Errorf("Could not process authorization without a configuration")
233+
return false
234+
}
235+
if !cfg.RPCAuthorization {
222236
return true
223237
}
238+
if req == nil {
239+
log.Errorf("Could not process authorization without a request")
240+
return false
241+
}
242+
if req.Agent == "" {
243+
log.Errorf("Could not process authorization without a agent name")
244+
return false
245+
}
246+
if si == nil {
247+
log.Errorf("Could not process authorization without a server info source")
248+
return false
249+
}
224250

225-
prov := strings.ToLower(a.Config.RPCAuthorizationProvider)
251+
prov := strings.ToLower(cfg.RPCAuthorizationProvider)
226252

227253
switch prov {
228254
case "action_policy":
229-
return actionPolicyAuthorize(req, a, a.Log)
255+
return actionPolicyAuthorize(req, cfg, log)
230256

231257
case "rego_policy":
232-
auth, err := regoPolicyAuthorize(req, a, a.Log)
258+
auth, err := regoPolicyAuthorize(req, fw, si, cfg, log)
233259
if err != nil {
234-
a.Log.Errorf("Could not process Open Policy Agent policy: %v", err)
260+
log.Errorf("Could not process Open Policy Agent policy: %v", err)
235261
return false
236262
}
237263
return auth
238264

239265
case "aaasvc", "aaasvc_policy":
240-
auth, err := aaasvcPolicyAuthorize(req, a, a.Log)
266+
auth, err := aaasvcPolicyAuthorize(req, cfg, log)
241267
if err != nil {
242-
a.Log.Errorf("Could not process JWT policy: %v", err)
268+
log.Errorf("Could not process JWT policy: %v", err)
243269
return false
244270
}
245271
return auth
246272

247273
default:
248-
a.Log.Errorf("Unsupported authorization provider: %s", prov)
274+
log.Errorf("Unsupported authorization provider: %s", prov)
249275

250276
}
251277

providers/agent/mcorpc/authz_actionpolicy.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020-2021, R.I. Pienaar and the Choria Project contributors
1+
// Copyright (c) 2020-2025, R.I. Pienaar and the Choria Project contributors
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

@@ -21,17 +21,16 @@ import (
2121
"github.com/sirupsen/logrus"
2222
)
2323

24-
func actionPolicyAuthorize(req *Request, agent *Agent, log *logrus.Entry) bool {
24+
func actionPolicyAuthorize(req *Request, cfg *config.Config, log *logrus.Entry) bool {
2525
logger := log.WithFields(logrus.Fields{
2626
"authorizer": "actionpolicy",
27-
"agent": agent.Name(),
27+
"agent": req.Agent,
2828
"request": req.RequestID,
2929
})
3030

3131
authz := &actionPolicy{
32-
cfg: agent.Config,
32+
cfg: cfg,
3333
req: req,
34-
agent: agent,
3534
matcher: &actionPolicyPolicy{log: logger},
3635
groups: make(map[string][]string),
3736
log: logger,
@@ -48,7 +47,6 @@ func actionPolicyAuthorize(req *Request, agent *Agent, log *logrus.Entry) bool {
4847
type actionPolicy struct {
4948
cfg *config.Config
5049
req *Request
51-
agent *Agent
5250
log *logrus.Entry
5351
matcher *actionPolicyPolicy
5452
groups map[string][]string
@@ -168,7 +166,7 @@ func (a *actionPolicy) checkRequestAgainstPolicy() (bool, error) {
168166
return false, nil
169167
}
170168

171-
factsMatched, err := pol.MatchesFacts(a.agent.Config, a.log)
169+
factsMatched, err := pol.MatchesFacts(a.cfg, a.log)
172170
if err != nil {
173171
return false, err
174172
}
@@ -204,7 +202,7 @@ func (a *actionPolicy) defaultPolicyFileName() string {
204202
}
205203

206204
func (a *actionPolicy) lookupPolicyFile() (string, error) {
207-
agentPolicy := filepath.Join(filepath.Dir(a.cfg.ConfigFile), "policies", a.agent.Name()+".policy")
205+
agentPolicy := filepath.Join(filepath.Dir(a.cfg.ConfigFile), "policies", a.req.Agent+".policy")
208206

209207
a.log.Debugf("Looking up agent policy in %s", agentPolicy)
210208
if util.FileExist(agentPolicy) {
@@ -218,7 +216,7 @@ func (a *actionPolicy) lookupPolicyFile() (string, error) {
218216
}
219217
}
220218

221-
return "", fmt.Errorf("no policy found for %s", a.agent.Name())
219+
return "", fmt.Errorf("no policy found for %s", a.req.Agent)
222220
}
223221

224222
func (a *actionPolicy) parseGroupFile(gfile string) error {

providers/agent/mcorpc/authz_actionpolicy_test.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2020-2021, R.I. Pienaar and the Choria Project contributors
1+
// Copyright (c) 2020-2025, R.I. Pienaar and the Choria Project contributors
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

@@ -21,7 +21,6 @@ var _ = Describe("ActionPolicy", func() {
2121
pol *actionPolicyPolicy
2222
logger *logrus.Entry
2323
mockctl *gomock.Controller
24-
fw *imock.MockFramework
2524
cfg *config.Config
2625
logbuffer *bytes.Buffer
2726
)
@@ -33,7 +32,7 @@ var _ = Describe("ActionPolicy", func() {
3332
pol = &actionPolicyPolicy{log: logger}
3433

3534
mockctl = gomock.NewController(GinkgoT())
36-
fw, cfg = imock.NewFrameworkForTests(mockctl, GinkgoWriter)
35+
_, cfg = imock.NewFrameworkForTests(mockctl, GinkgoWriter)
3736
cfg.ClassesFile = "testdata/classes.txt"
3837
cfg.FactSourceFile = "testdata/facts.json"
3938
cfg.DisableSecurityProviderVerify = true
@@ -48,11 +47,6 @@ var _ = Describe("ActionPolicy", func() {
4847
Action: "test",
4948
CallerID: "choria=ginkgo.mcollective",
5049
},
51-
agent: &Agent{
52-
Log: logger,
53-
Config: cfg,
54-
Choria: fw,
55-
},
5650
}
5751
})
5852

providers/agent/mcorpc/authz_jwt.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,22 @@ import (
2121
)
2222

2323
type aaasvcPolicy struct {
24-
cfg *config.Config
25-
req *Request
26-
agent *Agent
27-
log *logrus.Entry
24+
cfg *config.Config
25+
req *Request
26+
log *logrus.Entry
2827
}
2928

30-
func aaasvcPolicyAuthorize(req *Request, agent *Agent, log *logrus.Entry) (bool, error) {
29+
func aaasvcPolicyAuthorize(req *Request, cfg *config.Config, log *logrus.Entry) (bool, error) {
3130
logger := log.WithFields(logrus.Fields{
3231
"authorizer": "aaasvc",
33-
"agent": agent.Name(),
32+
"agent": req.Agent,
3433
"request": req.RequestID,
3534
})
3635

3736
authz := &aaasvcPolicy{
38-
cfg: agent.Config,
39-
req: req,
40-
agent: agent,
41-
log: logger,
37+
cfg: cfg,
38+
req: req,
39+
log: logger,
4240
}
4341

4442
return authz.authorize()

providers/agent/mcorpc/authz_jwt_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2022, R.I. Pienaar and the Choria Project contributors
1+
// Copyright (c) 2022-2025, R.I. Pienaar and the Choria Project contributors
22
//
33
// SPDX-License-Identifier: Apache-2.0
44

@@ -86,14 +86,14 @@ var _ = Describe("McoRPC/JWTAuthorizer", func() {
8686
})
8787

8888
It("Should fail for no caller public data", func() {
89-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
89+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
9090
Expect(err).To(MatchError("no policy received in request"))
9191
Expect(allowed).To(BeFalse())
9292
})
9393

9494
It("Should handle invalid tokens", func() {
9595
req.CallerPublicData = "blah"
96-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
96+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
9797
Expect(err).To(MatchError("invalid token in request: token contains an invalid number of segments"))
9898
Expect(allowed).To(BeFalse())
9999
})
@@ -105,7 +105,7 @@ var _ = Describe("McoRPC/JWTAuthorizer", func() {
105105
Expect(err).ToNot(HaveOccurred())
106106

107107
req.Agent = "discovery"
108-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
108+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
109109
Expect(err).ToNot(HaveOccurred())
110110
Expect(allowed).To(BeTrue())
111111
Expect(logBuff).To(gbytes.Say("Allowing discovery request"))
@@ -117,7 +117,7 @@ var _ = Describe("McoRPC/JWTAuthorizer", func() {
117117
req.CallerPublicData, err = tokens.SignToken(claims, prik)
118118
Expect(err).ToNot(HaveOccurred())
119119

120-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
120+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
121121
Expect(err).To(MatchError("no policy received in token"))
122122
Expect(allowed).To(BeFalse())
123123
})
@@ -129,7 +129,7 @@ var _ = Describe("McoRPC/JWTAuthorizer", func() {
129129
req.CallerPublicData, err = tokens.SignToken(claims, prik)
130130
Expect(err).ToNot(HaveOccurred())
131131

132-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
132+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
133133
Expect(err).To(MatchError("invalid agent policy: fail"))
134134
Expect(allowed).To(BeFalse())
135135
})
@@ -140,7 +140,7 @@ var _ = Describe("McoRPC/JWTAuthorizer", func() {
140140
req.CallerPublicData, err = tokens.SignToken(claims, prik)
141141
Expect(err).ToNot(HaveOccurred())
142142

143-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
143+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
144144
Expect(err).ToNot(HaveOccurred())
145145
Expect(allowed).To(BeTrue())
146146
})
@@ -153,7 +153,7 @@ var _ = Describe("McoRPC/JWTAuthorizer", func() {
153153
req.CallerPublicData, err = tokens.SignToken(claims, prik)
154154
Expect(err).ToNot(HaveOccurred())
155155

156-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
156+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
157157
Expect(err).To(HaveOccurred())
158158
Expect(err.Error()).To(MatchRegexp("could not initialize opa evaluator"))
159159
Expect(allowed).To(BeFalse())
@@ -165,7 +165,7 @@ var _ = Describe("McoRPC/JWTAuthorizer", func() {
165165
req.CallerPublicData, err = tokens.SignToken(claims, prik)
166166
Expect(err).ToNot(HaveOccurred())
167167

168-
allowed, err := aaasvcPolicyAuthorize(req, agent, log)
168+
allowed, err := aaasvcPolicyAuthorize(req, agent.Config, log)
169169
Expect(err).ToNot(HaveOccurred())
170170
Expect(allowed).To(BeTrue())
171171
})

0 commit comments

Comments
 (0)