diff --git a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdk.java b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdk.java index 7b212c9d8..076d35693 100644 --- a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdk.java +++ b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdk.java @@ -1,12 +1,10 @@ package com.symphony.bdk.core; import com.symphony.bdk.core.activity.ActivityRegistry; -import com.symphony.bdk.core.auth.AuthSession; -import com.symphony.bdk.core.auth.AuthenticatorFactory; -import com.symphony.bdk.core.auth.ExtensionAppAuthenticator; -import com.symphony.bdk.core.auth.OboAuthenticator; +import com.symphony.bdk.core.auth.*; import com.symphony.bdk.core.auth.exception.AuthInitializationException; import com.symphony.bdk.core.auth.exception.AuthUnauthorizedException; +import com.symphony.bdk.core.auth.impl.AuthenticatorFactoryImpl; import com.symphony.bdk.core.client.ApiClientFactory; import com.symphony.bdk.core.config.exception.BotNotConfiguredException; import com.symphony.bdk.core.config.model.BdkConfig; @@ -103,7 +101,7 @@ protected SymphonyBdk( } if (authenticatorFactory == null) { - authenticatorFactory = new AuthenticatorFactory(this.config, apiClientFactory); + authenticatorFactory = new AuthenticatorFactoryImpl(this.config, apiClientFactory); } this.oboAuthenticator = config.isOboConfigured() ? authenticatorFactory.getOboAuthenticator() : null; diff --git a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdkBuilder.java b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdkBuilder.java index fa69a479a..af73fbbf1 100644 --- a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdkBuilder.java +++ b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/SymphonyBdkBuilder.java @@ -1,6 +1,7 @@ package com.symphony.bdk.core; import com.symphony.bdk.core.auth.AuthenticatorFactory; +import com.symphony.bdk.core.auth.impl.AuthenticatorFactoryImpl; import com.symphony.bdk.core.auth.exception.AuthInitializationException; import com.symphony.bdk.core.auth.exception.AuthUnauthorizedException; import com.symphony.bdk.core.client.ApiClientFactory; @@ -22,7 +23,7 @@ * Fluent builder for advanced configuration of the {@link SymphonyBdk} entry point. * *

Please note that some of the parameters (such as {@link ApiClientBuilderProvider}, {@link ApiClientFactory} or - * {@link AuthenticatorFactory}) have to be used with caution. + * {@link AuthenticatorFactoryImpl}) have to be used with caution. */ @Generated @API(status = API.Status.EXPERIMENTAL) @@ -72,9 +73,9 @@ public SymphonyBdkBuilder apiClientFactory(@Nullable ApiClientFactory apiClientF } /** - * With custom {@link AuthenticatorFactory} instance. + * With custom {@link AuthenticatorFactoryImpl} instance. * - * @param authenticatorFactory a custom {@link AuthenticatorFactory} instance. + * @param authenticatorFactory a custom {@link AuthenticatorFactoryImpl} instance. * @return updated builder. */ public SymphonyBdkBuilder authenticatorFactory(@Nullable AuthenticatorFactory authenticatorFactory) { @@ -115,7 +116,7 @@ public SymphonyBdk build() throws AuthUnauthorizedException, AuthInitializationE } if (this.authenticatorFactory == null) { - this.authenticatorFactory = new AuthenticatorFactory(this.config, this.apiClientFactory); + this.authenticatorFactory = new AuthenticatorFactoryImpl(this.config, this.apiClientFactory); } final SymphonyBdk bdk = new SymphonyBdk(this.config, this.apiClientFactory, this.authenticatorFactory); diff --git a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/AuthenticatorFactory.java b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/AuthenticatorFactory.java index 7b862c7e7..5ee0e53f3 100644 --- a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/AuthenticatorFactory.java +++ b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/AuthenticatorFactory.java @@ -1,237 +1,46 @@ package com.symphony.bdk.core.auth; -import static com.symphony.bdk.core.util.DeprecationLogger.logDeprecation; -import static org.apache.commons.lang3.ObjectUtils.isNotEmpty; - import com.symphony.bdk.core.auth.exception.AuthInitializationException; -import com.symphony.bdk.core.auth.impl.BotAuthenticatorCertImpl; -import com.symphony.bdk.core.auth.impl.BotAuthenticatorRsaImpl; -import com.symphony.bdk.core.auth.impl.ExtensionAppAuthenticatorCertImpl; -import com.symphony.bdk.core.auth.impl.ExtensionAppAuthenticatorRsaImpl; -import com.symphony.bdk.core.auth.impl.InMemoryTokensRepository; -import com.symphony.bdk.core.auth.impl.OboAuthenticatorCertImpl; -import com.symphony.bdk.core.auth.impl.OboAuthenticatorRsaImpl; -import com.symphony.bdk.core.auth.jwt.JwtHelper; -import com.symphony.bdk.core.client.ApiClientFactory; -import com.symphony.bdk.core.config.model.BdkAuthenticationConfig; -import com.symphony.bdk.core.config.model.BdkConfig; - -import com.symphony.bdk.core.service.version.AgentVersionService; - -import com.symphony.bdk.gen.api.SignalsApi; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.IOUtils; import org.apiguardian.api.API; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.PrivateKey; - import javax.annotation.Nonnull; /** - * Factory class that provides new instances for the main authenticators : + * Factory responsible for creating different authenticators. *

*/ -@Slf4j @API(status = API.Status.STABLE) -public class AuthenticatorFactory { - - private final BdkConfig config; - private final ApiClientFactory apiClientFactory; - private final ExtensionAppTokensRepository extensionAppTokensRepository; - - public AuthenticatorFactory(@Nonnull BdkConfig bdkConfig, @Nonnull ApiClientFactory apiClientFactory) { - this(bdkConfig, apiClientFactory, new InMemoryTokensRepository()); - } - - public AuthenticatorFactory(@Nonnull BdkConfig bdkConfig, @Nonnull ApiClientFactory apiClientFactory, - @Nonnull ExtensionAppTokensRepository extensionAppTokensRepository) { - this.config = bdkConfig; - this.apiClientFactory = apiClientFactory; - this.extensionAppTokensRepository = extensionAppTokensRepository; - } +public interface AuthenticatorFactory { /** - * Creates a new instance of a {@link BotAuthenticator} service. + * Creates a new instance of a {@link BotAuthenticator}. * * @return a new {@link BotAuthenticator} instance. + * @throws AuthInitializationException if the authenticator cannot be instantiated. */ - public @Nonnull - BotAuthenticator getBotAuthenticator() throws AuthInitializationException { - if (this.config.getBot().isBothCertificateAndRsaConfigured()) { - throw new AuthInitializationException( - "Both of certificate and rsa authentication are configured. Only one of them should be provided."); - } - if (this.config.getBot().isCertificateAuthenticationConfigured()) { - if (!this.config.getBot().isCertificateConfigurationValid()) { - throw new AuthInitializationException( - "Only one of certificate path or content should be configured for bot authentication."); - } - return new BotAuthenticatorCertImpl( - this.config.getRetry(), - this.config.getBot().getUsername(), - this.config.getCommonJwt(), - this.apiClientFactory.getLoginClient(), - this.apiClientFactory.getSessionAuthClient(), - this.apiClientFactory.getKeyAuthClient(), - new AgentVersionService(new SignalsApi(this.apiClientFactory.getAgentClient())) - ); - } - if (this.config.getBot().isRsaAuthenticationConfigured()) { - if (!this.config.getBot().isRsaConfigurationValid()) { - throw new AuthInitializationException( - "Only one of private key path or content should be configured for bot authentication."); - } - return new BotAuthenticatorRsaImpl( - this.config.getRetry(), - this.config.getBot().getUsername(), - this.config.getCommonJwt(), - this.loadPrivateKeyFromAuthenticationConfig(this.config.getBot()), - this.apiClientFactory.getLoginClient(), - this.apiClientFactory.getRelayClient(), - new AgentVersionService(new SignalsApi(this.apiClientFactory.getAgentClient())) - ); - } - throw new AuthInitializationException("Neither RSA private key nor certificate is configured."); - } + @Nonnull + BotAuthenticator getBotAuthenticator() throws AuthInitializationException; /** - * Creates a new instance of an {@link OboAuthenticator} service. + * Creates a new instance of a {@link OboAuthenticator}. * * @return a new {@link OboAuthenticator} instance. + * @throws AuthInitializationException if the authenticator cannot be instantiated. */ - public @Nonnull - OboAuthenticator getOboAuthenticator() throws AuthInitializationException { - if (this.config.getApp().isBothCertificateAndRsaConfigured()) { - throw new AuthInitializationException( - "Both of certificate and rsa authentication are configured. Only one of them should be provided."); - } - if (this.config.getApp().isCertificateAuthenticationConfigured()) { - if (!this.config.getApp().isCertificateConfigurationValid()) { - throw new AuthInitializationException( - "Only one of certificate path or content should be configured for app authentication."); - } - return new OboAuthenticatorCertImpl( - this.config.getRetry(), - this.config.getApp().getAppId(), - this.apiClientFactory.getExtAppSessionAuthClient() - ); - } - if (this.config.getApp().isRsaAuthenticationConfigured()) { - if (!this.config.getApp().isRsaConfigurationValid()) { - throw new AuthInitializationException( - "Only one of private key path or content should be configured for app authentication."); - } - return new OboAuthenticatorRsaImpl( - this.config.getRetry(), - this.config.getApp().getAppId(), - this.loadPrivateKeyFromAuthenticationConfig(this.config.getApp()), - this.apiClientFactory.getLoginClient() - ); - } - throw new AuthInitializationException("Neither RSA private key nor certificate is configured."); - } + @Nonnull + OboAuthenticator getOboAuthenticator() throws AuthInitializationException; /** - * Creates a new instance of an {@link ExtensionAppAuthenticator} service. + * Creates a new instance of a {@link ExtensionAppAuthenticator}. * * @return a new {@link ExtensionAppAuthenticator} instance. + * @throws AuthInitializationException if the authenticator cannot be instantiated. */ - public @Nonnull - ExtensionAppAuthenticator getExtensionAppAuthenticator() throws AuthInitializationException { - if (this.config.getApp().isBothCertificateAndRsaConfigured()) { - throw new AuthInitializationException( - "Both of certificate and rsa authentication are configured. Only one of them should be provided."); - } - if (this.config.getApp().isCertificateAuthenticationConfigured()) { - if (!this.config.getApp().isCertificateConfigurationValid()) { - throw new AuthInitializationException( - "Only one of certificate path or content should be configured for app authentication."); - } - return new ExtensionAppAuthenticatorCertImpl( - this.config.getRetry(), - this.config.getApp().getAppId(), - this.apiClientFactory.getExtAppSessionAuthClient(), - extensionAppTokensRepository); - } - if (this.config.getApp().isRsaAuthenticationConfigured()) { - if (!this.config.getApp().isRsaConfigurationValid()) { - throw new AuthInitializationException( - "Only one of private key path or content should be configured for app authentication."); - } - return new ExtensionAppAuthenticatorRsaImpl( - this.config.getRetry(), - this.config.getApp().getAppId(), - this.loadPrivateKeyFromAuthenticationConfig(this.config.getApp()), - this.apiClientFactory.getLoginClient(), - this.apiClientFactory.getPodClient(), - extensionAppTokensRepository - ); - } - throw new AuthInitializationException("Neither RSA private key nor certificate is configured."); - } - - private PrivateKey loadPrivateKeyFromAuthenticationConfig(BdkAuthenticationConfig config) - throws AuthInitializationException { - String privateKeyPath = ""; - try { - String privateKey; - if (config.getPrivateKey() != null && config.getPrivateKey().isConfigured()) { - if (isNotEmpty(config.getPrivateKey().getContent())) { - privateKey = new String(config.getPrivateKey().getContent(), StandardCharsets.UTF_8); - } else { - privateKeyPath = config.getPrivateKey().getPath(); - log.debug("Loading RSA privateKey from path : {}", privateKeyPath); - privateKey = loadPrivateKey(privateKeyPath); - } - } else { - logDeprecation("RSA private key should be configured under \"privateKey\" field"); - if (isNotEmpty(config.getPrivateKeyContent())) { - privateKey = new String(config.getPrivateKeyContent(), StandardCharsets.UTF_8); - } else { - privateKeyPath = config.getPrivateKeyPath(); - log.debug("Loading RSA privateKey from path : {}", privateKeyPath); - privateKey = loadPrivateKey(privateKeyPath); - } - } - return JwtHelper.parseRsaPrivateKey(privateKey); - } catch (GeneralSecurityException e) { - final String message = String.format("Unable to parse RSA Private Key from path %s. Check if the format is " - + "correct.", privateKeyPath); - throw new AuthInitializationException(message, e); - } catch (IOException e) { - final String message = "Unable to read or find RSA Private Key from path " + privateKeyPath; - throw new AuthInitializationException(message, e); - } - } - - private static String loadPrivateKey(String privateKeyPath) throws IOException, AuthInitializationException { - InputStream is; - - // useful for testing when private key is located into resources - if (privateKeyPath.startsWith("classpath:")) { - log.warn("Warning: Keeping RSA private keys into project resources is dangerous. " - + "You should consider another location for production."); - is = AuthenticatorFactory.class.getResourceAsStream(privateKeyPath.replace("classpath:", "")); - if (is == null) { - throw new AuthInitializationException( - "Unable to find RSA private key as classpath resource from: " + privateKeyPath); - } - try (InputStream resourceStream = is) { - return IOUtils.toString(resourceStream, StandardCharsets.UTF_8); - } - } else { - try (InputStream fileStream = new FileInputStream(privateKeyPath)) { - return IOUtils.toString(fileStream, StandardCharsets.UTF_8); - } - } - } + @Nonnull + ExtensionAppAuthenticator getExtensionAppAuthenticator() throws AuthInitializationException; } diff --git a/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/impl/AuthenticatorFactoryImpl.java b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/impl/AuthenticatorFactoryImpl.java new file mode 100644 index 000000000..5e18bb5aa --- /dev/null +++ b/symphony-bdk-core/src/main/java/com/symphony/bdk/core/auth/impl/AuthenticatorFactoryImpl.java @@ -0,0 +1,237 @@ +package com.symphony.bdk.core.auth.impl; + +import static com.symphony.bdk.core.util.DeprecationLogger.logDeprecation; +import static org.apache.commons.lang3.ObjectUtils.isNotEmpty; + +import com.symphony.bdk.core.auth.*; +import com.symphony.bdk.core.auth.exception.AuthInitializationException; +import com.symphony.bdk.core.auth.jwt.JwtHelper; +import com.symphony.bdk.core.client.ApiClientFactory; +import com.symphony.bdk.core.config.model.BdkAuthenticationConfig; +import com.symphony.bdk.core.config.model.BdkConfig; + +import com.symphony.bdk.core.service.version.AgentVersionService; + +import com.symphony.bdk.gen.api.SignalsApi; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apiguardian.api.API; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.PrivateKey; + +import javax.annotation.Nonnull; + +/** + * Factory class that provides new instances for the main authenticators : + * + */ +@Slf4j +@API(status = API.Status.INTERNAL) +public class AuthenticatorFactoryImpl implements AuthenticatorFactory { + + private final BdkConfig config; + private final ApiClientFactory apiClientFactory; + private final ExtensionAppTokensRepository extensionAppTokensRepository; + + public AuthenticatorFactoryImpl(@Nonnull BdkConfig bdkConfig, @Nonnull ApiClientFactory apiClientFactory) { + this(bdkConfig, apiClientFactory, new InMemoryTokensRepository()); + } + + public AuthenticatorFactoryImpl(@Nonnull BdkConfig bdkConfig, @Nonnull ApiClientFactory apiClientFactory, + @Nonnull ExtensionAppTokensRepository extensionAppTokensRepository) { + this.config = bdkConfig; + this.apiClientFactory = apiClientFactory; + this.extensionAppTokensRepository = extensionAppTokensRepository; + } + + /** + * Creates a new instance of a {@link BotAuthenticator} service. + * + * @return a new {@link BotAuthenticator} instance. + */ + @Nonnull + @Override + public + BotAuthenticator getBotAuthenticator() throws AuthInitializationException { + if (this.config.getBot().isBothCertificateAndRsaConfigured()) { + throw new AuthInitializationException( + "Both of certificate and rsa authentication are configured. Only one of them should be provided."); + } + if (this.config.getBot().isCertificateAuthenticationConfigured()) { + if (!this.config.getBot().isCertificateConfigurationValid()) { + throw new AuthInitializationException( + "Only one of certificate path or content should be configured for bot authentication."); + } + return new BotAuthenticatorCertImpl( + this.config.getRetry(), + this.config.getBot().getUsername(), + this.config.getCommonJwt(), + this.apiClientFactory.getLoginClient(), + this.apiClientFactory.getSessionAuthClient(), + this.apiClientFactory.getKeyAuthClient(), + new AgentVersionService(new SignalsApi(this.apiClientFactory.getAgentClient())) + ); + } + if (this.config.getBot().isRsaAuthenticationConfigured()) { + if (!this.config.getBot().isRsaConfigurationValid()) { + throw new AuthInitializationException( + "Only one of private key path or content should be configured for bot authentication."); + } + return new BotAuthenticatorRsaImpl( + this.config.getRetry(), + this.config.getBot().getUsername(), + this.config.getCommonJwt(), + this.loadPrivateKeyFromAuthenticationConfig(this.config.getBot()), + this.apiClientFactory.getLoginClient(), + this.apiClientFactory.getRelayClient(), + new AgentVersionService(new SignalsApi(this.apiClientFactory.getAgentClient())) + ); + } + throw new AuthInitializationException("Neither RSA private key nor certificate is configured."); + } + + /** + * Creates a new instance of an {@link OboAuthenticator} service. + * + * @return a new {@link OboAuthenticator} instance. + */ + @Nonnull + @Override + public + OboAuthenticator getOboAuthenticator() throws AuthInitializationException { + if (this.config.getApp().isBothCertificateAndRsaConfigured()) { + throw new AuthInitializationException( + "Both of certificate and rsa authentication are configured. Only one of them should be provided."); + } + if (this.config.getApp().isCertificateAuthenticationConfigured()) { + if (!this.config.getApp().isCertificateConfigurationValid()) { + throw new AuthInitializationException( + "Only one of certificate path or content should be configured for app authentication."); + } + return new OboAuthenticatorCertImpl( + this.config.getRetry(), + this.config.getApp().getAppId(), + this.apiClientFactory.getExtAppSessionAuthClient() + ); + } + if (this.config.getApp().isRsaAuthenticationConfigured()) { + if (!this.config.getApp().isRsaConfigurationValid()) { + throw new AuthInitializationException( + "Only one of private key path or content should be configured for app authentication."); + } + return new OboAuthenticatorRsaImpl( + this.config.getRetry(), + this.config.getApp().getAppId(), + this.loadPrivateKeyFromAuthenticationConfig(this.config.getApp()), + this.apiClientFactory.getLoginClient() + ); + } + throw new AuthInitializationException("Neither RSA private key nor certificate is configured."); + } + + /** + * Creates a new instance of an {@link ExtensionAppAuthenticator} service. + * + * @return a new {@link ExtensionAppAuthenticator} instance. + */ + @Nonnull + @Override + public + ExtensionAppAuthenticator getExtensionAppAuthenticator() throws AuthInitializationException { + if (this.config.getApp().isBothCertificateAndRsaConfigured()) { + throw new AuthInitializationException( + "Both of certificate and rsa authentication are configured. Only one of them should be provided."); + } + if (this.config.getApp().isCertificateAuthenticationConfigured()) { + if (!this.config.getApp().isCertificateConfigurationValid()) { + throw new AuthInitializationException( + "Only one of certificate path or content should be configured for app authentication."); + } + return new ExtensionAppAuthenticatorCertImpl( + this.config.getRetry(), + this.config.getApp().getAppId(), + this.apiClientFactory.getExtAppSessionAuthClient(), + extensionAppTokensRepository); + } + if (this.config.getApp().isRsaAuthenticationConfigured()) { + if (!this.config.getApp().isRsaConfigurationValid()) { + throw new AuthInitializationException( + "Only one of private key path or content should be configured for app authentication."); + } + return new ExtensionAppAuthenticatorRsaImpl( + this.config.getRetry(), + this.config.getApp().getAppId(), + this.loadPrivateKeyFromAuthenticationConfig(this.config.getApp()), + this.apiClientFactory.getLoginClient(), + this.apiClientFactory.getPodClient(), + extensionAppTokensRepository + ); + } + throw new AuthInitializationException("Neither RSA private key nor certificate is configured."); + } + + private PrivateKey loadPrivateKeyFromAuthenticationConfig(BdkAuthenticationConfig config) + throws AuthInitializationException { + String privateKeyPath = ""; + try { + String privateKey; + if (config.getPrivateKey() != null && config.getPrivateKey().isConfigured()) { + if (isNotEmpty(config.getPrivateKey().getContent())) { + privateKey = new String(config.getPrivateKey().getContent(), StandardCharsets.UTF_8); + } else { + privateKeyPath = config.getPrivateKey().getPath(); + log.debug("Loading RSA privateKey from path : {}", privateKeyPath); + privateKey = loadPrivateKey(privateKeyPath); + } + } else { + logDeprecation("RSA private key should be configured under \"privateKey\" field"); + if (isNotEmpty(config.getPrivateKeyContent())) { + privateKey = new String(config.getPrivateKeyContent(), StandardCharsets.UTF_8); + } else { + privateKeyPath = config.getPrivateKeyPath(); + log.debug("Loading RSA privateKey from path : {}", privateKeyPath); + privateKey = loadPrivateKey(privateKeyPath); + } + } + return JwtHelper.parseRsaPrivateKey(privateKey); + } catch (GeneralSecurityException e) { + final String message = String.format("Unable to parse RSA Private Key from path %s. Check if the format is " + + "correct.", privateKeyPath); + throw new AuthInitializationException(message, e); + } catch (IOException e) { + final String message = "Unable to read or find RSA Private Key from path " + privateKeyPath; + throw new AuthInitializationException(message, e); + } + } + + private static String loadPrivateKey(String privateKeyPath) throws IOException, AuthInitializationException { + InputStream is; + + // useful for testing when private key is located into resources + if (privateKeyPath.startsWith("classpath:")) { + log.warn("Warning: Keeping RSA private keys into project resources is dangerous. " + + "You should consider another location for production."); + is = AuthenticatorFactoryImpl.class.getResourceAsStream(privateKeyPath.replace("classpath:", "")); + if (is == null) { + throw new AuthInitializationException( + "Unable to find RSA private key as classpath resource from: " + privateKeyPath); + } + try (InputStream resourceStream = is) { + return IOUtils.toString(resourceStream, StandardCharsets.UTF_8); + } + } else { + try (InputStream fileStream = new FileInputStream(privateKeyPath)) { + return IOUtils.toString(fileStream, StandardCharsets.UTF_8); + } + } + } +} diff --git a/symphony-bdk-core/src/test/java/com/symphony/bdk/core/auth/AuthenticatorFactoryTest.java b/symphony-bdk-core/src/test/java/com/symphony/bdk/core/auth/AuthenticatorFactoryTest.java index aadf71907..5c1b6e1b2 100644 --- a/symphony-bdk-core/src/test/java/com/symphony/bdk/core/auth/AuthenticatorFactoryTest.java +++ b/symphony-bdk-core/src/test/java/com/symphony/bdk/core/auth/AuthenticatorFactoryTest.java @@ -7,6 +7,7 @@ import static org.mockito.Mockito.when; import com.symphony.bdk.core.auth.exception.AuthInitializationException; +import com.symphony.bdk.core.auth.impl.AuthenticatorFactoryImpl; import com.symphony.bdk.core.auth.impl.BotAuthenticatorCertImpl; import com.symphony.bdk.core.auth.impl.BotAuthenticatorRsaImpl; import com.symphony.bdk.core.auth.impl.ExtensionAppAuthenticatorCertImpl; @@ -35,7 +36,7 @@ import java.util.function.Supplier; /** - * Test class for the {@link AuthenticatorFactory}. + * Test class for the {@link AuthenticatorFactoryImpl}. */ class AuthenticatorFactoryTest { @@ -62,7 +63,7 @@ void testGetBotAuthenticatorWithValidPrivateKey(@TempDir Path tempDir) throws Au return privateKeyPath.toAbsolutePath().toString(); }); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); final BotAuthenticator botAuth = factory.getBotAuthenticator(); assertNotNull(botAuth); assertEquals(BotAuthenticatorRsaImpl.class, botAuth.getClass()); @@ -72,7 +73,7 @@ void testGetBotAuthenticatorWithValidPrivateKey(@TempDir Path tempDir) throws Au void testGetBotAuthenticatorWithValidPrivateKeyInClasspath() throws AuthInitializationException { final BdkConfig config = createRsaConfig(() -> "classpath:/keys/private-key.pem"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); final BotAuthenticator botAuth = factory.getBotAuthenticator(); assertNotNull(botAuth); assertEquals(BotAuthenticatorRsaImpl.class, botAuth.getClass()); @@ -82,7 +83,7 @@ void testGetBotAuthenticatorWithValidPrivateKeyInClasspath() throws AuthInitiali void testGetBotAuthenticatorWithPrivateKeyNotFoundInClasspath() { final BdkConfig config = createRsaConfig(() -> "classpath:/keys/notfound.pem"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, () -> factory.getBotAuthenticator()); } @@ -92,7 +93,7 @@ void testGetAuthenticatorWithValidPrivateKeyContent() throws AuthInitializationE final BdkConfig config = new BdkConfig(); config.getBot().getPrivateKey().setContent(RSA_PRIVATE_KEY.getBytes()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); final BotAuthenticator botAuth = factory.getBotAuthenticator(); assertEquals(BotAuthenticatorRsaImpl.class, botAuth.getClass()); @@ -104,7 +105,7 @@ void testGetAuthenticatorWithInvalidPrivateKeyContent() { final BdkConfig config = new BdkConfig(); config.getBot().getPrivateKey().setContent("invalid-key".getBytes()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } @@ -118,7 +119,7 @@ void testGetBotAuthenticatorWithInvalidPrivateKey(@TempDir Path tempDir) { return privateKeyPath.toAbsolutePath().toString(); }); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } @@ -131,7 +132,7 @@ void testGetBotAuthenticatorWithInvalidPrivateKeyUsingDeprecatedField(@TempDir P return privateKeyPath.toAbsolutePath().toString(); }); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } @@ -140,7 +141,7 @@ void testGetBotAuthenticatorWithNotFoundPrivateKey(@TempDir Path tempDir) { final BdkConfig config = createRsaConfig(() -> tempDir.resolve(UUID.randomUUID().toString() + "-privateKey.pem").toAbsolutePath().toString()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } @@ -153,7 +154,7 @@ void testGetOboAuthenticatorWithValidPrivateKey(@TempDir Path tempDir) throws Au return privateKeyPath.toAbsolutePath().toString(); }); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); final OboAuthenticator oboAuth = factory.getOboAuthenticator(); assertNotNull(oboAuth); assertEquals(OboAuthenticatorRsaImpl.class, oboAuth.getClass()); @@ -165,7 +166,7 @@ void testGetBotCertificateAuthenticator() throws AuthInitializationException { config.getBot().getCertificate().setPath("/path/to/cert/file.p12"); config.getBot().getCertificate().setPassword("password"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); BotAuthenticator botAuthenticator = factory.getBotAuthenticator(); assertNotNull(botAuthenticator); assertEquals(BotAuthenticatorCertImpl.class, botAuthenticator.getClass()); @@ -177,7 +178,7 @@ void testGetOboCertificateAuthenticator() throws AuthInitializationException { config.getApp().getCertificate().setPath("/path/to/cert/file.p12"); config.getApp().getCertificate().setPassword("password"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); OboAuthenticator oboAuthenticator = factory.getOboAuthenticator(); assertNotNull(oboAuthenticator); assertEquals(OboAuthenticatorCertImpl.class, oboAuthenticator.getClass()); @@ -192,7 +193,7 @@ void testGetExtAppAuthenticatorWithValidPrivateKey(@TempDir Path tempDir) throws return privateKeyPath.toAbsolutePath().toString(); }); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); final ExtensionAppAuthenticator botAuth = factory.getExtensionAppAuthenticator(); assertEquals(ExtensionAppAuthenticatorRsaImpl.class, botAuth.getClass()); @@ -204,7 +205,7 @@ void testGetExtAppAuthenticatorWithValidCertificatePath(@TempDir Path tempDir) t config.getApp().getCertificate().setPath("/path/to/cert/file.p12"); config.getApp().getCertificate().setPassword("password"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); final ExtensionAppAuthenticator extAppAuthenticator = factory.getExtensionAppAuthenticator(); assertEquals(ExtensionAppAuthenticatorCertImpl.class, extAppAuthenticator.getClass()); @@ -219,7 +220,7 @@ void testGetAuthenticatorWithBothCertificatePathAndContentConfigured() { config.getApp().getCertificate().setPath("/path/to/cert/file.p12"); config.getApp().getCertificate().setPassword("password"); config.getApp().getCertificate().setContent("certificate-content".getBytes()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); assertThrows(AuthInitializationException.class, factory::getExtensionAppAuthenticator); @@ -233,7 +234,7 @@ void testGetAuthenticatorWithBothPrivateKeyPathAndContentConfigured() { config.getBot().getPrivateKey().setContent("privatekey-content".getBytes()); config.getApp().getPrivateKey().setPath("/path/to/cert/privatekey.pem"); config.getApp().getPrivateKey().setContent("privatekey-content".getBytes()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); assertThrows(AuthInitializationException.class, factory::getExtensionAppAuthenticator); @@ -249,7 +250,7 @@ void testGetExtAppAuthenticatorWithInvalidPrivateKey(@TempDir Path tempDir) { return privateKeyPath.toAbsolutePath().toString(); }); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getExtensionAppAuthenticator); } @@ -259,7 +260,7 @@ void testGetExtAppAuthenticatorWithNotFoundPrivateKey(@TempDir Path tempDir) { final BdkConfig config = createRsaConfig(() -> tempDir.resolve(UUID.randomUUID().toString() + "-privateKey.pem").toAbsolutePath().toString()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getExtensionAppAuthenticator); } @@ -269,7 +270,7 @@ void testGetAuthenticationRsaAndCertificateNotConfigured() { final BdkConfig config = new BdkConfig(); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); assertThrows(AuthInitializationException.class, factory::getOboAuthenticator); @@ -287,7 +288,7 @@ void testGetBotAuthenticatorBothRsaAndCertificateConfigured(@TempDir Path tempDi config.getBot().getCertificate().setPath("/path/to/cert/file.p12"); config.getBot().getCertificate().setPassword("password"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } @@ -303,7 +304,7 @@ void testGetAppAuthenticatorBothRsaAndCertificateConfigured(@TempDir Path tempDi config.getApp().getCertificate().setPath("/path/to/cert/file.p12"); config.getApp().getCertificate().setPassword("password"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getExtensionAppAuthenticator); assertThrows(AuthInitializationException.class, factory::getOboAuthenticator); @@ -321,7 +322,7 @@ void testGetAuthenticatorRsaInvalid(@TempDir Path tempDir) { config.getBot().setPrivateKey(privateKey); config.getApp().setPrivateKey(privateKey); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); assertThrows(AuthInitializationException.class, factory::getExtensionAppAuthenticator); @@ -335,7 +336,7 @@ void testGetAuthenticatorCertificateInvalid() { config.getBot().getCertificate().setPath("/path/to/cert/cert.pem"); config.getBot().setCertificatePath("/path/to/cert/cert.pem"); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } @@ -347,7 +348,7 @@ void testGetAuthenticatorBothPathAndContentInCertificateField() { config.getBot().getCertificate().setPath("/path/to/cert/cert.pem"); config.getBot().getCertificate().setContent("certificate-content".getBytes()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } @@ -359,7 +360,7 @@ void testGetAuthenticatorBothPathAndContentInPrivateKeyField() { config.getBot().getPrivateKey().setPath("/path/to/cert/privatekey.pem"); config.getBot().getPrivateKey().setContent("privatekey-content".getBytes()); - final AuthenticatorFactory factory = new AuthenticatorFactory(config, DUMMY_API_CLIENT_FACTORY); + final AuthenticatorFactory factory = new AuthenticatorFactoryImpl(config, DUMMY_API_CLIENT_FACTORY); assertThrows(AuthInitializationException.class, factory::getBotAuthenticator); } diff --git a/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/main/java/com/symphony/bdk/spring/config/BdkCoreConfig.java b/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/main/java/com/symphony/bdk/spring/config/BdkCoreConfig.java index 1719c2397..1ff4ef07a 100644 --- a/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/main/java/com/symphony/bdk/spring/config/BdkCoreConfig.java +++ b/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/main/java/com/symphony/bdk/spring/config/BdkCoreConfig.java @@ -4,6 +4,7 @@ import com.symphony.bdk.core.auth.AuthSession; import com.symphony.bdk.core.auth.AuthenticatorFactory; +import com.symphony.bdk.core.auth.impl.AuthenticatorFactoryImpl; import com.symphony.bdk.core.auth.ExtensionAppTokensRepository; import com.symphony.bdk.core.auth.impl.OAuthSession; import com.symphony.bdk.core.auth.impl.OAuthentication; @@ -102,7 +103,7 @@ public ExtensionAppTokensRepository extensionAppTokensRepository() { @ConditionalOnMissingBean public AuthenticatorFactory authenticatorFactory(SymphonyBdkCoreProperties properties, ApiClientFactory apiClientFactory, ExtensionAppTokensRepository extensionAppTokensRepository) { - return new AuthenticatorFactory(properties, apiClientFactory, extensionAppTokensRepository); + return new AuthenticatorFactoryImpl(properties, apiClientFactory, extensionAppTokensRepository); } @Bean diff --git a/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/test/java/com/symphony/bdk/spring/config/BdkCoreConfigTest.java b/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/test/java/com/symphony/bdk/spring/config/BdkCoreConfigTest.java index 8dad84753..aa77969ee 100644 --- a/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/test/java/com/symphony/bdk/spring/config/BdkCoreConfigTest.java +++ b/symphony-bdk-spring/symphony-bdk-core-spring-boot-starter/src/test/java/com/symphony/bdk/spring/config/BdkCoreConfigTest.java @@ -5,13 +5,10 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import com.symphony.bdk.core.auth.AuthSession; -import com.symphony.bdk.core.auth.AuthenticatorFactory; -import com.symphony.bdk.core.auth.BotAuthenticator; -import com.symphony.bdk.core.auth.ExtensionAppAuthenticator; -import com.symphony.bdk.core.auth.OboAuthenticator; +import com.symphony.bdk.core.auth.*; import com.symphony.bdk.core.auth.exception.AuthInitializationException; import com.symphony.bdk.core.auth.exception.AuthUnauthorizedException; +import com.symphony.bdk.core.auth.impl.AuthenticatorFactoryImpl; import com.symphony.bdk.core.client.ApiClientFactory; import com.symphony.bdk.core.config.model.BdkCommonJwtConfig; import com.symphony.bdk.core.config.model.BdkConfig; @@ -32,7 +29,7 @@ class BdkCoreConfigTest { void shouldFailToCreateBotSession() throws Exception { final BdkCoreConfig config = new BdkCoreConfig(); - final AuthenticatorFactory authFactory = mock(AuthenticatorFactory.class); + final AuthenticatorFactory authFactory = mock(AuthenticatorFactoryImpl.class); final BotAuthenticator botAuthenticator = mock(BotAuthenticator.class); when(botAuthenticator.authenticateBot()).thenThrow(AuthUnauthorizedException.class); @@ -79,7 +76,7 @@ void shouldCreateSessionAuthApiClient() { @Test void shouldCreateExtensionAppAuthenticator() throws AuthInitializationException { final BdkOboServiceConfig config = new BdkOboServiceConfig(); - final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactory.class); + final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactoryImpl.class); final ExtensionAppAuthenticator appAuthenticator = mock(ExtensionAppAuthenticator.class); when(authenticatorFactory.getExtensionAppAuthenticator()).thenReturn(appAuthenticator); @@ -89,7 +86,7 @@ void shouldCreateExtensionAppAuthenticator() throws AuthInitializationException @Test void shouldFailCreateExtensionAppAuthenticator() throws AuthInitializationException { final BdkOboServiceConfig config = new BdkOboServiceConfig(); - final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactory.class); + final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactoryImpl.class); when(authenticatorFactory.getExtensionAppAuthenticator()).thenThrow(AuthInitializationException.class); assertThrows(BeanInitializationException.class, () -> config.extensionAppAuthenticator(authenticatorFactory)); @@ -98,7 +95,7 @@ void shouldFailCreateExtensionAppAuthenticator() throws AuthInitializationExcept @Test void shouldCreateOboAuthenticator() throws AuthInitializationException { final BdkOboServiceConfig config = new BdkOboServiceConfig(); - final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactory.class); + final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactoryImpl.class); final OboAuthenticator oboAuthenticator = mock(OboAuthenticator.class); when(authenticatorFactory.getOboAuthenticator()).thenReturn(oboAuthenticator); @@ -108,7 +105,7 @@ void shouldCreateOboAuthenticator() throws AuthInitializationException { @Test void shouldFailCreateOboAuthenticator() throws AuthInitializationException { final BdkOboServiceConfig config = new BdkOboServiceConfig(); - final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactory.class); + final AuthenticatorFactory authenticatorFactory = mock(AuthenticatorFactoryImpl.class); when(authenticatorFactory.getOboAuthenticator()).thenThrow(AuthInitializationException.class); assertThrows(BeanInitializationException.class, () -> config.oboAuthenticator(authenticatorFactory));