From 7b7db3496bd8820a937fb7f6b78b7e1eaca7f59a Mon Sep 17 00:00:00 2001 From: KomachiSion Date: Mon, 17 Jan 2022 16:17:23 +0800 Subject: [PATCH] Do some refactor for IdentityContextBuilder --- .../alibaba/nacos/auth/AuthPluginManager.java | 42 +++---- ...uthService.java => AuthPluginService.java} | 29 +++-- .../nacos/auth/api/IdentityContext.java | 30 ++++- .../nacos/auth/common/AuthConfigs.java | 11 -- .../nacos/auth/constant/Constants.java | 2 - .../context/GrpcIdentityContextBuilder.java | 27 ++-- .../context/HttpIdentityContextBuilder.java | 45 +++---- ... com.alibaba.nacos.auth.AuthPluginService} | 0 .../nacos/auth/common/AuthConfigsTest.java | 4 - .../auth/common/AuthPluginManagerTest.java | 10 +- .../GrpcIdentityContextBuilderTest.java | 86 +++++++++++++ .../HtppIdentityContextBuilderTest.java | 119 ++++++++++++++++++ 12 files changed, 318 insertions(+), 87 deletions(-) rename auth/src/main/java/com/alibaba/nacos/auth/{AuthService.java => AuthPluginService.java} (61%) rename auth/src/main/resources/META-INF/services/{com.alibaba.nacos.auth.AuthService => com.alibaba.nacos.auth.AuthPluginService} (100%) create mode 100644 auth/src/test/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilderTest.java create mode 100644 auth/src/test/java/com/alibaba/nacos/auth/context/HtppIdentityContextBuilderTest.java diff --git a/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginManager.java b/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginManager.java index 846eabe6e..65da82144 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginManager.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginManager.java @@ -38,40 +38,40 @@ public class AuthPluginManager { private static final AuthPluginManager INSTANCE = new AuthPluginManager(); /** - * The relationship of context type and {@link AuthService}. + * The relationship of context type and {@link AuthPluginService}. */ - private Map authServiceMap = new HashMap<>(); + private final Map authServiceMap = new HashMap<>(); public AuthPluginManager() { initAuthServices(); } + private void initAuthServices() { + Collection authPluginServices = NacosServiceLoader.load(AuthPluginService.class); + for (AuthPluginService each : authPluginServices) { + if (StringUtils.isEmpty(each.getAuthServiceName())) { + LOGGER.warn( + "[AuthPluginManager] Load AuthPluginService({}) AuthServiceName(null/empty) fail. Please Add AuthServiceName to resolve.", + each.getClass()); + continue; + } + authServiceMap.put(each.getAuthServiceName(), each); + LOGGER.info("[AuthPluginManager] Load AuthPluginService({}) AuthServiceName({}) successfully.", + each.getClass(), each.getAuthServiceName()); + } + } + public static AuthPluginManager getInstance() { return INSTANCE; } - private void initAuthServices() { - Collection authServices = NacosServiceLoader.load(AuthService.class); - for (AuthService authService : authServices) { - if (StringUtils.isEmpty(authService.getAuthServiceName())) { - LOGGER.warn( - "[AuthPluginManager] Load AuthService({}) AuthServiceName(null/empty) fail. Please Add AuthServiceName to resolve.", - authService.getClass()); - continue; - } - authServiceMap.put(authService.getAuthServiceName(), authService); - LOGGER.info("[AuthPluginManager] Load AuthService({}) AuthServiceName({}) successfully.", - authService.getClass(), authService.getAuthServiceName()); - } - } - /** - * get AuthService instance which AuthService.getType() is type. + * get AuthPluginService instance which AuthPluginService.getType() is type. * - * @param authServiceName AuthServiceName, mark a AuthService instance. - * @return AuthService instance. + * @param authServiceName AuthServiceName, mark a AuthPluginService instance. + * @return AuthPluginService instance. */ - public Optional findAuthServiceSpiImpl(String authServiceName) { + public Optional findAuthServiceSpiImpl(String authServiceName) { return Optional.ofNullable(authServiceMap.get(authServiceName)); } diff --git a/auth/src/main/java/com/alibaba/nacos/auth/AuthService.java b/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginService.java similarity index 61% rename from auth/src/main/java/com/alibaba/nacos/auth/AuthService.java rename to auth/src/main/java/com/alibaba/nacos/auth/AuthPluginService.java index 916018d8a..328d9d8db 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/AuthService.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginService.java @@ -17,36 +17,47 @@ package com.alibaba.nacos.auth; import com.alibaba.nacos.auth.api.IdentityContext; -import com.alibaba.nacos.auth.exception.AccessException; import com.alibaba.nacos.auth.api.Permission; +import com.alibaba.nacos.auth.exception.AccessException; + +import java.util.Collection; /** * Auth service. * * @author Wuyfee */ -public interface AuthService { +public interface AuthPluginService { /** - * Authentication of request, identify the user who request the resource. + * Define which identity information needed from request. e.q: username, password, accessToken. + * + * @return identity names + */ + Collection identityNames(); + + /** + * To validate whether the identity context from request is legal or illegal. * * @param identityContext where we can find the user information * @return IdentityContext user auth result * @throws AccessException if authentication is failed */ - IdentityContext login(IdentityContext identityContext) throws AccessException; + IdentityContext validateIdentity(IdentityContext identityContext) throws AccessException; /** - * identity whether the user has the resource authority. + * Validate the identity whether has the resource authority. + * * @param identityContext where we can find the user information. - * @param permission permission to auth. + * @param permission permission to auth. * @return Boolean if the user has the resource authority. */ - Boolean authorityAccess(IdentityContext identityContext, Permission permission); + Boolean validateAuthority(IdentityContext identityContext, Permission permission); /** - * AuthService Name which for conveniently find AuthService instance. - * @return AuthServiceName mark a AuthService instance. + * AuthPluginService Name which for conveniently find AuthPluginService instance. + * + * @return AuthServiceName mark a AuthPluginService instance. */ String getAuthServiceName(); diff --git a/auth/src/main/java/com/alibaba/nacos/auth/api/IdentityContext.java b/auth/src/main/java/com/alibaba/nacos/auth/api/IdentityContext.java index 7771ea774..f85aa98f7 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/api/IdentityContext.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/api/IdentityContext.java @@ -33,17 +33,41 @@ public class IdentityContext { /** * get key from context. + * * @param key key of request * @return value of param key */ public Object getParameter(String key) { - return param.get(key); } + return param.get(key); + } + + /** + * Get identity by key. + * + * @param key identity name + * @param defaultValue default value when the value is {@code null} or the value is not expected class type + * @param classes type of identity value + * @return identity value + */ + public T getParameter(String key, T defaultValue) { + try { + T result = (T) param.get(key); + if (null != result) { + return result; + } + return defaultValue; + } catch (ClassCastException exception) { + return defaultValue; + } + } /** * put key and value to param. - * @param key key of request + * + * @param key key of request * @param value value of request's key */ public void setParameter(String key, Object value) { - param.put(key, value); } + param.put(key, value); + } } diff --git a/auth/src/main/java/com/alibaba/nacos/auth/common/AuthConfigs.java b/auth/src/main/java/com/alibaba/nacos/auth/common/AuthConfigs.java index 3fdc0b89d..8efec47f1 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/common/AuthConfigs.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/common/AuthConfigs.java @@ -49,12 +49,6 @@ public class AuthConfigs extends Subscriber { @JustForTest private static Boolean cachingEnabled = null; - /** - * Authority key set. - */ - @Value("${" + Constants.Auth.NACOS_CORE_AUTH_AUTHORITY_KEY + ":}") - private String[] authorityKey; - /** * Whether auth enabled. */ @@ -109,10 +103,6 @@ public class AuthConfigs extends Subscriber { return secretKeyBytes; } - public String[] getAuthorityKey() { - return authorityKey; - } - public long getTokenValidityInSeconds() { return tokenValidityInSeconds; } @@ -171,7 +161,6 @@ public class AuthConfigs extends Subscriber { enableUserAgentAuthWhite = EnvUtil.getProperty( Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE, Boolean.class, false); - authorityKey = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_AUTHORITY_KEY, "").split(","); nacosAuthSystemType = EnvUtil.getProperty(Constants.Auth.NACOS_CORE_AUTH_SYSTEM_TYPE, ""); } catch (Exception e) { LOGGER.warn("Upgrade auth config from env failed, use old value", e); diff --git a/auth/src/main/java/com/alibaba/nacos/auth/constant/Constants.java b/auth/src/main/java/com/alibaba/nacos/auth/constant/Constants.java index 44e8974e5..76295a6ce 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/constant/Constants.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/constant/Constants.java @@ -40,8 +40,6 @@ public class Constants { public static final String NACOS_CORE_AUTH_SERVER_IDENTITY_VALUE = "nacos.core.auth.server.identity.value"; public static final String NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE = "nacos.core.auth.enable.userAgentAuthWhite"; - - public static final String NACOS_CORE_AUTH_AUTHORITY_KEY = "nacos.core.auth.authorityKey"; } public static class Resource { diff --git a/auth/src/main/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilder.java b/auth/src/main/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilder.java index 01d41fc65..b8d9e95e6 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilder.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilder.java @@ -17,12 +17,14 @@ package com.alibaba.nacos.auth.context; import com.alibaba.nacos.api.remote.request.Request; +import com.alibaba.nacos.auth.AuthPluginManager; +import com.alibaba.nacos.auth.AuthPluginService; import com.alibaba.nacos.auth.api.IdentityContext; import com.alibaba.nacos.auth.common.AuthConfigs; -import java.util.Arrays; import java.util.HashSet; import java.util.Map; +import java.util.Optional; import java.util.Set; /** @@ -32,31 +34,34 @@ import java.util.Set; */ public class GrpcIdentityContextBuilder implements IdentityContextBuilder { - AuthConfigs authConfigs; - - public GrpcIdentityContextBuilder() { - authConfigs = new AuthConfigs(); - } + private final AuthConfigs authConfigs; public GrpcIdentityContextBuilder(AuthConfigs authConfigs) { this.authConfigs = authConfigs; } + /** * get identity context from grpc. + * * @param request grpc request * @return IdentityContext request context */ @Override public IdentityContext build(Request request) { - Set keySet = new HashSet(Arrays.asList(authConfigs.getAuthorityKey())); - IdentityContext identityContext = new IdentityContext(); + Optional authPluginService = AuthPluginManager.getInstance() + .findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType()); + IdentityContext result = new IdentityContext(); + if (!authPluginService.isPresent()) { + return result; + } + Set identityNames = new HashSet<>(authPluginService.get().identityNames()); Map map = request.getHeaders(); for (Map.Entry entry : map.entrySet()) { - if (keySet.contains(entry.getKey())) { - identityContext.setParameter(entry.getKey(), entry.getValue()); + if (identityNames.contains(entry.getKey())) { + result.setParameter(entry.getKey(), entry.getValue()); } } - return identityContext; + return result; } } diff --git a/auth/src/main/java/com/alibaba/nacos/auth/context/HttpIdentityContextBuilder.java b/auth/src/main/java/com/alibaba/nacos/auth/context/HttpIdentityContextBuilder.java index 36ccd485f..5a6a3c183 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/context/HttpIdentityContextBuilder.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/context/HttpIdentityContextBuilder.java @@ -16,14 +16,16 @@ package com.alibaba.nacos.auth.context; +import com.alibaba.nacos.auth.AuthPluginManager; +import com.alibaba.nacos.auth.AuthPluginService; import com.alibaba.nacos.auth.api.IdentityContext; import com.alibaba.nacos.auth.common.AuthConfigs; import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; +import java.util.Optional; import java.util.Set; /** @@ -33,11 +35,7 @@ import java.util.Set; */ public class HttpIdentityContextBuilder implements IdentityContextBuilder { - private AuthConfigs authConfigs; - - public HttpIdentityContextBuilder() { - authConfigs = new AuthConfigs(); - } + private final AuthConfigs authConfigs; public HttpIdentityContextBuilder(AuthConfigs authConfigs) { this.authConfigs = authConfigs; @@ -51,30 +49,35 @@ public class HttpIdentityContextBuilder implements IdentityContextBuilder keySet = new HashSet<>(Arrays.asList(authConfigs.getAuthorityKey())); + IdentityContext result = new IdentityContext(); + Optional authPluginService = AuthPluginManager.getInstance() + .findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType()); + if (!authPluginService.isPresent()) { + return result; + } + Set identityNames = new HashSet<>(authPluginService.get().identityNames()); + getIdentityFromHeader(request, result, identityNames); + getIdentityFromParameter(request, result, identityNames); + return result; + } + + private void getIdentityFromHeader(HttpServletRequest request, IdentityContext result, Set identityNames) { Enumeration headerEnu = request.getHeaderNames(); - while (headerEnu.hasMoreElements()) { String paraName = headerEnu.nextElement(); - if (keySet.contains(paraName)) { - identityContext.setParameter(paraName, request.getHeader(paraName)); - keySet.remove(paraName); + if (identityNames.contains(paraName)) { + result.setParameter(paraName, request.getHeader(paraName)); } } - - if (keySet.isEmpty()) { - return identityContext; - } - + } + + private void getIdentityFromParameter(HttpServletRequest request, IdentityContext result, Set identityNames) { Enumeration paramEnu = request.getParameterNames(); while (paramEnu.hasMoreElements()) { String paraName = paramEnu.nextElement(); - if (keySet.contains(paraName)) { - identityContext.setParameter(paraName, request.getParameter(paraName)); - keySet.remove(paraName); + if (identityNames.contains(paraName)) { + result.setParameter(paraName, request.getParameter(paraName)); } } - return identityContext; } } diff --git a/auth/src/main/resources/META-INF/services/com.alibaba.nacos.auth.AuthService b/auth/src/main/resources/META-INF/services/com.alibaba.nacos.auth.AuthPluginService similarity index 100% rename from auth/src/main/resources/META-INF/services/com.alibaba.nacos.auth.AuthService rename to auth/src/main/resources/META-INF/services/com.alibaba.nacos.auth.AuthPluginService diff --git a/auth/src/test/java/com/alibaba/nacos/auth/common/AuthConfigsTest.java b/auth/src/test/java/com/alibaba/nacos/auth/common/AuthConfigsTest.java index 5fc2c5bf2..ede4b3d4c 100644 --- a/auth/src/test/java/com/alibaba/nacos/auth/common/AuthConfigsTest.java +++ b/auth/src/test/java/com/alibaba/nacos/auth/common/AuthConfigsTest.java @@ -39,8 +39,6 @@ public class AuthConfigsTest { private static final boolean TEST_ENABLE_UA_WHITE = true; - private static final String AUTHORITYKEY = "username,password,token,tenant"; - private AuthConfigs authConfigs; private MockEnvironment environment; @@ -59,7 +57,6 @@ public class AuthConfigsTest { environment.setProperty("nacos.core.auth.server.identity.key", TEST_SERVER_IDENTITY_KEY); environment.setProperty("nacos.core.auth.server.identity.value", TEST_SERVER_IDENTITY_VALUE); environment.setProperty("nacos.core.auth.enable.userAgentAuthWhite", String.valueOf(TEST_ENABLE_UA_WHITE)); - environment.setProperty("nacos.core.auth.authorityKey", AUTHORITYKEY); authConfigs.onEvent(ServerConfigChangeEvent.newEvent()); assertEquals(TEST_AUTH_ENABLED, authConfigs.isAuthEnabled()); @@ -67,6 +64,5 @@ public class AuthConfigsTest { assertEquals(TEST_SERVER_IDENTITY_KEY, authConfigs.getServerIdentityKey()); assertEquals(TEST_SERVER_IDENTITY_VALUE, authConfigs.getServerIdentityValue()); assertEquals(TEST_ENABLE_UA_WHITE, authConfigs.isEnableUserAgentAuthWhite()); - Assert.assertTrue(Arrays.equals(AUTHORITYKEY.split(","), authConfigs.getAuthorityKey())); } } diff --git a/auth/src/test/java/com/alibaba/nacos/auth/common/AuthPluginManagerTest.java b/auth/src/test/java/com/alibaba/nacos/auth/common/AuthPluginManagerTest.java index 6bd92058d..76999f222 100644 --- a/auth/src/test/java/com/alibaba/nacos/auth/common/AuthPluginManagerTest.java +++ b/auth/src/test/java/com/alibaba/nacos/auth/common/AuthPluginManagerTest.java @@ -17,7 +17,7 @@ package com.alibaba.nacos.auth.common; import com.alibaba.nacos.auth.AuthPluginManager; -import com.alibaba.nacos.auth.AuthService; +import com.alibaba.nacos.auth.AuthPluginService; import com.alibaba.nacos.auth.api.IdentityContext; import com.alibaba.nacos.auth.api.Permission; import org.junit.Assert; @@ -44,7 +44,7 @@ public class AuthPluginManagerTest { private AuthPluginManager authPluginManager; @Mock - private AuthService authService; + private AuthPluginService authPluginService; private static final String TYPE = "test"; @@ -60,8 +60,8 @@ public class AuthPluginManagerTest { Class authPluginManagerClass = AuthPluginManager.class; Field authPlugins = authPluginManagerClass.getDeclaredField("authServiceMap"); authPlugins.setAccessible(true); - Map authServiceMap = (Map) authPlugins.get(authPluginManager); - authServiceMap.put(TYPE, authService); + Map authServiceMap = (Map) authPlugins.get(authPluginManager); + authServiceMap.put(TYPE, authPluginService); } @Test @@ -73,7 +73,7 @@ public class AuthPluginManagerTest { @Test public void testFindAuthServiceSpiImpl() { - Optional authServiceImpl = authPluginManager.findAuthServiceSpiImpl(TYPE); + Optional authServiceImpl = authPluginManager.findAuthServiceSpiImpl(TYPE); Assert.assertTrue(authServiceImpl.isPresent()); } diff --git a/auth/src/test/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilderTest.java b/auth/src/test/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilderTest.java new file mode 100644 index 000000000..ca9f50532 --- /dev/null +++ b/auth/src/test/java/com/alibaba/nacos/auth/context/GrpcIdentityContextBuilderTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 1999-2021 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.auth.context; + +import com.alibaba.nacos.api.remote.request.Request; +import com.alibaba.nacos.auth.AuthPluginManager; +import com.alibaba.nacos.auth.AuthPluginService; +import com.alibaba.nacos.auth.api.IdentityContext; +import com.alibaba.nacos.auth.common.AuthConfigs; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GrpcIdentityContextBuilderTest { + + private static final String TEST_PLUGIN = "test"; + + private static final String IDENTITY_TEST_KEY = "identity-test-key"; + + private static final String IDENTITY_TEST_VALUE = "identity-test-value"; + + @Mock + private AuthConfigs authConfigs; + + @Mock + private AuthPluginService authPluginService; + + @Mock + private Request request; + + private GrpcIdentityContextBuilder identityContextBuilder; + + @Before + public void setUp() throws Exception { + identityContextBuilder = new GrpcIdentityContextBuilder(authConfigs); + Field authServiceMapField = AuthPluginManager.class.getDeclaredField("authServiceMap"); + authServiceMapField.setAccessible(true); + Map authServiceMap = (Map) authServiceMapField + .get(AuthPluginManager.getInstance()); + authServiceMap.put(TEST_PLUGIN, authPluginService); + when(authConfigs.getNacosAuthSystemType()).thenReturn(TEST_PLUGIN); + when(authPluginService.identityNames()).thenReturn(Collections.singletonList(IDENTITY_TEST_KEY)); + Map headers = new HashMap<>(); + headers.put(IDENTITY_TEST_KEY, IDENTITY_TEST_VALUE); + when(request.getHeaders()).thenReturn(headers); + } + + @Test + public void testBuildWithoutPlugin() { + when(authConfigs.getNacosAuthSystemType()).thenReturn("non-exist"); + IdentityContext actual = identityContextBuilder.build(request); + assertNull(actual.getParameter(IDENTITY_TEST_KEY)); + } + + @Test + public void testBuild() { + IdentityContext actual = identityContextBuilder.build(request); + assertEquals(IDENTITY_TEST_VALUE, actual.getParameter(IDENTITY_TEST_KEY)); + } +} diff --git a/auth/src/test/java/com/alibaba/nacos/auth/context/HtppIdentityContextBuilderTest.java b/auth/src/test/java/com/alibaba/nacos/auth/context/HtppIdentityContextBuilderTest.java new file mode 100644 index 000000000..ab23afcdd --- /dev/null +++ b/auth/src/test/java/com/alibaba/nacos/auth/context/HtppIdentityContextBuilderTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 1999-2021 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.auth.context; + +import com.alibaba.nacos.auth.AuthPluginManager; +import com.alibaba.nacos.auth.AuthPluginService; +import com.alibaba.nacos.auth.api.IdentityContext; +import com.alibaba.nacos.auth.common.AuthConfigs; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HtppIdentityContextBuilderTest { + + private static final String TEST_PLUGIN = "test"; + + private static final String IDENTITY_TEST_KEY = "identity-test-key"; + + private static final String IDENTITY_TEST_VALUE = "identity-test-value"; + + @Mock + private AuthConfigs authConfigs; + + @Mock + private AuthPluginService authPluginService; + + @Mock + private HttpServletRequest request; + + @Mock + private Enumeration headerNames; + + @Mock + private Enumeration parameterNames; + + private HttpIdentityContextBuilder identityContextBuilder; + + @Before + public void setUp() throws Exception { + identityContextBuilder = new HttpIdentityContextBuilder(authConfigs); + Field authServiceMapField = AuthPluginManager.class.getDeclaredField("authServiceMap"); + authServiceMapField.setAccessible(true); + Map authServiceMap = (Map) authServiceMapField + .get(AuthPluginManager.getInstance()); + authServiceMap.put(TEST_PLUGIN, authPluginService); + when(authConfigs.getNacosAuthSystemType()).thenReturn(TEST_PLUGIN); + when(authPluginService.identityNames()).thenReturn(Collections.singletonList(IDENTITY_TEST_KEY)); + } + + @Test + public void testBuildWithoutPlugin() { + mockHeader(true); + mockParameter(true); + when(authConfigs.getNacosAuthSystemType()).thenReturn("non-exist"); + IdentityContext actual = identityContextBuilder.build(request); + assertNull(actual.getParameter(IDENTITY_TEST_KEY)); + } + + @Test + public void testBuildWithHeader() { + mockHeader(true); + mockParameter(false); + IdentityContext actual = identityContextBuilder.build(request); + assertEquals(IDENTITY_TEST_VALUE, actual.getParameter(IDENTITY_TEST_KEY)); + } + + @Test + public void testBuildWithParameter() { + mockHeader(false); + mockParameter(true); + IdentityContext actual = identityContextBuilder.build(request); + assertEquals(IDENTITY_TEST_VALUE, actual.getParameter(IDENTITY_TEST_KEY)); + } + + private void mockHeader(boolean contained) { + when(request.getHeaderNames()).thenReturn(headerNames); + if (contained) { + when(headerNames.hasMoreElements()).thenReturn(true, false); + when(headerNames.nextElement()).thenReturn(IDENTITY_TEST_KEY, (String) null); + when(request.getHeader(IDENTITY_TEST_KEY)).thenReturn(IDENTITY_TEST_VALUE); + } + } + + private void mockParameter(boolean contained) { + when(request.getParameterNames()).thenReturn(parameterNames); + if (contained) { + when(parameterNames.hasMoreElements()).thenReturn(true, false); + when(parameterNames.nextElement()).thenReturn(IDENTITY_TEST_KEY, (String) null); + when(request.getParameter(IDENTITY_TEST_KEY)).thenReturn(IDENTITY_TEST_VALUE); + } + } +}