diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/ApplicationAuthenticatorService.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/ApplicationAuthenticatorService.java index 021a881b70cd..ccb476acb5ba 100644 --- a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/ApplicationAuthenticatorService.java +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/ApplicationAuthenticatorService.java @@ -28,6 +28,7 @@ import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig; import org.wso2.carbon.identity.application.common.model.LocalAuthenticatorConfig; import org.wso2.carbon.identity.application.common.model.RequestPathAuthenticatorConfig; +import org.wso2.carbon.identity.application.common.model.UserDefinedLocalAuthenticatorConfig; import org.wso2.carbon.identity.application.common.util.UserDefinedLocalAuthenticatorValidator; import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.AuthenticationType; import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType; @@ -198,8 +199,9 @@ public void removeRequestPathAuthenticator(RequestPathAuthenticatorConfig authen * @return Updated LocalAuthenticatorConfig. * @throws AuthenticatorMgtException If an error occurs while creating the authenticator configuration. */ - public LocalAuthenticatorConfig createUserDefinedLocalAuthenticator(LocalAuthenticatorConfig authenticatorConfig, - AuthenticationType type, String tenantDomain) throws AuthenticatorMgtException { + public UserDefinedLocalAuthenticatorConfig createUserDefinedLocalAuthenticator( + UserDefinedLocalAuthenticatorConfig authenticatorConfig, AuthenticationType type, String tenantDomain) + throws AuthenticatorMgtException { LocalAuthenticatorConfig config = getLocalAuthenticatorByName(authenticatorConfig.getName(), tenantDomain); if (config != null) { @@ -221,13 +223,14 @@ public LocalAuthenticatorConfig createUserDefinedLocalAuthenticator(LocalAuthent * @param authenticatorConfig The Local Application Authenticator configuration. * @param tenantDomain Tenant Domain. * - * @return Updated LocalAuthenticatorConfig. + * @return Updated UserDefinedLocalAuthenticatorConfig. * @throws AuthenticatorMgtException If an error occurs while updating the authenticator configuration. */ - public LocalAuthenticatorConfig updateUserDefinedLocalAuthenticator(LocalAuthenticatorConfig authenticatorConfig, - String tenantDomain) throws AuthenticatorMgtException { + public UserDefinedLocalAuthenticatorConfig updateUserDefinedLocalAuthenticator( + UserDefinedLocalAuthenticatorConfig authenticatorConfig, String tenantDomain) + throws AuthenticatorMgtException { - LocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator( + UserDefinedLocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator( authenticatorConfig.getName(), tenantDomain); authenticatorValidator.validateDefinedByType(existingConfig.getDefinedByType()); authenticatorValidator.validateForBlank("Display name", authenticatorConfig.getDisplayName()); @@ -247,7 +250,8 @@ public LocalAuthenticatorConfig updateUserDefinedLocalAuthenticator(LocalAuthent public void deleteUserDefinedLocalAuthenticator(String authenticatorName, String tenantDomain) throws AuthenticatorMgtException { - LocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator(authenticatorName, tenantDomain); + UserDefinedLocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator( + authenticatorName, tenantDomain); authenticatorValidator.validateDefinedByType(existingConfig.getDefinedByType()); CACHE_BACKED_DAO.deleteUserDefinedLocalAuthenticator(authenticatorName, @@ -260,14 +264,14 @@ public void deleteUserDefinedLocalAuthenticator(String authenticatorName, String * @param authenticatorName Name of Local Application Authenticator configuration to be deleted. * @param tenantDomain Tenant domain. * - * @return Retrieved LocalAuthenticatorConfig. + * @return Retrieved UserDefinedLocalAuthenticatorConfig. * @throws AuthenticatorMgtException If an error occurs while retrieving the authenticator configuration. */ - public LocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenticatorName, String tenantDomain) - throws AuthenticatorMgtException { + public UserDefinedLocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenticatorName, + String tenantDomain) throws AuthenticatorMgtException { - LocalAuthenticatorConfig config = CACHE_BACKED_DAO.getUserDefinedLocalAuthenticator(authenticatorName, - IdentityTenantUtil.getTenantId(tenantDomain)); + UserDefinedLocalAuthenticatorConfig config = CACHE_BACKED_DAO.getUserDefinedLocalAuthenticator( + authenticatorName, IdentityTenantUtil.getTenantId(tenantDomain)); if (config != null && !config.getDefinedByType().equals(DefinedByType.USER)) { return null; @@ -277,11 +281,11 @@ public LocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenti } - private LocalAuthenticatorConfig resolveExistingAuthenticator(String authenticatorName, String tenantDomain) - throws AuthenticatorMgtException { + private UserDefinedLocalAuthenticatorConfig resolveExistingAuthenticator(String authenticatorName, + String tenantDomain) throws AuthenticatorMgtException { - LocalAuthenticatorConfig existingAuthenticatorConfig = CACHE_BACKED_DAO.getUserDefinedLocalAuthenticator( - authenticatorName, IdentityTenantUtil.getTenantId(tenantDomain)); + UserDefinedLocalAuthenticatorConfig existingAuthenticatorConfig = CACHE_BACKED_DAO. + getUserDefinedLocalAuthenticator(authenticatorName, IdentityTenantUtil.getTenantId(tenantDomain)); if (existingAuthenticatorConfig == null) { ErrorMessages error = ErrorMessages.ERROR_NOT_FOUND_AUTHENTICATOR; diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/constant/AuthenticatorMgtErrorConstants.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/constant/AuthenticatorMgtErrorConstants.java index 02ecc9e52d00..0e5fa90c883d 100644 --- a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/constant/AuthenticatorMgtErrorConstants.java +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/constant/AuthenticatorMgtErrorConstants.java @@ -48,7 +48,9 @@ public enum ErrorMessages { ERROR_WHILE_RETRIEVING_AUTHENTICATOR_BY_NAME("65003", "Error while retrieving authenticator.", "Error while retrieving authenticator from the system."), ERROR_WHILE_DELETING_AUTHENTICATOR("65004", "Error while deleting authenticator.", - "Error while deleting authenticator from the system."),; + "Error while deleting authenticator from the system."), + ERROR_CODE_ENDPOINT_CONFIG_MGT("65005", "Error while managing endpoint configurations.", + "Error while managing endpoint configurations for the user defined local authenticator %s."),; private final String code; private final String message; diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/exception/AuthenticatorEndpointConfigServerException.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/exception/AuthenticatorEndpointConfigServerException.java new file mode 100644 index 000000000000..b402c171b0a7 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/exception/AuthenticatorEndpointConfigServerException.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.application.common.exception; + +/** + * Exception class for user defined local authenticator endpoint configurations related exceptions. + */ +public class AuthenticatorEndpointConfigServerException extends AuthenticatorMgtServerException{ + + public AuthenticatorEndpointConfigServerException(String message) { + + super(message); + } + + public AuthenticatorEndpointConfigServerException(String errorCode, String message, Throwable throwable) { + + super(errorCode, message, throwable); + } +} \ No newline at end of file diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/VerificationAuthenticatorConfig.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/VerificationAuthenticatorConfig.java deleted file mode 100644 index 97efab22cc93..000000000000 --- a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/VerificationAuthenticatorConfig.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.wso2.carbon.identity.application.common.model; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Verification authenticator configuration. - */ -public class VerificationAuthenticatorConfig extends LocalAuthenticatorConfig { - - private static final String TAG_2FA = "2FA"; - - public VerificationAuthenticatorConfig() { - - setTags(new String[0]); - } - - @Override - public void setTags(String[] tagList) { - - // Check if "2FA" is in the tag list; if not, add it. - List tagsAsList = new ArrayList<>(Arrays.asList()); - if (tagsAsList.contains(TAG_2FA)) { - tags = tagList; - } - - tagsAsList.add(TAG_2FA); - tags = tagsAsList.toArray(new String[0]); - } -} diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/util/UserDefinedLocalAuthenticatorEndpointConfigManager.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/util/UserDefinedLocalAuthenticatorEndpointConfigManager.java new file mode 100644 index 000000000000..6a2963b8f160 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/util/UserDefinedLocalAuthenticatorEndpointConfigManager.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.application.common.util; + +import org.wso2.carbon.identity.action.management.exception.ActionMgtException; +import org.wso2.carbon.identity.action.management.model.Action; +import org.wso2.carbon.identity.action.management.model.EndpointConfig; +import org.wso2.carbon.identity.application.common.exception.AuthenticatorEndpointConfigServerException; +import org.wso2.carbon.identity.application.common.model.Property; +import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig; +import org.wso2.carbon.identity.application.common.model.UserDefinedLocalAuthenticatorConfig; +import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static org.wso2.carbon.identity.application.common.constant.AuthenticatorMgtErrorConstants + .ErrorMessages.ERROR_CODE_ENDPOINT_CONFIG_MGT; + +/** + * This class responsible for managing authenticator endpoint configurations for the user defined Local + * authenticators. + */ +public class UserDefinedLocalAuthenticatorEndpointConfigManager { + + private static final String ACTION_ID_PROPERTY = "actionId"; + + /** + * Create a new action for given endpoint configurations of the user defined authenticator. + * + * @param config The Local application authenticator configuration. + * @param tenantId The id of Tenant domain. + * @throws AuthenticatorEndpointConfigServerException If an error occurs while adding the action. + */ + public void addEndpointConfigurations(UserDefinedLocalAuthenticatorConfig config, int tenantId) + throws AuthenticatorEndpointConfigServerException { + + try { + Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService() + .addAction(Action.ActionTypes.AUTHENTICATION.getPathParam(), + buildActionToCreate(config.getName(), config.getEndpointConfig().getEndpointConfig()), + IdentityTenantUtil.getTenantDomain(tenantId)); + Property endpointProperty = new Property(); + endpointProperty.setName(ACTION_ID_PROPERTY); + endpointProperty.setValue(action.getId()); + config.setProperties(new Property[]{endpointProperty}); + } catch (ActionMgtException e) { + throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(), + "Error occurred while adding associated action for the authenticator:" + config.getName(), e); + } + } + + /** + * Updated associated action for given updated endpoint configurations of the user defined authenticator. + * + * @param newConfig The Local application authenticator configuration to be updated. + * @param oldConfig The current Local application authenticator configuration. + * @param tenantId The id of Tenant domain. + * @throws AuthenticatorEndpointConfigServerException If an error occurs while updating associated action. + */ + public void updateEndpointConfigurations(UserDefinedLocalAuthenticatorConfig newConfig, + UserDefinedLocalAuthenticatorConfig oldConfig, int tenantId) + throws AuthenticatorEndpointConfigServerException { + + String actionId = getActionIdFromProperty(oldConfig.getProperties(), oldConfig.getName()); + try { + IdpMgtServiceComponentHolder.getInstance().getActionManagementService() + .updateAction(Action.ActionTypes.AUTHENTICATION.getPathParam(), + actionId, + buildActionToUpdate(newConfig.getEndpointConfig().getEndpointConfig()), + IdentityTenantUtil.getTenantDomain(tenantId)); + newConfig.setProperties(oldConfig.getProperties()); + } catch (ActionMgtException e) { + throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(), + String.format("Error occurred while updating associated action with id %s for the authenticator %s", + actionId, oldConfig.getName()), e); + } + } + + /** + * Retrieve associated action of the user defined authenticator. + * + * @param config The Local application authenticator configuration. + * @param tenantId The id of Tenant domain. + * @return Local authenticator with endpoint configurations resolved. + * @throws AuthenticatorEndpointConfigServerException If an error occurs retrieving updating associated action. + */ + public UserDefinedLocalAuthenticatorConfig resolveEndpointConfigurations(UserDefinedLocalAuthenticatorConfig config, + int tenantId) throws AuthenticatorEndpointConfigServerException { + + String actionId = getActionIdFromProperty(config.getProperties(), config.getName()); + try { + Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService() + .getActionByActionId(Action.ActionTypes.AUTHENTICATION.getPathParam(), + actionId, + IdentityTenantUtil.getTenantDomain(tenantId)); + + config.setEndpointConfig(buildUserDefinedAuthenticatorEndpointConfig(action.getEndpoint())); + return config; + } catch (ActionMgtException e) { + throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(), + String.format("Error occurred retrieving associated action with id %s for the authenticator %s", + actionId, config.getName()), e); + } + } + + private UserDefinedAuthenticatorEndpointConfig buildUserDefinedAuthenticatorEndpointConfig( + EndpointConfig endpointConfig) { + + UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = + new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); + endpointConfigBuilder.uri(endpointConfig.getUri()); + endpointConfigBuilder.authenticationType(endpointConfig.getAuthentication().getType().getName()); + Map propMap = new HashMap<>(); + endpointConfig.getAuthentication().getProperties() + .forEach(prop -> propMap.put(prop.getName(), prop.getValue())); + endpointConfigBuilder.authenticationProperties(propMap); + return endpointConfigBuilder.build(); + } + + /** + * Delete associated action of the user defined authenticator. + * + * @param config The Local application authenticator configuration. + * @param tenantId The id of Tenant domain. + * + * @throws AuthenticatorEndpointConfigServerException If an error occurs while deleting associated action. + */ + public void deleteEndpointConfigurations(UserDefinedLocalAuthenticatorConfig config, int tenantId) throws + AuthenticatorEndpointConfigServerException { + + if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { + return; + } + + String actionId = getActionIdFromProperty(config.getProperties(), config.getName()); + try { + IdpMgtServiceComponentHolder.getInstance().getActionManagementService() + .deleteAction(Action.ActionTypes.AUTHENTICATION.getPathParam(), + actionId, + IdentityTenantUtil.getTenantDomain(tenantId)); + } catch (ActionMgtException e) { + throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(), + String.format("Error occurred while deleting associated action with id %s for the authenticator %s", + actionId, config.getName()), e); + } + } + + private Action buildActionToCreate(String authenticatorName, EndpointConfig endpointConfig) { + + Action.ActionRequestBuilder actionRequestBuilder = new Action.ActionRequestBuilder(); + actionRequestBuilder.name(authenticatorName); + actionRequestBuilder.description(String.format("This is the action associated to the user defined Local" + + "authenticator %s.", authenticatorName)); + actionRequestBuilder.endpoint(endpointConfig); + + return actionRequestBuilder.build(); + } + + private Action buildActionToUpdate(EndpointConfig endpointConfig) { + + Action.ActionRequestBuilder actionRequestBuilder = new Action.ActionRequestBuilder(); + actionRequestBuilder.endpoint(endpointConfig); + + return actionRequestBuilder.build(); + } + + private String getActionIdFromProperty(Property[] properties, String authenticatorName) + throws AuthenticatorEndpointConfigServerException { + + return Arrays.stream(properties) + .filter(property -> ACTION_ID_PROPERTY.equals(property.getName())) + .map(Property::getValue) + .findFirst() + .orElseThrow(() -> new AuthenticatorEndpointConfigServerException( + "No action Id was found in the properties of the authenticator configurations for" + + " the authenticator: " + authenticatorName)); + } +} diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/util/UserDefinedLocalAuthenticatorValidator.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/util/UserDefinedLocalAuthenticatorValidator.java index 1ff69af14d20..f01b294760e9 100644 --- a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/util/UserDefinedLocalAuthenticatorValidator.java +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/util/UserDefinedLocalAuthenticatorValidator.java @@ -55,7 +55,6 @@ public void validateForBlank(String fieldName, String fieldValue) throws Authent * Validate the user defined local authenticator name. * * @param name The authenticator name. - * * @throws AuthenticatorMgtClientException if the authenticator name is not valid. */ public void validateAuthenticatorName(String name) throws AuthenticatorMgtClientException { @@ -71,8 +70,7 @@ public void validateAuthenticatorName(String name) throws AuthenticatorMgtClient /** * Validate the authenticator is a user defined by authenticator. * - * @param authenticatorConfig The authenticator config. - * + * @param definedByType The defined by type of the authenticator config. * @throws AuthenticatorMgtClientException if the authenticator is not a user defined authenticator. */ public void validateDefinedByType(DefinedByType definedByType)