From 7c57a53384be9c4a3ca9c50b0ae8554d4f740ced Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Fri, 6 Jul 2018 10:55:17 -0400 Subject: [PATCH 1/3] UPSTREAM: 65906: Improve multi-authorizer errors --- vendor/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go | 2 +- .../k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/rbac.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/vendor/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go b/vendor/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go index 86e7f8ed3e0b..fc3a9dfcf9b5 100644 --- a/vendor/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go +++ b/vendor/k8s.io/kubernetes/pkg/auth/authorizer/abac/abac.go @@ -227,7 +227,7 @@ func (pl policyList) Authorize(a authorizer.Attributes) (authorizer.Decision, st return authorizer.DecisionAllow, "", nil } } - return authorizer.DecisionNoOpinion, "No policy matched.", nil + return authorizer.DecisionNoOpinion, "no ABAC policy matched", nil // TODO: Benchmark how much time policy matching takes with a medium size // policy file, compared to other steps such as encoding/decoding. // Then, add Caching only if needed. diff --git a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/rbac.go b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/rbac.go index a0f173c393bf..1701bbc3176f 100644 --- a/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/rbac.go +++ b/vendor/k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/rbac.go @@ -121,6 +121,8 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (aut reason := "" if len(ruleCheckingVisitor.errors) > 0 { reason = fmt.Sprintf("RBAC: %v", utilerrors.NewAggregate(ruleCheckingVisitor.errors)) + } else { + reason = "no RBAC policy matched" } return authorizer.DecisionNoOpinion, reason, nil } From fcf6caec4026e0b82822271d4f684c16d5282e37 Mon Sep 17 00:00:00 2001 From: Monis Khan Date: Fri, 3 Aug 2018 14:35:13 -0400 Subject: [PATCH 2/3] browsersafe reason Signed-off-by: Monis Khan --- .../authorizer/browsersafe/authorizer.go | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/pkg/authorization/authorizer/browsersafe/authorizer.go b/pkg/authorization/authorizer/browsersafe/authorizer.go index 32ab84ba3ffa..657c9c701819 100644 --- a/pkg/authorization/authorizer/browsersafe/authorizer.go +++ b/pkg/authorization/authorizer/browsersafe/authorizer.go @@ -1,6 +1,8 @@ package browsersafe import ( + "fmt" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/authorization/authorizer" ) @@ -25,8 +27,17 @@ func NewBrowserSafeAuthorizer(delegate authorizer.Authorizer, authenticatedGroup } func (a *browserSafeAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) { - browserSafeAttributes := a.getBrowserSafeAttributes(attributes) - return a.delegate.Authorize(browserSafeAttributes) + attrs := a.getBrowserSafeAttributes(attributes) + decision, reason, err := a.delegate.Authorize(attrs) + safeAttributes, changed := attrs.(*browserSafeAttributes) + + // check if the request was not allowed and we changed the attributes + if decision == authorizer.DecisionAllow || !changed { + return decision, reason, err + } + + // if so, use this information to update the reason + return decision, safeAttributes.reason(reason), err } func (a *browserSafeAuthorizer) getBrowserSafeAttributes(attributes authorizer.Attributes) authorizer.Attributes { @@ -77,3 +88,19 @@ func (b *browserSafeAttributes) GetSubresource() string { } return b.Attributes.GetSubresource() } + +func (b *browserSafeAttributes) reason(reason string) string { + if b.isProxyVerb { + if len(reason) != 0 { + reason += ", " + } + reason += fmt.Sprintf("%s verb changed to %s", proxyAction, unsafeProxy) + } + if b.isProxySubresource { + if len(reason) != 0 { + reason += ", " + } + reason += fmt.Sprintf("%s subresource changed to %s", proxyAction, unsafeProxy) + } + return reason +} From feb2c8566aad2827d90a2fce8317db024b2fe736 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 20 Jul 2018 11:11:56 -0400 Subject: [PATCH 3/3] Drop authorizer wrapper The openshift authorizer was wrapping kube authorizer only to generate Forbidden messages, but upstream already generate similar messages and we cannot intercept and change those. So let's just stop duplicating errors and use the upstream authorizer and error messages as is. Signed-off-by: Simo Sorce --- pkg/authorization/authorizer/authorizer.go | 49 ---- .../authorizer/browsersafe/authorizer_test.go | 12 +- pkg/authorization/authorizer/interfaces.go | 10 - pkg/authorization/authorizer/messages.go | 128 ----------- pkg/authorization/authorizer/messages_test.go | 212 ------------------ .../authorizer/scope/authorizer.go | 14 +- .../authorizer/scope/authorizer_test.go | 9 +- pkg/cmd/server/origin/authorizer.go | 6 +- test/cmd/authentication.sh | 10 +- test/cmd/basicresources.sh | 2 +- test/cmd/policy.sh | 2 +- test/integration/authorization_test.go | 40 ++-- test/integration/bootstrap_policy_test.go | 4 +- test/integration/oauth_cert_fallback_test.go | 2 +- 14 files changed, 47 insertions(+), 453 deletions(-) delete mode 100644 pkg/authorization/authorizer/authorizer.go delete mode 100644 pkg/authorization/authorizer/interfaces.go delete mode 100644 pkg/authorization/authorizer/messages.go delete mode 100644 pkg/authorization/authorizer/messages_test.go diff --git a/pkg/authorization/authorizer/authorizer.go b/pkg/authorization/authorizer/authorizer.go deleted file mode 100644 index 9ee04860a4b2..000000000000 --- a/pkg/authorization/authorizer/authorizer.go +++ /dev/null @@ -1,49 +0,0 @@ -package authorizer - -import ( - "errors" - - "k8s.io/apiserver/pkg/authorization/authorizer" -) - -type openshiftAuthorizer struct { - delegate authorizer.Authorizer - forbiddenMessageMaker ForbiddenMessageMaker -} - -func NewAuthorizer(delegate authorizer.Authorizer, forbiddenMessageMaker ForbiddenMessageMaker) authorizer.Authorizer { - return &openshiftAuthorizer{delegate: delegate, forbiddenMessageMaker: forbiddenMessageMaker} -} - -func (a *openshiftAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) { - if attributes.GetUser() == nil { - return authorizer.DecisionNoOpinion, "", errors.New("no user available on context") - } - authorizationDecision, delegateReason, err := a.delegate.Authorize(attributes) - if authorizationDecision == authorizer.DecisionAllow { - return authorizer.DecisionAllow, reason(attributes), nil - } - // errors are allowed to occur - if err != nil { - return authorizationDecision, "", err - } - - denyReason, err := a.forbiddenMessageMaker.MakeMessage(attributes) - if err != nil { - denyReason = err.Error() - } - if len(delegateReason) > 0 { - denyReason += ": " + delegateReason - } - - return authorizationDecision, denyReason, nil -} - -func reason(attributes authorizer.Attributes) string { - if len(attributes.GetNamespace()) == 0 { - return "allowed by cluster rule" - } - // not 100% accurate, because the rule may have been provided by a cluster rule. we no longer have - // this distinction upstream in practice. - return "allowed by openshift authorizer" -} diff --git a/pkg/authorization/authorizer/browsersafe/authorizer_test.go b/pkg/authorization/authorizer/browsersafe/authorizer_test.go index 55c0651325e9..57921d0818cb 100644 --- a/pkg/authorization/authorizer/browsersafe/authorizer_test.go +++ b/pkg/authorization/authorizer/browsersafe/authorizer_test.go @@ -13,6 +13,7 @@ func TestBrowserSafeAuthorizer(t *testing.T) { expectedVerb string expectedSubresource string + expectedReason string }{ "non-resource": { attributes: authorizer.AttributesRecord{ResourceRequest: false, Verb: "GET"}, @@ -29,15 +30,18 @@ func TestBrowserSafeAuthorizer(t *testing.T) { attributes: authorizer.AttributesRecord{ResourceRequest: true, Verb: "get", Resource: "pods", Subresource: "proxy"}, expectedVerb: "get", expectedSubresource: "unsafeproxy", + expectedReason: "proxy subresource changed to unsafeproxy", }, "unsafe proxy verb": { - attributes: authorizer.AttributesRecord{ResourceRequest: true, Verb: "proxy", Resource: "nodes"}, - expectedVerb: "unsafeproxy", + attributes: authorizer.AttributesRecord{ResourceRequest: true, Verb: "proxy", Resource: "nodes"}, + expectedVerb: "unsafeproxy", + expectedReason: "proxy verb changed to unsafeproxy", }, "unsafe proxy verb anonymous": { attributes: authorizer.AttributesRecord{ResourceRequest: true, Verb: "proxy", Resource: "nodes", User: &user.DefaultInfo{Name: "system:anonymous", Groups: []string{"system:unauthenticated"}}}, - expectedVerb: "unsafeproxy", + expectedVerb: "unsafeproxy", + expectedReason: "proxy verb changed to unsafeproxy", }, "proxy subresource authenticated": { @@ -51,7 +55,7 @@ func TestBrowserSafeAuthorizer(t *testing.T) { safeAuthorizer := NewBrowserSafeAuthorizer(delegateAuthorizer, "system:authenticated") authorized, reason, err := safeAuthorizer.Authorize(tc.attributes) - if authorized == authorizer.DecisionAllow || len(reason) != 0 || err != nil { + if authorized == authorizer.DecisionAllow || reason != tc.expectedReason || err != nil { t.Errorf("%s: unexpected output: %v %s %v", name, authorized, reason, err) continue } diff --git a/pkg/authorization/authorizer/interfaces.go b/pkg/authorization/authorizer/interfaces.go deleted file mode 100644 index 04a14eae26c2..000000000000 --- a/pkg/authorization/authorizer/interfaces.go +++ /dev/null @@ -1,10 +0,0 @@ -package authorizer - -import ( - "k8s.io/apiserver/pkg/authorization/authorizer" -) - -// ForbiddenMessageMaker creates a forbidden message from Attributes -type ForbiddenMessageMaker interface { - MakeMessage(attrs authorizer.Attributes) (string, error) -} diff --git a/pkg/authorization/authorizer/messages.go b/pkg/authorization/authorizer/messages.go deleted file mode 100644 index 7db853ee9285..000000000000 --- a/pkg/authorization/authorizer/messages.go +++ /dev/null @@ -1,128 +0,0 @@ -package authorizer - -import ( - "bytes" - "text/template" - - "k8s.io/apiserver/pkg/authorization/authorizer" - - authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization" -) - -const DefaultProjectRequestForbidden = "You may not request a new project via this API." - -type ForbiddenMessageResolver struct { - // TODO if these maps were map[string]map[sets.String]ForbiddenMessageMaker, we'd be able to handle cases where sets of resources wanted slightly different messages - // unfortunately, maps don't support keys like that, requiring sets.String serialization and deserialization. - namespacedVerbsToResourcesToForbiddenMessageMaker map[string]map[string]ForbiddenMessageMaker - rootScopedVerbsToResourcesToForbiddenMessageMaker map[string]map[string]ForbiddenMessageMaker - - nonResourceURLForbiddenMessageMaker ForbiddenMessageMaker - defaultForbiddenMessageMaker ForbiddenMessageMaker -} - -func NewForbiddenMessageResolver(projectRequestForbiddenTemplate string) *ForbiddenMessageResolver { - apiGroupIfNotEmpty := "{{if len .GetAPIGroup }}.{{.GetAPIGroup}}{{end}}" - resourceWithSubresourceIfNotEmpty := "{{if len .GetSubresource }}{{.GetResource}}/{{.GetSubresource}}{{else}}{{.GetResource}}{{end}}" - - messageResolver := &ForbiddenMessageResolver{ - namespacedVerbsToResourcesToForbiddenMessageMaker: map[string]map[string]ForbiddenMessageMaker{}, - rootScopedVerbsToResourcesToForbiddenMessageMaker: map[string]map[string]ForbiddenMessageMaker{}, - nonResourceURLForbiddenMessageMaker: newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot "{{.GetVerb}}" on "{{.GetPath}}"`), - defaultForbiddenMessageMaker: newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot "{{.GetVerb}}" "` + resourceWithSubresourceIfNotEmpty + apiGroupIfNotEmpty + `" with name "{{.GetName}}" in project "{{.GetNamespace}}"`), - } - - // general messages - messageResolver.addNamespacedForbiddenMessageMaker("create", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot create `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in project "{{.GetNamespace}}"`)) - messageResolver.addRootScopedForbiddenMessageMaker("create", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot create `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` at the cluster scope`)) - messageResolver.addNamespacedForbiddenMessageMaker("get", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot get `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in project "{{.GetNamespace}}"`)) - messageResolver.addRootScopedForbiddenMessageMaker("get", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot get `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` at the cluster scope`)) - messageResolver.addNamespacedForbiddenMessageMaker("list", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot list `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in project "{{.GetNamespace}}"`)) - messageResolver.addRootScopedForbiddenMessageMaker("list", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot list all `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in the cluster`)) - messageResolver.addNamespacedForbiddenMessageMaker("watch", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot watch `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in project "{{.GetNamespace}}"`)) - messageResolver.addRootScopedForbiddenMessageMaker("watch", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot watch all `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in the cluster`)) - messageResolver.addNamespacedForbiddenMessageMaker("update", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot update `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in project "{{.GetNamespace}}"`)) - messageResolver.addRootScopedForbiddenMessageMaker("update", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot update `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` at the cluster scope`)) - messageResolver.addNamespacedForbiddenMessageMaker("delete", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot delete `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` in project "{{.GetNamespace}}"`)) - messageResolver.addRootScopedForbiddenMessageMaker("delete", authorizationapi.ResourceAll, newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot delete `+resourceWithSubresourceIfNotEmpty+apiGroupIfNotEmpty+` at the cluster scope`)) - - // project request rejection - projectRequestDeny := projectRequestForbiddenTemplate - if len(projectRequestDeny) == 0 { - projectRequestDeny = DefaultProjectRequestForbidden - } - messageResolver.addRootScopedForbiddenMessageMaker("create", "projectrequests", newTemplateForbiddenMessageMaker(projectRequestDeny)) - - // projects "get" request rejection - messageResolver.addNamespacedForbiddenMessageMaker("get", "projects", newTemplateForbiddenMessageMaker(`User "{{.GetUser.GetName}}" cannot get project "{{.GetNamespace}}"`)) - - return messageResolver -} - -func (m *ForbiddenMessageResolver) addNamespacedForbiddenMessageMaker(verb, resource string, messageMaker ForbiddenMessageMaker) { - m.addForbiddenMessageMaker(m.namespacedVerbsToResourcesToForbiddenMessageMaker, verb, resource, messageMaker) -} - -func (m *ForbiddenMessageResolver) addRootScopedForbiddenMessageMaker(verb, resource string, messageMaker ForbiddenMessageMaker) { - m.addForbiddenMessageMaker(m.rootScopedVerbsToResourcesToForbiddenMessageMaker, verb, resource, messageMaker) -} - -func (m *ForbiddenMessageResolver) addForbiddenMessageMaker(target map[string]map[string]ForbiddenMessageMaker, verb, resource string, messageMaker ForbiddenMessageMaker) { - resourcesToForbiddenMessageMaker, exists := target[verb] - if !exists { - resourcesToForbiddenMessageMaker = map[string]ForbiddenMessageMaker{} - target[verb] = resourcesToForbiddenMessageMaker - } - - resourcesToForbiddenMessageMaker[resource] = messageMaker -} - -func (m *ForbiddenMessageResolver) MakeMessage(attrs authorizer.Attributes) (string, error) { - if !attrs.IsResourceRequest() { - return m.nonResourceURLForbiddenMessageMaker.MakeMessage(attrs) - } - - messageMakerMap := m.namespacedVerbsToResourcesToForbiddenMessageMaker - if len(attrs.GetNamespace()) == 0 { - messageMakerMap = m.rootScopedVerbsToResourcesToForbiddenMessageMaker - } - - resourcesToForbiddenMessageMaker, exists := messageMakerMap[attrs.GetVerb()] - if !exists { - resourcesToForbiddenMessageMaker, exists = messageMakerMap[authorizationapi.VerbAll] - if !exists { - return m.defaultForbiddenMessageMaker.MakeMessage(attrs) - } - } - - messageMaker, exists := resourcesToForbiddenMessageMaker[attrs.GetResource()] - if !exists { - messageMaker, exists = resourcesToForbiddenMessageMaker[authorizationapi.ResourceAll] - if !exists { - return m.defaultForbiddenMessageMaker.MakeMessage(attrs) - } - } - - specificMessage, err := messageMaker.MakeMessage(attrs) - if err != nil { - return m.defaultForbiddenMessageMaker.MakeMessage(attrs) - } - - return specificMessage, nil -} - -type templateForbiddenMessageMaker struct { - parsedTemplate *template.Template -} - -func newTemplateForbiddenMessageMaker(text string) templateForbiddenMessageMaker { - parsedTemplate := template.Must(template.New("").Parse(text)) - - return templateForbiddenMessageMaker{parsedTemplate} -} - -func (m templateForbiddenMessageMaker) MakeMessage(attrs authorizer.Attributes) (string, error) { - buffer := &bytes.Buffer{} - err := m.parsedTemplate.Execute(buffer, attrs) - return buffer.String(), err -} diff --git a/pkg/authorization/authorizer/messages_test.go b/pkg/authorization/authorizer/messages_test.go deleted file mode 100644 index 9581a47ee211..000000000000 --- a/pkg/authorization/authorizer/messages_test.go +++ /dev/null @@ -1,212 +0,0 @@ -package authorizer - -import ( - "testing" - - "k8s.io/apiserver/pkg/authentication/user" - kauthorizer "k8s.io/apiserver/pkg/authorization/authorizer" -) - -func TestDefaultForbiddenMessages(t *testing.T) { - messageResolver := NewForbiddenMessageResolver("") - - apiForbidden, err := messageResolver.defaultForbiddenMessageMaker.MakeMessage( - kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "get", - Resource: "pods", - Name: "hammer", - }, - ) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - expectedAPIForbidden := `User "chris" cannot "get" "pods" with name "hammer" in project "foo"` - if expectedAPIForbidden != apiForbidden { - t.Errorf("expected %v, got %v", expectedAPIForbidden, apiForbidden) - } - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: false, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "post", - Path: "/anything", - }, - expected: `User "chris" cannot "post" on "/anything"`, - }.run(t) -} - -func TestAttributeRecord(t *testing.T) { - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "get", - Resource: "users", - APIGroup: "user.openshift.io", - APIVersion: "v1", - Name: "hammer", - }, - expected: `User "chris" cannot get users.user.openshift.io in project "foo"`, - }.run(t) - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: false, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "get", - Resource: "users", - APIGroup: "user.openshift.io", - APIVersion: "v1", - Path: "/", - }, - expected: `User "chris" cannot "get" on "/"`, - }.run(t) -} - -func TestProjectRequestForbiddenMessage(t *testing.T) { - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Verb: "create", - Resource: "projectrequests", - }, - expected: DefaultProjectRequestForbidden, - }.run(t) -} - -func TestNamespacedForbiddenMessage(t *testing.T) { - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "create", - Resource: "builds", - }, - expected: `User "chris" cannot create builds in project "foo"`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "get", - Resource: "builds", - }, - expected: `User "chris" cannot get builds in project "foo"`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "list", - Resource: "builds", - }, - expected: `User "chris" cannot list builds in project "foo"`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "update", - Resource: "builds", - }, - expected: `User "chris" cannot update builds in project "foo"`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Namespace: "foo", - Verb: "delete", - Resource: "builds", - }, - expected: `User "chris" cannot delete builds in project "foo"`, - }.run(t) - -} - -func TestRootScopedForbiddenMessage(t *testing.T) { - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Verb: "create", - Resource: "builds", - }, - expected: `User "chris" cannot create builds at the cluster scope`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Verb: "get", - Resource: "builds", - }, - expected: `User "chris" cannot get builds at the cluster scope`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Verb: "list", - Resource: "builds", - }, - expected: `User "chris" cannot list all builds in the cluster`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Verb: "update", - Resource: "builds", - }, - expected: `User "chris" cannot update builds at the cluster scope`, - }.run(t) - - messageTest{ - attributes: kauthorizer.AttributesRecord{ - ResourceRequest: true, - User: &user.DefaultInfo{Name: "chris"}, - Verb: "delete", - Resource: "builds", - }, - expected: `User "chris" cannot delete builds at the cluster scope`, - }.run(t) - -} - -type messageTest struct { - attributes kauthorizer.Attributes - expected string -} - -func (test messageTest) run(t *testing.T) { - messageResolver := NewForbiddenMessageResolver("") - - forbidden, err := messageResolver.MakeMessage(test.attributes) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - - if test.expected != forbidden { - t.Errorf("expected %v, got %v", test.expected, forbidden) - } -} diff --git a/pkg/authorization/authorizer/scope/authorizer.go b/pkg/authorization/authorizer/scope/authorizer.go index 9545f35225b7..08d8e9ff8399 100644 --- a/pkg/authorization/authorizer/scope/authorizer.go +++ b/pkg/authorization/authorizer/scope/authorizer.go @@ -9,17 +9,14 @@ import ( authorizerrbac "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac" authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization" - defaultauthorizer "github.com/openshift/origin/pkg/authorization/authorizer" ) type scopeAuthorizer struct { clusterRoleGetter rbaclisters.ClusterRoleLister - - forbiddenMessageMaker defaultauthorizer.ForbiddenMessageMaker } -func NewAuthorizer(clusterRoleGetter rbaclisters.ClusterRoleLister, forbiddenMessageMaker defaultauthorizer.ForbiddenMessageMaker) authorizer.Authorizer { - return &scopeAuthorizer{clusterRoleGetter: clusterRoleGetter, forbiddenMessageMaker: forbiddenMessageMaker} +func NewAuthorizer(clusterRoleGetter rbaclisters.ClusterRoleLister) authorizer.Authorizer { + return &scopeAuthorizer{clusterRoleGetter: clusterRoleGetter} } func (a *scopeAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) { @@ -46,11 +43,6 @@ func (a *scopeAuthorizer) Authorize(attributes authorizer.Attributes) (authorize return authorizer.DecisionNoOpinion, "", nil } - denyReason, err := a.forbiddenMessageMaker.MakeMessage(attributes) - if err != nil { - denyReason = err.Error() - } - // the scope prevent this. We need to authoritatively deny - return authorizer.DecisionDeny, fmt.Sprintf("scopes %v prevent this action; %v", scopes, denyReason), kerrors.NewAggregate(nonFatalErrors) + return authorizer.DecisionDeny, fmt.Sprintf("scopes %v prevent this action", scopes), kerrors.NewAggregate(nonFatalErrors) } diff --git a/pkg/authorization/authorizer/scope/authorizer_test.go b/pkg/authorization/authorizer/scope/authorizer_test.go index a1cb91f92d77..0888ed4e4b77 100644 --- a/pkg/authorization/authorizer/scope/authorizer_test.go +++ b/pkg/authorization/authorizer/scope/authorizer_test.go @@ -8,7 +8,6 @@ import ( kauthorizer "k8s.io/apiserver/pkg/authorization/authorizer" authorizationapi "github.com/openshift/origin/pkg/authorization/apis/authorization" - defaultauthorizer "github.com/openshift/origin/pkg/authorization/authorizer" ) func TestAuthorize(t *testing.T) { @@ -63,7 +62,7 @@ func TestAuthorize(t *testing.T) { Namespace: "ns", }, expectedAllowed: kauthorizer.DecisionDeny, - expectedMsg: `scopes [does-not-exist] prevent this action; User "" cannot "" "" with name "" in project "ns"`, + expectedMsg: `scopes [does-not-exist] prevent this action`, expectedErr: `no scope evaluator found for "does-not-exist"`, }, { @@ -74,7 +73,7 @@ func TestAuthorize(t *testing.T) { Namespace: "ns", }, expectedAllowed: kauthorizer.DecisionDeny, - expectedMsg: `scopes [user:dne] prevent this action; User "" cannot "" "" with name "" in project "ns"`, + expectedMsg: `scopes [user:dne] prevent this action`, expectedErr: `unrecognized scope: user:dne`, }, { @@ -85,7 +84,7 @@ func TestAuthorize(t *testing.T) { Namespace: "ns", Verb: "get", Resource: "users", Name: "harold"}, expectedAllowed: kauthorizer.DecisionDeny, - expectedMsg: `scopes [user:info] prevent this action; User "" cannot get users in project "ns"`, + expectedMsg: `scopes [user:info] prevent this action`, }, { name: "scope covers", @@ -127,7 +126,7 @@ func TestAuthorize(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - authorizer := NewAuthorizer(nil, defaultauthorizer.NewForbiddenMessageResolver("")) + authorizer := NewAuthorizer(nil) actualAllowed, actualMsg, actualErr := authorizer.Authorize(tc.attributes) switch { diff --git a/pkg/cmd/server/origin/authorizer.go b/pkg/cmd/server/origin/authorizer.go index 757879305c6c..08706833c712 100644 --- a/pkg/cmd/server/origin/authorizer.go +++ b/pkg/cmd/server/origin/authorizer.go @@ -12,16 +12,14 @@ import ( rbacauthorizer "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac" kbootstrappolicy "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy" - openshiftauthorizer "github.com/openshift/origin/pkg/authorization/authorizer" "github.com/openshift/origin/pkg/authorization/authorizer/browsersafe" "github.com/openshift/origin/pkg/authorization/authorizer/scope" ) func NewAuthorizer(informers InformerAccess, projectRequestDenyMessage string) authorizer.Authorizer { - messageMaker := openshiftauthorizer.NewForbiddenMessageResolver(projectRequestDenyMessage) rbacInformers := informers.GetKubernetesInformers().Rbac().V1() - scopeLimitedAuthorizer := scope.NewAuthorizer(rbacInformers.ClusterRoles().Lister(), messageMaker) + scopeLimitedAuthorizer := scope.NewAuthorizer(rbacInformers.ClusterRoles().Lister()) kubeAuthorizer := rbacauthorizer.New( &rbacauthorizer.RoleGetter{Lister: rbacInformers.Roles().Lister()}, @@ -48,7 +46,7 @@ func NewAuthorizer(informers InformerAccess, projectRequestDenyMessage string) a authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup), nodeAuthorizer, // Wrap with an authorizer that detects unsafe requests and modifies verbs/resources appropriately so policy can address them separately - browsersafe.NewBrowserSafeAuthorizer(openshiftauthorizer.NewAuthorizer(kubeAuthorizer, messageMaker), user.AllAuthenticated), + browsersafe.NewBrowserSafeAuthorizer(kubeAuthorizer, user.AllAuthenticated), ) return openshiftAuthorizer diff --git a/test/cmd/authentication.sh b/test/cmd/authentication.sh index 58d0172557f2..aa7a6f9ac922 100755 --- a/test/cmd/authentication.sh +++ b/test/cmd/authentication.sh @@ -47,21 +47,21 @@ os::cmd::expect_success "oc policy can-i --list" whoamitoken="$(oc process -f "${OS_ROOT}/test/testdata/authentication/scoped-token-template.yaml" TOKEN_PREFIX=whoami SCOPE=user:info USER_NAME="${username}" USER_UID="${useruid}" | oc create -f - -o name | awk -F/ '{print $2}')" os::cmd::expect_success_and_text "oc get user/~ --token='${whoamitoken}'" "${username}" os::cmd::expect_success_and_text "oc whoami --token='${whoamitoken}'" "${username}" -os::cmd::expect_failure_and_text "oc get pods --token='${whoamitoken}' -n '${project}'" "prevent this action; User \"scoped-user\" cannot list pods in project \"${project}\"" +os::cmd::expect_failure_and_text "oc get pods --token='${whoamitoken}' -n '${project}'" "pods is forbidden: User \"scoped-user\" cannot list pods in the namespace \"${project}\"" listprojecttoken="$(oc process -f "${OS_ROOT}/test/testdata/authentication/scoped-token-template.yaml" TOKEN_PREFIX=listproject SCOPE=user:list-scoped-projects USER_NAME="${username}" USER_UID="${useruid}" | oc create -f - -o name | awk -F/ '{print $2}')" # this token doesn't have rights to see any projects even though it can hit the list endpoint, so an empty list is correct # we'll add another scope that allows listing all known projects even if this token has no other powers in them. os::cmd::expect_success_and_not_text "oc get projects --token='${listprojecttoken}'" "${project}" -os::cmd::expect_failure_and_text "oc get user/~ --token='${listprojecttoken}'" 'prevent this action; User "scoped-user" cannot get users.user.openshift.io at the cluster scope' -os::cmd::expect_failure_and_text "oc get pods --token='${listprojecttoken}' -n '${project}'" "prevent this action; User \"scoped-user\" cannot list pods in project \"${project}\"" +os::cmd::expect_failure_and_text "oc get user/~ --token='${listprojecttoken}'" 'User "scoped-user" cannot get users.user.openshift.io at the cluster scope' +os::cmd::expect_failure_and_text "oc get pods --token='${listprojecttoken}' -n '${project}'" "User \"scoped-user\" cannot list pods in the namespace \"${project}\"" listprojecttoken="$(oc process -f "${OS_ROOT}/test/testdata/authentication/scoped-token-template.yaml" TOKEN_PREFIX=listallprojects SCOPE=user:list-projects USER_NAME="${username}" USER_UID="${useruid}" | oc create -f - -o name | awk -F/ '{print $2}')" os::cmd::expect_success_and_text "oc get projects --token='${listprojecttoken}'" "${project}" adminnonescalatingpowerstoken="$(oc process -f "${OS_ROOT}/test/testdata/authentication/scoped-token-template.yaml" TOKEN_PREFIX=admin SCOPE=role:admin:* USER_NAME="${username}" USER_UID="${useruid}" | oc create -f - -o name | awk -F/ '{print $2}')" -os::cmd::expect_failure_and_text "oc get user/~ --token='${adminnonescalatingpowerstoken}'" 'prevent this action; User "scoped-user" cannot get users.user.openshift.io at the cluster scope' -os::cmd::expect_failure_and_text "oc get secrets --token='${adminnonescalatingpowerstoken}' -n '${project}'" "prevent this action; User \"scoped-user\" cannot list secrets in project \"${project}\"" +os::cmd::expect_failure_and_text "oc get user/~ --token='${adminnonescalatingpowerstoken}'" 'User "scoped-user" cannot get users.user.openshift.io at the cluster scope' +os::cmd::expect_failure_and_text "oc get secrets --token='${adminnonescalatingpowerstoken}' -n '${project}'" "User \"scoped-user\" cannot list secrets in the namespace \"${project}\"" os::cmd::expect_success_and_text "oc get 'projects/${project}' --token='${adminnonescalatingpowerstoken}' -n '${project}'" "${project}" allescalatingpowerstoken="$(oc process -f "${OS_ROOT}/test/testdata/authentication/scoped-token-template.yaml" TOKEN_PREFIX=clusteradmin SCOPE='role:cluster-admin:*:!' USER_NAME="${username}" USER_UID="${useruid}" | oc create -f - -o name | awk -F/ '{print $2}')" diff --git a/test/cmd/basicresources.sh b/test/cmd/basicresources.sh index 22e12e35a461..d42c5c8df230 100755 --- a/test/cmd/basicresources.sh +++ b/test/cmd/basicresources.sh @@ -235,7 +235,7 @@ project=$(oc project -q) os::cmd::expect_success 'oc policy add-role-to-user view view-user' os::cmd::expect_success 'oc login -u view-user -p anything' os::cmd::try_until_success 'oc project ${project}' -os::cmd::expect_failure_and_text "oc set env dc/test-deployment-config --list --resolve" "cannot get secrets in project" +os::cmd::expect_failure_and_text "oc set env dc/test-deployment-config --list --resolve" "cannot get secrets in the namespace" oc login -u system:admin # clean up os::cmd::expect_success "oc delete dc/test-deployment-config" diff --git a/test/cmd/policy.sh b/test/cmd/policy.sh index 6f277d04e213..0e4bccd6066a 100755 --- a/test/cmd/policy.sh +++ b/test/cmd/policy.sh @@ -234,7 +234,7 @@ os::cmd::expect_success_and_text 'oc policy scc-review -z default -f ${OS_ROOT} os::cmd::expect_success_and_text 'oc policy scc-review -z system:serviceaccount:policy-second:default -f ${OS_ROOT}/test/testdata/job.yaml --no-headers=true' 'Job/hello default lax' os::cmd::expect_success_and_text 'oc policy scc-review -f ${OS_ROOT}/test/extended/testdata/deployments/deployment-simple.yaml --no-headers=true' 'DeploymentConfig/deployment-simple default lax' os::cmd::expect_success_and_text 'oc policy scc-review -f ${OS_ROOT}/test/testdata/nginx_pod.yaml --no-headers=true' '' -os::cmd::expect_failure_and_text 'oc policy scc-review -z default -f ${OS_ROOT}/test/testdata/job.yaml --namespace=no-exist' 'error: unable to compute Pod Security Policy Review for "hello": podsecuritypolicyreviews.security.openshift.io is forbidden: User "bob" cannot create podsecuritypolicyreviews.security.openshift.io in the namespace "no-exist": User "bob" cannot create podsecuritypolicyreviews.security.openshift.io in project "no-exist"' +os::cmd::expect_failure_and_text 'oc policy scc-review -z default -f ${OS_ROOT}/test/testdata/job.yaml --namespace=no-exist' 'error: unable to compute Pod Security Policy Review for "hello": podsecuritypolicyreviews.security.openshift.io is forbidden: User "bob" cannot create podsecuritypolicyreviews.security.openshift.io in the namespace "no-exist"' os::cmd::expect_failure_and_text 'oc policy scc-review -z default -f ${OS_ROOT}/test/testdata/pspreview_unsupported_statefulset.yaml' 'error: StatefulSet "rd" with spec.volumeClaimTemplates currently not supported.' os::cmd::expect_failure_and_text 'oc policy scc-review -z no-exist -f ${OS_ROOT}/test/testdata/job.yaml' 'error: unable to compute Pod Security Policy Review for "hello": unable to retrieve ServiceAccount no-exist: serviceaccount "no-exist" not found' os::cmd::expect_success "oc login -u system:admin -n '${project}'" diff --git a/test/integration/authorization_test.go b/test/integration/authorization_test.go index 00142698d7d4..80f4780c7666 100644 --- a/test/integration/authorization_test.go +++ b/test/integration/authorization_test.go @@ -876,7 +876,7 @@ func TestAuthorizationSubjectAccessReviewAPIGroup(t *testing.T) { kubeAuthInterface: clusterAdminSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by openshift authorizer", + Reason: `RBAC: allowed by RoleBinding "admin/hammer-project" of ClusterRole "admin" to User "harold"`, Namespace: "hammer-project", }, }.run(t) @@ -890,7 +890,7 @@ func TestAuthorizationSubjectAccessReviewAPIGroup(t *testing.T) { kubeAuthInterface: clusterAdminSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "harold" cannot get horizontalpodautoscalers in project "hammer-project"`, + Reason: `no RBAC policy matched`, Namespace: "hammer-project", }, }.run(t) @@ -904,7 +904,7 @@ func TestAuthorizationSubjectAccessReviewAPIGroup(t *testing.T) { kubeAuthInterface: clusterAdminKubeClient.Authorization(), response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "harold" cannot get horizontalpodautoscalers.foo in project "hammer-project"`, + Reason: `no RBAC policy matched`, Namespace: "hammer-project", }, }.run(t) @@ -918,7 +918,7 @@ func TestAuthorizationSubjectAccessReviewAPIGroup(t *testing.T) { kubeAuthInterface: clusterAdminSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "harold" cannot get horizontalpodautoscalers.* in project "hammer-project"`, + Reason: `no RBAC policy matched`, Namespace: "hammer-project", }, }.run(t) @@ -1069,7 +1069,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: clusterAdminLocalSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by openshift authorizer", + Reason: `RBAC: allowed by RoleBinding "view/default" of ClusterRole "view" to User "danny"`, Namespace: "default", }, }.run(t) @@ -1080,7 +1080,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: clusterAdminLocalSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "danny" cannot get projects at the cluster scope`, + Reason: `no RBAC policy matched`, Namespace: "", }, }.run(t) @@ -1134,7 +1134,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: haroldSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by openshift authorizer", + Reason: `RBAC: allowed by RoleBinding "view/hammer-project" of ClusterRole "view" to User "valerie"`, Namespace: "hammer-project", }, }.run(t) @@ -1145,7 +1145,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: markSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "valerie" cannot get project "mallet-project"`, + Reason: `no RBAC policy matched`, Namespace: "mallet-project", }, }.run(t) @@ -1161,7 +1161,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: markSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by openshift authorizer", + Reason: `RBAC: allowed by RoleBinding "edit/mallet-project" of ClusterRole "edit" to User "edgar"`, Namespace: "mallet-project", }, }.run(t) @@ -1215,7 +1215,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: haroldSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by openshift authorizer", + Reason: `RBAC: allowed by RoleBinding "admin/hammer-project" of ClusterRole "admin" to User "harold"`, Namespace: "hammer-project", }, }.run(t) @@ -1231,7 +1231,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: clusterAdminLocalSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by cluster rule", + Reason: `RBAC: allowed by ClusterRoleBinding "cluster-admins" of ClusterRole "cluster-admin" to Group "system:cluster-admins"`, Namespace: "", }, }.run(t) @@ -1254,7 +1254,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: haroldSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by openshift authorizer", + Reason: `RBAC: allowed by RoleBinding "admin/hammer-project" of ClusterRole "admin" to User "harold"`, Namespace: "hammer-project", }, }.run(t) @@ -1265,7 +1265,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: anonymousSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: true, - Reason: "allowed by openshift authorizer", + Reason: `RBAC: allowed by RoleBinding "edit/hammer-project" of ClusterRole "edit" to User "system:anonymous"`, Namespace: "hammer-project", }, }.run(t) @@ -1278,7 +1278,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: haroldSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "harold" cannot create pods in project "mallet-project"`, + Reason: `no RBAC policy matched`, Namespace: "mallet-project", }, }.run(t) @@ -1289,7 +1289,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: anonymousSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "system:anonymous" cannot create pods in project "mallet-project"`, + Reason: `no RBAC policy matched`, Namespace: "mallet-project", }, }.run(t) @@ -1303,7 +1303,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: haroldSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "harold" cannot create pods in project "nonexistent-project"`, + Reason: `no RBAC policy matched`, Namespace: "nonexistent-project", }, }.run(t) @@ -1314,7 +1314,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { kubeAuthInterface: anonymousSARGetter, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "system:anonymous" cannot create pods in project "nonexistent-project"`, + Reason: `no RBAC policy matched`, Namespace: "nonexistent-project", }, }.run(t) @@ -1329,7 +1329,7 @@ func TestAuthorizationSubjectAccessReview(t *testing.T) { localReview: askCanICreatePolicyBindings, response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "harold" cannot create policybindings in project "hammer-project"`, + Reason: `no RBAC policy matched`, Namespace: "hammer-project", }, }.run(t) @@ -1369,8 +1369,8 @@ func TestBrowserSafeAuthorizer(t *testing.T) { if errProxy == nil { return false } - return strings.Contains(errProxy.Error(), `cannot "unsafeproxy" "pods" with name "podX1:8080" in project "ns"`) || - strings.Contains(errProxy.Error(), `cannot get pods/unsafeproxy in project "ns"`) + return strings.Contains(errProxy.Error(), `cannot proxy pods in the namespace "ns": proxy verb changed to unsafeproxy`) || + strings.Contains(errProxy.Error(), `cannot get pods/proxy in the namespace "ns": proxy subresource changed to unsafeproxy`) } for _, tc := range []struct { diff --git a/test/integration/bootstrap_policy_test.go b/test/integration/bootstrap_policy_test.go index 9cc349c9a56b..ae8e83970753 100644 --- a/test/integration/bootstrap_policy_test.go +++ b/test/integration/bootstrap_policy_test.go @@ -98,7 +98,7 @@ func TestBootstrapPolicySelfSubjectAccessReviews(t *testing.T) { kubeAuthInterface: valerieKubeClient.Authorization(), response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "valerie" cannot create policybindings in project "openshift"`, + Reason: ``, Namespace: "openshift", }, }.run(t) @@ -148,7 +148,7 @@ func TestSelfSubjectAccessReviewsNonExistingNamespace(t *testing.T) { kubeAuthInterface: valerieKubeClient.Authorization(), response: authorizationapi.SubjectAccessReviewResponse{ Allowed: false, - Reason: `User "valerie" cannot create pods in project "foo"`, + Reason: ``, Namespace: "foo", }, }.run(t) diff --git a/test/integration/oauth_cert_fallback_test.go b/test/integration/oauth_cert_fallback_test.go index 7cdd057db97e..3bdee45fe02f 100644 --- a/test/integration/oauth_cert_fallback_test.go +++ b/test/integration/oauth_cert_fallback_test.go @@ -35,7 +35,7 @@ func TestOAuthCertFallback(t *testing.T) { certUser = "system:admin" unauthorizedError = "Unauthorized" - anonymousError = `users.user.openshift.io "~" is forbidden: User "system:anonymous" cannot get users.user.openshift.io at the cluster scope: User "system:anonymous" cannot get users.user.openshift.io at the cluster scope` + anonymousError = `users.user.openshift.io "~" is forbidden: User "system:anonymous" cannot get users.user.openshift.io at the cluster scope: no RBAC policy matched` ) // Build master config