Skip to content

Commit b7120a8

Browse files
Merge pull request #17785 from deads2k/rbac-05-noopinion
Automatic merge from submit-queue (batch tested with PRs 17549, 17785). fix authorization to use no opinion where possible Followup to the rebase. NoOpinion matches previous behavior. /assign @liggitt /assign @simo5 @openshift/sig-security
2 parents bfc48b1 + 68a2891 commit b7120a8

File tree

10 files changed

+70
-56
lines changed

10 files changed

+70
-56
lines changed

pkg/authorization/authorizer/authorizer.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ func NewSubjectLocator(delegate authorizerrbac.SubjectLocator) SubjectLocator {
2929

3030
func (a *openshiftAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) {
3131
if attributes.GetUser() == nil {
32-
return authorizer.DecisionDeny, "", errors.New("no user available on context")
32+
return authorizer.DecisionNoOpinion, "", errors.New("no user available on context")
3333
}
34-
authorized, delegateReason, err := a.delegate.Authorize(attributes)
35-
if authorized == authorizer.DecisionAllow {
34+
authorizationDecision, delegateReason, err := a.delegate.Authorize(attributes)
35+
if authorizationDecision == authorizer.DecisionAllow {
3636
return authorizer.DecisionAllow, reason(attributes), nil
3737
}
3838
// errors are allowed to occur
3939
if err != nil {
40-
return authorizer.DecisionDeny, "", err
40+
return authorizationDecision, "", err
4141
}
4242

4343
denyReason, err := a.forbiddenMessageMaker.MakeMessage(attributes)
@@ -48,7 +48,7 @@ func (a *openshiftAuthorizer) Authorize(attributes authorizer.Attributes) (autho
4848
denyReason += ": " + delegateReason
4949
}
5050

51-
return authorizer.DecisionDeny, denyReason, nil
51+
return authorizationDecision, denyReason, nil
5252
}
5353

5454
// GetAllowedSubjects returns the subjects it knows can perform the action.

pkg/authorization/authorizer/browsersafe/authorizer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,5 @@ type recordingAuthorizer struct {
7171

7272
func (t *recordingAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
7373
t.attributes = a
74-
return authorizer.DecisionDeny, "", nil
74+
return authorizer.DecisionNoOpinion, "", nil
7575
}

pkg/authorization/authorizer/scope/authorizer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func NewAuthorizer(delegate authorizer.Authorizer, clusterRoleGetter rbaclisters
2626
func (a *scopeAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) {
2727
user := attributes.GetUser()
2828
if user == nil {
29-
return authorizer.DecisionDeny, "", fmt.Errorf("user missing from context")
29+
return authorizer.DecisionNoOpinion, "", fmt.Errorf("user missing from context")
3030
}
3131

3232
scopes := user.GetExtra()[authorizationapi.ScopesKey]
@@ -52,5 +52,6 @@ func (a *scopeAuthorizer) Authorize(attributes authorizer.Attributes) (authorize
5252
denyReason = err.Error()
5353
}
5454

55+
// the scope prevent this. We need to authoritatively deny
5556
return authorizer.DecisionDeny, fmt.Sprintf("scopes %v prevent this action; %v", scopes, denyReason), kerrors.NewAggregate(nonFatalErrors)
5657
}

pkg/authorization/authorizer/scope/authorizer_test.go

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ func TestAuthorize(t *testing.T) {
2828
ResourceRequest: true,
2929
Namespace: "ns",
3030
},
31-
expectedErr: `user missing from context`,
31+
expectedAllowed: kauthorizer.DecisionNoOpinion,
32+
expectedErr: `user missing from context`,
3233
},
3334
{
3435
name: "no extra",
@@ -37,7 +38,8 @@ func TestAuthorize(t *testing.T) {
3738
ResourceRequest: true,
3839
Namespace: "ns",
3940
},
40-
expectedCalled: true,
41+
expectedCalled: true,
42+
expectedAllowed: kauthorizer.DecisionNoOpinion,
4143
},
4244
{
4345
name: "empty extra",
@@ -46,7 +48,8 @@ func TestAuthorize(t *testing.T) {
4648
ResourceRequest: true,
4749
Namespace: "ns",
4850
},
49-
expectedCalled: true,
51+
expectedCalled: true,
52+
expectedAllowed: kauthorizer.DecisionNoOpinion,
5053
},
5154
{
5255
name: "empty scopes",
@@ -55,7 +58,8 @@ func TestAuthorize(t *testing.T) {
5558
ResourceRequest: true,
5659
Namespace: "ns",
5760
},
58-
expectedCalled: true,
61+
expectedCalled: true,
62+
expectedAllowed: kauthorizer.DecisionNoOpinion,
5963
},
6064
{
6165
name: "bad scope",
@@ -64,8 +68,9 @@ func TestAuthorize(t *testing.T) {
6468
ResourceRequest: true,
6569
Namespace: "ns",
6670
},
67-
expectedMsg: `scopes [does-not-exist] prevent this action; User "" cannot "" "" with name "" in project "ns"`,
68-
expectedErr: `no scope evaluator found for "does-not-exist"`,
71+
expectedAllowed: kauthorizer.DecisionDeny,
72+
expectedMsg: `scopes [does-not-exist] prevent this action; User "" cannot "" "" with name "" in project "ns"`,
73+
expectedErr: `no scope evaluator found for "does-not-exist"`,
6974
},
7075
{
7176
name: "bad scope 2",
@@ -74,8 +79,9 @@ func TestAuthorize(t *testing.T) {
7479
ResourceRequest: true,
7580
Namespace: "ns",
7681
},
77-
expectedMsg: `scopes [user:dne] prevent this action; User "" cannot "" "" with name "" in project "ns"`,
78-
expectedErr: `unrecognized scope: user:dne`,
82+
expectedAllowed: kauthorizer.DecisionDeny,
83+
expectedMsg: `scopes [user:dne] prevent this action; User "" cannot "" "" with name "" in project "ns"`,
84+
expectedErr: `unrecognized scope: user:dne`,
7985
},
8086
{
8187
name: "scope doesn't cover",
@@ -84,7 +90,8 @@ func TestAuthorize(t *testing.T) {
8490
ResourceRequest: true,
8591
Namespace: "ns",
8692
Verb: "get", Resource: "users", Name: "harold"},
87-
expectedMsg: `scopes [user:info] prevent this action; User "" cannot get users in project "ns"`,
93+
expectedAllowed: kauthorizer.DecisionDeny,
94+
expectedMsg: `scopes [user:info] prevent this action; User "" cannot get users in project "ns"`,
8895
},
8996
{
9097
name: "scope covers",
@@ -93,7 +100,8 @@ func TestAuthorize(t *testing.T) {
93100
ResourceRequest: true,
94101
Namespace: "ns",
95102
Verb: "get", Resource: "users", Name: "~"},
96-
expectedCalled: true,
103+
expectedCalled: true,
104+
expectedAllowed: kauthorizer.DecisionNoOpinion,
97105
},
98106
{
99107
name: "scope covers for discovery",
@@ -102,7 +110,8 @@ func TestAuthorize(t *testing.T) {
102110
ResourceRequest: false,
103111
Namespace: "ns",
104112
Verb: "get", Path: "/api"},
105-
expectedCalled: true,
113+
expectedCalled: true,
114+
expectedAllowed: kauthorizer.DecisionNoOpinion,
106115
},
107116
{
108117
name: "user:full covers any resource",
@@ -111,7 +120,8 @@ func TestAuthorize(t *testing.T) {
111120
ResourceRequest: true,
112121
Namespace: "ns",
113122
Verb: "update", Resource: "users", Name: "harold"},
114-
expectedCalled: true,
123+
expectedCalled: true,
124+
expectedAllowed: kauthorizer.DecisionNoOpinion,
115125
},
116126
{
117127
name: "user:full covers any non-resource",
@@ -120,35 +130,38 @@ func TestAuthorize(t *testing.T) {
120130
ResourceRequest: false,
121131
Namespace: "ns",
122132
Verb: "post", Path: "/foo/bar/baz"},
123-
expectedCalled: true,
133+
expectedCalled: true,
134+
expectedAllowed: kauthorizer.DecisionNoOpinion,
124135
},
125136
}
126137

127138
for _, tc := range testCases {
128-
delegate := &fakeAuthorizer{allowed: tc.delegateAuthAllowed}
129-
authorizer := NewAuthorizer(delegate, nil, defaultauthorizer.NewForbiddenMessageResolver(""))
139+
t.Run(tc.name, func(t *testing.T) {
140+
delegate := &fakeAuthorizer{allowed: tc.delegateAuthAllowed}
141+
authorizer := NewAuthorizer(delegate, nil, defaultauthorizer.NewForbiddenMessageResolver(""))
130142

131-
actualAllowed, actualMsg, actualErr := authorizer.Authorize(tc.attributes)
132-
switch {
133-
case len(tc.expectedErr) == 0 && actualErr == nil:
134-
case len(tc.expectedErr) == 0 && actualErr != nil:
135-
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
136-
case len(tc.expectedErr) != 0 && actualErr == nil:
137-
t.Errorf("%s: missing error: %v", tc.name, tc.expectedErr)
138-
case len(tc.expectedErr) != 0 && actualErr != nil:
139-
if !strings.Contains(actualErr.Error(), tc.expectedErr) {
140-
t.Errorf("%s: expected %v, got %v", tc.name, tc.expectedErr, actualErr)
143+
actualAllowed, actualMsg, actualErr := authorizer.Authorize(tc.attributes)
144+
switch {
145+
case len(tc.expectedErr) == 0 && actualErr == nil:
146+
case len(tc.expectedErr) == 0 && actualErr != nil:
147+
t.Errorf("%s: unexpected error: %v", tc.name, actualErr)
148+
case len(tc.expectedErr) != 0 && actualErr == nil:
149+
t.Errorf("%s: missing error: %v", tc.name, tc.expectedErr)
150+
case len(tc.expectedErr) != 0 && actualErr != nil:
151+
if !strings.Contains(actualErr.Error(), tc.expectedErr) {
152+
t.Errorf("expected %v, got %v", tc.expectedErr, actualErr)
153+
}
141154
}
142-
}
143-
if tc.expectedMsg != actualMsg {
144-
t.Errorf("%s: expected %v, got %v", tc.name, tc.expectedMsg, actualMsg)
145-
}
146-
if tc.expectedAllowed != actualAllowed {
147-
t.Errorf("%s: expected %v, got %v", tc.name, tc.expectedAllowed, actualAllowed)
148-
}
149-
if tc.expectedCalled != delegate.called {
150-
t.Errorf("%s: expected %v, got %v", tc.name, tc.expectedCalled, delegate.called)
151-
}
155+
if tc.expectedMsg != actualMsg {
156+
t.Errorf("expected %v, got %v", tc.expectedMsg, actualMsg)
157+
}
158+
if tc.expectedAllowed != actualAllowed {
159+
t.Errorf("expected %v, got %v", tc.expectedAllowed, actualAllowed)
160+
}
161+
if tc.expectedCalled != delegate.called {
162+
t.Errorf("expected %v, got %v", tc.expectedCalled, delegate.called)
163+
}
164+
})
152165
}
153166
}
154167

@@ -162,7 +175,7 @@ func (a *fakeAuthorizer) Authorize(passedAttributes kauthorizer.Attributes) (kau
162175
if a.allowed {
163176
return kauthorizer.DecisionAllow, "", nil
164177
}
165-
return kauthorizer.DecisionDeny, "", nil
178+
return kauthorizer.DecisionNoOpinion, "", nil
166179
}
167180

168181
func (a *fakeAuthorizer) GetAllowedSubjects(attributes kauthorizer.Attributes) (sets.String, sets.String, error) {

pkg/authorization/registry/localresourceaccessreview/rest_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (a *testAuthorizer) Authorize(attributes kauthorizer.Attributes) (decision
3636
return kauthorizer.DecisionAllow, "", nil
3737
}
3838

39-
return kauthorizer.DecisionDeny, "", errors.New("Unsupported")
39+
return kauthorizer.DecisionNoOpinion, "", errors.New("Unsupported")
4040
}
4141
func (a *testAuthorizer) GetAllowedSubjects(passedAttributes kauthorizer.Attributes) (sets.String, sets.String, error) {
4242
a.actualAttributes = passedAttributes

pkg/authorization/registry/localsubjectaccessreview/rest_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (a *testAuthorizer) GetAllowedSubjects(passedAttributes kauthorizer.Attribu
5454
func TestNoNamespace(t *testing.T) {
5555
test := &subjectAccessTest{
5656
authorizer: &testAuthorizer{
57-
allowed: kauthorizer.DecisionDeny,
57+
allowed: kauthorizer.DecisionNoOpinion,
5858
},
5959
reviewRequest: &authorizationapi.LocalSubjectAccessReview{
6060
Action: authorizationapi.Action{
@@ -73,7 +73,7 @@ func TestNoNamespace(t *testing.T) {
7373

7474
func TestConflictingNamespace(t *testing.T) {
7575
authorizer := &testAuthorizer{
76-
allowed: kauthorizer.DecisionDeny,
76+
allowed: kauthorizer.DecisionNoOpinion,
7777
}
7878
reviewRequest := &authorizationapi.LocalSubjectAccessReview{
7979
Action: authorizationapi.Action{
@@ -99,7 +99,7 @@ func TestConflictingNamespace(t *testing.T) {
9999
func TestEmptyReturn(t *testing.T) {
100100
test := &subjectAccessTest{
101101
authorizer: &testAuthorizer{
102-
allowed: kauthorizer.DecisionDeny,
102+
allowed: kauthorizer.DecisionNoOpinion,
103103
reason: "because reasons",
104104
},
105105
reviewRequest: &authorizationapi.LocalSubjectAccessReview{

pkg/authorization/registry/resourceaccessreview/rest_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ func (a *testAuthorizer) Authorize(attributes kauthorizer.Attributes) (allowed k
3535
// allow the initial check for "can I run this RAR at all"
3636
if attributes.GetResource() == "localresourceaccessreviews" {
3737
if len(a.deniedNamespaces) != 0 && a.deniedNamespaces.Has(attributes.GetNamespace()) {
38-
return kauthorizer.DecisionDeny, "denied initial check", nil
38+
return kauthorizer.DecisionNoOpinion, "no decision on initial check", nil
3939
}
4040

4141
return kauthorizer.DecisionAllow, "", nil
4242
}
4343

44-
return kauthorizer.DecisionDeny, "", errors.New("unsupported")
44+
return kauthorizer.DecisionNoOpinion, "", errors.New("unsupported")
4545
}
4646
func (a *testAuthorizer) GetAllowedSubjects(passedAttributes kauthorizer.Attributes) (sets.String, sets.String, error) {
4747
a.actualAttributes = passedAttributes
@@ -56,7 +56,7 @@ func TestDeniedNamespace(t *testing.T) {
5656
authorizer: &testAuthorizer{
5757
users: sets.String{},
5858
groups: sets.String{},
59-
err: "denied initial check",
59+
err: "no decision on initial check",
6060
deniedNamespaces: sets.NewString("foo"),
6161
},
6262
reviewRequest: &authorizationapi.ResourceAccessReview{

pkg/authorization/registry/subjectaccessreview/rest_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (a *testAuthorizer) Authorize(passedAttributes kauthorizer.Attributes) (all
3939
// allow the initial check for "can I run this SAR at all"
4040
if passedAttributes.GetResource() == "localsubjectaccessreviews" {
4141
if len(a.deniedNamespaces) != 0 && a.deniedNamespaces.Has(passedAttributes.GetNamespace()) {
42-
return kauthorizer.DecisionDeny, "denied initial check", nil
42+
return kauthorizer.DecisionNoOpinion, "no decision on initial check", nil
4343
}
4444

4545
return kauthorizer.DecisionAllow, "", nil
@@ -59,7 +59,7 @@ func (a *testAuthorizer) GetAllowedSubjects(passedAttributes kauthorizer.Attribu
5959
func TestDeniedNamespace(t *testing.T) {
6060
test := &subjectAccessTest{
6161
authorizer: &testAuthorizer{
62-
allowed: kauthorizer.DecisionDeny,
62+
allowed: kauthorizer.DecisionNoOpinion,
6363
err: "denied initial check",
6464
deniedNamespaces: sets.NewString("foo"),
6565
},
@@ -81,7 +81,7 @@ func TestDeniedNamespace(t *testing.T) {
8181
func TestEmptyReturn(t *testing.T) {
8282
test := &subjectAccessTest{
8383
authorizer: &testAuthorizer{
84-
allowed: kauthorizer.DecisionDeny,
84+
allowed: kauthorizer.DecisionNoOpinion,
8585
reason: "because reasons",
8686
},
8787
reviewRequest: &authorizationapi.SubjectAccessReview{

pkg/ingress/admission/ingress_admission_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func TestAdmission(t *testing.T) {
9595
},
9696
{
9797
admit: false,
98-
allow: authorizer.DecisionDeny,
98+
allow: authorizer.DecisionNoOpinion,
9999
config: emptyConfig(),
100100
op: admission.Create,
101101
newHost: "foo.com",

pkg/scheduler/admission/podnodeconstraints/admission_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,14 +425,14 @@ func fakeAuthorizer(t *testing.T) authorizer.Authorizer {
425425
func (a *fakeTestAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) {
426426
ui := attributes.GetUser()
427427
if ui == nil {
428-
return authorizer.DecisionDeny, "", fmt.Errorf("No valid UserInfo for Context")
428+
return authorizer.DecisionNoOpinion, "", fmt.Errorf("No valid UserInfo for Context")
429429
}
430430
// User with pods/bindings. permission:
431431
if ui.GetName() == "system:serviceaccount:openshift-infra:daemonset-controller" {
432432
return authorizer.DecisionAllow, "", nil
433433
}
434434
// User without pods/bindings. permission:
435-
return authorizer.DecisionDeny, "", nil
435+
return authorizer.DecisionNoOpinion, "", nil
436436
}
437437

438438
func reviewResponse(allowed bool, msg string) *authorizationapi.SubjectAccessReviewResponse {

0 commit comments

Comments
 (0)