From 2a7b73adea59f34668dbf92b08e17330bd880807 Mon Sep 17 00:00:00 2001 From: Hasanthi Dissanayake Date: Mon, 16 Oct 2023 16:15:48 +0530 Subject: [PATCH] Modify the TOTP Authenticator for the API Based Authentication --- .../authenticator/totp/TOTPAuthenticator.java | 47 +++++++++++++++ .../totp/TOTPAuthenticatorConstants.java | 2 + .../totp/TOTPAuthenticatorTest.java | 58 +++++++++++++++---- pom.xml | 2 +- 4 files changed, 98 insertions(+), 11 deletions(-) diff --git a/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticator.java b/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticator.java index ef6edb785..60f994d9d 100644 --- a/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticator.java +++ b/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticator.java @@ -35,7 +35,10 @@ import org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException; import org.wso2.carbon.identity.application.authentication.framework.exception.LogoutFailedException; import org.wso2.carbon.identity.application.authentication.framework.exception.UserIdNotFoundException; +import org.wso2.carbon.identity.application.authentication.framework.model.AdditionalData; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatorData; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatorParamMetadata; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkUtils; import org.wso2.carbon.identity.application.authenticator.totp.exception.TOTPException; @@ -65,7 +68,9 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -713,6 +718,48 @@ public String getName() { return TOTPAuthenticatorConstants.AUTHENTICATOR_NAME; } + /** + * This method is responsible for obtaining authenticator-specific data needed to + * initialize the authentication process within the provided authentication context. + * + * @param context The authentication context containing information about the current authentication attempt. + * @return An {@code Optional} containing an {@code AuthenticatorData} object representing the initiation data. + * If the initiation data is available, it is encapsulated within the {@code Optional}; otherwise, + * an empty {@code Optional} is returned. + */ + @Override + public Optional getAuthInitiationData(AuthenticationContext context) { + + AuthenticatorData authenticatorData = new AuthenticatorData(); + authenticatorData.setName(getName()); + authenticatorData.setDisplayName(getFriendlyName()); + String idpName = context.getExternalIdP().getIdPName(); + authenticatorData.setIdp(idpName); + + AdditionalData additionalData = new AdditionalData(); + additionalData.setPromptType(TOTPAuthenticatorConstants.REDIRECTION_PROMPT); + authenticatorData.setAdditionalData(additionalData); + + List authenticatorParamMetadataList = new ArrayList<>(); + AuthenticatorParamMetadata tokenMetadata = new AuthenticatorParamMetadata( + TOTPAuthenticatorConstants.TOKEN, FrameworkConstants.AuthenticatorParamType.STRING, 0); + authenticatorParamMetadataList.add(tokenMetadata); + authenticatorData.setAuthParams(authenticatorParamMetadataList); + + return Optional.of(authenticatorData); + } + + /** + * This method is responsible for validating whether the authenticator is supported for API Based Authentication. + * + * @return true if the authenticator is supported for API Based Authentication. + */ + @Override + public boolean isAPIBasedAuthenticationSupported() { + + return true; + } + /** * Generate TOTP token. * diff --git a/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorConstants.java b/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorConstants.java index 6758dadc9..f199618c5 100644 --- a/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorConstants.java +++ b/component/authenticator/src/main/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorConstants.java @@ -25,6 +25,8 @@ */ public abstract class TOTPAuthenticatorConstants { + public static final String REDIRECTION_PROMPT = "REDIRECTION_PROMPT"; + /* * Private Constructor will prevent the instantiation of this class directly. */ diff --git a/component/authenticator/src/test/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorTest.java b/component/authenticator/src/test/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorTest.java index f5a0674ca..5a49f0056 100644 --- a/component/authenticator/src/test/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorTest.java +++ b/component/authenticator/src/test/java/org/wso2/carbon/identity/application/authenticator/totp/TOTPAuthenticatorTest.java @@ -40,13 +40,17 @@ import org.wso2.carbon.identity.application.authentication.framework.config.ConfigurationFacade; import org.wso2.carbon.identity.application.authentication.framework.config.builder.FileBasedConfigurationBuilder; import org.wso2.carbon.identity.application.authentication.framework.config.model.AuthenticatorConfig; +import org.wso2.carbon.identity.application.authentication.framework.config.model.ExternalIdPConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.SequenceConfig; import org.wso2.carbon.identity.application.authentication.framework.config.model.StepConfig; import org.wso2.carbon.identity.application.authentication.framework.context.AuthenticationContext; import org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException; import org.wso2.carbon.identity.application.authentication.framework.exception.LogoutFailedException; import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatorData; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatorParamMetadata; import org.wso2.carbon.identity.application.authentication.framework.store.UserSessionStore; +import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import org.wso2.carbon.identity.application.authenticator.totp.exception.TOTPException; import org.wso2.carbon.identity.application.authenticator.totp.internal.TOTPDataHolder; import org.wso2.carbon.identity.application.authenticator.totp.util.TOTPUtil; @@ -68,9 +72,12 @@ import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import javax.servlet.http.HttpServletRequest; @@ -135,9 +142,6 @@ public class TOTPAuthenticatorTest { @Mock private UserStoreManager userStoreManager; - @Spy - private FederatedAuthenticatorUtil federatedAuthenticatorUtil; - @Mock private SequenceConfig sequenceConfig; @@ -163,13 +167,7 @@ public class TOTPAuthenticatorTest { private FileBasedConfigurationBuilder fileBasedConfigurationBuilder; @Mock - private ServiceURLBuilder serviceURLBuilder; - - @Mock - private ServiceURL serviceURL; - - @Mock - UserSessionStore userSessionStore; + ExternalIdPConfig externalIdPConfig; @BeforeMethod public void setUp() { @@ -745,4 +743,44 @@ public IObjectFactory getObjectFactory() { return new PowerMockObjectFactory(); } + + @Test + public void testIsAPIBasedAuthenticationSupported() { + + boolean isAPIBasedAuthenticationSupported = totpAuthenticator.isAPIBasedAuthenticationSupported(); + Assert.assertTrue(isAPIBasedAuthenticationSupported); + } + + @Test + public void testGetAuthInitiationData() { + + when(mockedContext.getExternalIdP()).thenReturn(externalIdPConfig); + when(mockedContext.getExternalIdP().getIdPName()).thenReturn(TOTPAuthenticatorConstants.LOCAL_AUTHENTICATOR); + + Optional authenticatorData = totpAuthenticator.getAuthInitiationData(mockedContext); + Assert.assertTrue(authenticatorData.isPresent()); + AuthenticatorData authenticatorDataObj = authenticatorData.get(); + + List authenticatorParamMetadataList = new ArrayList<>(); + AuthenticatorParamMetadata tokenMetadata = new AuthenticatorParamMetadata( + TOTPAuthenticatorConstants.TOKEN, FrameworkConstants.AuthenticatorParamType.STRING, 0); + authenticatorParamMetadataList.add(tokenMetadata); + + Assert.assertEquals(authenticatorDataObj.getName(), TOTPAuthenticatorConstants.AUTHENTICATOR_NAME); + Assert.assertEquals(authenticatorDataObj.getAuthParams().size(), authenticatorParamMetadataList.size(), + "Size of lists should be equal."); + Assert.assertEquals(authenticatorDataObj.getAdditionalDataObj().getPromptType(), TOTPAuthenticatorConstants. + REDIRECTION_PROMPT, "Prompt Type should match."); + for (int i = 0; i < authenticatorParamMetadataList.size(); i++) { + AuthenticatorParamMetadata expectedParam = authenticatorParamMetadataList.get(i); + AuthenticatorParamMetadata actualParam = authenticatorDataObj.getAuthParams().get(i); + + Assert.assertEquals(actualParam.getName(), expectedParam.getName(), "Parameter name should match."); + Assert.assertEquals(actualParam.getType(), expectedParam.getType(), "Parameter type should match."); + Assert.assertEquals(actualParam.getParamOrder(), expectedParam.getParamOrder(), + "Parameter order should match."); + Assert.assertEquals(actualParam.isConfidential(), expectedParam.isConfidential(), + "Parameter confidential status should match."); + } + } } diff --git a/pom.xml b/pom.xml index 6b69f38f5..22e95aaea 100644 --- a/pom.xml +++ b/pom.xml @@ -158,7 +158,7 @@ 4.8.7 [4.4.0, 5.0.0) - 5.25.260 + 5.25.394 1.0.0