From 44020825d6683393141f6c4047f5752625c48cd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E7=BF=8A=20SionYang?= Date: Wed, 13 Nov 2024 15:21:03 +0800 Subject: [PATCH] Add unit test for all ram auth plugin. (#18) --- pom.xml | 14 ++ .../AbstractCredentialClientProvider.java | 6 +- .../AutoRotateCredentialsProvider.java | 2 +- .../provider/StsTokenCredentialsProvider.java | 1 - .../client/aliyun/AliyunConfigFilterTest.java | 2 + ...yunExtensionClientAuthServiceImplTest.java | 161 ++++++++++++++++++ ...AbstractExtensionResourceInjectorTest.java | 94 ++++++++++ .../ConfigExtensionResourceInjectorTest.java | 80 +++++++++ .../AbstractCredentialClientProviderTest.java | 77 +++++++++ .../AbstractCredentialsProviderTest.java | 60 +++++++ .../AutoRotateCredentialsProviderTest.java | 98 +++++++++++ ...CredentialsUriCredentialsProviderTest.java | 46 +++++ .../OidcRoleArnCredentialsProviderTest.java | 61 +++++++ .../RamRoleArnCredentialsProviderTest.java | 96 +++++++++++ .../StsTokenCredentialsProviderTest.java | 66 +++++++ 15 files changed, 857 insertions(+), 7 deletions(-) create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/AliyunExtensionClientAuthServiceImplTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/AbstractExtensionResourceInjectorTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/ConfigExtensionResourceInjectorTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProviderTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialsProviderTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProviderTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/CredentialsUriCredentialsProviderTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/OidcRoleArnCredentialsProviderTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/RamRoleArnCredentialsProviderTest.java create mode 100644 src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProviderTest.java diff --git a/pom.xml b/pom.xml index 26ad523..8b317bb 100644 --- a/pom.xml +++ b/pom.xml @@ -128,6 +128,20 @@ RELEASE test + + + org.mockito + mockito-inline + 4.11.0 + test + + + + org.mockito + mockito-junit-jupiter + 4.11.0 + test + diff --git a/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProvider.java b/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProvider.java index edfc737..c68d8a0 100644 --- a/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProvider.java +++ b/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProvider.java @@ -22,10 +22,6 @@ public abstract class AbstractCredentialClientProvider implements ExtensionCrede private String signatureRegionId; - public Client getCredentialsClient() { - return credentialsClient; - } - @Override public void init(Properties properties) { synchronized (this) { @@ -47,9 +43,9 @@ public void init(Properties properties) { @Override public ExtensionRamContext getCredentialsForNacosClient() { - CredentialModel credentialModel = credentialsClient.getCredential(); ExtensionRamContext ramContext = new ExtensionRamContext(); if (null != credentialsClient) { + CredentialModel credentialModel = credentialsClient.getCredential(); ramContext.setAccessKey(credentialModel.getAccessKeyId()); ramContext.setSecretKey(credentialModel.getAccessKeySecret()); ramContext.setSecurityToken(credentialModel.getSecurityToken()); diff --git a/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProvider.java b/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProvider.java index 3f0e4ae..7cf22c4 100644 --- a/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProvider.java +++ b/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProvider.java @@ -45,7 +45,7 @@ private synchronized void buildSecretClient() { if (null == client) { client = SecretCacheClientBuilder.newClient(); } - } catch (CacheSecretException e) { + } catch (Exception e) { throw new NacosRuntimeException(ErrorCode.ILLEGAL_STATE.getCode(), e.getMessage(), e); } } diff --git a/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProvider.java b/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProvider.java index 1f72dda..020ea7c 100644 --- a/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProvider.java +++ b/src/main/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProvider.java @@ -1,6 +1,5 @@ package com.alibaba.nacos.client.aliyun.auth.provider; -import com.alibaba.nacos.api.PropertyKeyConst; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.client.aliyun.auth.ExtensionAuthPropertyKey; import com.alibaba.nacos.client.aliyun.auth.ExtensionRamContext; diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/AliyunConfigFilterTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/AliyunConfigFilterTest.java index 4483217..5b45ef7 100644 --- a/src/test/java/com/alibaba/nacos/client/aliyun/AliyunConfigFilterTest.java +++ b/src/test/java/com/alibaba/nacos/client/aliyun/AliyunConfigFilterTest.java @@ -10,6 +10,7 @@ import com.aliyuncs.kms.model.v20160120.GenerateDataKeyResponse; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.lang.reflect.Field; @@ -28,6 +29,7 @@ import static com.alibaba.nacos.client.aliyun.AliyunConst.KMS_DEFAULT_KEY_ID_VALUE; import static com.alibaba.nacos.client.aliyun.AliyunConst.KMS_KEY_SPEC_AES_256; +@Disabled("This unit test depend accessKey to request KMS, default disabled") public class AliyunConfigFilterTest { private static final String ENCRYPTED_DATA_KEY = "encryptedDataKey"; private static final String CONTENT = "content"; diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/AliyunExtensionClientAuthServiceImplTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/AliyunExtensionClientAuthServiceImplTest.java new file mode 100644 index 0000000..6d5e3b2 --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/AliyunExtensionClientAuthServiceImplTest.java @@ -0,0 +1,161 @@ +package com.alibaba.nacos.client.aliyun.auth; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.client.aliyun.auth.provider.ExtensionCredentialsProvider; +import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext; +import com.alibaba.nacos.plugin.auth.api.RequestResource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class AliyunExtensionClientAuthServiceImplTest { + + AliyunExtensionClientAuthServiceImpl clientAuthService; + + RequestResource resource; + + @BeforeEach + void setUp() { + clientAuthService = new AliyunExtensionClientAuthServiceImpl(); + resource = RequestResource.configBuilder().build(); + } + + @AfterEach + void tearDown() throws NacosException { + clientAuthService.shutdown(); + } + + @Test + void loginNoMatch() { + assertFalse(clientAuthService.login(new Properties())); + } + + @Test + void loginWithException() { + Properties properties = new Properties(); + properties.setProperty(ExtensionAuthPropertyKey.SECRET_NAME.getKey(), "secret"); + assertFalse(clientAuthService.login(properties)); + } + + @Test + void loginSuccess() { + Properties properties = new Properties(); + properties.setProperty(ExtensionAuthPropertyKey.SECURITY_TOKEN.getKey(), "securityToken"); + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_ID.getKey(), "accessKeyId"); + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_SECRET.getKey(), "accessKeySecret"); + assertTrue(clientAuthService.login(properties)); + } + + @Test + void getLoginIdentityContextForStsToken() throws NoSuchFieldException, IllegalAccessException { + injectMockProvider(true, true); + LoginIdentityContext context = clientAuthService.getLoginIdentityContext(resource); + assertEquals("accessKey", context.getParameter("Spas-AccessKey")); + assertEquals("securityToken", context.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + assertNotNull(context.getParameter("Spas-Signature")); + assertNotNull(context.getParameter("Timestamp")); + } + + @Test + void getLoginIdentityContextForAkSk() throws NoSuchFieldException, IllegalAccessException { + injectMockProvider(false, true); + LoginIdentityContext context = clientAuthService.getLoginIdentityContext(resource); + assertEquals("accessKey", context.getParameter("Spas-AccessKey")); + assertNull(context.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + assertNotNull(context.getParameter("Spas-Signature")); + assertNotNull(context.getParameter("Timestamp")); + } + + @Test + void getLoginIdentityContextForStsTokenInvalid() throws NoSuchFieldException, IllegalAccessException { + injectMockProvider(true, false); + LoginIdentityContext context = clientAuthService.getLoginIdentityContext(resource); + assertNull(context.getParameter("Spas-AccessKey")); + assertNull(context.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + assertNull(context.getParameter("Spas-Signature")); + assertNull(context.getParameter("Timestamp")); + } + + @Test + void getLoginIdentityContextForAkSkInvalid() throws NoSuchFieldException, IllegalAccessException { + injectMockProvider(false, false); + LoginIdentityContext context = clientAuthService.getLoginIdentityContext(resource); + assertNull(context.getParameter("Spas-AccessKey")); + assertNull(context.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + assertNull(context.getParameter("Spas-Signature")); + assertNull(context.getParameter("Timestamp")); + } + + @Test + void getLoginIdentityContextForNoInjector() throws NoSuchFieldException, IllegalAccessException { + injectMockProvider(true, true); + resource.setType("Mock"); + LoginIdentityContext context = clientAuthService.getLoginIdentityContext(resource); + assertNull(context.getParameter("Spas-AccessKey")); + assertNull(context.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + assertNull(context.getParameter("Spas-Signature")); + assertNull(context.getParameter("Timestamp")); + } + + @Test + void getLoginIdentityContextWithoutInit() { + LoginIdentityContext context = clientAuthService.getLoginIdentityContext(resource); + assertNull(context.getParameter("Spas-AccessKey")); + assertNull(context.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + assertNull(context.getParameter("Spas-Signature")); + assertNull(context.getParameter("Timestamp")); + } + + private void injectMockProvider(boolean ephemeralAccessKeyId, boolean validate) + throws NoSuchFieldException, IllegalAccessException { + MockCredentialsProvider mockProvider = new MockCredentialsProvider(); + mockProvider.ephemeralAccessKeyId = ephemeralAccessKeyId; + mockProvider.validate = validate; + Field matchedProviderField = clientAuthService.getClass().getDeclaredField("matchedProvider"); + matchedProviderField.setAccessible(true); + matchedProviderField.set(clientAuthService, mockProvider); + } + + private static class MockCredentialsProvider implements ExtensionCredentialsProvider { + + boolean ephemeralAccessKeyId = true; + + boolean validate; + + @Override + public boolean matchProvider(Properties properties) { + return true; + } + + @Override + public void init(Properties properties) { + } + + @Override + public ExtensionRamContext getCredentialsForNacosClient() { + ExtensionRamContext ramContext = new ExtensionRamContext(); + ramContext.setEphemeralAccessKeyId(ephemeralAccessKeyId); + if (validate) { + ramContext.setSecretKey("secretKey"); + ramContext.setAccessKey("accessKey"); + ramContext.setSecurityToken(ephemeralAccessKeyId ? "securityToken" : ""); + } else { + ramContext.setSecurityToken(ephemeralAccessKeyId ? "" : "securityToken"); + } + return ramContext; + } + + @Override + public void shutdown() throws NacosException { + } + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/AbstractExtensionResourceInjectorTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/AbstractExtensionResourceInjectorTest.java new file mode 100644 index 0000000..8384d8a --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/AbstractExtensionResourceInjectorTest.java @@ -0,0 +1,94 @@ +package com.alibaba.nacos.client.aliyun.auth.injector; + +import com.alibaba.nacos.client.aliyun.auth.ExtensionAuthConstants; +import com.alibaba.nacos.client.aliyun.auth.ExtensionRamContext; +import com.alibaba.nacos.plugin.auth.api.LoginIdentityContext; +import com.alibaba.nacos.plugin.auth.api.RequestResource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class AbstractExtensionResourceInjectorTest { + + AbstractExtensionResourceInjector resourceInjector; + + ExtensionRamContext ramContext; + + RequestResource resource; + + @BeforeEach + void setUp() { + resourceInjector = new MockExtensionResourceInjector(); + ramContext = new ExtensionRamContext(); + ramContext.setSecretKey("secret"); + ramContext.setEphemeralAccessKeyId(false); + resource = new RequestResource(); + } + + @AfterEach + void tearDown() { + } + + @Test + void doInjectForV4WithoutRegionId() { + LoginIdentityContext result = new LoginIdentityContext(); + resourceInjector.doInject(resource, ramContext, result); + assertEquals("secret", result.getParameter("sk")); + assertNull(result.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + } + + @Test + void doInjectForV4WithRegionId() { + ramContext.setExtensionSignatureRegionId("cn-hangzhou"); + LoginIdentityContext result = new LoginIdentityContext(); + resourceInjector.doInject(resource, ramContext, result); + assertNotEquals("secret", result.getParameter("sk")); + assertNull(result.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + } + + @Test + void doInjectForV4WithRegionIdAndStsToken() { + ramContext.setExtensionSignatureRegionId("cn-hangzhou"); + ramContext.setSecurityToken("token"); + ramContext.setEphemeralAccessKeyId(true); + LoginIdentityContext result = new LoginIdentityContext(); + resourceInjector.doInject(resource, ramContext, result); + assertNotEquals("secret", result.getParameter("sk")); + assertEquals("token", result.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + } + + @Test + void doInjectForV1WithRegionId() throws NoSuchFieldException, IllegalAccessException { + Field supportV4signatureField = resourceInjector.getClass().getSuperclass() + .getDeclaredField("supportV4signature"); + supportV4signatureField.setAccessible(true); + supportV4signatureField.set(resourceInjector, false); + ramContext.setExtensionSignatureRegionId("cn-hangzhou"); + LoginIdentityContext result = new LoginIdentityContext(); + resourceInjector.doInject(resource, ramContext, result); + assertEquals("secret", result.getParameter("sk")); + assertNull(result.getParameter(ExtensionAuthConstants.SECURITY_TOKEN_HEADER)); + } + + private static class MockExtensionResourceInjector extends AbstractExtensionResourceInjector { + + @Override + protected String getAccessKeyHeaderKey() { + return "Mock"; + } + + @Override + protected Map calculateSignature(RequestResource resource, String actualSecretKey, + ExtensionRamContext ramContext) { + return Collections.singletonMap("sk", actualSecretKey); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/ConfigExtensionResourceInjectorTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/ConfigExtensionResourceInjectorTest.java new file mode 100644 index 0000000..0b93e45 --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/injector/ConfigExtensionResourceInjectorTest.java @@ -0,0 +1,80 @@ +package com.alibaba.nacos.client.aliyun.auth.injector; + +import com.alibaba.nacos.client.auth.ram.utils.SpasAdapter; +import com.alibaba.nacos.plugin.auth.api.RequestResource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ConfigExtensionResourceInjectorTest { + + ConfigExtensionResourceInjector resourceInjector; + + @BeforeEach + void setUp() { + resourceInjector = new ConfigExtensionResourceInjector(); + } + + @AfterEach + void tearDown() { + } + + @Test + void getAccessKeyHeaderKey() { + assertEquals("Spas-AccessKey", resourceInjector.getAccessKeyHeaderKey()); + } + + @Test + void calculateSignatureWithTenant() { + RequestResource resource = RequestResource.configBuilder().setNamespace("TestNamespace").build(); + Map result = resourceInjector.calculateSignature(resource, "secret", null); + assertEquals(2, result.size()); + assertTrue(result.containsKey("Timestamp")); + String expected = SpasAdapter.signWithHmacSha1Encrypt("TestNamespace+" + result.get("Timestamp"), "secret"); + assertEquals(expected, result.get("Spas-Signature")); + } + + @Test + void calculateSignatureWithGroup() { + RequestResource resource = RequestResource.namingBuilder().setGroup("TestGroup").build(); + Map result = resourceInjector.calculateSignature(resource, "secret", null); + assertEquals(2, result.size()); + assertTrue(result.containsKey("Timestamp")); + String expected = SpasAdapter.signWithHmacSha1Encrypt("TestGroup+" + result.get("Timestamp"), "secret"); + assertEquals(expected, result.get("Spas-Signature")); + } + + @Test + void calculateSignatureWithAll() { + RequestResource resource = RequestResource.namingBuilder().setGroup("TestGroup").setNamespace("TestNamespace") + .build(); + Map result = resourceInjector.calculateSignature(resource, "secret", null); + assertEquals(2, result.size()); + assertTrue(result.containsKey("Timestamp")); + String expected = SpasAdapter.signWithHmacSha1Encrypt("TestNamespace+TestGroup+" + result.get("Timestamp"), + "secret"); + assertEquals(expected, result.get("Spas-Signature")); + } + + @Test + void calculateSignatureWithEmptyResource() { + RequestResource resource = RequestResource.namingBuilder().setResource("").build(); + Map result = resourceInjector.calculateSignature(resource, "secret", null); + assertEquals(2, result.size()); + assertTrue(result.containsKey("Timestamp")); + String expected = SpasAdapter.signWithHmacSha1Encrypt(result.get("Timestamp"), "secret"); + assertEquals(expected, result.get("Spas-Signature")); + } + + @Test + void calculateSignatureWithException() { + // Will Throw NPE. + Map result = resourceInjector.calculateSignature(null, "secret", null); + assertEquals(0, result.size()); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProviderTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProviderTest.java new file mode 100644 index 0000000..ab30b6e --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialClientProviderTest.java @@ -0,0 +1,77 @@ +package com.alibaba.nacos.client.aliyun.auth.provider; + +import com.alibaba.nacos.client.aliyun.auth.ExtensionRamContext; +import com.aliyun.credentials.Client; +import com.aliyun.credentials.models.CredentialModel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.lang.reflect.Field; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +abstract class AbstractCredentialClientProviderTest extends AbstractCredentialsProviderTest { + + @Mock + Client credentialsClient; + + protected CredentialModel credentialModel; + + @BeforeEach + void setUp() { + super.setUp(); + credentialModel = CredentialModel.builder().accessKeyId(ACCESS_KEY_ID).accessKeySecret(ACCESS_KEY_SECRET) + .securityToken(SECURITY_TOKEN).build(); + } + + @Test + void getCredentialsForNacosClient() throws NoSuchFieldException, IllegalAccessException { + injectMockCredentialsClient(); + initWithProperties(); + mockCredentialsClientReturn(credentialModel); + ExtensionRamContext context = getCredentialsProvider().getCredentialsForNacosClient(); + assertEquals(ACCESS_KEY_ID, context.getAccessKey()); + assertEquals(ACCESS_KEY_SECRET, context.getSecretKey()); + assertEquals(SECURITY_TOKEN, context.getSecurityToken()); + } + + @Test + void getCredentialsForNacosClientByEnv() throws NoSuchFieldException, IllegalAccessException { + injectMockCredentialsClient(); + initWithEnvProperties(); + mockCredentialsClientReturn(credentialModel); + ExtensionRamContext context = getCredentialsProvider().getCredentialsForNacosClient(); + assertEquals(ACCESS_KEY_ID, context.getAccessKey()); + assertEquals(ACCESS_KEY_SECRET, context.getSecretKey()); + assertEquals(SECURITY_TOKEN, context.getSecurityToken()); + } + + @Test + void getCredentialsForNacosClientWithoutInit() { + ExtensionRamContext context = getCredentialsProvider().getCredentialsForNacosClient(); + assertNull(context.getAccessKey()); + assertNull(context.getSecretKey()); + assertNull(context.getSecurityToken()); + } + + protected void injectMockCredentialsClient() throws NoSuchFieldException, IllegalAccessException { + Field clientField = credentialsProvider.getClass().getSuperclass().getDeclaredField("credentialsClient"); + clientField.setAccessible(true); + clientField.set(credentialsProvider, credentialsClient); + } + + protected void mockCredentialsClientReturn(CredentialModel credential) + throws NoSuchFieldException, IllegalAccessException { + when(credentialsClient.getCredential()).thenReturn(credential); + } + + protected AbstractCredentialClientProvider getCredentialsProvider() { + return (AbstractCredentialClientProvider) credentialsProvider; + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialsProviderTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialsProviderTest.java new file mode 100644 index 0000000..5d3e990 --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AbstractCredentialsProviderTest.java @@ -0,0 +1,60 @@ +package com.alibaba.nacos.client.aliyun.auth.provider; + +import com.alibaba.nacos.api.exception.NacosException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public abstract class AbstractCredentialsProviderTest { + + protected static final String ACCESS_KEY_ID = "accessKeyId"; + + protected static final String ACCESS_KEY_SECRET = "accessKeySecret"; + + protected static final String SECURITY_TOKEN = "securityToken"; + + protected static final String SIGNATURE_REGION_ID = "signatureRegionId"; + + ExtensionCredentialsProvider credentialsProvider; + + Properties properties; + + @BeforeEach + void setUp() { + credentialsProvider = buildCredentialsProvider(); + properties = new Properties(); + } + + protected abstract ExtensionCredentialsProvider buildCredentialsProvider(); + + @AfterEach + void tearDown() throws NacosException { + credentialsProvider.shutdown(); + } + + @Test + void matchProvider() { + assertFalse(credentialsProvider.matchProvider(properties)); + injectProperties(properties); + assertTrue(credentialsProvider.matchProvider(properties)); + } + + protected void initWithProperties() { + injectProperties(properties); + credentialsProvider.init(properties); + } + + protected void initWithEnvProperties() { + injectEnvProperties(properties); + credentialsProvider.init(properties); + } + + protected abstract void injectProperties(Properties properties); + + protected abstract void injectEnvProperties(Properties properties); +} diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProviderTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProviderTest.java new file mode 100644 index 0000000..02debe3 --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/AutoRotateCredentialsProviderTest.java @@ -0,0 +1,98 @@ +package com.alibaba.nacos.client.aliyun.auth.provider; + +import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException; +import com.alibaba.nacos.client.aliyun.auth.ExtensionAuthPropertyKey; +import com.alibaba.nacos.client.aliyun.auth.ExtensionRamContext; +import com.aliyuncs.kms.secretsmanager.client.SecretCacheClient; +import com.aliyuncs.kms.secretsmanager.client.exception.CacheSecretException; +import com.aliyuncs.kms.secretsmanager.client.model.SecretInfo; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.lang.reflect.Field; +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class AutoRotateCredentialsProviderTest extends AbstractCredentialsProviderTest { + + @Mock + private SecretCacheClient client; + + @Override + protected ExtensionCredentialsProvider buildCredentialsProvider() { + return new AutoRotateCredentialsProvider(); + } + + @Override + protected void injectProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.SECRET_NAME.getKey(), "secretName"); + } + + @Override + protected void injectEnvProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.SECRET_NAME.getEnvKey(), "secretName"); + + } + + @Test + void testInitWithException() { + assertThrows(NacosRuntimeException.class, this::initWithProperties); + } + + @Test + void getCredentialsForNacosClient() throws NoSuchFieldException, IllegalAccessException, CacheSecretException { + setClient(); + initWithProperties(); + ExtensionRamContext result = credentialsProvider.getCredentialsForNacosClient(); + assertEquals("accessKeyId", result.getAccessKey()); + assertEquals("accessKeySecret", result.getSecretKey()); + assertFalse(result.isEphemeralAccessKeyId()); + } + + @Test + void getCredentialsForNacosClientByEnv() throws NoSuchFieldException, IllegalAccessException, CacheSecretException { + setClient(); + initWithEnvProperties(); + ExtensionRamContext result = credentialsProvider.getCredentialsForNacosClient(); + assertEquals("accessKeyId", result.getAccessKey()); + assertEquals("accessKeySecret", result.getSecretKey()); + assertFalse(result.isEphemeralAccessKeyId()); + } + + @Test + void getCredentialsForNacosClientWithException() + throws NoSuchFieldException, IllegalAccessException, CacheSecretException { + setClient(); + when(client.getSecretInfo("secretName")).thenThrow(new CacheSecretException()); + initWithEnvProperties(); + ExtensionRamContext result = credentialsProvider.getCredentialsForNacosClient(); + assertNull(result.getAccessKey()); + assertNull(result.getSecretKey()); + assertFalse(result.isEphemeralAccessKeyId()); + } + + @Test + void getCredentialsForNacosClientWithoutInit() { + ExtensionRamContext result = credentialsProvider.getCredentialsForNacosClient(); + assertNull(result.getAccessKey()); + assertNull(result.getSecretKey()); + assertFalse(result.isEphemeralAccessKeyId()); + } + + private void setClient() throws NoSuchFieldException, IllegalAccessException, CacheSecretException { + Field clientField = credentialsProvider.getClass().getDeclaredField("client"); + clientField.setAccessible(true); + clientField.set(credentialsProvider, client); + SecretInfo secretInfo = new SecretInfo(); + secretInfo.setSecretValue("{\"AccessKeyId\":\"accessKeyId\",\"AccessKeySecret\":\"accessKeySecret\"}"); + when(client.getSecretInfo("secretName")).thenReturn(secretInfo); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/CredentialsUriCredentialsProviderTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/CredentialsUriCredentialsProviderTest.java new file mode 100644 index 0000000..53c762e --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/CredentialsUriCredentialsProviderTest.java @@ -0,0 +1,46 @@ +package com.alibaba.nacos.client.aliyun.auth.provider; + +import com.alibaba.nacos.client.aliyun.auth.ExtensionAuthPropertyKey; +import com.alibaba.nacos.client.aliyun.auth.ExtensionRamContext; +import com.aliyun.credentials.models.Config; +import com.aliyun.credentials.models.CredentialModel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.*; + +class CredentialsUriCredentialsProviderTest extends AbstractCredentialClientProviderTest { + + @Override + protected ExtensionCredentialsProvider buildCredentialsProvider() { + return new CredentialsUriCredentialsProvider(); + } + + @Override + protected void injectProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.CREDENTIALS_URI.getKey(), "http://localhost"); + } + + @Override + protected void injectEnvProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.CREDENTIALS_URI.getEnvKey(), "http://envhost"); + } + + @Test + void generateCredentialsConfig() { + initWithProperties(); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("credentials_uri", config.getType()); + assertEquals("http://localhost", config.getCredentialsUri()); + } + + @Test + void generateCredentialsConfigByEnv() { + initWithEnvProperties(); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("credentials_uri", config.getType()); + assertEquals("http://envhost", config.getCredentialsUri()); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/OidcRoleArnCredentialsProviderTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/OidcRoleArnCredentialsProviderTest.java new file mode 100644 index 0000000..6fbc9bc --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/OidcRoleArnCredentialsProviderTest.java @@ -0,0 +1,61 @@ +package com.alibaba.nacos.client.aliyun.auth.provider; + +import com.alibaba.nacos.client.aliyun.auth.ExtensionAuthPropertyKey; +import com.alibaba.nacos.client.aliyun.auth.ExtensionRamContext; +import com.aliyun.credentials.models.Config; +import org.junit.jupiter.api.Test; + +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class OidcRoleArnCredentialsProviderTest extends AbstractCredentialClientProviderTest { + + @Override + protected ExtensionCredentialsProvider buildCredentialsProvider() { + return new OidcRoleArnCredentialsProvider(); + } + + @Override + protected void injectProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.ROLE_ARN.getKey(), "role_arn"); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_SESSION_NAME.getKey(), "ram_role_arn_test"); + properties.setProperty(ExtensionAuthPropertyKey.OIDC_PROVIDER_ARN.getKey(), "oidc_provider_arn"); + properties.setProperty(ExtensionAuthPropertyKey.OIDC_TOKEN_FILE_PATH.getKey(), "oidc_token_file"); + } + + @Override + protected void injectEnvProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.ROLE_ARN.getEnvKey(), "role_arn"); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_SESSION_NAME.getEnvKey(), "ram_role_arn_test"); + properties.setProperty(ExtensionAuthPropertyKey.OIDC_PROVIDER_ARN.getEnvKey(), "oidc_provider_arn"); + properties.setProperty(ExtensionAuthPropertyKey.OIDC_TOKEN_FILE_PATH.getEnvKey(), "oidc_token_file"); + } + + @Test + void generateCredentialsConfig() { + initWithProperties(); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("oidc_role_arn", config.getType()); + assertEquals("role_arn", config.getRoleArn()); + assertEquals("ram_role_arn_test", config.getRoleSessionName()); + assertEquals("oidc_provider_arn", config.getOidcProviderArn()); + assertEquals("oidc_token_file", config.getOidcTokenFilePath()); + assertNull(config.getPolicy()); + assertEquals(3600, config.getRoleSessionExpiration()); + } + + @Test + void generateCredentialsConfigByEnv() { + initWithEnvProperties(); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("oidc_role_arn", config.getType()); + assertEquals("role_arn", config.getRoleArn()); + assertEquals("ram_role_arn_test", config.getRoleSessionName()); + assertEquals("oidc_provider_arn", config.getOidcProviderArn()); + assertEquals("oidc_token_file", config.getOidcTokenFilePath()); + assertNull(config.getPolicy()); + assertEquals(3600, config.getRoleSessionExpiration()); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/RamRoleArnCredentialsProviderTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/RamRoleArnCredentialsProviderTest.java new file mode 100644 index 0000000..607b530 --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/RamRoleArnCredentialsProviderTest.java @@ -0,0 +1,96 @@ +package com.alibaba.nacos.client.aliyun.auth.provider; + +import com.alibaba.nacos.client.aliyun.auth.ExtensionAuthPropertyKey; +import com.aliyun.credentials.models.Config; +import org.junit.jupiter.api.Test; + +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class RamRoleArnCredentialsProviderTest extends AbstractCredentialClientProviderTest { + + @Override + protected ExtensionCredentialsProvider buildCredentialsProvider() { + return new RamRoleArnCredentialsProvider(); + } + + @Override + protected void injectProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_ID.getKey(), ACCESS_KEY_ID); + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_SECRET.getKey(), ACCESS_KEY_SECRET); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_ARN.getKey(), "role_arn"); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_SESSION_NAME.getKey(), "ram_role_arn_test"); + } + + @Override + protected void injectEnvProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_ID.getEnvKey(), ACCESS_KEY_ID); + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_SECRET.getEnvKey(), ACCESS_KEY_SECRET); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_ARN.getEnvKey(), "role_arn"); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_SESSION_NAME.getEnvKey(), "ram_role_arn_test"); + } + + @Test + void generateCredentialsConfig() { + initWithProperties(); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("ram_role_arn", config.getType()); + assertEquals(ACCESS_KEY_ID, config.getAccessKeyId()); + assertEquals(ACCESS_KEY_SECRET, config.getAccessKeySecret()); + assertNull(config.getSecurityToken()); + assertEquals("role_arn", config.getRoleArn()); + assertEquals("ram_role_arn_test", config.getRoleSessionName()); + assertNull(config.getPolicy()); + assertEquals(3600, config.getRoleSessionExpiration()); + } + + @Test + void generateCredentialsConfigFull() { + initWithProperties(); + properties.setProperty(ExtensionAuthPropertyKey.SECURITY_TOKEN.getKey(), SECURITY_TOKEN); + properties.setProperty(ExtensionAuthPropertyKey.POLICY.getKey(), "policy"); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_SESSION_EXPIRATION.getKey(), "360"); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("ram_role_arn", config.getType()); + assertEquals(ACCESS_KEY_ID, config.getAccessKeyId()); + assertEquals(ACCESS_KEY_SECRET, config.getAccessKeySecret()); + assertEquals(SECURITY_TOKEN, config.getSecurityToken()); + assertEquals("role_arn", config.getRoleArn()); + assertEquals("ram_role_arn_test", config.getRoleSessionName()); + assertEquals("policy", config.getPolicy()); + assertEquals(360, config.getRoleSessionExpiration()); + } + + @Test + void generateCredentialsConfigByEnv() { + initWithEnvProperties(); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("ram_role_arn", config.getType()); + assertEquals(ACCESS_KEY_ID, config.getAccessKeyId()); + assertEquals(ACCESS_KEY_SECRET, config.getAccessKeySecret()); + assertNull(config.getSecurityToken()); + assertEquals("role_arn", config.getRoleArn()); + assertEquals("ram_role_arn_test", config.getRoleSessionName()); + assertNull(config.getPolicy()); + assertEquals(3600, config.getRoleSessionExpiration()); + } + + @Test + void generateCredentialsConfigByEnvFull() { + initWithProperties(); + properties.setProperty(ExtensionAuthPropertyKey.SECURITY_TOKEN.getEnvKey(), SECURITY_TOKEN); + properties.setProperty(ExtensionAuthPropertyKey.POLICY.getEnvKey(), "policy"); + properties.setProperty(ExtensionAuthPropertyKey.ROLE_SESSION_EXPIRATION.getEnvKey(), "360"); + Config config = getCredentialsProvider().generateCredentialsConfig(properties); + assertEquals("ram_role_arn", config.getType()); + assertEquals(ACCESS_KEY_ID, config.getAccessKeyId()); + assertEquals(ACCESS_KEY_SECRET, config.getAccessKeySecret()); + assertEquals(SECURITY_TOKEN, config.getSecurityToken()); + assertEquals("role_arn", config.getRoleArn()); + assertEquals("ram_role_arn_test", config.getRoleSessionName()); + assertEquals("policy", config.getPolicy()); + assertEquals(360, config.getRoleSessionExpiration()); + } +} \ No newline at end of file diff --git a/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProviderTest.java b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProviderTest.java new file mode 100644 index 0000000..3f03466 --- /dev/null +++ b/src/test/java/com/alibaba/nacos/client/aliyun/auth/provider/StsTokenCredentialsProviderTest.java @@ -0,0 +1,66 @@ +package com.alibaba.nacos.client.aliyun.auth.provider; + +import com.alibaba.nacos.client.aliyun.auth.ExtensionAuthPropertyKey; +import com.alibaba.nacos.client.aliyun.auth.ExtensionRamContext; +import org.junit.jupiter.api.Test; + +import java.util.Properties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class StsTokenCredentialsProviderTest extends AbstractCredentialsProviderTest { + + @Override + protected ExtensionCredentialsProvider buildCredentialsProvider() { + return new StsTokenCredentialsProvider(); + } + + @Override + protected void injectProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_ID.getKey(), ACCESS_KEY_ID); + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_SECRET.getKey(), ACCESS_KEY_SECRET); + properties.setProperty(ExtensionAuthPropertyKey.SECURITY_TOKEN.getKey(), SECURITY_TOKEN); + properties.setProperty(ExtensionAuthPropertyKey.SIGNATURE_REGION_ID.getKey(), SIGNATURE_REGION_ID); + } + + @Override + protected void injectEnvProperties(Properties properties) { + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_ID.getEnvKey(), ACCESS_KEY_ID); + properties.setProperty(ExtensionAuthPropertyKey.ACCESS_KEY_SECRET.getEnvKey(), ACCESS_KEY_SECRET); + properties.setProperty(ExtensionAuthPropertyKey.SECURITY_TOKEN.getEnvKey(), SECURITY_TOKEN); + properties.setProperty(ExtensionAuthPropertyKey.SIGNATURE_REGION_ID.getEnvKey(), SIGNATURE_REGION_ID); + } + + @Test + void getCredentialsForNacosClient() { + initWithProperties(); + ExtensionRamContext context = credentialsProvider.getCredentialsForNacosClient(); + assertEquals(ACCESS_KEY_ID, context.getAccessKey()); + assertEquals(ACCESS_KEY_SECRET, context.getSecretKey()); + assertEquals(SECURITY_TOKEN, context.getSecurityToken()); + assertEquals(SIGNATURE_REGION_ID, context.getExtensionSignatureRegionId()); + } + + @Test + void getCredentialsForNacosClientWithEnv() { + initWithEnvProperties(); + ExtensionRamContext context = credentialsProvider.getCredentialsForNacosClient(); + assertEquals(ACCESS_KEY_ID, context.getAccessKey()); + assertEquals(ACCESS_KEY_SECRET, context.getSecretKey()); + assertEquals(SECURITY_TOKEN, context.getSecurityToken()); + assertEquals(SIGNATURE_REGION_ID, context.getExtensionSignatureRegionId()); + } + + @Test + void getCredentialsForNacosClientWithoutSignatureRegionId() { + injectProperties(properties); + properties.remove(ExtensionAuthPropertyKey.SIGNATURE_REGION_ID.getKey()); + credentialsProvider.init(properties); + ExtensionRamContext context = credentialsProvider.getCredentialsForNacosClient(); + assertEquals(ACCESS_KEY_ID, context.getAccessKey()); + assertEquals(ACCESS_KEY_SECRET, context.getSecretKey()); + assertEquals(SECURITY_TOKEN, context.getSecurityToken()); + assertNull(context.getExtensionSignatureRegionId()); + } +} \ No newline at end of file