diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/pom.xml b/components/action-mgt/org.wso2.carbon.identity.action.management/pom.xml index d322798ba601..deac82f059f1 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/pom.xml +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/pom.xml @@ -41,6 +41,10 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.secret.mgt.core + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.certificate.management + org.json.wso2 json @@ -54,6 +58,7 @@ org.mockito mockito-core + test org.wso2.carbon.identity.framework @@ -178,14 +183,14 @@ - 0.70 + 0.77 COMPLEXITY COVEREDRATIO - 0.60 + 0.68 diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementService.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementService.java index fe1851cb1b13..fe3899c521a3 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementService.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementService.java @@ -20,7 +20,6 @@ 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.Authentication; import java.util.List; import java.util.Map; @@ -115,17 +114,4 @@ Action updateAction(String actionType, String actionId, Action action, String te * @throws ActionMgtException If an error occurs while retrieving the Action of a given Action ID. */ Action getActionByActionId(String actionType, String actionId, String tenantDomain) throws ActionMgtException; - - /** - * Update the authentication of the action endpoint. - * - * @param actionType Action Type. - * @param actionId Action ID. - * @param authentication Authentication Information to be updated. - * @param tenantDomain Tenant domain. - * @return Action response after update. - * @throws ActionMgtException If an error occurs while updating action endpoint authentication information. - */ - Action updateActionEndpointAuthentication(String actionType, String actionId, Authentication authentication, - String tenantDomain) throws ActionMgtException; } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImpl.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImpl.java index 33fd7ca6a465..632cfdd92ed9 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImpl.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImpl.java @@ -27,7 +27,6 @@ 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.Authentication; -import org.wso2.carbon.identity.action.management.model.EndpointConfig; import org.wso2.carbon.identity.action.management.util.ActionManagementAuditLogger; import org.wso2.carbon.identity.action.management.util.ActionManagementUtil; import org.wso2.carbon.identity.action.management.util.ActionValidator; @@ -237,32 +236,6 @@ public Action getActionByActionId(String actionType, String actionId, String ten IdentityTenantUtil.getTenantId(tenantDomain)); } - /** - * Update endpoint authentication of a given action. - * - * @param actionType Action type. - * @param actionId Action ID. - * @param authentication Authentication Information to be updated. - * @param tenantDomain Tenant domain. - * @return Updated action. - * @throws ActionMgtException if an error occurred while updating endpoint authentication information. - */ - @Override - public Action updateActionEndpointAuthentication(String actionType, String actionId, Authentication authentication, - String tenantDomain) throws ActionMgtException { - - String resolvedActionType = getActionTypeFromPath(actionType); - Action existingAction = checkIfActionExists(resolvedActionType, actionId, tenantDomain); - doEndpointAuthenticationValidation(authentication); - if (existingAction.getEndpoint().getAuthentication().getType().equals(authentication.getType())) { - // Only need to update the properties since the authentication type is same. - return updateEndpointAuthenticationProperties(resolvedActionType, actionId, authentication, tenantDomain); - } else { - // Need to update the authentication type and properties. - return updateEndpoint(resolvedActionType, actionId, existingAction, authentication, tenantDomain); - } - } - /** * Get Action Type from path. * @@ -317,61 +290,11 @@ private Action checkIfActionExists(String actionType, String actionId, String te return action; } - /** - * Update the authentication type and properties of the action endpoint. - * - * @param actionType Action Type. - * @param actionId Action Id. - * @param existingAction Existing Action Information. - * @param authentication Authentication Information to be updated. - * @param tenantDomain Tenant Domain. - * @return Action response after update. - * @throws ActionMgtException If an error occurs while updating action endpoint authentication. - */ - private Action updateEndpoint(String actionType, String actionId, Action existingAction, - Authentication authentication, String tenantDomain) - throws ActionMgtException { - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Updating endpoint authentication of Action Type: %s " + - "and Action ID: %s to Authentication Type: %s", actionType, actionId, - authentication.getType().name())); - } - EndpointConfig endpoint = new EndpointConfig.EndpointConfigBuilder() - .uri(existingAction.getEndpoint().getUri()) - .authentication(authentication).build(); - return CACHE_BACKED_DAO.updateActionEndpoint(actionType, actionId, endpoint, - existingAction.getEndpoint().getAuthentication(), IdentityTenantUtil.getTenantId(tenantDomain)); - } - - /** - * Update the authentication properties of the action endpoint. - * - * @param actionType Action Type. - * @param actionId Action Id. - * @param authentication Authentication Information to be updated. - * @param tenantDomain Tenant domain. - * @return Action response after update. - * @throws ActionMgtException If an error occurs while updating action endpoint authentication properties. - */ - private Action updateEndpointAuthenticationProperties(String actionType, String actionId, - Authentication authentication, String tenantDomain) - throws ActionMgtException { - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Updating endpoint authentication properties of Action Type: %s " + - "Action ID: %s and Authentication Type: %s", actionType, actionId, - authentication.getType().name())); - } - return CACHE_BACKED_DAO.updateActionEndpointAuthProperties(actionType, actionId, authentication, - IdentityTenantUtil.getTenantId(tenantDomain)); - } - /** * Perform pre validations on action model when creating an action. * * @param action Action create model. - * @throws ActionMgtException if action model is invalid. + * @throws ActionMgtClientException if action model is invalid. */ private void doPreAddActionValidations(Action action) throws ActionMgtClientException { diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtConstants.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtConstants.java index 5eff6fda6669..118368b8cc58 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtConstants.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtConstants.java @@ -23,8 +23,10 @@ */ public class ActionMgtConstants { - public static final String URI_ATTRIBUTE = "uri"; - public static final String AUTHN_TYPE_ATTRIBUTE = "authnType"; + public static final String URI_PROPERTY = "uri"; + public static final String AUTHN_TYPE_PROPERTY = "authnType"; + public static final String PASSWORD_SHARING_FORMAT_PROPERTY = "passwordSharingFormat"; + public static final String CERTIFICATE_ID_PROPERTY = "certificateId"; public static final String IDN_SECRET_TYPE_ACTION_SECRETS = "ACTION_API_ENDPOINT_AUTH_SECRETS"; public static final String ACTION_NAME_FIELD = "Action name"; @@ -53,19 +55,30 @@ public enum ErrorMessages { "%s is empty."), ERROR_INVALID_ACTION_REQUEST_FIELD("60005", "Invalid request.", "%s is invalid."), + ERROR_INVALID_ACTION_CERTIFICATE("60006", "Invalid request.", "Provided certificate is invalid."), + + // Client errors thrown at REST API layer. + ERROR_INVALID_ACTION_ENDPOINT_AUTHENTICATION_PROPERTIES("60007", "Unable to perform the operation.", + "Required authentication properties are not provided or invalid."), + ERROR_INVALID_ACTION_ENDPOINT_AUTH_TYPE("60008", "Invalid Authentication Type for Action Endpoint.", + "Invalid authentication type used for path parameter."), + ERROR_EMPTY_ACTION_ENDPOINT_AUTHENTICATION_PROPERTIES("60009", "Unable to perform the operation.", + "Authentication property values cannot be empty."), + ERROR_NO_ACTION_FOUND_ON_GIVEN_ACTION_TYPE_AND_ID("60010", "Action is not found.", + "No action is found for given action id and action type"), // Server errors. ERROR_WHILE_ADDING_ACTION("65001", "Error while adding Action.", "Error while persisting Action in the system."), - ERROR_WHILE_ADDING_ENDPOINT_PROPERTIES("65002", "Error while adding Endpoint properties", - "Error while persisting Action Endpoint properties in the system."), - ERROR_WHILE_RETRIEVING_ACTION_ENDPOINT_PROPERTIES("65003", - "Error while retrieving Action Endpoint properties", - "Error while retrieving Action Endpoint properties from the system."), + ERROR_WHILE_ADDING_ACTION_PROPERTIES("65002", "Error while adding Action properties", + "Error while persisting Action properties in the system."), + ERROR_WHILE_RETRIEVING_ACTION_PROPERTIES("65003", + "Error while retrieving Action properties", + "Error while retrieving Action properties from the system."), ERROR_WHILE_RETRIEVING_ACTIONS_BY_ACTION_TYPE("65004", "Error while retrieving Actions by Action Type", "Error while retrieving Actions by Action Type from the system."), - ERROR_WHILE_UPDATING_ENDPOINT_PROPERTIES("65005", + ERROR_WHILE_UPDATING_ACTION_PROPERTIES("65005", "Error while updating Action Endpoint properties", "Error while updating Action Endpoint properties in the system."), ERROR_WHILE_UPDATING_ACTION("65006", "Error while updating Action.", @@ -84,11 +97,22 @@ public enum ErrorMessages { ERROR_WHILE_DECRYPTING_ACTION_ENDPOINT_AUTH_PROPERTIES("65012", "Error while decrypting Action Endpoint Authentication properties", "Error while decrypting Action Endpoint Authentication properties in the system."), - ERROR_NO_AUTHENTICATION_TYPE("65013", - "Error while retrieving Action Endpoint Authentication configurations", - "Authentication type is not defined for the Action Endpoint."), - ERROR_WHILE_UPDATING_ACTION_BASIC_INFO("65014", "Error while updating basic Action information", - "Error while updating basic Action information in the system."); + ERROR_WHILE_UPDATING_ACTION_BASIC_INFO("65013", "Error while updating basic Action information", + "Error while updating basic Action information in the system."), + ERROR_WHILE_BUILDING_ACTION_RESPONSE("65014", "Error while building Action response.", + "Error while building Action response object."), + ERROR_WHILE_ADDING_ACTION_CERTIFICATE("65015", "Error while adding action certificate.", + "Error while persisting certificate in the system."), + ERROR_WHILE_RETRIEVING_ACTION_CERTIFICATE("65016", "Error while retrieving action certificate.", + "Error while retrieving certificate from the system."), + ERROR_WHILE_UPDATING_ACTION_CERTIFICATE("65017", "Error while updating action certificate.", + "Error while updating certificate in the system."), + ERROR_WHILE_DELETING_ACTION_CERTIFICATE("65018", "Error while deleting action certificate.", + "Error while deleting certificate from the system."), + + // Server errors thrown at REST API layer. + ERROR_NOT_IMPLEMENTED_ACTION_TYPE("650015", "Unable to perform the operation.", + "The requested action type is not currently supported by the server."); private final String code; private final String message; diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtSQLConstants.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtSQLConstants.java index b41fb5282228..21a19098c941 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtSQLConstants.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/constant/ActionMgtSQLConstants.java @@ -55,18 +55,18 @@ public static class Query { public static final String ADD_ACTION_TO_ACTION_TYPE = "INSERT INTO IDN_ACTION (UUID, TYPE, NAME, " + "DESCRIPTION, STATUS, TENANT_ID) VALUES (:UUID;, :TYPE;, :NAME;, :DESCRIPTION;, :STATUS;, :TENANT_ID;)"; - public static final String ADD_ACTION_ENDPOINT_PROPERTIES = "INSERT INTO IDN_ACTION_ENDPOINT (ACTION_UUID, " + + public static final String ADD_ACTION_ENDPOINT_PROPERTIES = "INSERT INTO IDN_ACTION_PROPERTIES (ACTION_UUID, " + "PROPERTY_NAME, PROPERTY_VALUE, TENANT_ID) VALUES (:ACTION_UUID;, :PROPERTY_NAME;, :PROPERTY_VALUE;, " + ":TENANT_ID;)"; public static final String GET_ACTION_BASIC_INFO_BY_ID = "SELECT TYPE, NAME, DESCRIPTION, STATUS FROM " + "IDN_ACTION WHERE TYPE = :TYPE; AND UUID = :UUID; AND TENANT_ID = :TENANT_ID;"; public static final String GET_ACTION_ENDPOINT_INFO_BY_ID = "SELECT PROPERTY_NAME, PROPERTY_VALUE FROM " + - "IDN_ACTION_ENDPOINT WHERE ACTION_UUID = :ACTION_UUID; AND TENANT_ID = :TENANT_ID;"; + "IDN_ACTION_PROPERTIES WHERE ACTION_UUID = :ACTION_UUID; AND TENANT_ID = :TENANT_ID;"; public static final String GET_ACTIONS_BASIC_INFO_BY_ACTION_TYPE = "SELECT UUID, TYPE, NAME, DESCRIPTION," + " STATUS FROM IDN_ACTION WHERE TYPE = :TYPE; AND TENANT_ID = :TENANT_ID;"; public static final String UPDATE_ACTION_BASIC_INFO = "UPDATE IDN_ACTION SET NAME = :NAME;, DESCRIPTION = " + ":DESCRIPTION; WHERE UUID = :UUID; AND TYPE = :TYPE; AND TENANT_ID = :TENANT_ID;"; - public static final String DELETE_ACTION_ENDPOINT_PROPERTIES = "DELETE FROM IDN_ACTION_ENDPOINT WHERE " + + public static final String DELETE_ACTION_ENDPOINT_PROPERTIES = "DELETE FROM IDN_ACTION_PROPERTIES WHERE " + "ACTION_UUID = :ACTION_UUID; AND TENANT_ID = :TENANT_ID;"; public static final String DELETE_ACTION = "DELETE FROM IDN_ACTION WHERE UUID = :UUID; AND TYPE = :TYPE;" + " AND TENANT_ID = :TENANT_ID;"; @@ -74,9 +74,6 @@ public static class Query { ":UUID; AND TYPE = :TYPE; AND TENANT_ID = :TENANT_ID;"; public static final String GET_ACTIONS_COUNT_PER_ACTION_TYPE = "SELECT TYPE, COUNT(UUID) AS COUNT" + " FROM IDN_ACTION WHERE TENANT_ID = :TENANT_ID; GROUP BY TYPE"; - public static final String UPDATE_ACTION_ENDPOINT_PROPERTIES = "UPDATE IDN_ACTION_ENDPOINT SET " + - "PROPERTY_VALUE = :PROPERTY_VALUE; WHERE ACTION_UUID = :ACTION_UUID; AND " + - "TENANT_ID = :TENANT_ID; AND PROPERTY_NAME = :PROPERTY_NAME;"; private Query() { diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAO.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAO.java index 9def55c4247b..ecb131d1adf6 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAO.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAO.java @@ -20,8 +20,6 @@ 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.Authentication; -import org.wso2.carbon.identity.action.management.model.EndpointConfig; import java.util.List; import java.util.Map; @@ -118,30 +116,4 @@ Action updateAction(String actionType, String actionId, Action updatingAction, A * @throws ActionMgtException If an error occurs while retrieving the Action of a given Action ID. */ Action getActionByActionId(String actionType, String actionId, Integer tenantId) throws ActionMgtException; - - /** - * Update the endpoint authentication properties of an {@link Action} by given Action ID. - * - * @param actionId Action ID. - * @param authentication Authentication information to be updated. - * @param tenantId Tenant Id. - * @return Updated Action. - * @throws ActionMgtException If an error occurs while updating the Action endpoint authentication properties. - */ - Action updateActionEndpointAuthProperties(String actionType, String actionId, Authentication authentication, - int tenantId) throws ActionMgtException; - - /** - * Update the endpoint authentication properties of an {@link Action} by given Action ID. - * - * @param actionType Action Type. - * @param actionId Action ID. - * @param endpoint Endpoint information to be updated. - * @param currentAuthentication Current Action endpoint authentication information. - * @param tenantId Tenant Id. - * @return Updated Action. - * @throws ActionMgtException If an error occurs while updating the Action endpoint. - */ - Action updateActionEndpoint(String actionType, String actionId, EndpointConfig endpoint, - Authentication currentAuthentication, int tenantId) throws ActionMgtException; } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/ActionManagementDAOImpl.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/ActionManagementDAOImpl.java index 95bc2f54917a..34ded3675b1a 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/ActionManagementDAOImpl.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/ActionManagementDAOImpl.java @@ -28,21 +28,33 @@ import org.wso2.carbon.identity.action.management.constant.ActionMgtConstants; import org.wso2.carbon.identity.action.management.constant.ActionMgtSQLConstants; import org.wso2.carbon.identity.action.management.dao.ActionManagementDAO; +import org.wso2.carbon.identity.action.management.exception.ActionMgtClientException; import org.wso2.carbon.identity.action.management.exception.ActionMgtException; import org.wso2.carbon.identity.action.management.exception.ActionMgtRuntimeException; -import org.wso2.carbon.identity.action.management.exception.ActionMgtServerException; +import org.wso2.carbon.identity.action.management.internal.ActionMgtServiceComponentHolder; import org.wso2.carbon.identity.action.management.model.Action; import org.wso2.carbon.identity.action.management.model.AuthProperty; import org.wso2.carbon.identity.action.management.model.Authentication; import org.wso2.carbon.identity.action.management.model.EndpointConfig; +import org.wso2.carbon.identity.action.management.model.PreUpdatePasswordAction; import org.wso2.carbon.identity.action.management.util.ActionManagementUtil; +import org.wso2.carbon.identity.certificate.management.exception.CertificateMgtClientException; +import org.wso2.carbon.identity.certificate.management.exception.CertificateMgtException; +import org.wso2.carbon.identity.certificate.management.model.Certificate; import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.identity.secret.mgt.core.exception.SecretManagementException; +import java.sql.SQLException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; + +import static org.wso2.carbon.identity.action.management.constant.ActionMgtConstants.AUTHN_TYPE_PROPERTY; +import static org.wso2.carbon.identity.action.management.constant.ActionMgtConstants.CERTIFICATE_ID_PROPERTY; +import static org.wso2.carbon.identity.action.management.constant.ActionMgtConstants.PASSWORD_SHARING_FORMAT_PROPERTY; +import static org.wso2.carbon.identity.action.management.constant.ActionMgtConstants.URI_PROPERTY; /** * This class implements the {@link ActionManagementDAO} interface. @@ -75,19 +87,17 @@ public Action addAction(String actionType, String actionId, Action action, Integ statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); }, action, false); - // Encrypt secrets. - List encryptedAuthProperties = actionSecretProcessor - .encryptAssociatedSecrets(action.getEndpoint().getAuthentication(), actionId); - - // Add Endpoint configuration properties. - addEndpointProperties(actionId, getEndpointProperties(action.getEndpoint().getUri(), - action.getEndpoint().getAuthentication().getType().name(), encryptedAuthProperties), tenantId); + // Add action properties. + addActionProperties(actionType, actionId, action, tenantId); return null; }); return getActionByActionId(actionType, actionId, tenantId); } catch (TransactionException e) { + if (e.getCause() instanceof ActionMgtClientException) { + throw (ActionMgtClientException) e.getCause(); + } if (LOG.isDebugEnabled()) { LOG.debug(String.format("Error while creating the Action of Action Type: %s in Tenant Domain: %s." + " Rolling back created action information and deleting added secrets.", actionType, @@ -102,27 +112,35 @@ public Action addAction(String actionType, String actionId, Action action, Integ public List getActionsByActionType(String actionType, Integer tenantId) throws ActionMgtException { NamedJdbcTemplate jdbcTemplate = new NamedJdbcTemplate(IdentityDatabaseUtil.getDataSource()); + List actions = new ArrayList<>(); try { - return jdbcTemplate.executeQuery(ActionMgtSQLConstants.Query.GET_ACTIONS_BASIC_INFO_BY_ACTION_TYPE, - (resultSet, rowNumber) -> new Action.ActionResponseBuilder() - .id(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_UUID)) - .type(Action.ActionTypes - .valueOf(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_TYPE))) - .name(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_NAME)) - .description(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_DESCRIPTION)) - .status(Action.Status - .valueOf(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_STATUS))) - .endpoint(getActionEndpointConfigById( - resultSet.getString(ActionMgtSQLConstants.Column.ACTION_UUID), tenantId)) - .build(), + jdbcTemplate.executeQuery(ActionMgtSQLConstants.Query.GET_ACTIONS_BASIC_INFO_BY_ACTION_TYPE, + (resultSet, rowNumber) -> { + String actionId = resultSet.getString(ActionMgtSQLConstants.Column.ACTION_UUID); + Action actionBasicInfo = new Action.ActionResponseBuilder() + .id(actionId) + .type(Action.ActionTypes + .valueOf(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_TYPE))) + .name(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_NAME)) + .description(resultSet.getString(ActionMgtSQLConstants.Column.ACTION_DESCRIPTION)) + .status(Action.Status.valueOf( + resultSet.getString(ActionMgtSQLConstants.Column.ACTION_STATUS))) + .build(); + + Map actionProperties = getActionPropertiesById(actionId, tenantId); + actions.add(buildActionResponse(actionType, actionBasicInfo, actionProperties, tenantId)); + return null; + }, statement -> { statement.setString(ActionMgtSQLConstants.Column.ACTION_TYPE, actionType); statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); }); + + return actions; } catch (ActionMgtRuntimeException | DataAccessException e) { /** * Handling {@link ActionMgtRuntimeException}, which is intentionally thrown to represent underlying - * exceptions from the {@link #getActionEndpointConfigById(String, Integer)} method. + * exceptions from the {@link #buildActionResponse(String, Action, Map, Integer)} method. */ throw ActionManagementUtil.handleServerException( ActionMgtConstants.ErrorMessages.ERROR_WHILE_RETRIEVING_ACTIONS_BY_ACTION_TYPE, e); @@ -138,14 +156,17 @@ public Action updateAction(String actionType, String actionId, Action updatingAc jdbcTemplate.withTransaction(template -> { // Update Basic Info. updateBasicInfo(actionType, actionId, updatingAction, existingAction, tenantId); - // Update Endpoint URI and Authentication. - updateEndpointUriAndAuthentication(actionId, updatingAction, existingAction, tenantId); + // Update Action Properties. + updateActionProperties(actionType, actionId, updatingAction, existingAction, tenantId); return null; }); return getActionByActionId(actionType, actionId, tenantId); } catch (TransactionException e) { + if (e.getCause() instanceof ActionMgtClientException) { + throw (ActionMgtClientException) e.getCause(); + } if (LOG.isDebugEnabled()) { LOG.debug(String.format("Error while updating the Action of Action Type: %s and Action ID: %s in" + " Tenant Domain: %s. Rolling back updated action information.", actionType, actionId, @@ -171,6 +192,8 @@ public void deleteAction(String actionType, String actionId, Action action, Inte }); // Delete action endpoint authentication related secrets. actionSecretProcessor.deleteAssociatedSecrets(action.getEndpoint().getAuthentication(), actionId); + // Delete action type specific properties. + deleteActionTypeSpecificProperties(actionType, action, tenantId); return null; }); @@ -223,158 +246,134 @@ public Action getActionByActionId(String actionType, String actionId, Integer te try { Action action = getActionBasicInfoById(actionType, actionId, tenantId); if (action != null) { - action = new Action.ActionResponseBuilder() - .id(actionId) - .type(Action.ActionTypes.valueOf(actionType)) - .name(action.getName()) - .description(action.getDescription()) - .status(action.getStatus()) - .endpoint(getActionEndpointConfigById(actionId, tenantId)) - .build(); + Map actionProperties = getActionPropertiesById(actionId, tenantId); + action = buildActionResponse(actionType, action, actionProperties, tenantId); } return action; - } catch (ActionMgtException | ActionMgtRuntimeException e) { + } catch (ActionMgtException | ActionMgtRuntimeException | SQLException e) { /** * Handling {@link ActionMgtRuntimeException}, which is intentionally thrown to represent underlying - * exceptions from the {@link #getActionEndpointConfigById(String, Integer)} method. + * exceptions from the {@link #buildActionResponse(String, Action, Map, Integer)} method. */ throw ActionManagementUtil.handleServerException( ActionMgtConstants.ErrorMessages.ERROR_WHILE_RETRIEVING_ACTION_BY_ID, e); } } - @Override - public Action updateActionEndpointAuthProperties(String actionType, String actionId, Authentication authentication, - int tenantId) throws ActionMgtException { - - updateActionEndpointAuthProperties(actionId, authentication, tenantId); - return getActionByActionId(actionType, actionId, tenantId); - } - - @Override - public Action updateActionEndpoint(String actionType, String actionId, EndpointConfig endpoint, - Authentication currentAuthentication, int tenantId) - throws ActionMgtException { - - updateActionEndpoint(actionId, endpoint, currentAuthentication, tenantId); - return getActionByActionId(actionType, actionId, tenantId); - } - /** - * Update the endpoint authentication properties of an {@link Action} by given Action ID. + * Add Action properties. * - * @param actionId Action ID. - * @param authentication Authentication information to be updated. - * @param tenantId Tenant Id. - * @throws ActionMgtServerException If an error occurs while updating the Action endpoint authentication properties. + * @param actionType Type of the Action. + * @param actionId UUID of the created Action. + * @param action Properties of the Action. + * @param tenantId Tenant ID. + * @throws ActionMgtException If an error occurs while adding action properties to the database. */ - private void updateActionEndpointAuthProperties(String actionId, Authentication authentication, int tenantId) - throws ActionMgtServerException { + private void addActionProperties(String actionType, String actionId, Action action, + Integer tenantId) throws ActionMgtException { - NamedJdbcTemplate jdbcTemplate = new NamedJdbcTemplate(IdentityDatabaseUtil.getDataSource()); try { - Map nonSecretEndpointProperties = authentication.getProperties().stream() - .filter(property -> !property.getIsConfidential()) - .collect(Collectors.toMap(AuthProperty::getName, AuthProperty::getValue)); - - jdbcTemplate.withTransaction(template -> { - // Update non-secret endpoint properties. - updateActionEndpointProperties(actionId, nonSecretEndpointProperties, tenantId); - // Encrypt and update secret endpoint properties. - actionSecretProcessor.encryptAssociatedSecrets(authentication, actionId); - return null; - }); - } catch (TransactionException e) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Error while updating the Action Endpoint Authentication Properties of " + - "Auth type: %s and Action ID: %s in Tenant Domain: %s. Rolling back updated action" + - " endpoint authentication properties.", authentication.getType(), actionId, - IdentityTenantUtil.getTenantDomain(tenantId))); - } + Map actionProperties = + resolveActionTypeSpecificProperties(actionType, actionId, action, null, tenantId); + + EndpointConfig endpoint = action.getEndpoint(); + // Encrypt the authentication secrets. + List authProperties = + actionSecretProcessor.encryptAssociatedSecrets(endpoint.getAuthentication(), actionId); + + actionProperties.put(URI_PROPERTY, endpoint.getUri()); + actionProperties.put(AUTHN_TYPE_PROPERTY, endpoint.getAuthentication().getType().name()); + authProperties.forEach(authProperty -> actionProperties.put(authProperty.getName(), + authProperty.getValue())); + + addActionPropertiesToDB(actionId, actionProperties, tenantId); + } catch (ActionMgtClientException e) { + throw e; + } catch (ActionMgtException | SecretManagementException | TransactionException e) { throw ActionManagementUtil.handleServerException( - ActionMgtConstants.ErrorMessages.ERROR_WHILE_UPDATING_ENDPOINT_PROPERTIES, e); + ActionMgtConstants.ErrorMessages.ERROR_WHILE_ADDING_ACTION_PROPERTIES, e); } } /** - * Update the endpoint information of an {@link Action} by given Action ID. + * Add Action properties to the Database. * - * @param actionId Action ID. - * @param endpoint Endpoint information to be updated. - * @param currentAuthentication Current Action endpoint authentication information. - * @param tenantId Tenant Id. - * @throws ActionMgtServerException If an error occurs while updating the Action endpoint. + * @param actionId UUID of the created Action. + * @param actionProperties Properties of the Action. + * @param tenantId Tenant ID. + * @throws TransactionException If an error occurs while persisting action properties to the database. */ - private void updateActionEndpoint(String actionId, EndpointConfig endpoint, Authentication currentAuthentication, - int tenantId) throws ActionMgtServerException { + private void addActionPropertiesToDB(String actionId, Map actionProperties, Integer tenantId) + throws TransactionException { NamedJdbcTemplate jdbcTemplate = new NamedJdbcTemplate(IdentityDatabaseUtil.getDataSource()); - try { - jdbcTemplate.withTransaction(template -> { - template.executeUpdate(ActionMgtSQLConstants.Query.DELETE_ACTION_ENDPOINT_PROPERTIES, + jdbcTemplate.withTransaction(template -> { + template.executeBatchInsert(ActionMgtSQLConstants.Query.ADD_ACTION_ENDPOINT_PROPERTIES, statement -> { - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_UUID, actionId); - statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); - }); + for (Map.Entry property : actionProperties.entrySet()) { + statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_UUID, actionId); + statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); + statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_NAME, + property.getKey()); + statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_VALUE, + property.getValue()); + statement.addBatch(); + } + }, null); + return null; + }); + } - // Add new Endpoint configuration properties. - Map propertiesMap = getEndpointProperties(endpoint.getUri(), - endpoint.getAuthentication().getType().name(), - endpoint.getAuthentication().getPropertiesWithSecretReferences(actionId)); - addEndpointProperties(actionId, propertiesMap, tenantId); - // Encrypt and add new endpoint properties secrets. - actionSecretProcessor.encryptAssociatedSecrets(endpoint.getAuthentication(), actionId); + /** + * Update the properties of an {@link Action} by given Action ID. + * + * @param actionId Action ID. + * @param updatingAction Information to be updated. + * @param existingAction Existing Action information. + * @param tenantId Tenant ID. + * @throws ActionMgtException If an error occurs while updating the Action properties. + */ + private void updateActionProperties(String actionType, String actionId, Action updatingAction, + Action existingAction, Integer tenantId) throws ActionMgtException { - // Delete old secrets. - actionSecretProcessor.deleteAssociatedSecrets(currentAuthentication, actionId); - return null; - }); - } catch (TransactionException e) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Error while updating the Action Endpoint Authentication from Auth type: %s" + - " to Auth type: %s of Action ID: %s in Tenant Domain: %s. Rolling back updated" + - " action endpoint authentication.", currentAuthentication.getType(), - endpoint.getAuthentication().getType(), actionId, - IdentityTenantUtil.getTenantDomain(tenantId))); - } + try { + Map actionProperties = resolveEndpointProperties(actionId, updatingAction, existingAction); + actionProperties.putAll(resolveActionTypeSpecificProperties(actionType, actionId, updatingAction, + existingAction, tenantId)); + + updateActionPropertiesInDB(actionId, actionProperties, tenantId); + } catch (ActionMgtClientException e) { + throw e; + } catch (ActionMgtException | SecretManagementException | TransactionException e) { throw ActionManagementUtil.handleServerException( - ActionMgtConstants.ErrorMessages.ERROR_WHILE_UPDATING_ENDPOINT_PROPERTIES, e); + ActionMgtConstants.ErrorMessages.ERROR_WHILE_UPDATING_ACTION_PROPERTIES, e); } } /** - * Add Action Endpoint properties to the Database. + * Update the basic information of an {@link Action} by given Action ID. * * @param actionId UUID of the created Action. - * @param endpointProperties Endpoint properties of the Action. + * @param updatingProperties Action properties to be updated. * @param tenantId Tenant ID. - * @throws ActionMgtServerException If an error occurs while adding endpoint properties to the database. + * @throws TransactionException If an error occurs while updating the Action properties. */ - private void addEndpointProperties(String actionId, Map endpointProperties, Integer tenantId) - throws ActionMgtException { + private void updateActionPropertiesInDB(String actionId, Map updatingProperties, + Integer tenantId) throws TransactionException { NamedJdbcTemplate jdbcTemplate = new NamedJdbcTemplate(IdentityDatabaseUtil.getDataSource()); - try { - jdbcTemplate.withTransaction(template -> { - template.executeBatchInsert(ActionMgtSQLConstants.Query.ADD_ACTION_ENDPOINT_PROPERTIES, + jdbcTemplate.withTransaction(template -> { + template.executeUpdate(ActionMgtSQLConstants.Query.DELETE_ACTION_ENDPOINT_PROPERTIES, statement -> { - for (Map.Entry property : endpointProperties.entrySet()) { - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_UUID, actionId); - statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_NAME, - property.getKey()); - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_VALUE, - property.getValue()); - statement.addBatch(); - } - }, null); - return null; - }); - } catch (TransactionException e) { - throw ActionManagementUtil.handleServerException( - ActionMgtConstants.ErrorMessages.ERROR_WHILE_ADDING_ENDPOINT_PROPERTIES, e); - } + statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_UUID, actionId); + statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); + }); + + // Add updated action properties. + addActionPropertiesToDB(actionId, updatingProperties, tenantId); + return null; + }); } /** @@ -410,115 +409,35 @@ private Action getActionBasicInfoById(String actionType, String actionId, Intege } /** - * Get Action Endpoint properties by ID. + * Get Action properties by ID. * - * @param actionUUID UUID of the created Action. - * @param tenantId Tenant ID. - * @return Endpoint Configuration. - * @throws ActionMgtRuntimeException If an error occurs while retrieving endpoint properties from the database. + * @param actionId UUID of the created Action. + * @param tenantId Tenant ID. + * @return A map of action properties, including any additional data based on action type. + * @throws SQLException If an error occurs while retrieving action properties from the database. */ - private EndpointConfig getActionEndpointConfigById(String actionUUID, Integer tenantId) - throws ActionMgtRuntimeException { + private Map getActionPropertiesById(String actionId, Integer tenantId) + throws SQLException { NamedJdbcTemplate jdbcTemplate = new NamedJdbcTemplate(IdentityDatabaseUtil.getDataSource()); + Map actionEndpointProperties = new HashMap<>(); try { - Map actionEndpointProperties = new HashMap<>(); jdbcTemplate.executeQuery(ActionMgtSQLConstants.Query.GET_ACTION_ENDPOINT_INFO_BY_ID, - (resultSet, rowNumber) -> { - actionEndpointProperties.put( - resultSet.getString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_NAME), - resultSet.getString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_VALUE)); - return null; - }, + (resultSet, rowNumber) -> { + actionEndpointProperties.put( + resultSet.getString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_NAME), + resultSet.getString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_VALUE)); + return null; + }, statement -> { - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_UUID, actionUUID); + statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_UUID, actionId); statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); - }); - - Authentication authentication = null; - if (actionEndpointProperties.containsKey(ActionMgtConstants.AUTHN_TYPE_ATTRIBUTE)) { - authentication = new Authentication.AuthenticationBuilder() - .type(Authentication.Type.valueOf( - actionEndpointProperties.get(ActionMgtConstants.AUTHN_TYPE_ATTRIBUTE))) - .properties(actionEndpointProperties) - .build(); - } else { - throw ActionManagementUtil.handleServerException( - ActionMgtConstants.ErrorMessages.ERROR_NO_AUTHENTICATION_TYPE, null); - } - - return new EndpointConfig.EndpointConfigBuilder() - .uri(actionEndpointProperties.get(ActionMgtConstants.URI_ATTRIBUTE)) - .authentication(authentication).build(); - } catch (ActionMgtServerException | DataAccessException e) { - /** - * Throwing a runtime exception because {@link ActionMgtServerException} and {@link DataAccessException} - * is not handled in {@link org.wso2.carbon.database.utils.jdbc.RowMapper} of - * {@link NamedJdbcTemplate#executeQuery(String, org.wso2.carbon.database.utils.jdbc.RowMapper, - * org.wso2.carbon.database.utils.jdbc.NamedQueryFilter)} - */ - throw ActionManagementUtil.handleRuntimeException( - ActionMgtConstants.ErrorMessages.ERROR_WHILE_RETRIEVING_ACTION_ENDPOINT_PROPERTIES.getMessage(), e); - } - } - - /** - * Get Action Endpoint properties Map. - * - * @param endpointUri Endpoint URI of the Action. - * @param authType Authentication Type of the Action. - * @param authProperties Authentication Properties of the Endpoint. - * @return Endpoint Properties Map. - */ - private Map getEndpointProperties(String endpointUri, String authType, - List authProperties) { - - Map endpointProperties = new HashMap<>(); - if (endpointUri != null) { - endpointProperties.put(ActionMgtConstants.URI_ATTRIBUTE, endpointUri); - } - if (authType != null) { - endpointProperties.put(ActionMgtConstants.AUTHN_TYPE_ATTRIBUTE, authType); - } - if (authProperties != null) { - for (AuthProperty property : authProperties) { - endpointProperties.put(property.getName(), property.getValue()); - } - } - - return endpointProperties; - } - - /** - * Update Action Endpoint properties. - * - * @param actionId UUID of the created Action. - * @param endpointProperties Endpoint Properties to be updated. - * @param tenantId Tenant ID. - */ - private void updateActionEndpointProperties(String actionId, Map endpointProperties, - Integer tenantId) throws ActionMgtException { + }); - NamedJdbcTemplate jdbcTemplate = new NamedJdbcTemplate(IdentityDatabaseUtil.getDataSource()); - try { - jdbcTemplate.withTransaction(template -> { - template.executeBatchInsert(ActionMgtSQLConstants.Query.UPDATE_ACTION_ENDPOINT_PROPERTIES, - statement -> { - for (Map.Entry property : endpointProperties.entrySet()) { - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_VALUE, - property.getValue()); - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_PROPERTY_NAME, - property.getKey()); - statement.setString(ActionMgtSQLConstants.Column.ACTION_ENDPOINT_UUID, actionId); - statement.setInt(ActionMgtSQLConstants.Column.TENANT_ID, tenantId); - statement.addBatch(); - } - }, null); - return null; - }); - } catch (TransactionException e) { - throw ActionManagementUtil.handleServerException( - ActionMgtConstants.ErrorMessages.ERROR_WHILE_UPDATING_ENDPOINT_PROPERTIES, e); + return actionEndpointProperties; + } catch (DataAccessException e) { + throw new SQLException(ActionMgtConstants.ErrorMessages + .ERROR_WHILE_RETRIEVING_ACTION_PROPERTIES.getMessage(), e); } } @@ -559,10 +478,10 @@ private Action changeActionStatus(String actionType, String actionId, String sta * @param updatingAction Information to be updated. * @param existingAction Existing Action information. * @param tenantId Tenant ID. - * @throws ActionMgtServerException If an error occurs while updating the Action basic information. + * @throws ActionMgtException If an error occurs while updating the Action basic information. */ private void updateBasicInfo(String actionType, String actionId, Action updatingAction, Action existingAction, - Integer tenantId) throws ActionMgtServerException { + Integer tenantId) throws ActionMgtException { if (updatingAction.getName() == null && updatingAction.getDescription() == null) { return; @@ -588,48 +507,351 @@ private void updateBasicInfo(String actionType, String actionId, Action updating } /** - * Update the endpoint URI and authentication properties of an {@link Action} by given Action ID. + * Resolves the endpoint properties for an action when action is updating. + * This method ensures that authentication secrets are handled appropriately, and the URI is resolved + * based on the provided or existing endpoint configurations. + * When the updating action does not contain endpoint configuration, it uses the existing endpoint's properties. * * @param actionId Action ID. - * @param updatingAction Information to be updated. - * @param existingAction Existing Action information. - * @param tenantId Tenant ID. - * @throws ActionMgtException If an error occurs while updating the Action endpoint. + * @param updatingAction Action to update. + * @param existingAction Existing Action. + * @return A map containing the resolved endpoint properties to be stored. + * @throws SecretManagementException If an error occurs while updating the authentication secrets. */ - private void updateEndpointUriAndAuthentication(String actionId, Action updatingAction, Action existingAction, - Integer tenantId) throws ActionMgtException { + private Map resolveEndpointProperties(String actionId, Action updatingAction, Action existingAction) + throws SecretManagementException { EndpointConfig updatingEndpoint = updatingAction.getEndpoint(); - if (updatingEndpoint == null) { - // No update needed if there's no endpoint configuration in the updating action. - return; + EndpointConfig existingEndpoint = existingAction.getEndpoint(); + + Map resolvedEndpointProperties = + resolveEndpointAuthenticationProperties(actionId, updatingEndpoint, existingEndpoint); + + if (updatingEndpoint != null && updatingEndpoint.getUri() != null) { + resolvedEndpointProperties.put(URI_PROPERTY, updatingEndpoint.getUri()); + } else { + resolvedEndpointProperties.put(URI_PROPERTY, existingEndpoint.getUri()); } - Authentication updatingAuthentication = updatingEndpoint.getAuthentication(); - if (updatingAuthentication == null) { - // When updating action, updates the URI only. - updateActionEndpointProperties(actionId, getEndpointProperties(updatingEndpoint.getUri(), null, - null), tenantId); - return; + return resolvedEndpointProperties; + } + + /** + * Resolves the authentication properties for an endpoint when action is updating. + * This deletes existing secrets and updates them with new properties as necessary. + * When the updating endpoint does not contain authentication, it uses the existing endpoint's properties. + * + * @param actionId Action ID. + * @param updatingEndpoint Endpoint configurations to be updated. + * @param existingEndpoint Existing Endpoint configurations. + * @return A map containing the resolved endpoint authentication properties to be stored. + * @throws SecretManagementException If an error occurs while updating the authentication secrets. + */ + private Map resolveEndpointAuthenticationProperties(String actionId, + EndpointConfig updatingEndpoint, + EndpointConfig existingEndpoint) + throws SecretManagementException { + + Authentication updatingAuthentication = updatingEndpoint != null ? updatingEndpoint.getAuthentication() : null; + Authentication existingAuthentication = existingEndpoint.getAuthentication(); + + Map authentication = new HashMap<>(); + Authentication.Type resolvedAuthType = existingAuthentication.getType(); + List resolvedAuthProperties = existingAuthentication.getProperties(); + + if (updatingAuthentication != null) { + if (resolvedAuthType != updatingAuthentication.getType()) { + // Delete existing secrets. + actionSecretProcessor.deleteAssociatedSecrets(existingAuthentication, actionId); + resolvedAuthType = updatingAuthentication.getType(); + } + + // Add new secrets or update existing secrets. + resolvedAuthProperties = actionSecretProcessor.encryptAssociatedSecrets(updatingAuthentication, actionId); + } + + authentication.put(AUTHN_TYPE_PROPERTY, resolvedAuthType.getName()); + resolvedAuthProperties.forEach(property -> authentication.put(property.getName(), property.getValue())); + + return authentication; + } + + /** + * Resolve the action type specific properties for creating or updating an action. + * + * @param actionType Action Type. + * @param actionId Action ID. + * @param inputAction A map containing the properties for the new or updated action. + * @param existingAction A map containing the existing properties. + * @param tenantId Tenant ID. + * @return A map containing the resolved action type specific properties. + * @throws ActionMgtException If an error occurs while handling action type specific properties. + */ + private Map resolveActionTypeSpecificProperties(String actionType, String actionId, + Action inputAction, + Action existingAction, + Integer tenantId) throws ActionMgtException { + + Map actionTypeSpecificProperties = new HashMap<>(); + switch (Action.ActionTypes.valueOf(actionType)) { + case PRE_UPDATE_PASSWORD: + PreUpdatePasswordAction inputPreUpdatePasswordAction = (PreUpdatePasswordAction) inputAction; + PreUpdatePasswordAction existingPreUpdatePasswordAction = (PreUpdatePasswordAction) existingAction; + + if (inputPreUpdatePasswordAction.getPasswordSharingFormat() != null) { + actionTypeSpecificProperties.put(PASSWORD_SHARING_FORMAT_PROPERTY, + inputPreUpdatePasswordAction.getPasswordSharingFormat().name()); + } else { + actionTypeSpecificProperties.put(PASSWORD_SHARING_FORMAT_PROPERTY, + existingPreUpdatePasswordAction.getPasswordSharingFormat().name()); + } + + // Handle certificate changes. + String certificateId = handleCertificateChanges(actionId, inputPreUpdatePasswordAction, + existingPreUpdatePasswordAction, tenantId); + if (StringUtils.isNotEmpty(certificateId)) { + actionTypeSpecificProperties.put(CERTIFICATE_ID_PROPERTY, certificateId); + } + + break; + case PRE_ISSUE_ACCESS_TOKEN: + default: + break; + } + + return actionTypeSpecificProperties; + } + + /** + * Deletes action type-specific properties associated with the provided action. + * + * @param actionType Type of the Action. + * @param action Action information. + * @param tenantId Tenant Id. + * @throws ActionMgtException If an error occurs while deleting action type specific properties. + */ + private void deleteActionTypeSpecificProperties(String actionType, Action action, Integer tenantId) + throws ActionMgtException { + + switch (Action.ActionTypes.valueOf(actionType)) { + case PRE_UPDATE_PASSWORD: + Certificate certificate = ((PreUpdatePasswordAction) action).getCertificate(); + if (certificate != null) { + deleteCertificate(certificate.getId(), tenantId); + } + break; + case PRE_ISSUE_ACCESS_TOKEN: + default: + break; } + } + + /** + * Updates the certificate associated with an action based on the provided updating properties. + * If a new certificate is provided, it persists the certificate and returns its ID. + * If the existing certificate is being removed (empty value), it deletes the certificate and returns null. + * If the existing certificate is being updated, it updates the certificate and returns its existing ID. + * + * @param actionId Action ID. + * @param inputAction A map containing the properties to update, including the certificate. + * @param existingAction A map containing the existing properties, including the current certificate ID. + * @param tenantId Tenant ID. + * @return The updated certificate ID, or null if the certificate was deleted. + * @throws ActionMgtException If an error occurs while updating the certificate. + */ + private String handleCertificateChanges(String actionId, PreUpdatePasswordAction inputAction, + PreUpdatePasswordAction existingAction, Integer tenantId) + throws ActionMgtException { - Authentication existingAuthentication = existingAction.getEndpoint().getAuthentication(); - if (updatingAuthentication.getType().equals(existingAuthentication.getType())) { - // When updating action, updates the URI and the authentication properties only. - if (updatingEndpoint.getUri() != null) { - updateActionEndpointProperties(actionId, getEndpointProperties(updatingEndpoint.getUri(), null, - null), tenantId); + String inputCertificate = inputAction.getCertificate() != null ? + inputAction.getCertificate().getCertificateContent() : null; + String certificateId = existingAction != null && existingAction.getCertificate() != null + ? existingAction.getCertificate().getId() : null; + + if (inputCertificate != null) { + if (StringUtils.isEmpty(certificateId)) { + // Add the new certificate. + certificateId = addCertificate(actionId, inputCertificate, tenantId); + } else if (inputCertificate.isEmpty()) { + // Delete the existing certificate. + deleteCertificate(certificateId, tenantId); + certificateId = null; + } else { + // Update the existing certificate. + updateCertificate(certificateId, inputCertificate, tenantId); } - updateActionEndpointAuthProperties(actionId, updatingAuthentication, tenantId); - return; } - // When updating action, updates the entire endpoint. - updatingEndpoint = StringUtils.isNotEmpty(updatingEndpoint.getUri()) ? updatingEndpoint : - new EndpointConfig.EndpointConfigBuilder() - .uri(existingAction.getEndpoint().getUri()) - .authentication(updatingAuthentication) + return certificateId; + } + + /** + * Add the certificate in the database. + * + * @param actionId UUID of the created Action. + * @param certificateContent Certificate to be added. + * @param tenantId Tenant ID. + * @throws ActionMgtException If an error occurs while adding the certificate. + * @returns Certificate ID. + */ + private String addCertificate(String actionId, String certificateContent, Integer tenantId) + throws ActionMgtException { + try { + Certificate certificate = new Certificate.Builder() + .name("ACTIONS:" + actionId) + .certificateContent(certificateContent) + .build(); + return ActionMgtServiceComponentHolder.getInstance().getCertificateManagementService() + .addCertificate(certificate, IdentityTenantUtil.getTenantDomain(tenantId)); + } catch (CertificateMgtClientException e) { + throw ActionManagementUtil.handleClientException( + ActionMgtConstants.ErrorMessages.ERROR_INVALID_ACTION_CERTIFICATE, e); + } catch (CertificateMgtException e) { + throw ActionManagementUtil.handleServerException( + ActionMgtConstants.ErrorMessages.ERROR_WHILE_ADDING_ACTION_CERTIFICATE, e); + } + } + + /** + * Get the certificate content by certificate ID. + * + * @param certificateId Certificate ID. + * @param tenantId Tenant ID. + * @return Certificate information. + * @throws ActionMgtException If an error occurs while retrieving the certificate from the database. + */ + private Certificate getCertificate(String certificateId, Integer tenantId) + throws ActionMgtException { + + try { + return ActionMgtServiceComponentHolder.getInstance().getCertificateManagementService() + .getCertificate(certificateId, IdentityTenantUtil.getTenantDomain(tenantId)); + } catch (CertificateMgtException e) { + throw ActionManagementUtil.handleServerException( + ActionMgtConstants.ErrorMessages.ERROR_WHILE_RETRIEVING_ACTION_CERTIFICATE, e); + } + } + + /** + * Update the certificate by certificate ID. + * + * @param certificateId Certificate ID. + * @param updatingCertificate Certificate to be updated. + * @param tenantId Tenant ID. + * @throws ActionMgtException If an error occurs while updating the certificate in the database. + */ + private void updateCertificate(String certificateId, String updatingCertificate, Integer tenantId) + throws ActionMgtException { + + try { + ActionMgtServiceComponentHolder.getInstance().getCertificateManagementService() + .updateCertificateContent(certificateId, updatingCertificate, + IdentityTenantUtil.getTenantDomain(tenantId)); + } catch (CertificateMgtClientException e) { + throw ActionManagementUtil.handleClientException( + ActionMgtConstants.ErrorMessages.ERROR_INVALID_ACTION_CERTIFICATE, e); + } catch (CertificateMgtException e) { + throw ActionManagementUtil.handleServerException( + ActionMgtConstants.ErrorMessages.ERROR_WHILE_UPDATING_ACTION_CERTIFICATE, e); + } + } + + /** + * Delete the certificate by certificate ID. + * + * @param certificateId Certificate ID. + * @param tenantId Tenant ID. + * @throws ActionMgtException If an error occurs while deleting the certificate in the database. + */ + private void deleteCertificate(String certificateId, Integer tenantId) throws ActionMgtException { + + try { + ActionMgtServiceComponentHolder.getInstance().getCertificateManagementService() + .deleteCertificate(certificateId, IdentityTenantUtil.getTenantDomain(tenantId)); + } catch (CertificateMgtException e) { + throw ActionManagementUtil.handleServerException( + ActionMgtConstants.ErrorMessages.ERROR_WHILE_DELETING_ACTION_CERTIFICATE, e); + } + } + + /** + * Build the Action Response Object according to the actionType. + * + * @param actionType Action Type. + * @param action Action basic information. + * @param actionProperties Action Properties. + * @param tenantId Tenant Id. + * @return Action Response. + * @throws ActionMgtRuntimeException If an error occurs while retrieving the certificate. + */ + private Action buildActionResponse(String actionType, Action action, Map actionProperties, + Integer tenantId) { + + Action.ActionResponseBuilder actionResponseBuilder; + try { + switch (Action.ActionTypes.valueOf(actionType)) { + case PRE_UPDATE_PASSWORD: + Certificate certificate = actionProperties.get(CERTIFICATE_ID_PROPERTY) != null ? + getCertificate(actionProperties.get(CERTIFICATE_ID_PROPERTY), tenantId) : null; + + actionResponseBuilder = new PreUpdatePasswordAction.ResponseBuilder() + .certificate(certificate) + .passwordSharingFormat(PreUpdatePasswordAction.PasswordFormat.valueOf( + actionProperties.get(PASSWORD_SHARING_FORMAT_PROPERTY))); + break; + case PRE_ISSUE_ACCESS_TOKEN: + default: + actionResponseBuilder = new Action.ActionResponseBuilder(); + break; + } + + Authentication authentication = null; + Authentication.Type authnType = + Authentication.Type.valueOf(actionProperties.get(ActionMgtConstants.AUTHN_TYPE_PROPERTY)); + switch (authnType) { + case BASIC: + authentication = new Authentication.BasicAuthBuilder( + actionProperties.get(Authentication.Property.USERNAME.getName()), + actionProperties.get(Authentication.Property.PASSWORD.getName())).build(); + break; + case BEARER: + authentication = new Authentication.BearerAuthBuilder( + actionProperties.get(Authentication.Property.ACCESS_TOKEN.getName())).build(); + break; + case API_KEY: + authentication = new Authentication.APIKeyAuthBuilder( + actionProperties.get(Authentication.Property.HEADER.getName()), + actionProperties.get(Authentication.Property.VALUE.getName())).build(); + break; + case NONE: + authentication = new Authentication.NoneAuthBuilder().build(); + break; + default: + break; + } + + EndpointConfig endpointConfig = new EndpointConfig.EndpointConfigBuilder() + .uri(actionProperties.get(ActionMgtConstants.URI_PROPERTY)) + .authentication(authentication) .build(); - updateActionEndpoint(actionId, updatingEndpoint, existingAuthentication, tenantId); + + return actionResponseBuilder + .id(action.getId()) + .type(Action.ActionTypes.valueOf(actionType)) + .name(action.getName()) + .description(action.getDescription()) + .status(action.getStatus()) + .endpoint(endpointConfig) + .build(); + } catch (ActionMgtException e) { + /** + * Throwing a runtime exception because {@link ActionMgtException} is not handled in + * {@link org.wso2.carbon.database.utils.jdbc.RowMapper} of {@link NamedJdbcTemplate#executeQuery(String, + * org.wso2.carbon.database.utils.jdbc.RowMapper,org.wso2.carbon.database.utils.jdbc.NamedQueryFilter)} + * in {@link #getActionsByActionType(String, Integer)} + */ + throw ActionManagementUtil.handleRuntimeException( + ActionMgtConstants.ErrorMessages.ERROR_WHILE_BUILDING_ACTION_RESPONSE.getMessage(), e); + } } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/CacheBackedActionMgtDAO.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/CacheBackedActionMgtDAO.java index 1ef2ff2d3ca3..f3f2918d5b2c 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/CacheBackedActionMgtDAO.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/dao/impl/CacheBackedActionMgtDAO.java @@ -27,8 +27,6 @@ import org.wso2.carbon.identity.action.management.dao.ActionManagementDAO; 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.Authentication; -import org.wso2.carbon.identity.action.management.model.EndpointConfig; import java.util.List; import java.util.Map; @@ -157,23 +155,6 @@ public Action getActionByActionId(String actionType, String actionId, Integer te return action; } - @Override - public Action updateActionEndpointAuthProperties(String actionType, String actionId, Authentication authentication, - int tenantId) throws ActionMgtException { - - return actionManagementDAO.updateActionEndpointAuthProperties(actionType, actionId, authentication, tenantId); - } - - @Override - public Action updateActionEndpoint(String actionType, String actionId, EndpointConfig endpoint, - Authentication currentAuthentication, int tenantId) - throws ActionMgtException { - - actionCacheByType.clearCacheEntry(new ActionTypeCacheKey(actionType), tenantId); - return actionManagementDAO.updateActionEndpoint(actionType, actionId, endpoint, currentAuthentication, - tenantId); - } - private void updateCache(Action action, ActionCacheEntry entry, ActionTypeCacheKey cacheKey, int tenantId) { if (LOG.isDebugEnabled()) { diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/exception/ActionMgtClientException.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/exception/ActionMgtClientException.java index 551c2ce2e59a..bd085eb43999 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/exception/ActionMgtClientException.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/exception/ActionMgtClientException.java @@ -27,4 +27,9 @@ public ActionMgtClientException(String message, String description, String error super(message, description, errorCode); } + + public ActionMgtClientException(String message, String description, String errorCode, Throwable cause) { + + super(message, description, errorCode, cause); + } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponent.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponent.java index 44fe7f894eac..ff34ec5b3259 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponent.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponent.java @@ -30,6 +30,7 @@ import org.osgi.service.component.annotations.ReferencePolicy; import org.wso2.carbon.identity.action.management.ActionManagementService; import org.wso2.carbon.identity.action.management.ActionManagementServiceImpl; +import org.wso2.carbon.identity.certificate.management.service.CertificateManagementService; import org.wso2.carbon.identity.secret.mgt.core.SecretManager; import org.wso2.carbon.identity.secret.mgt.core.SecretResolveManager; @@ -78,11 +79,13 @@ protected void deactivate(ComponentContext context) { private void setSecretManager(SecretManager secretManager) { ActionMgtServiceComponentHolder.getInstance().setSecretManager(secretManager); + LOG.debug("SecretManager set in ActionMgtServiceComponentHolder bundle."); } private void unsetSecretManager(SecretManager secretManager) { ActionMgtServiceComponentHolder.getInstance().setSecretManager(null); + LOG.debug("SecretManager unset in ActionMgtServiceComponentHolder bundle."); } @Reference( @@ -95,10 +98,31 @@ private void unsetSecretManager(SecretManager secretManager) { private void setSecretResolveManager(SecretResolveManager secretResolveManager) { ActionMgtServiceComponentHolder.getInstance().setSecretResolveManager(secretResolveManager); + LOG.debug("SecretResolveManager set in ActionMgtServiceComponentHolder bundle."); } private void unsetSecretResolveManager(SecretResolveManager secretResolveManager) { ActionMgtServiceComponentHolder.getInstance().setSecretResolveManager(null); + LOG.debug("SecretResolveManager unset in ActionMgtServiceComponentHolder bundle."); + } + + @Reference( + name = "org.wso2.carbon.identity.certificate.management.service.CertificateManagementService", + service = CertificateManagementService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetCertificateManagementService" + ) + private void setCertificateManagementService(CertificateManagementService certificateManagementService) { + + ActionMgtServiceComponentHolder.getInstance().setCertificateManagementService(certificateManagementService); + LOG.debug("CertificateManagementService set in ActionMgtServiceComponentHolder bundle."); + } + + private void unsetCertificateManagementService(CertificateManagementService certificateManagementService) { + + ActionMgtServiceComponentHolder.getInstance().setCertificateManagementService(null); + LOG.debug("CertificateManagementService unset in ActionMgtServiceComponentHolder bundle."); } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponentHolder.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponentHolder.java index 5866841fdbaa..d921157e0af1 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponentHolder.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/internal/ActionMgtServiceComponentHolder.java @@ -18,6 +18,7 @@ package org.wso2.carbon.identity.action.management.internal; +import org.wso2.carbon.identity.certificate.management.service.CertificateManagementService; import org.wso2.carbon.identity.secret.mgt.core.SecretManager; import org.wso2.carbon.identity.secret.mgt.core.SecretResolveManager; @@ -28,6 +29,7 @@ public class ActionMgtServiceComponentHolder { private SecretManager secretManager; private SecretResolveManager secretResolveManager; + private CertificateManagementService certificateMgtService; public static final ActionMgtServiceComponentHolder INSTANCE = new ActionMgtServiceComponentHolder(); @@ -84,4 +86,24 @@ public void setSecretResolveManager(SecretResolveManager secretResolveManager) { this.secretResolveManager = secretResolveManager; } + + /** + * Get the CertificateManagementService. + * + * @return CertificateManagementService instance. + */ + public CertificateManagementService getCertificateManagementService() { + + return certificateMgtService; + } + + /** + * Set the CertificateManagementService. + * + * @param certificateMgtService CertificateManagementService instance. + */ + public void setCertificateManagementService(CertificateManagementService certificateMgtService) { + + this.certificateMgtService = certificateMgtService; + } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/model/Action.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/model/Action.java index 99fa95aee93d..dc1f3030bf47 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/model/Action.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/model/Action.java @@ -115,7 +115,7 @@ public static ActionTypes[] filterByCategory(Category category) { */ public enum Category { PRE_POST, - IN_FLOW; + IN_FLOW } } @@ -124,30 +124,10 @@ public enum Category { */ public enum Status { - ACTIVE("ACTIVE"), - INACTIVE("INACTIVE"); - - private final String value; - - Status(String v) { - this.value = v; - } - - public String value() { - return value; - } - - public static Status fromValue(String value) { - for (Status b : Status.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } + ACTIVE, + INACTIVE } - private String id; private ActionTypes type; private String name; @@ -155,9 +135,6 @@ public static Status fromValue(String value) { private Status status; private EndpointConfig endpointConfig; - public Action() { - } - public Action(ActionResponseBuilder actionResponseBuilder) { this.id = actionResponseBuilder.id; @@ -205,11 +182,6 @@ public EndpointConfig getEndpoint() { return endpointConfig; } - public void setEndpoint(EndpointConfig endpointConfig) { - - this.endpointConfig = endpointConfig; - } - /** * ActionResponseBuilder. */ @@ -222,9 +194,6 @@ public static class ActionResponseBuilder { private Status status; private EndpointConfig endpointConfig; - public ActionResponseBuilder() { - } - public ActionResponseBuilder id(String id) { this.id = id; @@ -276,9 +245,6 @@ public static class ActionRequestBuilder { private String description; private EndpointConfig endpointConfig; - public ActionRequestBuilder() { - } - public ActionRequestBuilder name(String name) { this.name = name; diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/model/PreUpdatePasswordAction.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/model/PreUpdatePasswordAction.java new file mode 100644 index 000000000000..f1731179603b --- /dev/null +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/model/PreUpdatePasswordAction.java @@ -0,0 +1,181 @@ +/* + * 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.action.management.model; + +import org.wso2.carbon.identity.certificate.management.model.Certificate; + +/** + * PreUpdatePasswordAction. + */ +public class PreUpdatePasswordAction extends Action { + + /** + * Password Format Enum. + * Defines the category of the password sharing types. + */ + public enum PasswordFormat { + + PLAIN_TEXT, + SHA256_HASHED; + } + + private final PasswordFormat passwordSharingFormat; + private final Certificate certificate; + + public PreUpdatePasswordAction(ResponseBuilder responseBuilder) { + + super(responseBuilder); + this.passwordSharingFormat = responseBuilder.passwordSharingFormat; + this.certificate = responseBuilder.certificate; + } + + public PreUpdatePasswordAction(RequestBuilder requestBuilder) { + + super(requestBuilder); + this.passwordSharingFormat = requestBuilder.passwordSharingFormat; + this.certificate = requestBuilder.certificate; + } + + public PasswordFormat getPasswordSharingFormat() { + + return passwordSharingFormat; + } + + public Certificate getCertificate() { + + return certificate; + } + + /** + * Response Builder for PreUpdatePasswordAction. + */ + public static class ResponseBuilder extends ActionResponseBuilder { + + private PasswordFormat passwordSharingFormat; + private Certificate certificate; + + public ResponseBuilder passwordSharingFormat(PasswordFormat passwordSharingFormat) { + + this.passwordSharingFormat = passwordSharingFormat; + return this; + } + + public ResponseBuilder certificate(Certificate certificate) { + + this.certificate = certificate; + return this; + } + + @Override + public ResponseBuilder id(String id) { + + super.id(id); + return this; + } + + @Override + public ResponseBuilder type(ActionTypes type) { + + super.type(type); + return this; + } + + @Override + public ResponseBuilder name(String name) { + + super.name(name); + return this; + } + + @Override + public ResponseBuilder description(String description) { + + super.description(description); + return this; + } + + @Override + public ResponseBuilder status(Status status) { + + super.status(status); + return this; + } + + @Override + public ResponseBuilder endpoint(EndpointConfig endpoint) { + + super.endpoint(endpoint); + return this; + } + + @Override + public PreUpdatePasswordAction build() { + + return new PreUpdatePasswordAction(this); + } + } + + /** + * Request Builder for PreUpdatePasswordAction. + */ + public static class RequestBuilder extends ActionRequestBuilder { + + private PasswordFormat passwordSharingFormat; + private Certificate certificate; + + public RequestBuilder passwordSharingFormat(PasswordFormat passwordSharingFormat) { + + this.passwordSharingFormat = passwordSharingFormat; + return this; + } + + public RequestBuilder certificate(Certificate certificate) { + + this.certificate = certificate; + return this; + } + + @Override + public RequestBuilder name(String name) { + + super.name(name); + return this; + } + + @Override + public RequestBuilder description(String description) { + + super.description(description); + return this; + } + + @Override + public RequestBuilder endpoint(EndpointConfig endpoint) { + + super.endpoint(endpoint); + return this; + } + + @Override + public PreUpdatePasswordAction build() { + + return new PreUpdatePasswordAction(this); + } + } +} diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/util/ActionManagementUtil.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/util/ActionManagementUtil.java index 2ba8cf79da7e..8a14d98fb402 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/util/ActionManagementUtil.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/main/java/org/wso2/carbon/identity/action/management/util/ActionManagementUtil.java @@ -47,6 +47,18 @@ public static ActionMgtClientException handleClientException( return new ActionMgtClientException(error.getMessage(), description, error.getCode()); } + /** + * Handle Action Management client exceptions. + * + * @param error Error message. + * @param e Throwable. + * @return ActionMgtClientException. + */ + public static ActionMgtClientException handleClientException(ActionMgtConstants.ErrorMessages error, Throwable e) { + + return new ActionMgtClientException(error.getMessage(), error.getDescription(), error.getCode(), e); + } + /** * Handle Action Management server exceptions. * diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImplTest.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImplTest.java index 949efc721833..a18308cd69ad 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImplTest.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/ActionManagementServiceImplTest.java @@ -18,23 +18,20 @@ package org.wso2.carbon.identity.action.management; -import org.mockito.MockedStatic; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.identity.action.management.exception.ActionMgtException; import org.wso2.carbon.identity.action.management.internal.ActionMgtServiceComponentHolder; import org.wso2.carbon.identity.action.management.model.Action; import org.wso2.carbon.identity.action.management.model.AuthProperty; import org.wso2.carbon.identity.action.management.model.Authentication; -import org.wso2.carbon.identity.action.management.model.EndpointConfig; +import org.wso2.carbon.identity.action.management.util.TestUtil; import org.wso2.carbon.identity.common.testng.WithCarbonHome; import org.wso2.carbon.identity.common.testng.WithH2Database; import org.wso2.carbon.identity.common.testng.WithRealmService; import org.wso2.carbon.identity.core.internal.IdentityCoreServiceDataHolder; -import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.secret.mgt.core.SecretManagerImpl; import org.wso2.carbon.identity.secret.mgt.core.exception.SecretManagementException; import org.wso2.carbon.identity.secret.mgt.core.model.SecretType; @@ -46,6 +43,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.wso2.carbon.identity.action.management.util.TestUtil.PRE_ISSUE_ACCESS_TOKEN_PATH; +import static org.wso2.carbon.identity.action.management.util.TestUtil.TENANT_DOMAIN; /** * This class is a test suite for the ActionManagementServiceImpl class. @@ -57,19 +56,15 @@ @WithRealmService(injectToSingletons = {IdentityCoreServiceDataHolder.class}) public class ActionManagementServiceImplTest { - private MockedStatic identityDatabaseUtil; - private Action action; - private String tenantDomain; - private ActionManagementService serviceImpl; + private ActionManagementService actionManagementService; + + private Action preIssueAccessTokenAction; private Map secretProperties; - private static final String ACCESS_TOKEN = "6e47f1f7-bd29-41e9-b5dc-e9dd70ac22b7"; - private static final String PRE_ISSUE_ACCESS_TOKEN = Action.ActionTypes.PRE_ISSUE_ACCESS_TOKEN.getPathParam(); @BeforeClass public void setUpClass() { - serviceImpl = ActionManagementServiceImpl.getInstance(); - tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + actionManagementService = ActionManagementServiceImpl.getInstance(); } @BeforeMethod @@ -85,56 +80,57 @@ public void setUp() throws SecretManagementException { @Test(priority = 1) public void testAddAction() throws ActionMgtException, SecretManagementException { - Action creatingAction = buildMockAction( + Action creatingAction = TestUtil.buildMockAction( "PreIssueAccessToken", "To configure PreIssueAccessToken", "https://example.com", - buildMockBasicAuthentication("admin", "admin")); - action = serviceImpl.addAction(PRE_ISSUE_ACCESS_TOKEN, creatingAction, - tenantDomain); - Assert.assertNotNull(action.getId()); - Assert.assertEquals(creatingAction.getName(), action.getName()); - Assert.assertEquals(creatingAction.getDescription(), action.getDescription()); - Assert.assertEquals(Action.Status.ACTIVE, action.getStatus()); + TestUtil.buildMockBasicAuthentication("admin", "admin")); + preIssueAccessTokenAction = actionManagementService.addAction(PRE_ISSUE_ACCESS_TOKEN_PATH, creatingAction, + TENANT_DOMAIN); + Assert.assertNotNull(preIssueAccessTokenAction.getId()); + Assert.assertEquals(creatingAction.getName(), preIssueAccessTokenAction.getName()); + Assert.assertEquals(creatingAction.getDescription(), preIssueAccessTokenAction.getDescription()); + Assert.assertEquals(Action.Status.ACTIVE, preIssueAccessTokenAction.getStatus()); Assert.assertEquals(Action.ActionTypes.PRE_ISSUE_ACCESS_TOKEN.getActionType(), - action.getType().getActionType()); - Assert.assertEquals(creatingAction.getEndpoint().getUri(), action.getEndpoint().getUri()); + preIssueAccessTokenAction.getType().getActionType()); + Assert.assertEquals(creatingAction.getEndpoint().getUri(), preIssueAccessTokenAction.getEndpoint().getUri()); Assert.assertEquals(creatingAction.getEndpoint().getAuthentication().getType(), - action.getEndpoint().getAuthentication().getType()); + preIssueAccessTokenAction.getEndpoint().getAuthentication().getType()); Assert.assertEquals(creatingAction.getEndpoint().getAuthentication().getProperties().size(), - action.getEndpoint().getAuthentication().getProperties().size()); + preIssueAccessTokenAction.getEndpoint().getAuthentication().getProperties().size()); Assert.assertEquals(creatingAction.getEndpoint().getAuthentication().getProperties().size(), - action.getEndpoint().getAuthentication().getPropertiesWithSecretReferences(action.getId()).size()); - secretProperties = mapActionAuthPropertiesWithSecrets(action); - Assert.assertEquals( - action.getEndpoint().getAuthentication().getProperty(Authentication.Property.USERNAME).getValue(), + preIssueAccessTokenAction.getEndpoint().getAuthentication().getPropertiesWithSecretReferences( + preIssueAccessTokenAction.getId()).size()); + secretProperties = mapActionAuthPropertiesWithSecrets(preIssueAccessTokenAction); + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getAuthentication() + .getProperty(Authentication.Property.USERNAME).getValue(), secretProperties.get(Authentication.Property.USERNAME.getName())); - Assert.assertEquals( - action.getEndpoint().getAuthentication().getProperty(Authentication.Property.PASSWORD).getValue(), + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getAuthentication() + .getProperty(Authentication.Property.PASSWORD).getValue(), secretProperties.get(Authentication.Property.PASSWORD.getName())); } @Test(priority = 2, expectedExceptions = ActionMgtException.class, expectedExceptionsMessageRegExp = "Unable to create an Action.") public void testAddActionWithInvalidData() throws ActionMgtException { - Action creatingAction = buildMockAction( + Action creatingAction = TestUtil.buildMockAction( "PreIssueAccessToken_#1", "To configure PreIssueAccessToken", "https://example.com", - buildMockAPIKeyAuthentication("-test-header", "thisisapikey")); - Action action = serviceImpl.addAction(PRE_ISSUE_ACCESS_TOKEN, creatingAction, tenantDomain); + TestUtil.buildMockAPIKeyAuthentication("-test-header", "thisisapikey")); + Action action = actionManagementService.addAction(PRE_ISSUE_ACCESS_TOKEN_PATH, creatingAction, TENANT_DOMAIN); Assert.assertNull(action); } @Test(priority = 3, expectedExceptions = ActionMgtException.class, expectedExceptionsMessageRegExp = "Unable to create an Action.") public void testAddActionWithEmptyData() throws ActionMgtException { - Action creatingAction = buildMockAction( + Action creatingAction = TestUtil.buildMockAction( "", "To configure PreIssueAccessToken", "https://example.com", - buildMockBasicAuthentication(null, "admin")); - Action action = serviceImpl.addAction(PRE_ISSUE_ACCESS_TOKEN, creatingAction, tenantDomain); + TestUtil.buildMockBasicAuthentication(null, "admin")); + Action action = actionManagementService.addAction(PRE_ISSUE_ACCESS_TOKEN_PATH, creatingAction, TENANT_DOMAIN); Assert.assertNull(action); } @@ -142,28 +138,29 @@ public void testAddActionWithEmptyData() throws ActionMgtException { expectedExceptionsMessageRegExp = "Unable to create an Action.") public void testAddMaximumActionsPerType() throws ActionMgtException { - Action creatingAction = buildMockAction( + Action creatingAction = TestUtil.buildMockAction( "PreIssueAccessToken", "To configure PreIssueAccessToken", "https://example.com", - buildMockBasicAuthentication("admin", "admin")); - action = serviceImpl.addAction(PRE_ISSUE_ACCESS_TOKEN, creatingAction, - tenantDomain); + TestUtil.buildMockBasicAuthentication("admin", "admin")); + preIssueAccessTokenAction = actionManagementService.addAction(PRE_ISSUE_ACCESS_TOKEN_PATH, creatingAction, + TENANT_DOMAIN); } @Test(priority = 5) public void testGetActionsByActionType() throws ActionMgtException, SecretManagementException { - List actions = serviceImpl.getActionsByActionType(PRE_ISSUE_ACCESS_TOKEN, tenantDomain); + List actions = actionManagementService.getActionsByActionType(PRE_ISSUE_ACCESS_TOKEN_PATH, + TENANT_DOMAIN); Assert.assertEquals(1, actions.size()); for (Action result: actions) { - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType().getActionType(), result.getType().getActionType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(action.getEndpoint().getAuthentication().getType(), + Assert.assertEquals(preIssueAccessTokenAction.getId(), result.getId()); + Assert.assertEquals(preIssueAccessTokenAction.getName(), result.getName()); + Assert.assertEquals(preIssueAccessTokenAction.getDescription(), result.getDescription()); + Assert.assertEquals(preIssueAccessTokenAction.getType().getActionType(), result.getType().getActionType()); + Assert.assertEquals(preIssueAccessTokenAction.getStatus(), result.getStatus()); + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); secretProperties = mapActionAuthPropertiesWithSecrets(result); Assert.assertEquals( @@ -178,14 +175,15 @@ public void testGetActionsByActionType() throws ActionMgtException, SecretManage @Test(priority = 6) public void testGetActionByActionId() throws ActionMgtException, SecretManagementException { - Action result = serviceImpl.getActionByActionId(action.getType().getPathParam(), action.getId(), tenantDomain); - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(action.getEndpoint().getAuthentication().getType(), + Action result = actionManagementService.getActionByActionId(preIssueAccessTokenAction.getType().getPathParam(), + preIssueAccessTokenAction.getId(), TENANT_DOMAIN); + Assert.assertEquals(preIssueAccessTokenAction.getId(), result.getId()); + Assert.assertEquals(preIssueAccessTokenAction.getName(), result.getName()); + Assert.assertEquals(preIssueAccessTokenAction.getDescription(), result.getDescription()); + Assert.assertEquals(preIssueAccessTokenAction.getType(), result.getType()); + Assert.assertEquals(preIssueAccessTokenAction.getStatus(), result.getStatus()); + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); secretProperties = mapActionAuthPropertiesWithSecrets(result); Assert.assertEquals( @@ -200,17 +198,17 @@ public void testGetActionByActionId() throws ActionMgtException, SecretManagemen public void testGetActionsByActionTypeFromCache() throws ActionMgtException, SecretManagementException { // Verify that the action is retrieved from the cache based on action type. - List actions = serviceImpl.getActionsByActionType( - PRE_ISSUE_ACCESS_TOKEN, tenantDomain); + List actions = actionManagementService.getActionsByActionType( + PRE_ISSUE_ACCESS_TOKEN_PATH, TENANT_DOMAIN); Assert.assertEquals(1, actions.size()); Action result = actions.get(0); - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(action.getEndpoint().getAuthentication().getType(), + Assert.assertEquals(preIssueAccessTokenAction.getId(), result.getId()); + Assert.assertEquals(preIssueAccessTokenAction.getName(), result.getName()); + Assert.assertEquals(preIssueAccessTokenAction.getDescription(), result.getDescription()); + Assert.assertEquals(preIssueAccessTokenAction.getType(), result.getType()); + Assert.assertEquals(preIssueAccessTokenAction.getStatus(), result.getStatus()); + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(preIssueAccessTokenAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); secretProperties = mapActionAuthPropertiesWithSecrets(result); Assert.assertEquals( @@ -224,17 +222,18 @@ public void testGetActionsByActionTypeFromCache() throws ActionMgtException, Sec @Test(priority = 8) public void testUpdateAction() throws ActionMgtException, SecretManagementException { - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( "Pre Issue Access Token", "To update configuration pre issue access token", "https://sample.com", - buildMockAPIKeyAuthentication("header", "value")); - Action result = serviceImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, tenantDomain); - Assert.assertEquals(action.getId(), result.getId()); + TestUtil.buildMockAPIKeyAuthentication("header", "value")); + Action result = actionManagementService.updateAction(PRE_ISSUE_ACCESS_TOKEN_PATH, + preIssueAccessTokenAction.getId(), updatingAction, TENANT_DOMAIN); + Assert.assertEquals(preIssueAccessTokenAction.getId(), result.getId()); Assert.assertEquals(updatingAction.getName(), result.getName()); Assert.assertEquals(updatingAction.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); + Assert.assertEquals(preIssueAccessTokenAction.getType(), result.getType()); + Assert.assertEquals(preIssueAccessTokenAction.getStatus(), result.getStatus()); Assert.assertEquals(updatingAction.getEndpoint().getUri(), result.getEndpoint().getUri()); Assert.assertEquals( updatingAction.getEndpoint().getAuthentication().getType(), @@ -246,30 +245,30 @@ public void testUpdateAction() throws ActionMgtException, SecretManagementExcept Assert.assertEquals( result.getEndpoint().getAuthentication().getProperty(Authentication.Property.VALUE).getValue(), secretProperties.get(Authentication.Property.VALUE.getName())); - action = result; + preIssueAccessTokenAction = result; } @Test(priority = 9) public void testDeactivateAction() throws ActionMgtException { - Assert.assertEquals(Action.Status.ACTIVE, action.getStatus()); - Action deactivatedAction = serviceImpl.deactivateAction( - PRE_ISSUE_ACCESS_TOKEN, action.getId(), tenantDomain); + Assert.assertEquals(Action.Status.ACTIVE, preIssueAccessTokenAction.getStatus()); + Action deactivatedAction = actionManagementService.deactivateAction( + PRE_ISSUE_ACCESS_TOKEN_PATH, preIssueAccessTokenAction.getId(), TENANT_DOMAIN); Assert.assertEquals(Action.Status.INACTIVE, deactivatedAction.getStatus()); } @Test(priority = 10) public void testActivateAction() throws ActionMgtException { - Action result = serviceImpl.activateAction( - PRE_ISSUE_ACCESS_TOKEN, action.getId(), tenantDomain); + Action result = actionManagementService.activateAction( + PRE_ISSUE_ACCESS_TOKEN_PATH, preIssueAccessTokenAction.getId(), TENANT_DOMAIN); Assert.assertEquals(Action.Status.ACTIVE, result.getStatus()); } @Test(priority = 11) public void testGetActionsCountPerType() throws ActionMgtException { - Map actionMap = serviceImpl.getActionsCountPerType(tenantDomain); + Map actionMap = actionManagementService.getActionsCountPerType(TENANT_DOMAIN); Assert.assertNull(actionMap.get(Action.ActionTypes.PRE_UPDATE_PASSWORD.getActionType())); Assert.assertNull(actionMap.get(Action.ActionTypes.PRE_UPDATE_PROFILE.getActionType())); Assert.assertNull(actionMap.get(Action.ActionTypes.PRE_REGISTRATION.getActionType())); @@ -281,43 +280,14 @@ public void testGetActionsCountPerType() throws ActionMgtException { } @Test(priority = 12) - public void testUpdateEndpointConfigWithSameAuthenticationType() - throws ActionMgtException, SecretManagementException { - - Authentication authentication = buildMockAPIKeyAuthentication("newheader", "newvalue"); - Action result = serviceImpl.updateActionEndpointAuthentication( - PRE_ISSUE_ACCESS_TOKEN, action.getId(), authentication, tenantDomain); - Assert.assertEquals(Authentication.Type.API_KEY, result.getEndpoint().getAuthentication().getType()); - Assert.assertEquals(authentication.getProperty(Authentication.Property.HEADER).getValue(), - result.getEndpoint().getAuthentication().getProperty(Authentication.Property.HEADER).getValue()); - secretProperties = mapActionAuthPropertiesWithSecrets(result); - Assert.assertEquals( - result.getEndpoint().getAuthentication().getProperty(Authentication.Property.VALUE).getValue(), - secretProperties.get(Authentication.Property.VALUE.getName())); - } - - @Test(priority = 13) - public void testUpdateEndpointConfigWithDifferentAuthenticationType() - throws ActionMgtException, SecretManagementException { - - Authentication authentication = buildMockBearerAuthentication(ACCESS_TOKEN); - Action result = serviceImpl.updateActionEndpointAuthentication( - PRE_ISSUE_ACCESS_TOKEN, action.getId(), authentication, tenantDomain); - Assert.assertEquals(Authentication.Type.BEARER, result.getEndpoint().getAuthentication().getType()); - secretProperties = mapActionAuthPropertiesWithSecrets(result); - Assert.assertEquals( - result.getEndpoint().getAuthentication().getProperty(Authentication.Property.ACCESS_TOKEN).getValue(), - secretProperties.get(Authentication.Property.ACCESS_TOKEN.getName())); - } - - @Test(priority = 14) public void testDeleteAction() throws ActionMgtException { - serviceImpl.deleteAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), tenantDomain); - Assert.assertNull(serviceImpl.getActionByActionId(action.getType().getPathParam(), action.getId(), - tenantDomain)); - Map actions = serviceImpl.getActionsCountPerType(tenantDomain); - Assert.assertNull(actions.get(PRE_ISSUE_ACCESS_TOKEN)); + actionManagementService.deleteAction(PRE_ISSUE_ACCESS_TOKEN_PATH, preIssueAccessTokenAction.getId(), + TENANT_DOMAIN); + Assert.assertNull(actionManagementService.getActionByActionId(PRE_ISSUE_ACCESS_TOKEN_PATH, + preIssueAccessTokenAction.getId(), TENANT_DOMAIN)); + Map actions = actionManagementService.getActionsCountPerType(TENANT_DOMAIN); + Assert.assertNull(actions.get(PRE_ISSUE_ACCESS_TOKEN_PATH)); } private Map mapActionAuthPropertiesWithSecrets(Action action) throws SecretManagementException { @@ -327,43 +297,4 @@ private Map mapActionAuthPropertiesWithSecrets(Action action) th .stream() .collect(Collectors.toMap(AuthProperty::getName, AuthProperty::getValue)); } - - private Authentication buildMockBasicAuthentication(String username, String password) { - - return new Authentication.BasicAuthBuilder(username, password).build(); - } - - private Authentication buildMockBearerAuthentication(String accessToken) { - - return new Authentication.BearerAuthBuilder(accessToken).build(); - } - - private Authentication buildMockAPIKeyAuthentication(String header, String value) { - - return new Authentication.APIKeyAuthBuilder(header, value).build(); - } - - private EndpointConfig buildMockEndpointConfig(String uri, Authentication authentication) { - - if (uri == null && authentication == null) { - return null; - } - - return new EndpointConfig.EndpointConfigBuilder() - .uri(uri) - .authentication(authentication) - .build(); - } - - private Action buildMockAction(String name, - String description, - String uri, - Authentication authentication) { - - return new Action.ActionRequestBuilder() - .name(name) - .description(description) - .endpoint(buildMockEndpointConfig(uri, authentication)) - .build(); - } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/PreUpdatePasswordActionServiceImplTest.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/PreUpdatePasswordActionServiceImplTest.java new file mode 100644 index 000000000000..16400b29f3cc --- /dev/null +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/PreUpdatePasswordActionServiceImplTest.java @@ -0,0 +1,486 @@ +/* + * 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.action.management; + +import org.apache.commons.lang.StringUtils; +import org.junit.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.action.management.constant.ActionMgtConstants; +import org.wso2.carbon.identity.action.management.exception.ActionMgtClientException; +import org.wso2.carbon.identity.action.management.exception.ActionMgtException; +import org.wso2.carbon.identity.action.management.exception.ActionMgtServerException; +import org.wso2.carbon.identity.action.management.internal.ActionMgtServiceComponentHolder; +import org.wso2.carbon.identity.action.management.model.Action; +import org.wso2.carbon.identity.action.management.model.PreUpdatePasswordAction; +import org.wso2.carbon.identity.action.management.util.TestUtil; +import org.wso2.carbon.identity.certificate.management.exception.CertificateMgtClientException; +import org.wso2.carbon.identity.certificate.management.exception.CertificateMgtException; +import org.wso2.carbon.identity.certificate.management.exception.CertificateMgtServerException; +import org.wso2.carbon.identity.certificate.management.model.Certificate; +import org.wso2.carbon.identity.certificate.management.service.CertificateManagementService; +import org.wso2.carbon.identity.common.testng.WithCarbonHome; +import org.wso2.carbon.identity.common.testng.WithH2Database; +import org.wso2.carbon.identity.common.testng.WithRealmService; +import org.wso2.carbon.identity.core.internal.IdentityCoreServiceDataHolder; +import org.wso2.carbon.identity.secret.mgt.core.SecretManagerImpl; +import org.wso2.carbon.identity.secret.mgt.core.exception.SecretManagementException; +import org.wso2.carbon.identity.secret.mgt.core.model.SecretType; + +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.wso2.carbon.identity.action.management.util.TestUtil.CERTIFICATE; +import static org.wso2.carbon.identity.action.management.util.TestUtil.CERTIFICATE_ID; +import static org.wso2.carbon.identity.action.management.util.TestUtil.CERTIFICATE_NAME; +import static org.wso2.carbon.identity.action.management.util.TestUtil.PRE_UPDATE_PASSWORD_PATH; +import static org.wso2.carbon.identity.action.management.util.TestUtil.PRE_UPDATE_PASSWORD_TYPE; +import static org.wso2.carbon.identity.action.management.util.TestUtil.TENANT_DOMAIN; +import static org.wso2.carbon.identity.action.management.util.TestUtil.UPDATED_CERTIFICATE; +import static org.wso2.carbon.identity.certificate.management.constant.CertificateMgtErrors.ERROR_INVALID_CERTIFICATE_CONTENT; + +/** + * This class is a test suite for the ActionManagementDAOImpl class. + * It contains unit tests to verify the functionality of the methods in the ActionManagementDAOImpl class + * for PRE_UPDATE_PASSWORD action type. + */ +@WithCarbonHome +@WithH2Database(files = {"dbscripts/h2.sql"}) +@WithRealmService(injectToSingletons = {IdentityCoreServiceDataHolder.class}) +public class PreUpdatePasswordActionServiceImplTest { + + private ActionManagementService actionManagementService; + private CertificateManagementService certificateManagementService; + + private PreUpdatePasswordAction preUpdatePasswordAction; + private Certificate certificate; + private CertificateMgtServerException serverException; + private CertificateMgtClientException clientException; + + @BeforeClass + public void setUpClass() { + + actionManagementService = ActionManagementServiceImpl.getInstance(); + } + + @BeforeMethod + public void setUp() throws SecretManagementException { + + SecretManagerImpl secretManager = mock(SecretManagerImpl.class); + SecretType secretType = mock(SecretType.class); + ActionMgtServiceComponentHolder.getInstance().setSecretManager(secretManager); + when(secretType.getId()).thenReturn("secretId"); + when(secretManager.getSecretType(any())).thenReturn(secretType); + + certificateManagementService = mock(CertificateManagementService.class); + ActionMgtServiceComponentHolder.getInstance() + .setCertificateManagementService(certificateManagementService); + + serverException = new CertificateMgtServerException("server_error_message", "server_error_description", "65030", + new Throwable()); + clientException = new CertificateMgtClientException(ERROR_INVALID_CERTIFICATE_CONTENT.getMessage(), + ERROR_INVALID_CERTIFICATE_CONTENT.getDescription(), ERROR_INVALID_CERTIFICATE_CONTENT.getCode()); + } + + @Test(priority = 1) + public void testAddPreUpdatePasswordAction() throws ActionMgtException, CertificateMgtException { + + PreUpdatePasswordAction actionModel = TestUtil.buildMockPreUpdatePasswordAction( + "PreUpdatePassword", + "To configure PreUpdatePassword", + "https://example.com", + TestUtil.buildMockBasicAuthentication("admin", "admin"), + PreUpdatePasswordAction.PasswordFormat.PLAIN_TEXT, + CERTIFICATE); + certificate = new Certificate.Builder() + .id(String.valueOf(CERTIFICATE_ID)) + .name(CERTIFICATE_NAME) + .certificateContent(CERTIFICATE) + .build(); + + doReturn(CERTIFICATE_ID).when(certificateManagementService).addCertificate(any(), any()); + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + preUpdatePasswordAction = (PreUpdatePasswordAction) actionManagementService.addAction(PRE_UPDATE_PASSWORD_PATH, + actionModel, TENANT_DOMAIN); + + Assert.assertNotNull(preUpdatePasswordAction.getId()); + Assert.assertEquals(actionModel.getName(), preUpdatePasswordAction.getName()); + Assert.assertEquals(actionModel.getDescription(), preUpdatePasswordAction.getDescription()); + Assert.assertEquals(PRE_UPDATE_PASSWORD_TYPE, preUpdatePasswordAction.getType().getActionType()); + Assert.assertEquals(Action.Status.ACTIVE, preUpdatePasswordAction.getStatus()); + Assert.assertEquals(actionModel.getEndpoint().getUri(), preUpdatePasswordAction.getEndpoint().getUri()); + Assert.assertEquals(actionModel.getEndpoint().getAuthentication().getType(), + preUpdatePasswordAction.getEndpoint().getAuthentication().getType()); + Assert.assertEquals(actionModel.getPasswordSharingFormat(), preUpdatePasswordAction.getPasswordSharingFormat()); + Assert.assertNotNull(preUpdatePasswordAction.getCertificate()); + Assert.assertEquals(CERTIFICATE_ID, preUpdatePasswordAction.getCertificate().getId()); + Assert.assertEquals(CERTIFICATE_NAME, preUpdatePasswordAction.getCertificate().getName()); + } + + @Test(priority = 2, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testGetPreUpdatePasswordActionByActionId() throws ActionMgtException, CertificateMgtException { + + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + PreUpdatePasswordAction fetchedAction = (PreUpdatePasswordAction) actionManagementService + .getActionByActionId(PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), TENANT_DOMAIN); + + Assert.assertEquals(preUpdatePasswordAction.getId(), fetchedAction.getId()); + Assert.assertEquals(preUpdatePasswordAction.getName(), fetchedAction.getName()); + Assert.assertEquals(preUpdatePasswordAction.getDescription(), fetchedAction.getDescription()); + Assert.assertEquals(preUpdatePasswordAction.getType(), fetchedAction.getType()); + Assert.assertEquals(preUpdatePasswordAction.getStatus(), fetchedAction.getStatus()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getUri(), fetchedAction.getEndpoint().getUri()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getAuthentication().getType(), + fetchedAction.getEndpoint().getAuthentication().getType()); + Assert.assertEquals( + preUpdatePasswordAction.getPasswordSharingFormat(), fetchedAction.getPasswordSharingFormat()); + Assert.assertNotNull(fetchedAction.getCertificate()); + Assert.assertEquals(preUpdatePasswordAction.getCertificate().getId(), fetchedAction.getCertificate().getId()); + Assert.assertEquals( + preUpdatePasswordAction.getCertificate().getName(), fetchedAction.getCertificate().getName()); + } + + @Test(priority = 3, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testGetPreUpdatePasswordActionsByActionType() throws ActionMgtException, CertificateMgtException { + + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + List preUpdatePasswordActionList = + actionManagementService.getActionsByActionType(PRE_UPDATE_PASSWORD_PATH, TENANT_DOMAIN); + + Assert.assertEquals(1, preUpdatePasswordActionList.size()); + PreUpdatePasswordAction fetchedAction = (PreUpdatePasswordAction) preUpdatePasswordActionList.get(0); + Assert.assertEquals(preUpdatePasswordAction.getId(), fetchedAction.getId()); + Assert.assertEquals(preUpdatePasswordAction.getName(), fetchedAction.getName()); + Assert.assertEquals(preUpdatePasswordAction.getDescription(), fetchedAction.getDescription()); + Assert.assertEquals(preUpdatePasswordAction.getType(), fetchedAction.getType()); + Assert.assertEquals(preUpdatePasswordAction.getStatus(), fetchedAction.getStatus()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getUri(), fetchedAction.getEndpoint().getUri()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getAuthentication().getType(), + fetchedAction.getEndpoint().getAuthentication().getType()); + Assert.assertEquals( + preUpdatePasswordAction.getPasswordSharingFormat(), fetchedAction.getPasswordSharingFormat()); + Assert.assertNotNull(fetchedAction.getCertificate()); + Assert.assertEquals(preUpdatePasswordAction.getCertificate().getId(), fetchedAction.getCertificate().getId()); + Assert.assertEquals( + preUpdatePasswordAction.getCertificate().getName(), fetchedAction.getCertificate().getName()); + + } + + @Test(priority = 4, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testUpdatePreUpdatePasswordAction() throws ActionMgtException, CertificateMgtException { + + PreUpdatePasswordAction updateActionModel = TestUtil.buildMockPreUpdatePasswordAction( + "Updated PreUpdatePassword Action", + "To configure PreUpdatePassword of wso2.com organization", + "https://my-extension.com/pre-update-password", + TestUtil.buildMockNoneAuthentication(), + PreUpdatePasswordAction.PasswordFormat.SHA256_HASHED, + UPDATED_CERTIFICATE); + + certificate = new Certificate.Builder() + .id(String.valueOf(CERTIFICATE_ID)) + .name(CERTIFICATE_NAME) + .certificateContent(UPDATED_CERTIFICATE) + .build(); + + doNothing().when(certificateManagementService).updateCertificateContent(anyString(), anyString(), anyString()); + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + + PreUpdatePasswordAction updatedAction = (PreUpdatePasswordAction) actionManagementService.updateAction( + PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), updateActionModel, TENANT_DOMAIN); + + Assert.assertEquals(preUpdatePasswordAction.getId(), updatedAction.getId()); + Assert.assertEquals(updateActionModel.getName(), updatedAction.getName()); + Assert.assertEquals(updateActionModel.getDescription(), updatedAction.getDescription()); + Assert.assertEquals(preUpdatePasswordAction.getType(), updatedAction.getType()); + Assert.assertEquals(preUpdatePasswordAction.getStatus(), updatedAction.getStatus()); + Assert.assertEquals(updateActionModel.getEndpoint().getUri(), updatedAction.getEndpoint().getUri()); + Assert.assertEquals(updateActionModel.getEndpoint().getAuthentication().getType(), + updatedAction.getEndpoint().getAuthentication().getType()); + Assert.assertEquals(updateActionModel.getPasswordSharingFormat(), updatedAction.getPasswordSharingFormat()); + Assert.assertNotNull(updatedAction.getCertificate()); + Assert.assertEquals(certificate.getId(), updatedAction.getCertificate().getId()); + Assert.assertEquals(certificate.getName(), updatedAction.getCertificate().getName()); + Assert.assertEquals(certificate.getCertificateContent(), + updatedAction.getCertificate().getCertificateContent()); + + preUpdatePasswordAction = updatedAction; + } + + @Test(priority = 5, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testGetPreUpdatePasswordActionWithServerErrorFromCertificate() throws CertificateMgtException { + + doThrow(serverException).when(certificateManagementService).getCertificate(anyString(), anyString()); + try { + actionManagementService.getActionByActionId(PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), + TENANT_DOMAIN); + Assert.fail("Successful retrieval of the action without an exception is considered as a failure"); + } catch (ActionMgtException e) { + Assert.assertEquals(e.getClass(), ActionMgtServerException.class); + Assert.assertEquals(e.getMessage(), + ActionMgtConstants.ErrorMessages.ERROR_WHILE_RETRIEVING_ACTION_BY_ID.getMessage()); + for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) { + if (cause instanceof CertificateMgtServerException) { + return; + } + } + Assert.fail("Expected cause of type CertificateMgtServerException was not found in the exception chain"); + } + } + + @Test(priority = 6, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testUpdatePreUpdatePasswordActionWithServerErrorFromCertificate() throws CertificateMgtException { + + PreUpdatePasswordAction updateActionModel = TestUtil.buildMockPreUpdatePasswordAction( + "Updated PreUpdatePassword Action", + "To configure PreUpdatePassword of wso2.com organization", + "https://my-extension.com/pre-update-password", + TestUtil.buildMockNoneAuthentication(), + PreUpdatePasswordAction.PasswordFormat.SHA256_HASHED, + CERTIFICATE); + + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + doThrow(serverException).when(certificateManagementService).updateCertificateContent(any(), any(), any()); + try { + actionManagementService.updateAction(PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), + updateActionModel, TENANT_DOMAIN); + Assert.fail("Successful update of the action without an exception is considered as a failure"); + } catch (ActionMgtException e) { + Assert.assertEquals(ActionMgtServerException.class, e.getClass()); + Assert.assertEquals(ActionMgtConstants.ErrorMessages.ERROR_WHILE_UPDATING_ACTION.getMessage(), + e.getMessage()); + for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) { + if (cause instanceof CertificateMgtServerException) { + return; + } + } + Assert.fail("Expected cause of type CertificateMgtServerException was not found in the exception chain"); + } + } + + @Test(priority = 7, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testUpdatePreUpdatePasswordActionWithClientErrorFromCertificate() throws CertificateMgtException { + + PreUpdatePasswordAction updateActionModel = TestUtil.buildMockPreUpdatePasswordAction( + "Updated PreUpdatePassword Action", + "To configure PreUpdatePassword of wso2.com organization", + "https://my-extension.com/pre-update-password", + TestUtil.buildMockNoneAuthentication(), + PreUpdatePasswordAction.PasswordFormat.SHA256_HASHED, + CERTIFICATE); + + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + doThrow(clientException).when(certificateManagementService).updateCertificateContent(any(), any(), any()); + try { + actionManagementService.updateAction(PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), + updateActionModel, TENANT_DOMAIN); + Assert.fail("Successful update of the action without an exception is considered as a failure"); + } catch (ActionMgtException e) { + Assert.assertEquals(ActionMgtClientException.class, e.getClass()); + Assert.assertEquals(ActionMgtConstants.ErrorMessages.ERROR_INVALID_ACTION_CERTIFICATE.getMessage(), + e.getMessage()); + for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) { + if (cause instanceof CertificateMgtClientException) { + return; + } + } + Assert.fail("Expected cause of type CertificateMgtClientException was not found in the exception chain"); + } + } + + @Test(priority = 8, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testDeleteCertificateOfPreUpdatePasswordActionWithServerError() throws CertificateMgtException { + + PreUpdatePasswordAction updateActionModel = TestUtil.buildMockPreUpdatePasswordAction(null, null, + null, null, null, StringUtils.EMPTY); + + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + doThrow(serverException).when(certificateManagementService).deleteCertificate(any(), any()); + try { + actionManagementService.updateAction(PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), + updateActionModel, TENANT_DOMAIN); + Assert.fail("Successful update of the action without an exception is considered as a failure"); + } catch (ActionMgtException e) { + Assert.assertEquals(ActionMgtServerException.class, e.getClass()); + Assert.assertEquals(ActionMgtConstants.ErrorMessages.ERROR_WHILE_UPDATING_ACTION.getMessage(), + e.getMessage()); + for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) { + if (cause instanceof CertificateMgtServerException) { + return; + } + } + Assert.fail("Expected cause of type CertificateMgtServerException was not found in the exception chain"); + } + } + + @Test(priority = 9, dependsOnMethods = "testUpdatePreUpdatePasswordAction") + public void testDeleteCertificateOfPreUpdatePasswordAction() throws ActionMgtException, CertificateMgtException { + + PreUpdatePasswordAction updateActionModel = TestUtil.buildMockPreUpdatePasswordAction(null, null, + null, null, null, StringUtils.EMPTY); + + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + doNothing().when(certificateManagementService).deleteCertificate(anyString(), anyString()); + + PreUpdatePasswordAction updatedAction = (PreUpdatePasswordAction) actionManagementService.updateAction( + PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), updateActionModel, TENANT_DOMAIN); + + Assert.assertEquals(preUpdatePasswordAction.getId(), updatedAction.getId()); + Assert.assertEquals(preUpdatePasswordAction.getName(), updatedAction.getName()); + Assert.assertEquals(preUpdatePasswordAction.getDescription(), updatedAction.getDescription()); + Assert.assertEquals(preUpdatePasswordAction.getType(), updatedAction.getType()); + Assert.assertEquals(preUpdatePasswordAction.getStatus(), updatedAction.getStatus()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getUri(), updatedAction.getEndpoint().getUri()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getAuthentication().getType(), + updatedAction.getEndpoint().getAuthentication().getType()); + Assert.assertEquals(preUpdatePasswordAction.getPasswordSharingFormat(), + updatedAction.getPasswordSharingFormat()); + Assert.assertNull(updatedAction.getCertificate()); + + preUpdatePasswordAction = updatedAction; + } + + @Test(priority = 10, dependsOnMethods = "testDeleteCertificateOfPreUpdatePasswordAction") + public void testAddCertificateOfPreUpdatePasswordAction() throws ActionMgtException, CertificateMgtException { + + PreUpdatePasswordAction updateActionModel = TestUtil.buildMockPreUpdatePasswordAction(null, null, + null, null, null, CERTIFICATE); + + doReturn(CERTIFICATE_ID).when(certificateManagementService).addCertificate(any(), anyString()); + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + + PreUpdatePasswordAction updatedAction = (PreUpdatePasswordAction) actionManagementService.updateAction( + PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), updateActionModel, TENANT_DOMAIN); + + Assert.assertEquals(preUpdatePasswordAction.getId(), updatedAction.getId()); + Assert.assertEquals(preUpdatePasswordAction.getName(), updatedAction.getName()); + Assert.assertEquals(preUpdatePasswordAction.getDescription(), updatedAction.getDescription()); + Assert.assertEquals(preUpdatePasswordAction.getType(), updatedAction.getType()); + Assert.assertEquals(preUpdatePasswordAction.getStatus(), updatedAction.getStatus()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getUri(), updatedAction.getEndpoint().getUri()); + Assert.assertEquals(preUpdatePasswordAction.getEndpoint().getAuthentication().getType(), + updatedAction.getEndpoint().getAuthentication().getType()); + Assert.assertEquals(preUpdatePasswordAction.getPasswordSharingFormat(), + updatedAction.getPasswordSharingFormat()); + + Assert.assertNotNull(updatedAction.getCertificate()); + Assert.assertEquals(certificate.getId(), updatedAction.getCertificate().getId()); + Assert.assertEquals(certificate.getName(), updatedAction.getCertificate().getName()); + Assert.assertEquals(certificate.getCertificateContent(), + updatedAction.getCertificate().getCertificateContent()); + + preUpdatePasswordAction = updatedAction; + } + + @Test(priority = 8, dependsOnMethods = "testAddPreUpdatePasswordAction") + public void testDeletePreUpdatePasswordActionWithServerErrorFromCertificate() throws CertificateMgtException { + + doReturn(certificate).when(certificateManagementService).getCertificate(anyString(), anyString()); + doThrow(serverException).when(certificateManagementService).deleteCertificate(any(), any()); + try { + actionManagementService.deleteAction(PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), + TENANT_DOMAIN); + Assert.fail("Successful deletion of the action without an exception is considered as a failure"); + } catch (ActionMgtException e) { + Assert.assertEquals(ActionMgtServerException.class, e.getClass()); + Assert.assertEquals(ActionMgtConstants.ErrorMessages.ERROR_WHILE_DELETING_ACTION.getMessage(), + e.getMessage()); + for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) { + if (cause instanceof CertificateMgtServerException) { + return; + } + } + Assert.fail("Expected cause of type CertificateMgtServerException was not found in the exception chain"); + } + } + + @Test(priority = 11) + public void testDeletePreUpdatePasswordAction() throws ActionMgtException, CertificateMgtException { + + doNothing().when(certificateManagementService).deleteCertificate(anyString(), anyString()); + + actionManagementService.deleteAction(PRE_UPDATE_PASSWORD_PATH, preUpdatePasswordAction.getId(), TENANT_DOMAIN); + + Assert.assertNull(actionManagementService.getActionByActionId(PRE_UPDATE_PASSWORD_PATH, + preUpdatePasswordAction.getId(), TENANT_DOMAIN)); + } + + @Test(priority = 12) + public void testAddPreUpdatePasswordActionWithServerErrorFromCertificate() throws CertificateMgtException { + + PreUpdatePasswordAction actionModel = TestUtil.buildMockPreUpdatePasswordAction( + "PreUpdatePassword", + "To configure PreUpdatePassword", + "https://example.com", + TestUtil.buildMockBasicAuthentication("admin", "admin"), + PreUpdatePasswordAction.PasswordFormat.PLAIN_TEXT, + CERTIFICATE); + + doThrow(serverException).when(certificateManagementService).addCertificate(any(), any()); + try { + actionManagementService.addAction(PRE_UPDATE_PASSWORD_PATH, actionModel, TENANT_DOMAIN); + Assert.fail("Successful addition of the action without an exception is considered as a failure"); + } catch (ActionMgtException e) { + Assert.assertEquals(ActionMgtServerException.class, e.getClass()); + Assert.assertEquals(ActionMgtConstants.ErrorMessages.ERROR_WHILE_ADDING_ACTION.getMessage(), + e.getMessage()); + for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) { + if (cause instanceof CertificateMgtServerException) { + return; + } + } + Assert.fail("Expected cause of type CertificateMgtServerException was not found in the exception chain"); + } + } + + @Test(priority = 13) + public void testAddPreUpdatePasswordActionWithClientErrorFromCertificate() throws CertificateMgtException { + + PreUpdatePasswordAction actionModel = TestUtil.buildMockPreUpdatePasswordAction( + "PreUpdatePassword", + "To configure PreUpdatePassword", + "https://example.com", + TestUtil.buildMockBasicAuthentication("admin", "admin"), + PreUpdatePasswordAction.PasswordFormat.PLAIN_TEXT, + CERTIFICATE); + + doThrow(clientException).when(certificateManagementService).addCertificate(any(), any()); + try { + actionManagementService.addAction(PRE_UPDATE_PASSWORD_PATH, actionModel, TENANT_DOMAIN); + Assert.fail("Successful addition of the action without an exception is considered as a failure"); + } catch (ActionMgtException e) { + Assert.assertEquals(ActionMgtClientException.class, e.getClass()); + Assert.assertEquals(ActionMgtConstants.ErrorMessages.ERROR_INVALID_ACTION_CERTIFICATE.getMessage(), + e.getMessage()); + for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) { + if (cause instanceof CertificateMgtClientException) { + return; + } + } + Assert.fail("Expected cause of type CertificateMgtServerException was not found in the exception chain"); + } + } +} diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAOImplTest.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAOImplTest.java index 2c3a5237ee5a..1aedcae591b9 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAOImplTest.java +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/dao/ActionManagementDAOImplTest.java @@ -28,8 +28,8 @@ import org.wso2.carbon.identity.action.management.exception.ActionMgtException; import org.wso2.carbon.identity.action.management.internal.ActionMgtServiceComponentHolder; import org.wso2.carbon.identity.action.management.model.Action; -import org.wso2.carbon.identity.action.management.model.Authentication; -import org.wso2.carbon.identity.action.management.model.EndpointConfig; +import org.wso2.carbon.identity.action.management.model.PreUpdatePasswordAction; +import org.wso2.carbon.identity.action.management.util.TestUtil; import org.wso2.carbon.identity.common.testng.WithCarbonHome; import org.wso2.carbon.identity.common.testng.WithH2Database; import org.wso2.carbon.identity.core.util.IdentityTenantUtil; @@ -37,6 +37,7 @@ import org.wso2.carbon.identity.secret.mgt.core.exception.SecretManagementException; import org.wso2.carbon.identity.secret.mgt.core.model.SecretType; +import java.util.List; import java.util.Map; import java.util.UUID; @@ -45,11 +46,15 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; +import static org.wso2.carbon.identity.action.management.util.TestUtil.PRE_ISSUE_ACCESS_TOKEN_ACTION_ID; +import static org.wso2.carbon.identity.action.management.util.TestUtil.PRE_ISSUE_ACCESS_TOKEN_TYPE; +import static org.wso2.carbon.identity.action.management.util.TestUtil.PRE_UPDATE_PASSWORD_ACTION_ID; +import static org.wso2.carbon.identity.action.management.util.TestUtil.PRE_UPDATE_PASSWORD_TYPE; +import static org.wso2.carbon.identity.action.management.util.TestUtil.TENANT_ID; /** * This class is a test suite for the ActionManagementDAOImpl class. - * It contains unit tests to verify the functionality of the methods - * in the ActionManagementDAOImpl class. + * It contains unit tests to verify the functionality of the methods in the ActionManagementDAOImpl class. */ @WithH2Database(files = {"dbscripts/h2.sql"}) @WithCarbonHome @@ -57,9 +62,7 @@ public class ActionManagementDAOImplTest { private ActionManagementDAOImpl daoImpl; private MockedStatic identityTenantUtil; - private static final String PRE_ISSUE_ACCESS_TOKEN = "PRE_ISSUE_ACCESS_TOKEN"; - private static final int TENANT_ID = 2; - private Action action; + private Action createdAction; @BeforeClass public void setUpClass() { @@ -88,111 +91,117 @@ public void tearDown() { @Test(priority = 1) public void testAddAction() throws ActionMgtException { - String id = String.valueOf(UUID.randomUUID()); - Action creatingAction = buildMockAction( + Action creatingAction = TestUtil.buildMockAction( "PreIssueAccessToken", "To configure PreIssueAccessToken", "https://example.com", - buildMockBasicAuthentication("admin", "admin")); - action = daoImpl.addAction(PRE_ISSUE_ACCESS_TOKEN, id, creatingAction, TENANT_ID); - Assert.assertEquals(id, action.getId()); - Assert.assertEquals(creatingAction.getName(), action.getName()); - Assert.assertEquals(creatingAction.getDescription(), action.getDescription()); - Assert.assertEquals(PRE_ISSUE_ACCESS_TOKEN, action.getType().getActionType()); - Assert.assertEquals(Action.Status.ACTIVE, action.getStatus()); - Assert.assertEquals(creatingAction.getEndpoint().getUri(), action.getEndpoint().getUri()); + TestUtil.buildMockBasicAuthentication("admin", "admin")); + + createdAction = daoImpl.addAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, PRE_ISSUE_ACCESS_TOKEN_ACTION_ID, creatingAction, + TENANT_ID); + Assert.assertEquals(PRE_ISSUE_ACCESS_TOKEN_ACTION_ID, createdAction.getId()); + Assert.assertEquals(creatingAction.getName(), createdAction.getName()); + Assert.assertEquals(creatingAction.getDescription(), createdAction.getDescription()); + Assert.assertEquals(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getType().getActionType()); + Assert.assertEquals(Action.Status.ACTIVE, createdAction.getStatus()); + Assert.assertEquals(creatingAction.getEndpoint().getUri(), createdAction.getEndpoint().getUri()); Assert.assertEquals(creatingAction.getEndpoint().getAuthentication().getType(), - action.getEndpoint().getAuthentication().getType()); + createdAction.getEndpoint().getAuthentication().getType()); } @Test(priority = 2, expectedExceptions = ActionMgtException.class, expectedExceptionsMessageRegExp = "Error while adding Action.") public void testAddActionWithoutName() throws ActionMgtException { - Action action = buildMockAction( + Action action = TestUtil.buildMockAction( null, "To configure PreIssueAccessToken", "https://example.com", - buildMockBasicAuthentication("admin", "admin")); - this.action = daoImpl.addAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), action, TENANT_ID); + TestUtil.buildMockBasicAuthentication("admin", "admin")); + + daoImpl.addAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, String.valueOf(UUID.randomUUID()), action, TENANT_ID); } - @Test(priority = 3) + @Test(priority = 3, dependsOnMethods = "testAddAction") public void testGetActionsByActionType() throws ActionMgtException { - Assert.assertEquals(1, daoImpl.getActionsByActionType(PRE_ISSUE_ACCESS_TOKEN, TENANT_ID).size()); - Action result = daoImpl.getActionsByActionType(PRE_ISSUE_ACCESS_TOKEN, TENANT_ID).get(0); - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(action.getEndpoint().getAuthentication().getType(), + List actionList = daoImpl.getActionsByActionType(PRE_ISSUE_ACCESS_TOKEN_TYPE, TENANT_ID); + Assert.assertEquals(1, actionList.size()); + Action result = actionList.get(0); + Assert.assertEquals(createdAction.getId(), result.getId()); + Assert.assertEquals(createdAction.getName(), result.getName()); + Assert.assertEquals(createdAction.getDescription(), result.getDescription()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); + Assert.assertEquals(createdAction.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(createdAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); } @Test(priority = 4) public void testGetActionByActionId() throws ActionMgtException { - Action result = daoImpl.getActionByActionId(PRE_ISSUE_ACCESS_TOKEN, action.getId(), TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(action.getEndpoint().getAuthentication().getType(), + Action result = daoImpl.getActionByActionId(PRE_ISSUE_ACCESS_TOKEN_TYPE, PRE_ISSUE_ACCESS_TOKEN_ACTION_ID, + TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); + Assert.assertEquals(createdAction.getName(), result.getName()); + Assert.assertEquals(createdAction.getDescription(), result.getDescription()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); + Assert.assertEquals(createdAction.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(createdAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); } @Test(priority = 5) public void testDeleteAction() throws ActionMgtException { - daoImpl.deleteAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), action, TENANT_ID); - Assert.assertNull(daoImpl.getActionByActionId(PRE_ISSUE_ACCESS_TOKEN, action.getId(), TENANT_ID)); + daoImpl.deleteAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, PRE_ISSUE_ACCESS_TOKEN_ACTION_ID, createdAction, TENANT_ID); + Assert.assertNull(daoImpl.getActionByActionId(PRE_ISSUE_ACCESS_TOKEN_TYPE, PRE_ISSUE_ACCESS_TOKEN_ACTION_ID, + TENANT_ID)); } @Test(priority = 6) public void testAddActionWithoutDescription() throws ActionMgtException { String id = String.valueOf(UUID.randomUUID()); - Action creatingAction = buildMockAction( + Action creatingAction = TestUtil.buildMockAction( "PreIssueAccessToken", null, "https://example.com", - buildMockBasicAuthentication("admin", "admin")); - action = daoImpl.addAction(PRE_ISSUE_ACCESS_TOKEN, id, creatingAction, TENANT_ID); - Assert.assertEquals(id, action.getId()); - Assert.assertEquals(creatingAction.getName(), action.getName()); - Assert.assertNull(null, action.getDescription()); - Assert.assertEquals(PRE_ISSUE_ACCESS_TOKEN, action.getType().getActionType()); - Assert.assertEquals(Action.Status.ACTIVE, action.getStatus()); - Assert.assertEquals(creatingAction.getEndpoint().getUri(), action.getEndpoint().getUri()); + TestUtil.buildMockBasicAuthentication("admin", "admin")); + createdAction = daoImpl.addAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, id, creatingAction, TENANT_ID); + Assert.assertEquals(id, createdAction.getId()); + Assert.assertEquals(creatingAction.getName(), createdAction.getName()); + Assert.assertNull(null, createdAction.getDescription()); + Assert.assertEquals(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getType().getActionType()); + Assert.assertEquals(Action.Status.ACTIVE, createdAction.getStatus()); + Assert.assertEquals(creatingAction.getEndpoint().getUri(), createdAction.getEndpoint().getUri()); Assert.assertEquals(creatingAction.getEndpoint().getAuthentication().getType(), - action.getEndpoint().getAuthentication().getType()); + createdAction.getEndpoint().getAuthentication().getType()); } @Test(priority = 7, dependsOnMethods = "testAddActionWithoutDescription") public void testUpdateAction() throws ActionMgtException { - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( "Pre Issue Access Token", "To configure pre issue access token", "https://sample.com", - buildMockBasicAuthentication("updatingadmin", "updatingadmin")); - Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, action, TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); + TestUtil.buildMockBasicAuthentication("updatingadmin", "updatingadmin")); + Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), updatingAction, + createdAction, TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); Assert.assertEquals(updatingAction.getName(), result.getName()); Assert.assertEquals(updatingAction.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); Assert.assertEquals(updatingAction.getEndpoint().getUri(), result.getEndpoint().getUri()); Assert.assertEquals( updatingAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType() ); - action = result; + createdAction = result; } @Test(priority = 8) @@ -200,17 +209,18 @@ public void testUpdateActionWithoutNameAndDescription() throws ActionMgtExceptio // TODO: 'Name' is a required attribute. Thus, DAO layer should throw an exception if name is null. // This should be fixed in DAO layer and test case needs to be updated accordingly. - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( null, null, "https://sample.com", - buildMockBasicAuthentication("updatingadmin", "updatingadmin")); - Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, action, TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); + TestUtil.buildMockBasicAuthentication("updatingadmin", "updatingadmin")); + Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), updatingAction, + createdAction, TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); + Assert.assertEquals(createdAction.getName(), result.getName()); + Assert.assertEquals(createdAction.getDescription(), result.getDescription()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); Assert.assertEquals(updatingAction.getEndpoint().getUri(), result.getEndpoint().getUri()); Assert.assertEquals(updatingAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); @@ -222,217 +232,150 @@ public void testUpdateActionWithNameAndDescription() throws ActionMgtException { // TODO: 'Uri','AuthenticationType','AuthProperties' are required attributes. Thus, DAO layer should throw an // exception if those attributes are null. This should be fixed in DAO layer and test case needs to be updated // accordingly. - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( "Pre Issue Access Token", "To configure pre issue access token", null, null); - Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, action, TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); + Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), updatingAction, + createdAction, TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); Assert.assertEquals(updatingAction.getName(), result.getName()); Assert.assertEquals(updatingAction.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(action.getEndpoint().getAuthentication().getType(), + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); + Assert.assertEquals(createdAction.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(createdAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); } @Test(priority = 10) - public void testUpdateActionEndpointAuthSecretProperties() throws ActionMgtException { - - Authentication authentication = buildMockBasicAuthentication("newadmin", "newadmin"); - Action result = daoImpl.updateActionEndpointAuthProperties(PRE_ISSUE_ACCESS_TOKEN, action.getId(), - authentication, TENANT_ID); - Assert.assertEquals(Authentication.Type.BASIC, result.getEndpoint().getAuthentication().getType()); - Assert.assertEquals( - action.getEndpoint().getAuthentication().getProperty(Authentication.Property.USERNAME).getValue(), - result.getEndpoint().getAuthentication().getProperty(Authentication.Property.USERNAME).getValue()); - Assert.assertEquals( - action.getEndpoint().getAuthentication().getProperty(Authentication.Property.PASSWORD).getValue(), - result.getEndpoint().getAuthentication().getProperty(Authentication.Property.PASSWORD).getValue()); - } - - @Test(priority = 11) public void testUpdateActionWithoutEndpointUri() throws ActionMgtException { // TODO: 'Uri' is a required attribute. Thus, DAO layer should throw an exception if Uri is null. // This should be fixed in DAO layer and test case needs to be updated accordingly. - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( "Pre Issue Access Token", "To configure pre issue access token", null, - buildMockBasicAuthentication("updatingadmin", "updatingadmin")); - Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, action, TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); + TestUtil.buildMockBasicAuthentication("updatingadmin", "updatingadmin")); + Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), updatingAction, + createdAction, TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); Assert.assertEquals(updatingAction.getName(), result.getName()); Assert.assertEquals(updatingAction.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); + Assert.assertEquals(createdAction.getEndpoint().getUri(), result.getEndpoint().getUri()); Assert.assertEquals(updatingAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); } - @Test(priority = 12) + @Test(priority = 11) public void testUpdateActionWithAuthType() throws ActionMgtException { - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( "Pre Issue Access Token", "To configure pre issue access token", "https://sample.com", - buildMockBearerAuthentication("57c7df90-cacc-4f56-9b0a-f14bfbff3076")); - Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, action, TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); + TestUtil.buildMockBearerAuthentication("57c7df90-cacc-4f56-9b0a-f14bfbff3076")); + Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), updatingAction, + createdAction, TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); + Assert.assertEquals(createdAction.getName(), result.getName()); + Assert.assertEquals(createdAction.getDescription(), result.getDescription()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); Assert.assertEquals(updatingAction.getEndpoint().getUri(), result.getEndpoint().getUri()); Assert.assertEquals(updatingAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); - action = result; + createdAction = result; } - @Test(priority = 13) + @Test(priority = 12) public void testUpdateActionWithUri() throws ActionMgtException { // TODO: 'Name','AuthenticationType' and 'AuthProperties' are required attributes. Thus, DAO layer should throw // an exception if those attributes are null. This should be fixed in DAO layer and test case needs to be // updated accordingly. - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( null, null, "https://sample.com", null); - Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, action, TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); - Assert.assertEquals(action.getName(), result.getName()); - Assert.assertEquals(action.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); + Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), updatingAction, + createdAction, TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); + Assert.assertEquals(createdAction.getName(), result.getName()); + Assert.assertEquals(createdAction.getDescription(), result.getDescription()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); Assert.assertEquals(updatingAction.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(action.getEndpoint().getAuthentication().getType(), + Assert.assertEquals(createdAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); - action = result; + createdAction = result; } - @Test(priority = 14) + @Test(priority = 13) public void testUpdateActionWithAuthTypeWithoutUri() throws ActionMgtException { // TODO: 'Uri' is a required attribute. Thus, DAO layer should throw an exception if uri is null. // This should be fixed in DAO layer and test case needs to be updated accordingly. - Action updatingAction = buildMockAction( + Action updatingAction = TestUtil.buildMockAction( "Pre Issue Access Token", "To configure pre issue access token", null, - buildMockBasicAuthentication("updatingadmin", "updatingadmin")); - Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), updatingAction, action, TENANT_ID); - Assert.assertEquals(action.getId(), result.getId()); + TestUtil.buildMockBasicAuthentication("updatingadmin", "updatingadmin")); + Action result = daoImpl.updateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), updatingAction, + createdAction, TENANT_ID); + Assert.assertEquals(createdAction.getId(), result.getId()); Assert.assertEquals(updatingAction.getName(), result.getName()); Assert.assertEquals(updatingAction.getDescription(), result.getDescription()); - Assert.assertEquals(action.getType(), result.getType()); - Assert.assertEquals(action.getStatus(), result.getStatus()); - Assert.assertEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); + Assert.assertEquals(createdAction.getType(), result.getType()); + Assert.assertEquals(createdAction.getStatus(), result.getStatus()); + Assert.assertEquals(createdAction.getEndpoint().getUri(), result.getEndpoint().getUri()); Assert.assertEquals(updatingAction.getEndpoint().getAuthentication().getType(), result.getEndpoint().getAuthentication().getType()); } - @Test(priority = 15) - public void testUpdateActionEndpointAuthNonSecretProperties() throws ActionMgtException { - - Action sampleAction = buildMockAction( - "Pre Issue Access Token", - "To configure pre issue access token", - "https://sample.com", - buildMockAPIKeyAuthentication("header", "value")); - Action updatingAction = daoImpl.updateAction( - PRE_ISSUE_ACCESS_TOKEN, action.getId(), sampleAction, action, TENANT_ID); - Authentication authentication = buildMockAPIKeyAuthentication("updatingheader", "updatingvalue"); - Action result = daoImpl.updateActionEndpointAuthProperties(PRE_ISSUE_ACCESS_TOKEN, updatingAction.getId(), - authentication, TENANT_ID); - Assert.assertEquals(Authentication.Type.API_KEY, result.getEndpoint().getAuthentication().getType()); - Assert.assertEquals(authentication.getProperty(Authentication.Property.HEADER).getValue(), - result.getEndpoint().getAuthentication().getProperty(Authentication.Property.HEADER).getValue()); - Assert.assertEquals( - updatingAction.getEndpoint().getAuthentication().getProperty(Authentication.Property.VALUE).getValue(), - result.getEndpoint().getAuthentication().getProperty(Authentication.Property.VALUE).getValue()); - } - - @Test(priority = 16) + @Test(priority = 14) public void testDeactivateAction() throws ActionMgtException { - Assert.assertEquals(Action.Status.ACTIVE, action.getStatus()); - Action deactivatedAction = daoImpl.deactivateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), TENANT_ID); + Assert.assertEquals(Action.Status.ACTIVE, createdAction.getStatus()); + Action deactivatedAction = daoImpl.deactivateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), + TENANT_ID); Assert.assertEquals(Action.Status.INACTIVE, deactivatedAction.getStatus()); } - @Test(priority = 17) + @Test(priority = 15) public void testActivateAction() throws ActionMgtException { - Action result = daoImpl.activateAction(PRE_ISSUE_ACCESS_TOKEN, action.getId(), TENANT_ID); + Action result = daoImpl.activateAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, createdAction.getId(), TENANT_ID); Assert.assertEquals(Action.Status.ACTIVE, result.getStatus()); } - @Test(priority = 18) - public void testUpdateActionEndpoint() throws ActionMgtException { - - EndpointConfig endpointConfig = buildMockEndpointConfig("https://template.com", - buildMockBearerAuthentication("c7fce95f-3f5b-4cda-8bb1-4cb7b3990f83")); - Action result = daoImpl.updateActionEndpoint( - PRE_ISSUE_ACCESS_TOKEN, action.getId(), endpointConfig, action.getEndpoint() - .getAuthentication(), TENANT_ID); - Assert.assertNotEquals(action.getEndpoint().getUri(), result.getEndpoint().getUri()); - Assert.assertEquals(Authentication.Type.BEARER.getName(), - result.getEndpoint().getAuthentication().getType().getName()); - } - - @Test(priority = 19) + @Test(priority = 16) public void testGetActionsCountPerType() throws ActionMgtException { - Map actionMap = daoImpl.getActionsCountPerType(TENANT_ID); - for (Map.Entry entry: actionMap.entrySet()) { - Assert.assertEquals(PRE_ISSUE_ACCESS_TOKEN, entry.getKey()); - Assert.assertEquals(1, entry.getValue().intValue()); - } - } - - private Authentication buildMockBasicAuthentication(String username, String password) { - - return new Authentication.BasicAuthBuilder(username, password).build(); - } - - private Authentication buildMockBearerAuthentication(String accessToken) { - - return new Authentication.BearerAuthBuilder(accessToken).build(); - } - - private Authentication buildMockAPIKeyAuthentication(String header, String value) { - - return new Authentication.APIKeyAuthBuilder(header, value).build(); - } - - private EndpointConfig buildMockEndpointConfig(String uri, Authentication authentication) { - - if (uri == null && authentication == null) { - return null; - } - - return new EndpointConfig.EndpointConfigBuilder() - .uri(uri) - .authentication(authentication) - .build(); - } - - private Action buildMockAction(String name, - String description, - String uri, - Authentication authentication) { + PreUpdatePasswordAction actionModel = TestUtil.buildMockPreUpdatePasswordAction( + "PreUpdatePassword", + "To configure PreUpdatePassword", + "https://example.com", + TestUtil.buildMockBasicAuthentication("admin", "admin"), + PreUpdatePasswordAction.PasswordFormat.PLAIN_TEXT, + null); - return new Action.ActionRequestBuilder() - .name(name) - .description(description) - .endpoint(buildMockEndpointConfig(uri, authentication)) - .build(); + Action preUpdatePasswordAction = daoImpl.addAction(PRE_UPDATE_PASSWORD_TYPE, PRE_UPDATE_PASSWORD_ACTION_ID, + actionModel, TENANT_ID); + + Map actionMap = daoImpl.getActionsCountPerType(TENANT_ID); + Assert.assertTrue(actionMap.containsKey(PRE_ISSUE_ACCESS_TOKEN_TYPE)); + Assert.assertEquals(1, actionMap.get(PRE_ISSUE_ACCESS_TOKEN_TYPE).intValue()); + Assert.assertTrue(actionMap.containsKey(PRE_UPDATE_PASSWORD_TYPE)); + Assert.assertEquals(1, actionMap.get(PRE_UPDATE_PASSWORD_TYPE).intValue()); + + daoImpl.deleteAction(PRE_UPDATE_PASSWORD_TYPE, PRE_UPDATE_PASSWORD_ACTION_ID, preUpdatePasswordAction, + TENANT_ID); + daoImpl.deleteAction(PRE_ISSUE_ACCESS_TOKEN_TYPE, PRE_ISSUE_ACCESS_TOKEN_ACTION_ID, createdAction, TENANT_ID); } } diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/util/TestUtil.java b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/util/TestUtil.java new file mode 100644 index 000000000000..e1be2e3fd1cc --- /dev/null +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/java/org/wso2/carbon/identity/action/management/util/TestUtil.java @@ -0,0 +1,105 @@ +/* + * 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.action.management.util; + +import org.wso2.carbon.identity.action.management.model.Action; +import org.wso2.carbon.identity.action.management.model.Authentication; +import org.wso2.carbon.identity.action.management.model.EndpointConfig; +import org.wso2.carbon.identity.action.management.model.PreUpdatePasswordAction; +import org.wso2.carbon.identity.action.management.model.PreUpdatePasswordAction.PasswordFormat; +import org.wso2.carbon.identity.certificate.management.model.Certificate; + +import java.util.UUID; + +/** + * Utility class for Action Management Tests. + */ +public class TestUtil { + + public static final int TENANT_ID = 2; + public static final String TENANT_DOMAIN = "carbon.super"; + + public static final String PRE_ISSUE_ACCESS_TOKEN_TYPE = Action.ActionTypes.PRE_ISSUE_ACCESS_TOKEN.getActionType(); + public static final String PRE_UPDATE_PASSWORD_TYPE = Action.ActionTypes.PRE_UPDATE_PASSWORD.getActionType(); + + public static final String PRE_ISSUE_ACCESS_TOKEN_PATH = Action.ActionTypes.PRE_ISSUE_ACCESS_TOKEN.getPathParam(); + public static final String PRE_UPDATE_PASSWORD_PATH = Action.ActionTypes.PRE_UPDATE_PASSWORD.getPathParam(); + + public static final String PRE_ISSUE_ACCESS_TOKEN_ACTION_ID = String.valueOf(UUID.randomUUID()); + public static final String PRE_UPDATE_PASSWORD_ACTION_ID = String.valueOf(UUID.randomUUID()); + public static final String CERTIFICATE_ID = String.valueOf(UUID.randomUUID()); + public static final String CERTIFICATE_NAME = "ACTIONS:" + PRE_UPDATE_PASSWORD_ACTION_ID; + public static final String CERTIFICATE = "sample-certificate"; + public static final String UPDATED_CERTIFICATE = "updated-sample-certificate"; + + public static Action buildMockAction(String name, String description, String uri, Authentication authentication) { + + return new Action.ActionRequestBuilder() + .name(name) + .description(description) + .endpoint(buildMockEndpointConfig(uri, authentication)) + .build(); + } + + public static PreUpdatePasswordAction buildMockPreUpdatePasswordAction(String name, String description, String uri, + Authentication authentication, + PasswordFormat passwordSharingFormat, + String certificate) { + + return new PreUpdatePasswordAction.RequestBuilder() + .name(name) + .description(description) + .endpoint(buildMockEndpointConfig(uri, authentication)) + .passwordSharingFormat(passwordSharingFormat) + .certificate(new Certificate.Builder().certificateContent(certificate).build()) + .build(); + } + + public static Authentication buildMockBasicAuthentication(String username, String password) { + + return new Authentication.BasicAuthBuilder(username, password).build(); + } + + public static Authentication buildMockBearerAuthentication(String accessToken) { + + return new Authentication.BearerAuthBuilder(accessToken).build(); + } + + public static Authentication buildMockAPIKeyAuthentication(String header, String value) { + + return new Authentication.APIKeyAuthBuilder(header, value).build(); + } + + public static Authentication buildMockNoneAuthentication() { + + return new Authentication.NoneAuthBuilder().build(); + } + + private static EndpointConfig buildMockEndpointConfig(String uri, Authentication authentication) { + + if (uri == null && authentication == null) { + return null; + } + + return new EndpointConfig.EndpointConfigBuilder() + .uri(uri) + .authentication(authentication) + .build(); + } +} diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/dbscripts/h2.sql b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/dbscripts/h2.sql index 776921371a60..9bf8470be8e8 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/dbscripts/h2.sql +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/dbscripts/h2.sql @@ -8,7 +8,7 @@ CREATE TABLE IF NOT EXISTS IDN_ACTION ( PRIMARY KEY (UUID) ); -CREATE TABLE IF NOT EXISTS IDN_ACTION_ENDPOINT ( +CREATE TABLE IF NOT EXISTS IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, diff --git a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/testng.xml b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/testng.xml index 60acc4cb2749..cb1fe221091d 100644 --- a/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/testng.xml +++ b/components/action-mgt/org.wso2.carbon.identity.action.management/src/test/resources/testng.xml @@ -23,6 +23,7 @@ + diff --git a/components/secret-mgt/org.wso2.carbon.identity.secret.mgt.core/src/main/java/org/wso2/carbon/identity/secret/mgt/core/dao/impl/SecretDAOImpl.java b/components/secret-mgt/org.wso2.carbon.identity.secret.mgt.core/src/main/java/org/wso2/carbon/identity/secret/mgt/core/dao/impl/SecretDAOImpl.java index fe6adb91a790..f22352f0f108 100644 --- a/components/secret-mgt/org.wso2.carbon.identity.secret.mgt.core/src/main/java/org/wso2/carbon/identity/secret/mgt/core/dao/impl/SecretDAOImpl.java +++ b/components/secret-mgt/org.wso2.carbon.identity.secret.mgt.core/src/main/java/org/wso2/carbon/identity/secret/mgt/core/dao/impl/SecretDAOImpl.java @@ -212,12 +212,15 @@ public void deleteSecretByName(String name, String secretTypeId, int tenantId) t NamedJdbcTemplate jdbcTemplate = getNewTemplate(); try { - jdbcTemplate.executeUpdate(SQLConstants.DELETE_SECRET, preparedStatement -> { - preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SECRET_NAME, name); - preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_TYPE, secretTypeId); - preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, tenantId); + jdbcTemplate.withTransaction(template -> { + template.executeUpdate(SQLConstants.DELETE_SECRET, preparedStatement -> { + preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SECRET_NAME, name); + preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_TYPE, secretTypeId); + preparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, tenantId); + }); + return null; }); - } catch (DataAccessException e) { + } catch (TransactionException e) { throw handleServerException(ERROR_CODE_DELETE_SECRET, e); } } @@ -282,14 +285,17 @@ public Secret updateSecretValue(Secret secret, String value) throws SecretManage Timestamp currentTime = new java.sql.Timestamp(new Date().getTime()); NamedJdbcTemplate jdbcTemplate = getNewTemplate(); try { - jdbcTemplate.executeUpdate(UPDATE_SECRET_VALUE, preparedStatement -> { - preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ID, secret.getSecretId()); - preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SECRET_VALUE, value); - preparedStatement.setTimeStamp(DB_SCHEMA_COLUMN_NAME_LAST_MODIFIED, currentTime, calendar); + jdbcTemplate.withTransaction(template -> { + template.executeUpdate(UPDATE_SECRET_VALUE, preparedStatement -> { + preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ID, secret.getSecretId()); + preparedStatement.setString(DB_SCHEMA_COLUMN_NAME_SECRET_VALUE, value); + preparedStatement.setTimeStamp(DB_SCHEMA_COLUMN_NAME_LAST_MODIFIED, currentTime, calendar); + }); + return null; }); secret.setLastModified(currentTime.toInstant().toString()); secret.setSecretValue(value); - } catch (DataAccessException e) { + } catch (TransactionException e) { throw handleServerException(ERROR_CODE_UPDATE_SECRET, "value", e); } return secret; diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql index 99b5c560d56b..81f72be60ee2 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql @@ -2087,7 +2087,7 @@ CREATE TABLE IDN_ACTION ( PRIMARY KEY (UUID) ) / -CREATE TABLE IDN_ACTION_ENDPOINT ( +CREATE TABLE IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -2435,7 +2435,7 @@ CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); / -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID); / -- XACML -- diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql index 78602660830e..9b84806ad5af 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql @@ -1366,7 +1366,7 @@ CREATE TABLE IF NOT EXISTS IDN_ACTION ( PRIMARY KEY (UUID) ); -CREATE TABLE IF NOT EXISTS IDN_ACTION_ENDPOINT ( +CREATE TABLE IF NOT EXISTS IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -1609,7 +1609,7 @@ CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID); -- XACML -- CREATE INDEX IDX_POLICY_ATTRIBUTE ON IDN_XACML_POLICY_ATTRIBUTE (POLICY_ID, VERSION, TENANT_ID); CREATE INDEX IDX_POLICY_EDITOR_DATA_FK ON IDN_XACML_POLICY_EDITOR_DATA (POLICY_ID, VERSION, TENANT_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql index 983b4213cf58..e6a4feda92ac 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql @@ -1514,8 +1514,8 @@ CREATE TABLE IDN_ACTION ( PRIMARY KEY (UUID) ); -IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_ACTION_ENDPOINT]') AND TYPE in (N'U')) -CREATE TABLE IDN_ACTION_ENDPOINT ( +IF NOT EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[IDN_ACTION_PROPERTIES]') AND TYPE in (N'U')) +CREATE TABLE IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -1770,7 +1770,7 @@ CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID); -- XACML -- CREATE INDEX IDX_POLICY_ATTRIBUTE ON IDN_XACML_POLICY_ATTRIBUTE (POLICY_ID, VERSION, TENANT_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql index f79856f5220e..aa9ca6181f7e 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql @@ -1529,7 +1529,7 @@ CREATE TABLE IF NOT EXISTS IDN_ACTION ( PRIMARY KEY (UUID) )ENGINE NDB; -CREATE TABLE IF NOT EXISTS IDN_ACTION_ENDPOINT ( +CREATE TABLE IF NOT EXISTS IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -1801,7 +1801,7 @@ CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID); -- XACML -- CREATE INDEX IDX_POLICY_ATTRIBUTE ON IDN_XACML_POLICY_ATTRIBUTE (POLICY_ID, VERSION, TENANT_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql index 45642386c353..89319a62aa01 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql @@ -1397,7 +1397,7 @@ CREATE TABLE IF NOT EXISTS IDN_ACTION ( PRIMARY KEY (UUID) )DEFAULT CHARACTER SET latin1 ENGINE INNODB; -CREATE TABLE IF NOT EXISTS IDN_ACTION_ENDPOINT ( +CREATE TABLE IF NOT EXISTS IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -1637,7 +1637,7 @@ CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID); -- XACML -- CREATE INDEX IDX_POLICY_ATTRIBUTE ON IDN_XACML_POLICY_ATTRIBUTE (POLICY_ID, VERSION, TENANT_ID); diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql index 6ffa2eb13894..296fb4aa1874 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql @@ -2149,7 +2149,7 @@ CREATE TABLE IDN_ACTION ( PRIMARY KEY (UUID) ) / -CREATE TABLE IDN_ACTION_ENDPOINT ( +CREATE TABLE IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -2493,7 +2493,7 @@ CREATE INDEX IDX_CON_FILE_RES_ID ON IDN_CONFIG_FILE (RESOURCE_ID) -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID) / -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID) +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID) / -- XACML -- diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql index 5bc4ad184d76..343ff0139294 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql @@ -2082,7 +2082,7 @@ CREATE TABLE IDN_ACTION ( PRIMARY KEY (UUID) ) / -CREATE TABLE IDN_ACTION_ENDPOINT ( +CREATE TABLE IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -2398,7 +2398,7 @@ CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME) -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID) / -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID) +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID) / -- XACML -- diff --git a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql index 3ac7225cb2d0..b7fed4a41894 100644 --- a/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql +++ b/features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql @@ -1634,8 +1634,8 @@ CREATE TABLE IF NOT EXISTS IDN_ACTION ( PRIMARY KEY (UUID) ); -DROP TABLE IF EXISTS IDN_ACTION_ENDPOINT; -CREATE TABLE IF NOT EXISTS IDN_ACTION_ENDPOINT ( +DROP TABLE IF EXISTS IDN_ACTION_PROPERTIES; +CREATE TABLE IF NOT EXISTS IDN_ACTION_PROPERTIES ( ACTION_UUID CHAR(36) NOT NULL, PROPERTY_NAME VARCHAR(100) NOT NULL, PROPERTY_VALUE VARCHAR(255) NOT NULL, @@ -1898,7 +1898,7 @@ CREATE INDEX API_ID_NAME_INDEX ON SCOPE (API_ID, NAME); -- ACTIONS -- CREATE INDEX IDX_IDN_ACTION_TY_TI ON IDN_ACTION (TYPE, TENANT_ID); -CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_ENDPOINT (ACTION_UUID, TENANT_ID); +CREATE INDEX IDX_IDN_ACTION_ENDPOINT_AU_TI ON IDN_ACTION_PROPERTIES (ACTION_UUID, TENANT_ID); -- XACML -- CREATE INDEX IDX_POLICY_ATTRIBUTE ON IDN_XACML_POLICY_ATTRIBUTE (POLICY_ID, VERSION, TENANT_ID);