diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/pom.xml b/components/application-mgt/org.wso2.carbon.identity.application.common/pom.xml index 66b5699de624..69fb99b306c4 100644 --- a/components/application-mgt/org.wso2.carbon.identity.application.common/pom.xml +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/pom.xml @@ -61,6 +61,10 @@ org.wso2.carbon.identity.framework org.wso2.carbon.identity.central.log.mgt + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.action.management + diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/FederatedAuthenticatorConfig.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/FederatedAuthenticatorConfig.java index 7805ecfd177f..fe35e5aa8626 100644 --- a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/FederatedAuthenticatorConfig.java +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/FederatedAuthenticatorConfig.java @@ -67,6 +67,11 @@ public class FederatedAuthenticatorConfig implements Serializable { @XmlElement(name = "DefinedBy") protected DefinedByType definedByType; + public FederatedAuthenticatorConfig() { + + definedByType = DefinedByType.SYSTEM; + } + public static FederatedAuthenticatorConfig build(OMElement federatedAuthenticatorConfigOM) { if (federatedAuthenticatorConfigOM == null) { diff --git a/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/UserDefinedFederatedAuthenticatorConfig.java b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/UserDefinedFederatedAuthenticatorConfig.java new file mode 100644 index 000000000000..cfda30305971 --- /dev/null +++ b/components/application-mgt/org.wso2.carbon.identity.application.common/src/main/java/org/wso2/carbon/identity/application/common/model/UserDefinedFederatedAuthenticatorConfig.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.application.common.model; + +import org.wso2.carbon.identity.action.management.model.EndpointConfig; +import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.AuthenticationType; +import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType; + +/** + * Verification authenticator configuration. + */ +public class UserDefinedFederatedAuthenticatorConfig extends FederatedAuthenticatorConfig { + + private static final String TAG_2FA = "2FA"; + private static final String TAG_CUSTOM = "CUSTOM"; + + protected EndpointConfig endpointConfig; + + public UserDefinedFederatedAuthenticatorConfig(AuthenticationType type) { + + definedByType = DefinedByType.USER; + if (AuthenticationType.VERIFICATION == type) { + setTags(new String[]{TAG_CUSTOM, TAG_2FA}); + } else { + setTags(new String[]{TAG_CUSTOM}); + } + } + + /** + * Get the endpoint config of the Local authenticator config. + * + * @return DefinedByType + */ + public EndpointConfig getEndpointConfig() { + + return endpointConfig; + } + + /** + * Set the defined by type of the Local authenticator config. + * + * @param endpointConfig The endpoint config of the local authenticator config. + */ + public void setEndpointConfig(EndpointConfig endpointConfig) { + + this.endpointConfig = endpointConfig; + } +} diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java index a6ee6a7b45c2..64f2c590d6eb 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAO.java @@ -62,6 +62,7 @@ import org.wso2.carbon.idp.mgt.internal.IdpMgtServiceComponentHolder; import org.wso2.carbon.idp.mgt.model.ConnectedAppsResult; import org.wso2.carbon.idp.mgt.model.FilterQueryBuilder; +import org.wso2.carbon.idp.mgt.util.AuthenticatorEndpointConfigurationManager; import org.wso2.carbon.idp.mgt.util.IdPManagementConstants; import org.wso2.carbon.idp.mgt.util.IdPManagementUtil; import org.wso2.carbon.user.api.UserStoreException; @@ -106,6 +107,7 @@ import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.EMAIL_OTP_AUTHENTICATOR_NAME; import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.EMAIL_OTP_ONLY_NUMERIC_CHARS_PROPERTY; import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.EMAIL_OTP_USE_ALPHANUMERIC_CHARS_PROPERTY; +import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.ErrorMessage.ERROR_CODE_ASSOCIATED_ACTION_MGT; import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.ID; import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.IS_TRUSTED_TOKEN_ISSUER; import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.MySQL; @@ -125,6 +127,8 @@ public class IdPManagementDAO { private static final String OPENID_IDP_ENTITY_ID = "IdPEntityId"; private static final String ENABLE_SMS_OTP_IF_RECOVERY_NOTIFICATION_ENABLED = "OnDemandConfig.OnInitialUse.EnableSMSOTPPasswordRecoveryIfConnectorEnabled"; + private final AuthenticatorEndpointConfigurationManager endpointConfigurationManager = + new AuthenticatorEndpointConfigurationManager(); /** * @param dbConnection @@ -1116,7 +1120,7 @@ private void updateIdentityProviderProperties(Connection dbConnection, int idpId */ private FederatedAuthenticatorConfig[] getFederatedAuthenticatorConfigs( Connection dbConnection, String idPName, IdentityProvider federatedIdp, int tenantId) - throws IdentityProviderManagementClientException, SQLException { + throws IdentityProviderManagementClientException, SQLException, IdentityProviderManagementServerException { int idPId = getIdentityProviderIdentifier(dbConnection, idPName, tenantId); @@ -1138,7 +1142,9 @@ private FederatedAuthenticatorConfig[] getFederatedAuthenticatorConfigs( rs = prepStmt1.executeQuery(); while (rs.next()) { - FederatedAuthenticatorConfig authnConfig = new FederatedAuthenticatorConfig(); + FederatedAuthenticatorConfig authnConfig = endpointConfigurationManager + .createFederatedAuthenticatorConfig(DefinedByType.valueOf( + rs.getString("DEFINED_BY"))); int authnId = rs.getInt("ID"); authnConfig.setName(rs.getString("NAME")); @@ -1149,7 +1155,6 @@ private FederatedAuthenticatorConfig[] getFederatedAuthenticatorConfigs( } authnConfig.setDisplayName(rs.getString("DISPLAY_NAME")); - authnConfig.setDefinedByType(DefinedByType.valueOf(rs.getString("DEFINED_BY"))); if (defaultAuthName != null && authnConfig.getName().equals(defaultAuthName)) { federatedIdp.getDefaultAuthenticatorConfig().setDisplayName(authnConfig.getDisplayName()); @@ -1170,6 +1175,7 @@ private FederatedAuthenticatorConfig[] getFederatedAuthenticatorConfigs( properties.add(property); } authnConfig.setProperties(properties.toArray(new Property[properties.size()])); + endpointConfigurationManager.resolveEndpointConfigurations(authnConfig, tenantId); if (isEmailOTPAuthenticator(authnConfig.getName())) { // This is to support backward compatibility. @@ -1327,6 +1333,8 @@ private void updateFederatedAuthenticatorConfig(FederatedAuthenticatorConfig new PreparedStatement prepStmt1 = null; try { + endpointConfigurationManager.updateEndpointConfigurations(newFederatedAuthenticatorConfig, + oldFederatedAuthenticatorConfig, tenantId); String sqlStmt = IdPManagementConstants.SQLQueries.UPDATE_IDP_AUTH_SQL; prepStmt1 = dbConnection.prepareStatement(sqlStmt); @@ -1416,6 +1424,7 @@ public void addFederatedAuthenticatorConfig(FederatedAuthenticatorConfig authnCo String sqlStmt = IdPManagementConstants.SQLQueries.ADD_IDP_AUTH_SQL; try { + endpointConfigurationManager.addEndpointConfigurations(authnConfig, tenantId); prepStmt1 = dbConnection.prepareStatement(sqlStmt); prepStmt1.setInt(1, idpId); prepStmt1.setInt(2, tenantId); @@ -1461,6 +1470,7 @@ private void deleteFederatedAuthenticatorConfig(FederatedAuthenticatorConfig aut Connection dbConnection, int idpId, int tenantId) throws IdentityProviderManagementException, SQLException { + endpointConfigurationManager.deleteEndpointConfigurations(authnConfig, tenantId); try (PreparedStatement prepStmt = dbConnection.prepareStatement(IdPManagementConstants.SQLQueries .DELETE_IDP_AUTH_SQL)) { prepStmt.setInt(1, idpId); @@ -3981,9 +3991,17 @@ public String addIdPWithResourceId(IdentityProvider identityProvider, int tenant throw new IdentityProviderManagementException("An error occurred while processing content stream.", e); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); + endpointConfigurationManager.deleteEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); throw new IdentityProviderManagementException("Error occurred while adding Identity Provider for tenant " + tenantId, e); - } catch (ConnectorException e) { + } catch (IdentityProviderManagementException e) { + if (ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode().equals(e.getErrorCode())) { + IdentityDatabaseUtil.rollbackTransaction(dbConnection);; + } + throw e; + } + catch (ConnectorException e) { throw new IdentityProviderManagementException("An error occurred while filtering IDP properties.", e); } catch (SecretManagementException e) { throw new IdentityProviderManagementException("An error occurred while storing encrypted IDP secrets of " + @@ -4310,8 +4328,15 @@ public void updateIdPWithResourceId(String resourceId, IdentityProvider throw new IdentityProviderManagementException("An error occurred while processing content stream.", e); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); + endpointConfigurationManager.updateEndpointConfigurations(currentIdentityProvider + .getDefaultAuthenticatorConfig(), newIdentityProvider.getDefaultAuthenticatorConfig(), tenantId); throw new IdentityProviderManagementException("Error occurred while updating Identity Provider " + "information for tenant " + tenantId, e); + } catch (IdentityProviderManagementException e) { + if (ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode().equals(e.getErrorCode())) { + IdentityDatabaseUtil.rollbackTransaction(dbConnection);; + } + throw e; } catch (ConnectorException e) { throw new IdentityProviderManagementException("An error occurred while filtering IDP properties.", e); } catch (SecretManagementException e) { @@ -4374,19 +4399,29 @@ public void deleteIdP(String idPName, int tenantId, String tenantDomain) throws IdentityProviderManagementException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); + IdentityProvider identityProvider = null; try { - IdentityProvider identityProvider = getIdPByName(dbConnection, idPName, tenantId, + identityProvider = getIdPByName(dbConnection, idPName, tenantId, tenantDomain); if (identityProvider == null) { String msg = "Trying to delete non-existent Identity Provider: %s in tenantDomain: %s"; throw new IdentityProviderManagementException(String.format(msg, idPName, tenantDomain)); } + endpointConfigurationManager.deleteEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); deleteIdP(dbConnection, tenantId, idPName, null); IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); + endpointConfigurationManager.addEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); throw new IdentityProviderManagementException("Error occurred while deleting Identity Provider of tenant " + tenantDomain, e); + } catch (IdentityProviderManagementException e) { + if (ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode().equals(e.getErrorCode())) { + IdentityDatabaseUtil.rollbackTransaction(dbConnection);; + } + throw e; } finally { IdentityDatabaseUtil.closeConnection(dbConnection); } @@ -4405,6 +4440,7 @@ public void deleteIdPs(int tenantId) throws IdentityProviderManagementException IdPManagementConstants.SQLQueries.DELETE_ALL_IDP_BY_TENANT_ID_SQL); prepStmt.setInt(1, tenantId); prepStmt.executeUpdate(); + } catch (SQLException e) { throw new IdentityProviderManagementException("Error occurred while deleting Identity Providers of tenant " + tenantId, e); @@ -4422,14 +4458,17 @@ public void deleteIdPByResourceId(String resourceId, int tenantId, String tenant Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); String idPName = ""; + IdentityProvider identityProvider = null; try { - IdentityProvider identityProvider = getIDPbyResourceId(dbConnection, resourceId, tenantId, + identityProvider = getIDPbyResourceId(dbConnection, resourceId, tenantId, tenantDomain); if (identityProvider == null) { String msg = "Trying to delete non-existent Identity Provider with resource ID: %s in tenantDomain: %s"; throw new IdentityProviderManagementException(String.format(msg, resourceId, tenantDomain)); } idPName = identityProvider.getIdentityProviderName(); + endpointConfigurationManager.deleteEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); deleteIdP(dbConnection, tenantId, null, resourceId); // Delete IdP related secrets from the IDN_SECRET table. if (IdpMgtServiceComponentHolder.getInstance().getIdPSecretsProcessorService() != null) { @@ -4441,8 +4480,15 @@ public void deleteIdPByResourceId(String resourceId, int tenantId, String tenant IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); + endpointConfigurationManager.addEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); throw new IdentityProviderManagementException("Error occurred while deleting Identity Provider of tenant " + tenantDomain, e); + } catch (IdentityProviderManagementException e) { + if (ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode().equals(e.getErrorCode())) { + IdentityDatabaseUtil.rollbackTransaction(dbConnection);; + } + throw e; } catch (SecretManagementException e) { throw new IdentityProviderManagementException("Error while deleting IDP secrets of Identity provider : " + idPName + " in tenant : " + tenantDomain, e); @@ -4456,8 +4502,9 @@ public void forceDeleteIdP(String idPName, String tenantDomain) throws IdentityProviderManagementException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); + IdentityProvider identityProvider = null; try { - IdentityProvider identityProvider = getIdPByName(dbConnection, idPName, tenantId, tenantDomain); + identityProvider = getIdPByName(dbConnection, idPName, tenantId, tenantDomain); if (identityProvider == null) { String msg = "Trying to force delete non-existent Identity Provider: %s in tenantDomain: %s"; throw new IdentityProviderManagementException(String.format(msg, idPName, tenantDomain)); @@ -4473,14 +4520,23 @@ public void forceDeleteIdP(String idPName, log.debug(String.format("Deleting SP Provisioning Associations for IDP:%s of tenantDomain:%s", idPName, tenantDomain)); } + endpointConfigurationManager.deleteEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); deleteIdpSpProvisioningAssociations(dbConnection, tenantId, idPName); deleteIdP(dbConnection, tenantId, idPName, null); IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); + endpointConfigurationManager.addEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); throw new IdentityProviderManagementException( String.format("Error occurred while deleting Identity Provider:%s of tenant:%s ", idPName, tenantDomain), e); + } catch (IdentityProviderManagementException e) { + if (ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode().equals(e.getErrorCode())) { + IdentityDatabaseUtil.rollbackTransaction(dbConnection);; + } + throw e; } finally { IdentityDatabaseUtil.closeConnection(dbConnection); } @@ -4490,8 +4546,9 @@ public void forceDeleteIdPByResourceId(String resourceId, int tenantId, String t IdentityProviderManagementException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); + IdentityProvider identityProvider = null; try { - IdentityProvider identityProvider = getIDPbyResourceId(dbConnection, resourceId, tenantId, + identityProvider = getIDPbyResourceId(dbConnection, resourceId, tenantId, tenantDomain); if (identityProvider == null) { String msg = "Trying to force delete non-existent Identity Provider with resource ID: %s in " + @@ -4510,13 +4567,22 @@ public void forceDeleteIdPByResourceId(String resourceId, int tenantId, String t identityProvider.getIdentityProviderName(), tenantDomain)); } deleteIdpSpProvisioningAssociations(dbConnection, tenantId, identityProvider.getIdentityProviderName()); + endpointConfigurationManager.deleteEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); deleteIdP(dbConnection, tenantId, null, resourceId); IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); + endpointConfigurationManager.addEndpointConfigurations(identityProvider.getDefaultAuthenticatorConfig(), + tenantId); throw new IdentityProviderManagementException( String.format("Error occurred while deleting Identity Provider with resource ID:%s of tenant:%s ", resourceId, tenantDomain), e); + } catch (IdentityProviderManagementException e) { + if (ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode().equals(e.getErrorCode())) { + IdentityDatabaseUtil.rollbackTransaction(dbConnection);; + } + throw e; } finally { IdentityDatabaseUtil.closeConnection(dbConnection); } diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdPManagementServiceComponent.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdPManagementServiceComponent.java index 585feda6e5ae..2f59b269b7cf 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdPManagementServiceComponent.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdPManagementServiceComponent.java @@ -33,6 +33,7 @@ import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicy; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.identity.action.management.ActionManagementService; import org.wso2.carbon.identity.application.common.model.IdentityProvider; import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService; @@ -490,4 +491,21 @@ protected void unsetClaimMetaMgtService(ClaimMetadataManagementService claimMeta IdpMgtServiceComponentHolder.getInstance().setClaimMetadataManagementService(null); } + + @Reference( + name = "action.management.service", + service = ActionManagementService.class, + cardinality = ReferenceCardinality.MANDATORY, + policy = ReferencePolicy.DYNAMIC, + unbind = "unsetActionManagementService" + ) + protected void setActionManagementService(ActionManagementService actionManagementService) { + + IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); + } + + protected void unsetActionManagementService(ActionManagementService actionManagementService) { + + IdpMgtServiceComponentHolder.getInstance().setActionManagementService(null); + } } diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdpMgtServiceComponentHolder.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdpMgtServiceComponentHolder.java index 3fc4ca4135a4..8dda2fb98351 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdpMgtServiceComponentHolder.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/internal/IdpMgtServiceComponentHolder.java @@ -19,6 +19,7 @@ package org.wso2.carbon.idp.mgt.internal; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.identity.action.management.ActionManagementService; import org.wso2.carbon.identity.application.common.model.IdentityProvider; import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService; @@ -53,7 +54,6 @@ public static IdpMgtServiceComponentHolder getInstance() { private volatile List identityConnectorConfigList = new ArrayList<>(); private RoleManagementService roleManagementService; private ClaimMetadataManagementService claimMetadataManagementService; - private SecretsProcessor idpSecretsProcessorService; private List metadataConverters = new ArrayList<>(); @@ -155,4 +155,14 @@ public void setClaimMetadataManagementService(ClaimMetadataManagementService cla this.claimMetadataManagementService = claimMetadataManagementService; } + + public ActionManagementService getActionManagementService() { + + return actionManagementService; + } + + public void setActionManagementService(ActionManagementService actionManagementService) { + + this.actionManagementService = actionManagementService; + } } diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/AuthenticatorEndpointConfigurationManager.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/AuthenticatorEndpointConfigurationManager.java new file mode 100644 index 000000000000..7312896e6ff5 --- /dev/null +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/AuthenticatorEndpointConfigurationManager.java @@ -0,0 +1,196 @@ +/* + * 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.idp.mgt.util; + +import org.wso2.carbon.identity.action.management.ActionManagementService; +import org.wso2.carbon.identity.action.management.exception.ActionMgtException; +import org.wso2.carbon.identity.action.management.model.Action; +import org.wso2.carbon.identity.action.management.model.EndpointConfig; +import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig; +import org.wso2.carbon.identity.application.common.model.Property; +import org.wso2.carbon.identity.application.common.model.UserDefinedFederatedAuthenticatorConfig; +import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants; +import org.wso2.carbon.identity.core.util.IdentityTenantUtil; +import org.wso2.carbon.idp.mgt.IdentityProviderManagementServerException; +import org.wso2.carbon.idp.mgt.internal.IdpMgtServiceComponentHolder; + +import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.ErrorMessage.ERROR_CODE_ASSOCIATED_ACTION_MGT; + +/** + * This class responsible for managing authenticator endpoint configurations as the actions associated. + */ +public class AuthenticatorEndpointConfigurationManager { + + private final String ACTION_ID_PROPERTY = "actionId"; + + /** + * Create a new action for given endpoint configurations of the user defined authenticator. + * + * @param config The federated application authenticator configuration. + * @param tenantId The id of Tenant domain. + * + * @throws IdentityProviderManagementServerException If an error occurs while adding the action. + */ + public void addEndpointConfigurations(FederatedAuthenticatorConfig config, int tenantId) + throws IdentityProviderManagementServerException { + + if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { + return; + } + + try { + UserDefinedFederatedAuthenticatorConfig castedConfig = (UserDefinedFederatedAuthenticatorConfig) config; + Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService().addAction(Action.ActionTypes.AUTHENTICATION.toString(), + buildActionToCreate(castedConfig.getName(), castedConfig.getEndpointConfig()), + IdentityTenantUtil.getTenantDomain(tenantId)); + Property endpointProperty = new Property(); + endpointProperty.setName(ACTION_ID_PROPERTY); + endpointProperty.setValue(action.getId()); + config.setProperties(new Property[]{endpointProperty}); + } catch (ActionMgtException e) { + throw new IdentityProviderManagementServerException(ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode(), + "Error occurred while adding associated action for the authenticator:" + config.getName(), e); + } + } + + /** + * Updated associated action for given updated endpoint configurations of the user defined authenticator. + * + * @param newConfig The federated application authenticator configuration to be updated. + * @param oldConfig The current federated application authenticator configuration. + * @param tenantId The id of Tenant domain. + * + * @throws IdentityProviderManagementServerException If an error occurs while updating associated action. + */ + public void updateEndpointConfigurations(FederatedAuthenticatorConfig newConfig, FederatedAuthenticatorConfig oldConfig, + int tenantId) throws IdentityProviderManagementServerException { + + if (oldConfig.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { + return; + } + + String actionId = getActionIdFromProperty(oldConfig.getProperties()); + try { + UserDefinedFederatedAuthenticatorConfig castedConfig = (UserDefinedFederatedAuthenticatorConfig) newConfig; + IdpMgtServiceComponentHolder.getInstance().getActionManagementService().updateAction( + Action.ActionTypes.AUTHENTICATION.toString(), actionId, buildActionToUpdate( + castedConfig.getEndpointConfig()), IdentityTenantUtil.getTenantDomain(tenantId)); + } catch (ActionMgtException e) { + throw new IdentityProviderManagementServerException(ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode(), + String.format("Error occurred while updating associated action with id %s for the authenticator %s", + actionId, oldConfig.getName()), e); + } + } + + /** + * Retrieve associated action of the user defined authenticator. + * + * @param config The federated application authenticator configuration. + * @param tenantId The id of Tenant domain. + * + * @throws IdentityProviderManagementServerException If an error occurs retrieving updating associated action. + */ + public FederatedAuthenticatorConfig resolveEndpointConfigurations(FederatedAuthenticatorConfig config, + int tenantId) throws IdentityProviderManagementServerException { + + if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { + return config; + } + + String actionId = getActionIdFromProperty(config.getProperties()); + try { + UserDefinedFederatedAuthenticatorConfig castedConfig = (UserDefinedFederatedAuthenticatorConfig) config; + Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService() + .getActionByActionId(Action.ActionTypes.AUTHENTICATION.toString(), + actionId, IdentityTenantUtil.getTenantDomain(tenantId)); + castedConfig.setEndpointConfig(action.getEndpoint()); + return castedConfig; + } catch (ActionMgtException e) { + throw new IdentityProviderManagementServerException(ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode(), + String.format("Error occurred retrieving associated action with id %s for the authenticator %s", + actionId, config.getName()), e); + } + } + + /** + * Delete associated action of the user defined authenticator. + * + * @param config The federated application authenticator configuration. + * @param tenantId The id of Tenant domain. + * + * @throws IdentityProviderManagementServerException If an error occurs while deleting associated action. + */ + public void deleteEndpointConfigurations(FederatedAuthenticatorConfig config, int tenantId) throws + IdentityProviderManagementServerException { + + if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { + return; + } + + String actionId = getActionIdFromProperty(config.getProperties()); + try { + IdpMgtServiceComponentHolder.getInstance().getActionManagementService().deleteAction( + Action.ActionTypes.AUTHENTICATION.toString(), actionId, + IdentityTenantUtil.getTenantDomain(tenantId)); + } catch (ActionMgtException e) { + throw new IdentityProviderManagementServerException(ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode(), + String.format("Error occurred while deleting associated action with id %s for the authenticator %s", + actionId, config.getName()), e); + } + } + + public FederatedAuthenticatorConfig createFederatedAuthenticatorConfig(AuthenticatorPropertyConstants.DefinedByType + definedByType) { + + if (definedByType == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { + return new FederatedAuthenticatorConfig(); + } + + return new UserDefinedFederatedAuthenticatorConfig( + AuthenticatorPropertyConstants.AuthenticationType.Identification); + } + + private Action buildActionToCreate(String authenticatorName, EndpointConfig endpointConfig) { + + Action.ActionRequestBuilder actionRequestBuilder = new Action.ActionRequestBuilder(); + actionRequestBuilder.name(authenticatorName); + actionRequestBuilder.description(String.format("This is the action associated to the user defined federated" + + "authenticator %s.", authenticatorName)); + actionRequestBuilder.endpoint(endpointConfig); + + return actionRequestBuilder.build(); + } + + private Action buildActionToUpdate(EndpointConfig endpointConfig) { + + Action.ActionRequestBuilder actionRequestBuilder = new Action.ActionRequestBuilder(); + actionRequestBuilder.endpoint(endpointConfig); + + return actionRequestBuilder.build(); + } + + private String getActionIdFromProperty(Property[] properties) throws IdentityProviderManagementServerException { + for (Property property : properties) { + if (ACTION_ID_PROPERTY.equals(property.getName())) { + return property.getValue(); + } + } + throw new IdentityProviderManagementServerException(String.format("No action id found from the property.")); + } +} diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java index 2d48f381b0c2..65c73029b7d1 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/IdPManagementConstants.java @@ -618,7 +618,8 @@ public enum ErrorMessage { "applications of Identity Provider with resource ID: %s."), ERROR_CODE_VALIDATING_OUTBOUND_PROVISIONING_ROLES("IDP-65008", "Error while validating " + "the outbound provisioning roles"), - ERROR_CODE_RETRIEVING_IDP_GROUPS("IDP-65009", "Error while retrieving IDP groups"); + ERROR_CODE_RETRIEVING_IDP_GROUPS("IDP-65009", "Error while retrieving IDP groups"), + ERROR_CODE_ASSOCIATED_ACTION_MGT("IDP-65010", "Error occurred with associated action management."),; private final String code; private final String message;