From 0831b7dc808c0de8fee3a45060eb03eb1e50960a Mon Sep 17 00:00:00 2001 From: Lenny Phan Date: Tue, 15 Sep 2020 05:03:20 +0000 Subject: [PATCH 1/2] Rest authentication of requests should use namespace scope for Dedicated selection strategy --- .../java/oracle/kubernetes/operator/Main.java | 4 ++ .../operator/helpers/AuthenticationProxy.java | 8 +-- .../operator/rest/RestBackendImpl.java | 4 +- .../helpers/AuthenticationProxyTest.java | 72 +++++++++++++++++++ 4 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java diff --git a/operator/src/main/java/oracle/kubernetes/operator/Main.java b/operator/src/main/java/oracle/kubernetes/operator/Main.java index a57517276e4..70cdad8c07e 100644 --- a/operator/src/main/java/oracle/kubernetes/operator/Main.java +++ b/operator/src/main/java/oracle/kubernetes/operator/Main.java @@ -497,6 +497,10 @@ public static DomainNamespaceSelectionStrategy getDomainNamespaceSelectionStrate return strategy; } + public static String getOperatorNamespace() { + return operatorNamespace; + } + public static boolean isDedicated() { return DomainNamespaceSelectionStrategy.Dedicated.equals(getDomainNamespaceSelectionStrategy()); } diff --git a/operator/src/main/java/oracle/kubernetes/operator/helpers/AuthenticationProxy.java b/operator/src/main/java/oracle/kubernetes/operator/helpers/AuthenticationProxy.java index fd8fba31493..44cbd8dc9a4 100644 --- a/operator/src/main/java/oracle/kubernetes/operator/helpers/AuthenticationProxy.java +++ b/operator/src/main/java/oracle/kubernetes/operator/helpers/AuthenticationProxy.java @@ -15,7 +15,7 @@ public class AuthenticationProxy { private static final LoggingFacade LOGGER = LoggingFactory.getLogger("Operator", "Operator"); - private static final AuthorizationProxy authorizationProxy = new AuthorizationProxy(); + private static AuthorizationProxy authorizationProxy = new AuthorizationProxy(); /** * Check if the specified access token can be authenticated. @@ -25,7 +25,7 @@ public class AuthenticationProxy { * @return V1TokenReviewStatus containing either info about the authenticated user or an error * explaining why the user couldn't be authenticated */ - public V1TokenReviewStatus check(String principal, String token) { + public V1TokenReviewStatus check(String principal, String token, String namespace) { LOGGER.entering(principal); // Don't expose the token since it's a credential @@ -37,8 +37,8 @@ public V1TokenReviewStatus check(String principal, String token) { AuthorizationProxy.Operation.create, AuthorizationProxy.Resource.TOKENREVIEWS, null, - AuthorizationProxy.Scope.cluster, - null); + namespace == null ? AuthorizationProxy.Scope.cluster : AuthorizationProxy.Scope.namespace, + namespace); if (allowed) { result = new CallBuilder().createTokenReview(prepareTokenReview(token)); } else { diff --git a/operator/src/main/java/oracle/kubernetes/operator/rest/RestBackendImpl.java b/operator/src/main/java/oracle/kubernetes/operator/rest/RestBackendImpl.java index 3a3ee01780c..a282f4d441f 100644 --- a/operator/src/main/java/oracle/kubernetes/operator/rest/RestBackendImpl.java +++ b/operator/src/main/java/oracle/kubernetes/operator/rest/RestBackendImpl.java @@ -25,6 +25,7 @@ import io.kubernetes.client.openapi.models.V1ObjectMeta; import io.kubernetes.client.openapi.models.V1TokenReviewStatus; import io.kubernetes.client.openapi.models.V1UserInfo; +import oracle.kubernetes.operator.Main; import oracle.kubernetes.operator.helpers.AuthenticationProxy; import oracle.kubernetes.operator.helpers.AuthorizationProxy; import oracle.kubernetes.operator.helpers.AuthorizationProxy.Operation; @@ -133,7 +134,8 @@ private String getNamespace(String domainUid) { private V1UserInfo authenticate(String accessToken) { LOGGER.entering(); - V1TokenReviewStatus status = atn.check(principal, accessToken); + V1TokenReviewStatus status = atn.check(principal, accessToken, + Main.isDedicated() ? Main.getOperatorNamespace() : null); if (status == null) { throw new AssertionError(LOGGER.formatMessage(MessageKeys.NULL_TOKEN_REVIEW_STATUS)); } diff --git a/operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java b/operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java new file mode 100644 index 00000000000..3e4acab3759 --- /dev/null +++ b/operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java @@ -0,0 +1,72 @@ +// Copyright (c) 2020, Oracle Corporation and/or its affiliates. +// Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. + +package oracle.kubernetes.operator.helpers; + +import java.util.ArrayList; +import java.util.List; + +import com.meterware.simplestub.Memento; +import com.meterware.simplestub.StaticStubSupport; +import oracle.kubernetes.operator.helpers.AuthorizationProxy.Scope; +import oracle.kubernetes.utils.TestUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.junit.MatcherAssert.assertThat; + +public class AuthenticationProxyTest { + + private final List mementos = new ArrayList<>(); + private final KubernetesTestSupport testSupport = new KubernetesTestSupport(); + private final AuthorizationProxyStub authorizationProxyStub = new AuthorizationProxyStub(); + + /** + * Setup test. + * @throws Exception on failure + */ + @Before + public void setUp() throws Exception { + mementos.add(TestUtils.silenceOperatorLogger()); + mementos.add(testSupport.install()); + mementos.add( + StaticStubSupport.install(AuthenticationProxy.class, "authorizationProxy", authorizationProxyStub)); + } + + @After + public void tearDown() { + mementos.forEach(Memento::revert); + } + + @Test + public void verify_authorizationScope_isCluster_whenNamespaceIsNull() { + AuthenticationProxy authorizationProxy = new AuthenticationProxy(); + authorizationProxy.check("", "", null); + assertThat(authorizationProxyStub.scope, equalTo(Scope.cluster)); + } + + @Test + public void verify_authorizationScope_isNamespace_whenNamespaceIsDefined() { + AuthenticationProxy authorizationProxy = new AuthenticationProxy(); + authorizationProxy.check("", "", "NS"); + assertThat(authorizationProxyStub.scope, equalTo(Scope.namespace)); + } + + private class AuthorizationProxyStub extends AuthorizationProxy { + Scope scope; + + public boolean check( + String principal, + Operation operation, + Resource resource, + String resourceName, + Scope scope, + String namespaceName) { + this.scope = scope; + System.out.println("AuthorizationProxyStub.check scope: " + scope); + return true; + } + } +} From 176fdbf517f967a8eeb5bd3d38669fe09ac8ff08 Mon Sep 17 00:00:00 2001 From: Lenny Phan Date: Tue, 15 Sep 2020 21:00:42 +0000 Subject: [PATCH 2/2] remove System.out.println from unit test --- .../kubernetes/operator/helpers/AuthenticationProxyTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java b/operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java index 3e4acab3759..386af37a07a 100644 --- a/operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java +++ b/operator/src/test/java/oracle/kubernetes/operator/helpers/AuthenticationProxyTest.java @@ -65,7 +65,6 @@ public boolean check( Scope scope, String namespaceName) { this.scope = scope; - System.out.println("AuthorizationProxyStub.check scope: " + scope); return true; } }