diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java index 9dbcdea2f0b1..3f03f684bd44 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/IdentityProviderManager.java @@ -62,6 +62,7 @@ import org.wso2.carbon.idp.mgt.util.IdPManagementConstants; import org.wso2.carbon.idp.mgt.util.IdPManagementUtil; import org.wso2.carbon.idp.mgt.util.MetadataConverter; +import org.wso2.carbon.idp.mgt.util.UserDefinedAuthenticatorEndpointConfigManager; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.UserCoreConstants; @@ -99,6 +100,8 @@ public class IdentityProviderManager implements IdpManager { private static volatile IdentityProviderManager instance = new IdentityProviderManager(); private final Pattern userDefinedAuthNameRegexPattern = Pattern.compile(IdPManagementConstants.USER_DEFINED_AUTHENTICATOR_NAME_REGEX); + private final UserDefinedAuthenticatorEndpointConfigManager endpointConfigurationManager = + new UserDefinedAuthenticatorEndpointConfigManager(); private IdentityProviderManager() { @@ -832,6 +835,7 @@ public IdentityProvider getIdPByName(String idPName, String tenantDomain, IdentityApplicationConstants.DEFAULT_IDP_CONFIG); } } + populateEndpointConfig(identityProvider, tenantDomain); return identityProvider; } @@ -865,6 +869,7 @@ public IdentityProvider getIdPById(String id, String tenantDomain, IdentityApplicationConstants.DEFAULT_IDP_CONFIG); } } + populateEndpointConfig(identityProvider, tenantDomain); return identityProvider; } @@ -876,6 +881,7 @@ public IdentityProvider getIdPByResourceId(String resourceId, String tenantDomai validateGetIdPInputValues(resourceId); int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); IdentityProvider identityProvider = dao.getIdPByResourceId(resourceId, tenantId, tenantDomain); + populateEndpointConfig(identityProvider, tenantDomain); if (identityProvider == null) { identityProvider = new FileBasedIdPMgtDAO().getIdPByResourceId(resourceId, tenantDomain); if (identityProvider == null) { @@ -920,6 +926,7 @@ public IdentityProvider getEnabledIdPByName(String idPName, String tenantDomain, throws IdentityProviderManagementException { IdentityProvider idp = getIdPByName(idPName, tenantDomain, ignoreFileBasedIdps); + populateEndpointConfig(idp, tenantDomain); if (idp != null && idp.isEnable()) { return idp; } @@ -970,6 +977,7 @@ public IdentityProvider getIdPByAuthenticatorPropertyValue(String property, Stri IdentityProvider identityProvider = dao.getIdPByAuthenticatorPropertyValue( null, property, value, tenantId, tenantDomain); + populateEndpointConfig(identityProvider, tenantDomain); if (identityProvider == null && !ignoreFileBasedIdps) { identityProvider = new FileBasedIdPMgtDAO() @@ -1001,6 +1009,7 @@ public IdentityProvider getIdPByAuthenticatorPropertyValue(String property, Stri IdentityProvider identityProvider = dao.getIdPByAuthenticatorPropertyValue( null, property, value, authenticator, tenantId, tenantDomain); + populateEndpointConfig(identityProvider, tenantDomain); if (identityProvider == null && !ignoreFileBasedIdps) { identityProvider = new FileBasedIdPMgtDAO() @@ -1531,8 +1540,18 @@ public IdentityProvider addIdPWithResourceId(IdentityProvider identityProvider, handleMetadata(tenantId, identityProvider); resolveAuthenticatorDefinedByProperty(identityProvider, true); - String resourceId = dao.addIdP(identityProvider, tenantId, tenantDomain); + + String resourceId; + addEndpointConfig(identityProvider, tenantDomain); + try { + resourceId = dao.addIdP(identityProvider, tenantId, tenantDomain); + } catch (IdentityProviderManagementException e) { + deleteEndpointConfig(identityProvider, tenantDomain); + throw e; + } + identityProvider = dao.getIdPByResourceId(resourceId, tenantId, tenantDomain); + populateEndpointConfig(identityProvider, tenantDomain); // invoking the post listeners for (IdentityProviderMgtListener listener : listeners) { @@ -1593,7 +1612,7 @@ public void deleteIdP(String idPName, String tenantDomain) throws IdentityProvid if (identityProvider == null) { return; } - deleteIDP(identityProvider.getResourceId(), idPName, tenantDomain); + deleteIDP(identityProvider, tenantDomain); // Invoking the post listeners. for (IdentityProviderMgtListener listener : listeners) { @@ -1659,7 +1678,7 @@ public void deleteIdPByResourceId(String resourceId, String tenantDomain) throws if (identityProvider == null) { return; } - deleteIDP(resourceId, identityProvider.getIdentityProviderName(), tenantDomain); + deleteIDP(identityProvider, tenantDomain); // Invoking the post listeners. for (IdentityProviderMgtListener listener : listeners) { @@ -1689,20 +1708,27 @@ private void deleteMetadataStrings(String idpName, int tenantId) throws Identity /** * Delete an IDP. * - * @param resourceId Resource Id - * @param idpName Name of the IDP + * @param identityProvider Identity Provider * @param tenantDomain Tenant Domain * @throws IdentityProviderManagementException */ - private void deleteIDP(String resourceId, String idpName, String tenantDomain) throws + private void deleteIDP(IdentityProvider identityProvider, String tenantDomain) throws IdentityProviderManagementException { int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); // Delete metadata strings of the IDP - deleteMetadataStrings(idpName, tenantId); + deleteMetadataStrings(identityProvider.getIdentityProviderName(), tenantId); + + deleteEndpointConfig(identityProvider, tenantDomain); + + try { + dao.deleteIdPByResourceId(identityProvider.getResourceId(), tenantId, tenantDomain); + } catch (IdentityProviderManagementException e) { + addEndpointConfig(identityProvider, tenantDomain); + throw e; + } - dao.deleteIdPByResourceId(resourceId, tenantId, tenantDomain); } /** @@ -1730,7 +1756,7 @@ public void forceDeleteIdp(String idpName, String tenantDomain) throws IdentityP throw IdPManagementUtil.handleClientException(IdPManagementConstants.ErrorMessage .ERROR_CODE_IDP_NAME_DOES_NOT_EXIST, idpName); } - forceDeleteIDP(identityProvider.getResourceId(), idpName, tenantDomain); + forceDeleteIDP(identityProvider, tenantDomain); // Invoking the post listeners. for (IdentityProviderMgtListener listener : listeners) { @@ -1763,7 +1789,7 @@ public void forceDeleteIdpByResourceId(String resourceId, String tenantDomain) t throw IdPManagementUtil.handleClientException(IdPManagementConstants.ErrorMessage .ERROR_CODE_IDP_DOES_NOT_EXIST, resourceId); } - forceDeleteIDP(resourceId, identityProvider.getIdentityProviderName(), tenantDomain); + forceDeleteIDP(identityProvider, tenantDomain); // Invoking the post listeners for (IdentityProviderMgtListener listener : listeners) { @@ -1774,17 +1800,23 @@ public void forceDeleteIdpByResourceId(String resourceId, String tenantDomain) t } } - private void forceDeleteIDP(String resourceId, String idpName, String tenantDomain) throws + private void forceDeleteIDP(IdentityProvider identityProvider, String tenantDomain) throws IdentityProviderManagementException { int tenantId = IdentityTenantUtil.getTenantId(tenantDomain); for (MetadataConverter metadataConverter : IdpMgtServiceComponentHolder.getInstance().getMetadataConverters()) { - if (metadataConverter.canDelete(tenantId, idpName)) { - metadataConverter.deleteMetadataString(tenantId, idpName); + if (metadataConverter.canDelete(tenantId, identityProvider.getIdentityProviderName())) { + metadataConverter.deleteMetadataString(tenantId, identityProvider.getIdentityProviderName()); } } - dao.forceDeleteIdPByResourceId(resourceId, tenantId, tenantDomain); + deleteEndpointConfig(identityProvider, tenantDomain); + try { + dao.forceDeleteIdPByResourceId(identityProvider.getResourceId(), tenantId, tenantDomain); + } catch (IdentityProviderManagementException e) { + addEndpointConfig(identityProvider, tenantDomain); + throw e; + } } /** @@ -1855,7 +1887,6 @@ public IdentityProvider updateIdPByResourceId(String resourceId, IdentityProvide newIdentityProvider.setTrustedTokenIssuer(isTrustedTokenIssuer(newIdentityProvider)); validateUpdateIdPInputValues(currentIdentityProvider, resourceId, newIdentityProvider, tenantDomain); - validateFederatedAuthenticatorConfigName(newIdentityProvider.getFederatedAuthenticatorConfigs(), tenantDomain); updateIDP(currentIdentityProvider, newIdentityProvider, tenantId, tenantDomain); // Invoking the post listeners. @@ -1865,7 +1896,9 @@ public IdentityProvider updateIdPByResourceId(String resourceId, IdentityProvide return null; } } - return dao.getUpdatedIdPByResourceId(resourceId, tenantId, tenantDomain); + IdentityProvider identityProvider = dao.getUpdatedIdPByResourceId(resourceId, tenantId, tenantDomain); + populateEndpointConfig(identityProvider, tenantDomain); + return identityProvider; } private void updateIDP(IdentityProvider currentIdentityProvider, IdentityProvider newIdentityProvider, int tenantId, @@ -1882,7 +1915,14 @@ private void updateIDP(IdentityProvider currentIdentityProvider, IdentityProvide validateIdPIssuerName(currentIdentityProvider, newIdentityProvider, tenantId, tenantDomain); handleMetadata(tenantId, newIdentityProvider); resolveAuthenticatorDefinedByProperty(newIdentityProvider, false); - dao.updateIdP(newIdentityProvider, currentIdentityProvider, tenantId, tenantDomain); + updateEndpointConfig(newIdentityProvider, currentIdentityProvider, tenantDomain); + try { + dao.updateIdP(newIdentityProvider, currentIdentityProvider, tenantId, tenantDomain); + } catch (IdentityProviderManagementException e) { + updateEndpointConfig(currentIdentityProvider, newIdentityProvider, tenantDomain); + throw e; + } + } /** @@ -2663,6 +2703,9 @@ private Map> createFedAuthConfidentialPropsMap() throws Ide Map> metaFedAuthConfigMap = new HashMap<>(); FederatedAuthenticatorConfig[] metaFedAuthConfigs = getAllFederatedAuthenticators(); for (FederatedAuthenticatorConfig metaFedAuthConfig : metaFedAuthConfigs) { + if (metaFedAuthConfig.getDefinedByType() == DefinedByType.USER) { + continue; + } List secretProperties = new ArrayList<>(); for (Property property : metaFedAuthConfig.getProperties()) { if (property.isConfidential()) { @@ -2745,4 +2788,46 @@ private void resolveAuthenticatorDefinedByProperty(IdentityProvider idp, boolean } } } + + private void populateEndpointConfig(IdentityProvider identityProvider, String tenantDomain) + throws AuthenticatorEndpointConfigServerException { + + if (identityProvider == null || identityProvider.getFederatedAuthenticatorConfigs().length == 0) { + return; + } + endpointConfigurationManager.resolveEndpointConfig(identityProvider.getFederatedAuthenticatorConfigs()[0], + tenantDomain); + } + + private void addEndpointConfig(IdentityProvider identityProvider, String tenantDomain) + throws AuthenticatorEndpointConfigServerException { + + if (identityProvider == null || identityProvider.getFederatedAuthenticatorConfigs().length == 0) { + return; + } + endpointConfigurationManager.addEndpointConfig(identityProvider.getFederatedAuthenticatorConfigs()[0], + tenantDomain); + } + + private void updateEndpointConfig(IdentityProvider newIdentityProvider, IdentityProvider oldIdentityProvider, + String tenantDomain) + throws AuthenticatorEndpointConfigServerException { + + if (newIdentityProvider == null || newIdentityProvider.getFederatedAuthenticatorConfigs().length == 0) { + return; + } + endpointConfigurationManager.updateEndpointConfig(newIdentityProvider.getFederatedAuthenticatorConfigs()[0], + oldIdentityProvider.getFederatedAuthenticatorConfigs()[0], + tenantDomain); + } + + private void deleteEndpointConfig(IdentityProvider identityProvider, String tenantDomain) + throws AuthenticatorEndpointConfigServerException { + + if (identityProvider == null || identityProvider.getFederatedAuthenticatorConfigs().length == 0) { + return; + } + endpointConfigurationManager.deleteEndpointConfig(identityProvider.getFederatedAuthenticatorConfigs()[0], + tenantDomain); + } } 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 fc92d36ff5c4..132198d00a2c 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 @@ -58,7 +58,6 @@ import org.wso2.carbon.identity.core.util.IdentityTenantUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.secret.mgt.core.exception.SecretManagementException; -import org.wso2.carbon.idp.mgt.AuthenticatorEndpointConfigServerException; import org.wso2.carbon.idp.mgt.IdentityProviderManagementClientException; import org.wso2.carbon.idp.mgt.IdentityProviderManagementException; import org.wso2.carbon.idp.mgt.IdentityProviderManagementServerException; @@ -66,7 +65,6 @@ 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.UserDefinedAuthenticatorEndpointConfigManager; import org.wso2.carbon.idp.mgt.util.IdPManagementConstants; import org.wso2.carbon.idp.mgt.util.IdPManagementUtil; import org.wso2.carbon.idp.mgt.util.IdPSecretsProcessor; @@ -135,8 +133,6 @@ public class IdPManagementDAO { = "OnDemandConfig.OnInitialUse.EnableSMSOTPPasswordRecoveryIfConnectorEnabled"; private static final String ENABLE_SMS_USERNAME_RECOVERY_IF_CONNECTOR_ENABLED = "OnDemandConfig.OnInitialUse.EnableSMSUsernameRecoveryIfConnectorEnabled"; - private final UserDefinedAuthenticatorEndpointConfigManager endpointConfigurationManager = - new UserDefinedAuthenticatorEndpointConfigManager(); /** * @param dbConnection @@ -1145,7 +1141,7 @@ private void updateIdentityProviderProperties(Connection dbConnection, int idpId */ private FederatedAuthenticatorConfig[] getFederatedAuthenticatorConfigs( Connection dbConnection, String idPName, IdentityProvider federatedIdp, int tenantId) - throws SQLException, IdentityProviderManagementException { + throws IdentityProviderManagementClientException, SQLException { int idPId = getIdentityProviderIdentifier(dbConnection, idPName, tenantId); @@ -1199,7 +1195,6 @@ private FederatedAuthenticatorConfig[] getFederatedAuthenticatorConfigs( properties.add(property); } authnConfig.setProperties(properties.toArray(new Property[properties.size()])); - endpointConfigurationManager.resolveEndpointConfig(authnConfig, tenantId); if (isEmailOTPAuthenticator(authnConfig.getName())) { // This is to support backward compatibility. @@ -1371,8 +1366,6 @@ private void updateFederatedAuthenticatorConfig(FederatedAuthenticatorConfig new int authnId = getAuthenticatorIdentifier(dbConnection, idpId, newFederatedAuthenticatorConfig.getName()); - endpointConfigurationManager.updateEndpointConfig(newFederatedAuthenticatorConfig, - oldFederatedAuthenticatorConfig, tenantId); List unUpdatedProperties = new ArrayList<>(); List singleValuedProperties = new ArrayList<>(); @@ -1465,7 +1458,6 @@ public void addFederatedAuthenticatorConfig(FederatedAuthenticatorConfig authnCo prepStmt1.execute(); int authnId = getAuthenticatorIdentifier(dbConnection, idpId, authnConfig.getName()); - endpointConfigurationManager.addEndpointConfig(authnConfig, tenantId); sqlStmt = IdPManagementConstants.SQLQueries.ADD_IDP_AUTH_PROP_SQL; @@ -1503,7 +1495,6 @@ private void deleteFederatedAuthenticatorConfig(FederatedAuthenticatorConfig aut prepStmt.setString(2, authnConfig.getName()); prepStmt.execute(); } - endpointConfigurationManager.deleteEndpointConfig(authnConfig, tenantId); } private void updateSingleValuedFederatedConfigProperties(Connection dbConnection, int authnId, int tenantId, @@ -4009,19 +4000,9 @@ public String addIdPWithResourceId(IdentityProvider identityProvider, int tenant throw new IdentityProviderManagementException("An error occurred while processing content stream.", e); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); - /* Since only one federated authenticator per newly creating IDP is allowed, the custom IDPs will always - have a single federated authenticator. For older IDPs, executing this 'if' code block is unnecessary. */ - if (identityProvider.getFederatedAuthenticatorConfigs().length == 1) { - endpointConfigurationManager.deleteEndpointConfig( - identityProvider.getFederatedAuthenticatorConfigs()[0], tenantId); - } throw new IdentityProviderManagementException("Error occurred while adding Identity Provider for tenant " + tenantId, e); - } catch (AuthenticatorEndpointConfigServerException e) { - IdentityDatabaseUtil.rollbackTransaction(dbConnection); - throw e; - } - catch (ConnectorException 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 " + @@ -4344,18 +4325,8 @@ public void updateIdPWithResourceId(String resourceId, IdentityProvider throw new IdentityProviderManagementException("An error occurred while processing content stream.", e); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); - /* Since only one federated authenticator per newly creating IDP is allowed, the custom IDPs will always - have a single federated authenticator. For older IDPs, executing this 'if' code block is unnecessary. */ - if (currentIdentityProvider.getFederatedAuthenticatorConfigs().length == 1) { - endpointConfigurationManager.updateEndpointConfig(currentIdentityProvider - .getFederatedAuthenticatorConfigs()[0], newIdentityProvider.getFederatedAuthenticatorConfigs()[0], - tenantId); - } throw new IdentityProviderManagementException("Error occurred while updating Identity Provider " + "information for tenant " + tenantId, e); - } catch (AuthenticatorEndpointConfigServerException e) { - IdentityDatabaseUtil.rollbackTransaction(dbConnection); - throw e; } catch (ConnectorException e) { throw new IdentityProviderManagementException("An error occurred while filtering IDP properties.", e); } catch (SecretManagementException e) { @@ -4418,30 +4389,19 @@ public void deleteIdP(String idPName, int tenantId, String tenantDomain) throws IdentityProviderManagementException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); - IdentityProvider identityProvider = null; try { - identityProvider = getIdPByName(dbConnection, idPName, tenantId, + IdentityProvider 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)); } - /* Since only one federated authenticator per newly creating IDP is allowed, the custom IDPs will always - have a single federated authenticator. For older IDPs, executing this 'if' code block is unnecessary. */ - if (identityProvider.getFederatedAuthenticatorConfigs().length == 1) { - endpointConfigurationManager.deleteEndpointConfig( - identityProvider.getFederatedAuthenticatorConfigs()[0], tenantId); - } deleteIdP(dbConnection, tenantId, idPName, null); IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); - rollBackEndpointConfigurationDeletion(identityProvider, tenantId); throw new IdentityProviderManagementException("Error occurred while deleting Identity Provider of tenant " + tenantDomain, e); - } catch (AuthenticatorEndpointConfigServerException e) { - IdentityDatabaseUtil.rollbackTransaction(dbConnection); - throw e; } finally { IdentityDatabaseUtil.closeConnection(dbConnection); } @@ -4477,33 +4437,22 @@ public void deleteIdPByResourceId(String resourceId, int tenantId, String tenant Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); String idPName = ""; - IdentityProvider identityProvider = null; try { - identityProvider = getIDPbyResourceId(dbConnection, resourceId, tenantId, + IdentityProvider 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(); - /* Since only one federated authenticator per newly creating IDP is allowed, the custom IDPs will always - have a single federated authenticator. For older IDPs, executing this 'if' code block is unnecessary. */ - if (identityProvider.getFederatedAuthenticatorConfigs().length == 1) { - endpointConfigurationManager.deleteEndpointConfig( - identityProvider.getFederatedAuthenticatorConfigs()[0], tenantId); - } deleteIdP(dbConnection, tenantId, null, resourceId); // Delete IdP related secrets from the IDN_SECRET table. idpSecretsProcessorService.deleteAssociatedSecrets(identityProvider); IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); - rollBackEndpointConfigurationDeletion(identityProvider, tenantId); throw new IdentityProviderManagementException("Error occurred while deleting Identity Provider of tenant " + tenantDomain, e); - } catch (AuthenticatorEndpointConfigServerException e) { - IdentityDatabaseUtil.rollbackTransaction(dbConnection); - throw e; } catch (SecretManagementException e) { throw new IdentityProviderManagementException("Error while deleting IDP secrets of Identity provider : " + idPName + " in tenant : " + tenantDomain, e); @@ -4517,9 +4466,8 @@ public void forceDeleteIdP(String idPName, String tenantDomain) throws IdentityProviderManagementException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); - IdentityProvider identityProvider = null; try { - identityProvider = getIdPByName(dbConnection, idPName, tenantId, tenantDomain); + IdentityProvider 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)); @@ -4535,24 +4483,14 @@ public void forceDeleteIdP(String idPName, log.debug(String.format("Deleting SP Provisioning Associations for IDP:%s of tenantDomain:%s", idPName, tenantDomain)); } - /* Since only one federated authenticator per newly creating IDP is allowed, the custom IDPs will always - have a single federated authenticator. For older IDPs, executing this 'if' code block is unnecessary. */ - if (identityProvider.getFederatedAuthenticatorConfigs().length == 1) { - endpointConfigurationManager.deleteEndpointConfig( - identityProvider.getFederatedAuthenticatorConfigs()[0], tenantId); - } deleteIdpSpProvisioningAssociations(dbConnection, tenantId, idPName); deleteIdP(dbConnection, tenantId, idPName, null); IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); - rollBackEndpointConfigurationDeletion(identityProvider, tenantId); throw new IdentityProviderManagementException( String.format("Error occurred while deleting Identity Provider:%s of tenant:%s ", idPName, tenantDomain), e); - } catch (AuthenticatorEndpointConfigServerException e) { - IdentityDatabaseUtil.rollbackTransaction(dbConnection); - throw e; } finally { IdentityDatabaseUtil.closeConnection(dbConnection); } @@ -4562,9 +4500,8 @@ public void forceDeleteIdPByResourceId(String resourceId, int tenantId, String t IdentityProviderManagementException { Connection dbConnection = IdentityDatabaseUtil.getDBConnection(); - IdentityProvider identityProvider = null; try { - identityProvider = getIDPbyResourceId(dbConnection, resourceId, tenantId, + IdentityProvider identityProvider = getIDPbyResourceId(dbConnection, resourceId, tenantId, tenantDomain); if (identityProvider == null) { String msg = "Trying to force delete non-existent Identity Provider with resource ID: %s in " + @@ -4583,23 +4520,13 @@ public void forceDeleteIdPByResourceId(String resourceId, int tenantId, String t identityProvider.getIdentityProviderName(), tenantDomain)); } deleteIdpSpProvisioningAssociations(dbConnection, tenantId, identityProvider.getIdentityProviderName()); - /* Since only one federated authenticator per newly creating IDP is allowed, the custom IDPs will always - have a single federated authenticator. For older IDPs, executing this 'if' code block is unnecessary. */ - if (identityProvider.getFederatedAuthenticatorConfigs().length == 1) { - endpointConfigurationManager.deleteEndpointConfig( - identityProvider.getFederatedAuthenticatorConfigs()[0], tenantId); - } deleteIdP(dbConnection, tenantId, null, resourceId); IdentityDatabaseUtil.commitTransaction(dbConnection); } catch (SQLException e) { IdentityDatabaseUtil.rollbackTransaction(dbConnection); - rollBackEndpointConfigurationDeletion(identityProvider, tenantId); throw new IdentityProviderManagementException( String.format("Error occurred while deleting Identity Provider with resource ID:%s of tenant:%s ", resourceId, tenantDomain), e); - } catch (AuthenticatorEndpointConfigServerException e) { - IdentityDatabaseUtil.rollbackTransaction(dbConnection); - throw e; } finally { IdentityDatabaseUtil.closeConnection(dbConnection); } @@ -6174,17 +6101,6 @@ private void performConfigCorrectionForPasswordRecoveryConfigs(Connection dbConn updateIdentityProviderProperties(dbConnection, idpId, idpProperties, tenantId); } - private void rollBackEndpointConfigurationDeletion(IdentityProvider identityProvider, int tenantId) throws - IdentityProviderManagementException { - - /* Since only one federated authenticator per newly creating IDP is allowed, the custom IDPs will always have a - single federated authenticator. For older IDPs, executing this 'if' code block is unnecessary. */ - if (identityProvider != null && identityProvider.getFederatedAuthenticatorConfigs().length == 1) { - endpointConfigurationManager.addEndpointConfig( - identityProvider.getFederatedAuthenticatorConfigs()[0], tenantId); - } - } - private FederatedAuthenticatorConfig createFederatedAuthenticatorConfig(AuthenticatorPropertyConstants.DefinedByType definedByType) { 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 2215cd0ddba6..1d1d2ca6a24b 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 @@ -625,7 +625,7 @@ public enum ErrorMessage { ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND("IDP-60012", "No system authenticator found for the " + "provided authenticator Id %s."), ERROR_CODE_AUTHENTICATOR_NAME_ALREADY_TAKEN("IDP-60013", "Federated authenticator name %s" + - "is already taken."), + " is already taken."), ERROR_INVALID_AUTHENTICATOR_NAME("IDP-60014", "Federated authenticator name does not match the" + " regex pattern %s."), diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/UserDefinedAuthenticatorEndpointConfigManager.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/UserDefinedAuthenticatorEndpointConfigManager.java index 8b4ffd694f32..fdc45c0ea834 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/UserDefinedAuthenticatorEndpointConfigManager.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/main/java/org/wso2/carbon/idp/mgt/util/UserDefinedAuthenticatorEndpointConfigManager.java @@ -47,10 +47,10 @@ public class UserDefinedAuthenticatorEndpointConfigManager { * 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. + * @param tenantDomain The id of Tenant domain. * @throws AuthenticatorEndpointConfigServerException If an error occurs while adding the action. */ - public void addEndpointConfig(FederatedAuthenticatorConfig config, int tenantId) + public void addEndpointConfig(FederatedAuthenticatorConfig config, String tenantDomain) throws AuthenticatorEndpointConfigServerException { if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { @@ -63,10 +63,11 @@ public void addEndpointConfig(FederatedAuthenticatorConfig config, int tenantId) .addAction(Action.ActionTypes.AUTHENTICATION.getPathParam(), buildActionToCreate(castedConfig.getName(), castedConfig.getEndpointConfig().getEndpointConfig()), - IdentityTenantUtil.getTenantDomain(tenantId)); + tenantDomain); Property endpointProperty = new Property(); endpointProperty.setName(ACTION_ID_PROPERTY); endpointProperty.setValue(action.getId()); + endpointProperty.setConfidential(false); config.setProperties(new Property[]{endpointProperty}); } catch (ActionMgtException e) { ErrorMessage error = ErrorMessage.ERROR_CODE_ADDING_ENDPOINT_CONFIG; @@ -80,11 +81,11 @@ public void addEndpointConfig(FederatedAuthenticatorConfig config, int tenantId) * * @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. + * @param tenantDomain The id of Tenant domain. * @throws AuthenticatorEndpointConfigServerException If an error occurs while updating associated action. */ public void updateEndpointConfig(FederatedAuthenticatorConfig newConfig, FederatedAuthenticatorConfig oldConfig, - int tenantId) throws AuthenticatorEndpointConfigServerException { + String tenantDomain) throws AuthenticatorEndpointConfigServerException { if (oldConfig.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { return; @@ -97,7 +98,7 @@ public void updateEndpointConfig(FederatedAuthenticatorConfig newConfig, Federat .updateAction(Action.ActionTypes.AUTHENTICATION.getPathParam(), actionId, buildActionToUpdate(castedConfig.getEndpointConfig().getEndpointConfig()), - IdentityTenantUtil.getTenantDomain(tenantId)); + tenantDomain); newConfig.setProperties(oldConfig.getProperties()); } catch (ActionMgtException e) { ErrorMessage error = ErrorMessage.ERROR_CODE_UPDATING_ENDPOINT_CONFIG; @@ -110,12 +111,12 @@ public void updateEndpointConfig(FederatedAuthenticatorConfig newConfig, Federat * Retrieve associated action of the user defined authenticator. * * @param config The federated application authenticator configuration. - * @param tenantId The id of Tenant domain. + * @param tenantDomain The id of Tenant domain. * @return Federated authenticator with endpoint configurations resolved. * @throws AuthenticatorEndpointConfigServerException If an error occurs retrieving updating associated action. */ public FederatedAuthenticatorConfig resolveEndpointConfig(FederatedAuthenticatorConfig config, - int tenantId) throws AuthenticatorEndpointConfigServerException { + String tenantDomain) throws AuthenticatorEndpointConfigServerException { if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { return config; @@ -127,7 +128,7 @@ public FederatedAuthenticatorConfig resolveEndpointConfig(FederatedAuthenticator Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService() .getActionByActionId(Action.ActionTypes.AUTHENTICATION.getPathParam(), actionId, - IdentityTenantUtil.getTenantDomain(tenantId)); + tenantDomain); castedConfig.setEndpointConfig(buildUserDefinedAuthenticatorEndpointConfig(action.getEndpoint())); return castedConfig; @@ -155,11 +156,11 @@ private UserDefinedAuthenticatorEndpointConfig buildUserDefinedAuthenticatorEndp * Delete associated action of the user defined authenticator. * * @param config The federated application authenticator configuration. - * @param tenantId The id of Tenant domain. + * @param tenantDomain The id of Tenant domain. * * @throws AuthenticatorEndpointConfigServerException If an error occurs while deleting associated action. */ - public void deleteEndpointConfig(FederatedAuthenticatorConfig config, int tenantId) throws + public void deleteEndpointConfig(FederatedAuthenticatorConfig config, String tenantDomain) throws AuthenticatorEndpointConfigServerException { if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) { @@ -171,7 +172,7 @@ public void deleteEndpointConfig(FederatedAuthenticatorConfig config, int tenant IdpMgtServiceComponentHolder.getInstance().getActionManagementService() .deleteAction(Action.ActionTypes.AUTHENTICATION.getPathParam(), actionId, - IdentityTenantUtil.getTenantDomain(tenantId)); + tenantDomain); } catch (ActionMgtException e) { ErrorMessage error = ErrorMessage.ERROR_CODE_DELETING_ENDPOINT_CONFIG; throw new AuthenticatorEndpointConfigServerException(error.getCode(), String.format(error.getMessage(), @@ -206,7 +207,7 @@ private String getActionIdFromProperty(Property[] properties, String authenticat .map(Property::getValue) .findFirst() .orElseThrow(() -> new AuthenticatorEndpointConfigServerException( - "No action Id was found in the properties of the authenticator configurations for the authenticator: " - + authenticatorName)); + "No action Id was found in the properties of the authenticator configurations for the " + + "authenticator: " + authenticatorName)); } } diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/IdentityProviderManagementServiceTest.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/IdentityProviderManagementServiceTest.java index ef59c3740b86..a5c0036ae3ab 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/IdentityProviderManagementServiceTest.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/IdentityProviderManagementServiceTest.java @@ -27,6 +27,11 @@ import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.wso2.carbon.core.util.CryptoUtil; +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.Authentication; +import org.wso2.carbon.identity.action.management.model.EndpointConfig; import org.wso2.carbon.identity.application.common.ApplicationAuthenticatorService; import org.wso2.carbon.identity.application.common.ProvisioningConnectorService; import org.wso2.carbon.identity.application.common.model.Claim; @@ -40,6 +45,7 @@ import org.wso2.carbon.identity.application.common.model.Property; import org.wso2.carbon.identity.application.common.model.ProvisioningConnectorConfig; import org.wso2.carbon.identity.application.common.model.RoleMapping; +import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig; import org.wso2.carbon.identity.application.common.model.UserDefinedFederatedAuthenticatorConfig; import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants; import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType; @@ -59,6 +65,7 @@ import org.wso2.carbon.idp.mgt.dao.IdPManagementDAO; import org.wso2.carbon.idp.mgt.internal.IdpMgtServiceComponentHolder; import org.wso2.carbon.idp.mgt.util.IdPManagementConstants; +import org.wso2.carbon.idp.mgt.util.IdPManagementConstants.ErrorMessage; import org.wso2.carbon.idp.mgt.util.MetadataConverter; import java.io.ByteArrayInputStream; @@ -68,18 +75,23 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.xml.stream.XMLStreamException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; 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.mockStatic; import static org.mockito.Mockito.when; import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertThrows; import static org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_ID; import static java.lang.Boolean.TRUE; @@ -99,6 +111,14 @@ public class IdentityProviderManagementServiceTest { private IdentityProviderManagementService identityProviderManagementService; private MockedStatic cryptoUtil; + private static final String ASSOCIATED_ACTION_ID = "Dummp_Action_ID"; + private static final String CUSTOM_IDP_NAME = "customIdP"; + private static Action action; + private static EndpointConfig endpointConfig; + private static EndpointConfig endpointConfigToBeUpdated; + private IdentityProvider idpForErrorScenarios; + private IdentityProvider userDefinedIdP; + @BeforeClass public void setUpClass() throws Exception { @@ -120,12 +140,14 @@ public void setUpClass() throws Exception { field.setAccessible(true); field.set(identityProviderManager, dao); - FederatedAuthenticatorConfig config = new FederatedAuthenticatorConfig(); - config.setName("Name"); - FederatedAuthenticatorConfig samlConfig = new FederatedAuthenticatorConfig(); - samlConfig.setName("SAMLSSOAuthenticator"); - ApplicationAuthenticatorService.getInstance().addFederatedAuthenticator(config); - ApplicationAuthenticatorService.getInstance().addFederatedAuthenticator(samlConfig); + registerSystemAuthenticators(); + + endpointConfig = createEndpointConfig("http://localhost", "admin", "admin"); + endpointConfigToBeUpdated = createEndpointConfig("http://localhost1", "admin1", "admin1"); + action = createAction(endpointConfig); + userDefinedIdP = createIdPWithUserDefinedFederatedAuthenticatorConfig(CUSTOM_IDP_NAME, action.getEndpoint()); + idpForErrorScenarios = createIdPWithUserDefinedFederatedAuthenticatorConfig( + CUSTOM_IDP_NAME + "Error", action.getEndpoint()); } @AfterClass @@ -139,6 +161,13 @@ public void setUp() throws Exception { mockMetadataConverter = mock(MetadataConverter.class); List metadataConverterList = Arrays.asList(mockMetadataConverter); IdpMgtServiceComponentHolder.getInstance().setMetadataConverters(metadataConverterList); + + ActionManagementService actionManagementService = mock(ActionManagementService.class); + IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); + when(actionManagementService.addAction(anyString(), any(), any())).thenReturn(action); + when(actionManagementService.updateAction(anyString(), any(), any(), any())).thenReturn(action); + when(actionManagementService.getActionByActionId(anyString(), any(), any())).thenReturn(action); + doNothing().when(actionManagementService).deleteAction(anyString(), any(), any()); } @AfterMethod @@ -148,6 +177,30 @@ public void tearDown() throws Exception { removeTestIdps(); } + private void registerSystemAuthenticators() { + + FederatedAuthenticatorConfig federatedAuthenticatorConfig = new FederatedAuthenticatorConfig(); + federatedAuthenticatorConfig.setDisplayName("DisplayName"); + federatedAuthenticatorConfig.setName("SAMLSSOAuthenticator"); + federatedAuthenticatorConfig.setEnabled(true); + federatedAuthenticatorConfig.setDefinedByType(DefinedByType.SYSTEM); + Property property1 = new Property(); + property1.setName("SPEntityId"); + property1.setConfidential(false); + Property property2 = new Property(); + property2.setName("meta_data_saml"); + property2.setConfidential(false); + federatedAuthenticatorConfig.setProperties(new Property[]{property1, property2}); + ApplicationAuthenticatorService.getInstance().addFederatedAuthenticator(federatedAuthenticatorConfig); + + FederatedAuthenticatorConfig config = new FederatedAuthenticatorConfig(); + config.setName("Name"); + config.setDisplayName("DisplayName"); + config.setEnabled(true); + config.setDefinedByType(DefinedByType.USER); + ApplicationAuthenticatorService.getInstance().addFederatedAuthenticator(config); + } + @DataProvider public Object[][] addFederatedAuthenticatorData() { @@ -170,25 +223,40 @@ public Object[][] addFederatedAuthenticatorData() { userDefinedAuthWithInvalidName.setDefinedByType(DefinedByType.USER); return new Object[][]{ - {systemDefinedAuthWithInvalidName}, - {userDefinedAuthWithExistingName}, - {userDefinedAuthWithInvalidName} + {systemDefinedAuthWithInvalidName, ErrorMessage.ERROR_CODE_NO_SYSTEM_AUTHENTICATOR_FOUND}, + {userDefinedAuthWithExistingName, ErrorMessage.ERROR_CODE_AUTHENTICATOR_NAME_ALREADY_TAKEN}, + {userDefinedAuthWithInvalidName, ErrorMessage.ERROR_INVALID_AUTHENTICATOR_NAME} }; } @Test(dataProvider = "addFederatedAuthenticatorData") - public void testFederatedAuthenticatorNameValidation(FederatedAuthenticatorConfig config) + public void testFederatedAuthenticatorNameValidation(FederatedAuthenticatorConfig config, ErrorMessage error) throws IdentityProviderManagementException { IdentityProvider identityProvider = new IdentityProvider(); - identityProvider.setDisplayName("testIdP1"); + identityProvider.setIdentityProviderName("testInvalidIdP"); + identityProvider.setDisplayName("test Invalid IdP"); identityProvider.setFederatedAuthenticatorConfigs(new FederatedAuthenticatorConfig[]{config}); - assertThrows(IdentityProviderManagementException.class, () -> - identityProviderManagementService.addIdP(identityProvider)); - identityProviderManagementService.deleteIdP("testIdP1"); + // asst error code + IdentityProviderManagementException thrownException = assertThrows( + IdentityProviderManagementException.class, + () -> identityProviderManagementService.addIdP(identityProvider) + ); + assertEquals(thrownException.getErrorCode(), error.getCode()); } + @Test + public void testAddIdPActionException() throws Exception { + + ActionManagementService actionManagementService = mock(ActionManagementService.class); + when(actionManagementService.addAction(anyString(), any(), any())).thenThrow(ActionMgtException.class); + IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); + + assertThrows(IdentityProviderManagementException.class, () -> + identityProviderManagementService.addIdP(idpForErrorScenarios)); + identityProviderManagementService.getIdPByName(idpForErrorScenarios.getIdentityProviderName()); + } @DataProvider public Object[][] addIdPData() { @@ -274,6 +342,7 @@ public Object[][] addIdPData() { {idp2}, // IDP with only the name. {idp3}, + {userDefinedIdP} }; } @@ -284,9 +353,7 @@ public void testAddIdP(Object identityProvider) throws Exception { identityProviderManagementService.addIdP(((IdentityProvider) identityProvider)); IdentityProvider idpFromDb = identityProviderManagementService.getIdPByName(idpName); - for (FederatedAuthenticatorConfig config: idpFromDb.getFederatedAuthenticatorConfigs()) { - Assert.assertEquals(config.getDefinedByType(), DefinedByType.SYSTEM); - } + assertIdPResult(idpFromDb, ((IdentityProvider) identityProvider).getIdentityProviderName()); Assert.assertEquals(idpFromDb.getIdentityProviderName(), idpName); } @@ -327,6 +394,7 @@ public Object[][] getIdPByNameData() { {"testIdP1"}, {"testIdP2"}, {"testIdP3"}, + {userDefinedIdP.getIdentityProviderName()} }; } @@ -336,9 +404,7 @@ public void testGetIdPByName(String idpName) throws Exception { addTestIdps(); IdentityProvider idpFromDb = identityProviderManagementService.getIdPByName(idpName); - for (FederatedAuthenticatorConfig config: idpFromDb.getFederatedAuthenticatorConfigs()) { - Assert.assertEquals(config.getDefinedByType(), DefinedByType.SYSTEM); - } + assertIdPResult(idpFromDb, idpName); Assert.assertEquals(idpFromDb.getIdentityProviderName(), idpName); } @@ -385,7 +451,7 @@ public void testGetAllIdpCount() throws Exception { // With 3 idps in database. addTestIdps(); idpCount = identityProviderManagementService.getAllIdpCount(); - Assert.assertEquals(idpCount, 3); + Assert.assertEquals(idpCount, 4); } @Test @@ -398,19 +464,19 @@ public void testGetAllIdps() throws Exception { // With 3 idps in database. addTestIdps(); idpsList = identityProviderManagementService.getAllIdPs(); - Assert.assertEquals(idpsList.length, 3); + Assert.assertEquals(idpsList.length, 4); // With 3 idps and Shared idp in database. addSharedIdp(); idpsList = identityProviderManagementService.getAllIdPs(); - Assert.assertEquals(idpsList.length, 3); + Assert.assertEquals(idpsList.length, 4); } @DataProvider public Object[][] getAllPaginatedIdpInfoData() { return new Object[][]{ - {1, 3}, + {1, 4}, {2, 0}, }; } @@ -446,10 +512,10 @@ public void testGetAllPaginatedIdpInfoException(int pageNumber) throws Exception public Object[][] getPaginatedIdpInfoData() { return new Object[][]{ - {1, "", 3}, + {1, "", 4}, {1, "name sw test", 3}, {1, "homeRealmIdentifier eq 1", 1}, - {1, "isEnabled co true", 3}, + {1, "isEnabled co true", 4}, {1, "isEnabled eq false", 0}, {1, "id ew NotExist", 0}, {2, "name eq testIdP2", 0}, @@ -489,9 +555,9 @@ public void testGetPaginatedIdpInfoException(int pageNumber, String filter) thro public Object[][] getFilteredIdpCountData() { return new Object[][]{ - {"", 3}, + {"", 4}, {"name ew 1", 1}, - {"name co IdP", 3}, + {"name co IdP", 4}, {"description eq Test Idp 1", 1} }; } @@ -509,7 +575,7 @@ public void testGetFilteredIdpCount(String filter, int idpCount) throws Exceptio public Object[][] getAllIdPsSearchData() { return new Object[][]{ - {"", 3}, + {"", 4}, {"test*", 3}, {"????IdP*", 3}, {"tes_I*", 3}, @@ -538,7 +604,26 @@ public void testGetEnabledAllIdPs() throws Exception { addTestIdps(); IdentityProvider[] idpsList = identityProviderManagementService.getEnabledAllIdPs(); - Assert.assertEquals(idpsList.length, 3); + Assert.assertEquals(idpsList.length, 4); + } + + @Test + public void testDeleteIdPActionException() throws Exception { + + identityProviderManagementService.addIdP(userDefinedIdP); + + ActionManagementService actionManagementService = mock(ActionManagementService.class); + doThrow(ActionMgtException.class).when(actionManagementService).deleteAction(any(), any(), any()); + when(actionManagementService.getActionByActionId(anyString(), any(), any())).thenReturn(action); + IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); + + assertThrows(IdentityProviderManagementException.class, () -> + identityProviderManagementService.deleteIdP(userDefinedIdP.getIdentityProviderName())); + Assert.assertNotNull(identityProviderManagementService.getIdPByName(userDefinedIdP + .getIdentityProviderName())); + + // Clean up. + doNothing().when(actionManagementService).deleteAction(anyString(), any(), any()); } @DataProvider @@ -548,6 +633,7 @@ public Object[][] deleteIdPData() { {"testIdP1"}, {"testIdP2"}, {"testIdP3"}, + {userDefinedIdP.getIdentityProviderName()} }; } @@ -586,6 +672,7 @@ public Object[][] forceDeleteIdPData() { {"testIdP1"}, {"testIdP2"}, {"testIdP3"}, + {userDefinedIdP.getIdentityProviderName()} }; } @@ -617,6 +704,24 @@ public void testForceDeleteIdPException(String idpName) throws Exception { identityProviderManagementService.forceDeleteIdP(idpName)); } + @Test + public void testUpdateIdPActionException() throws Exception { + + IdentityProvider idpForErrorScenariosTobeUpdate = createIdPWithUserDefinedFederatedAuthenticatorConfig( + idpForErrorScenarios.getDisplayName(), endpointConfig); + identityProviderManagementService.addIdP(idpForErrorScenarios); + + ActionManagementService actionManagementService = mock(ActionManagementService.class); + when(actionManagementService.updateAction(any(), any(), any(), any())).thenThrow(ActionMgtException.class); + when(actionManagementService.getActionByActionId(anyString(), any(), any())).thenReturn(action); + IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); + + assertThrows(IdentityProviderManagementException.class, () -> + identityProviderManagementService.updateIdP(idpForErrorScenariosTobeUpdate.getIdentityProviderName(), + idpForErrorScenarios)); + identityProviderManagementService.getIdPByName(idpForErrorScenarios.getIdentityProviderName()); + } + @DataProvider public Object[][] updateIdPData() { @@ -687,6 +792,9 @@ public Object[][] updateIdPData() { IdentityProvider idp3New = new IdentityProvider(); idp3New.setIdentityProviderName("testIdP3New"); + IdentityProvider userDefinedIdPToBeUpdated = createIdPWithUserDefinedFederatedAuthenticatorConfig( + CUSTOM_IDP_NAME + "new", endpointConfigToBeUpdated); + return new Object[][]{ // IDP with PermissionsAndRoleConfig,FederatedAuthenticatorConfig,ProvisioningConnectorConfig,ClaimConf. {"testIdP1", idp1New}, @@ -694,6 +802,8 @@ public Object[][] updateIdPData() { {"testIdP2", idp2New}, // New IDP with Only name. {"testIdP3", idp3New}, + // IDP with User Defined Federated Authenticator. + {userDefinedIdP.getIdentityProviderName(), userDefinedIdPToBeUpdated} }; } @@ -707,9 +817,7 @@ public void testUpdateIdP(String oldIdpName, Object newIdp) throws Exception { Assert.assertNull(identityProviderManagementService.getIdPByName(oldIdpName)); IdentityProvider newIdpFromDb = identityProviderManagementService.getIdPByName(newIdpName); Assert.assertNotNull(newIdpFromDb); - for (FederatedAuthenticatorConfig config: newIdpFromDb.getFederatedAuthenticatorConfigs()) { - Assert.assertEquals(config.getDefinedByType(), DefinedByType.SYSTEM); - } + assertIdPResult(newIdpFromDb, newIdpName); } @Test(dataProvider = "updateIdPData") @@ -724,9 +832,7 @@ public void testUpdateIdPByResourceId(String oldIdpName, Object newIdp) throws E Assert.assertNull(identityProviderManagementService.getIdPByName(oldIdpName)); IdentityProvider newIdpFromDb = identityProviderManagementService.getIdPByName(newIdpName); Assert.assertNotNull(newIdpFromDb); - for (FederatedAuthenticatorConfig config: newIdpFromDb.getFederatedAuthenticatorConfigs()) { - Assert.assertEquals(config.getDefinedByType(), DefinedByType.SYSTEM); - } + assertIdPResult(newIdpFromDb, newIdpName); } @DataProvider @@ -791,11 +897,11 @@ public void testGetAllFederatedAuthenticators() throws Exception { Assert.assertEquals(allFederatedAuthenticators.length, 2); - FederatedAuthenticatorConfig federatedAuthenticatorConfig1 = mock(FederatedAuthenticatorConfig.class); + FederatedAuthenticatorConfig federatedAuthenticatorConfig1 = new FederatedAuthenticatorConfig(); federatedAuthenticatorConfig1.setDisplayName("DisplayName1"); federatedAuthenticatorConfig1.setName("Name1"); federatedAuthenticatorConfig1.setEnabled(true); - FederatedAuthenticatorConfig federatedAuthenticatorConfig2 = mock(FederatedAuthenticatorConfig.class); + FederatedAuthenticatorConfig federatedAuthenticatorConfig2 = new FederatedAuthenticatorConfig(); federatedAuthenticatorConfig2.setDisplayName("DisplayName2"); federatedAuthenticatorConfig2.setName("Name2"); federatedAuthenticatorConfig2.setEnabled(true); @@ -1121,6 +1227,10 @@ private void addTestIdps() throws IdentityProviderManagementException { // IDP with Only name. identityProviderManagementService.addIdP(idp3); + + // User defined IDP. + identityProviderManagementService.addIdP(userDefinedIdP); + userDefinedIdP = identityProviderManagementService.getIdPByName(userDefinedIdP.getIdentityProviderName()); } private void addResidentIdp() throws IdentityProviderManagementException { @@ -1232,4 +1342,74 @@ private FederatedAuthenticatorConfig federatedAuthenticatorConfigWithIdpEntityId return federatedAuthenticatorConfig; } + private Action createAction(EndpointConfig endpointConfig) { + + Action.ActionResponseBuilder actionResponseBuilder = new Action.ActionResponseBuilder(); + actionResponseBuilder.id(ASSOCIATED_ACTION_ID); + actionResponseBuilder.name("SampleAssociatedAction"); + actionResponseBuilder.type(Action.ActionTypes.AUTHENTICATION); + actionResponseBuilder.description("SampleDescription"); + actionResponseBuilder.status(Action.Status.ACTIVE); + actionResponseBuilder.endpoint(endpointConfig); + return actionResponseBuilder.build(); + } + + private EndpointConfig createEndpointConfig(String uri, String username, String password) { + + EndpointConfig.EndpointConfigBuilder endpointConfigBuilder = new EndpointConfig.EndpointConfigBuilder(); + endpointConfigBuilder.uri(uri); + endpointConfigBuilder.authentication( + new Authentication.BasicAuthBuilder(username, password).build()); + return endpointConfigBuilder.build(); + } + + private IdentityProvider createIdPWithUserDefinedFederatedAuthenticatorConfig(String idpName, + EndpointConfig endpointConfig) { + + // Initialize Test Identity Provider 4 with custom user defined federated authenticator. + IdentityProvider newUserDefinedIdp = new IdentityProvider(); + newUserDefinedIdp.setIdentityProviderName(idpName); + + UserDefinedFederatedAuthenticatorConfig userDefinedFederatedAuthenticatorConfig = new + UserDefinedFederatedAuthenticatorConfig(); + userDefinedFederatedAuthenticatorConfig.setDisplayName("DisplayName1"); + userDefinedFederatedAuthenticatorConfig.setName("customFedAuthenticator"); + userDefinedFederatedAuthenticatorConfig.setEnabled(true); + userDefinedFederatedAuthenticatorConfig.setEndpointConfig( + buildUserDefinedAuthenticatorEndpointConfig(endpointConfig)); + userDefinedFederatedAuthenticatorConfig.setDefinedByType(DefinedByType.USER); + userDefinedFederatedAuthenticatorConfig.setProperties(new Property[]{}); + newUserDefinedIdp.setFederatedAuthenticatorConfigs( + new FederatedAuthenticatorConfig[]{userDefinedFederatedAuthenticatorConfig}); + return newUserDefinedIdp; + } + + private UserDefinedAuthenticatorEndpointConfig buildUserDefinedAuthenticatorEndpointConfig( + EndpointConfig endpointConfig) { + + UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder = + new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder(); + endpointConfigBuilder.uri(endpointConfig.getUri()); + endpointConfigBuilder.authenticationType(endpointConfig.getAuthentication().getType().getName()); + Map propMap = new HashMap<>(); + endpointConfig.getAuthentication().getProperties() + .forEach(prop -> propMap.put(prop.getName(), prop.getValue())); + endpointConfigBuilder.authenticationProperties(propMap); + return endpointConfigBuilder.build(); + } + + private void assertIdPResult(IdentityProvider idpResult, String idpName) { + + for (FederatedAuthenticatorConfig config : idpResult.getFederatedAuthenticatorConfigs()) { + if (config instanceof UserDefinedFederatedAuthenticatorConfig) { + assertEquals(config.getDefinedByType(), DefinedByType.USER); + Property[] prop = idpResult.getFederatedAuthenticatorConfigs()[0].getProperties(); + assertEquals(prop.length, 1); + assertEquals(prop[0].getName(), "actionId"); + assertEquals(prop[0].getValue(), ASSOCIATED_ACTION_ID); + } else { + assertEquals(config.getDefinedByType(), DefinedByType.SYSTEM); + } + } + } } diff --git a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAOTest.java b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAOTest.java index fda092d4b3f7..a020b4b9d327 100644 --- a/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAOTest.java +++ b/components/idp-mgt/org.wso2.carbon.idp.mgt/src/test/java/org/wso2/carbon/idp/mgt/dao/IdPManagementDAOTest.java @@ -620,28 +620,6 @@ public void testGetCountOfFilteredIdPsException(int tenantId, List identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class)) { - try (Connection connection = getConnection(DB_NAME)) { - identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getDBConnection(anyBoolean())).thenReturn(connection); - identityDatabaseUtil.when(IdentityDatabaseUtil::getDBConnection).thenReturn(connection); - identityDatabaseUtil.when(IdentityDatabaseUtil::getDataSource).thenReturn(dataSourceMap.get(DB_NAME)); - - assertThrows(IdentityProviderManagementException.class, () -> - idPManagementDAO.addIdP(idpForErrorScenarios, SAMPLE_TENANT_ID2)); - // check identityDatabaseUtil.rollbackTransaction is called at least once. - identityDatabaseUtil.verify(() -> IdentityDatabaseUtil.rollbackTransaction(any()), atLeastOnce()); - } - } - } - @DataProvider public Object[][] addIdPData() { @@ -1219,34 +1197,6 @@ public void testGetIdPByAuthenticatorPropertyWithoutAuthenticatorData(int tenant } } - @Test - public void testUpdateIdPActionException() throws Exception { - - IdentityProvider idpForErrorScenariosTobeUpdate = createIdPWithUserDefinedFederatedAuthenticatorConfig( - idpForErrorScenarios.getDisplayName(), endpointConfig); - - try (MockedStatic identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class)) { - try (Connection connection = getConnection(DB_NAME)) { - identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getDBConnection(anyBoolean())).thenReturn(connection); - identityDatabaseUtil.when(IdentityDatabaseUtil::getDBConnection).thenReturn(connection); - identityDatabaseUtil.when(IdentityDatabaseUtil::getDataSource).thenReturn(dataSourceMap.get(DB_NAME)); - idPManagementDAO.addIdP(idpForErrorScenarios, SAMPLE_TENANT_ID2); - - ActionManagementService actionManagementService = mock(ActionManagementService.class); - IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); - when(actionManagementService.updateAction(any(), any(), any(), any())) - .thenThrow(ActionMgtException.class); - IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); - - assertThrows(IdentityProviderManagementException.class, () -> - idPManagementDAO.updateIdP( - idpForErrorScenariosTobeUpdate, idpForErrorScenarios, SAMPLE_TENANT_ID2)); - // check identityDatabaseUtil.rollbackTransaction is called at least once. - identityDatabaseUtil.verify(() -> IdentityDatabaseUtil.rollbackTransaction(any()), atLeastOnce()); - } - } - } - @DataProvider public Object[][] updateIdPData() { @@ -1376,7 +1326,7 @@ public Object[][] updateIdPData() { }; } - @Test(dataProvider = "updateIdPData", dependsOnMethods = {"testUpdateIdPActionException"}) + @Test(dataProvider = "updateIdPData") public void testUpdateIdP(Object oldIdp, Object newIdp, int tenantId) throws Exception { try (MockedStatic identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); @@ -1414,33 +1364,6 @@ public void testUpdateIdPException(Object oldIdp, Object newIdp, int tenantId) t } } - @Test - public void testDeleteIdPActionException() throws Exception { - - IdentityProvider idpForErrorScenariosTobeUpdate = createIdPWithUserDefinedFederatedAuthenticatorConfig( - idpForErrorScenarios.getDisplayName(), endpointConfig); - - try (MockedStatic identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class)) { - try (Connection connection = getConnection(DB_NAME)) { - identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getDBConnection(anyBoolean())).thenReturn(connection); - identityDatabaseUtil.when(IdentityDatabaseUtil::getDBConnection).thenReturn(connection); - identityDatabaseUtil.when(IdentityDatabaseUtil::getDataSource).thenReturn(dataSourceMap.get(DB_NAME)); - idPManagementDAO.addIdP(idpForErrorScenarios, SAMPLE_TENANT_ID2); - - ActionManagementService actionManagementService = mock(ActionManagementService.class); - IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); - doThrow(ActionMgtException.class).when(actionManagementService).deleteAction(any(), any(), any()); - IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService); - - assertThrows(IdentityProviderManagementException.class, () -> - idPManagementDAO.updateIdP( - idpForErrorScenariosTobeUpdate, idpForErrorScenarios, SAMPLE_TENANT_ID2)); - // check identityDatabaseUtil.rollbackTransaction is called at least once. - identityDatabaseUtil.verify(() -> IdentityDatabaseUtil.rollbackTransaction(any()), atLeastOnce()); - } - } - } - @DataProvider public Object[][] deleteIdPData() { @@ -2193,6 +2116,11 @@ private IdentityProvider createIdPWithUserDefinedFederatedAuthenticatorConfig(St userDefinedFederatedAuthenticatorConfig.setEnabled(true); userDefinedFederatedAuthenticatorConfig.setEndpointConfig( buildUserDefinedAuthenticatorEndpointConfig(endpointConfig)); + Property property = new Property(); + property.setName("actionId"); + property.setValue(ASSOCIATED_ACTION_ID); + property.setConfidential(false); + userDefinedFederatedAuthenticatorConfig.setProperties(new Property[]{property}); newUserDefinedIdp.setFederatedAuthenticatorConfigs( new FederatedAuthenticatorConfig[]{userDefinedFederatedAuthenticatorConfig}); newUserDefinedIdp.setDefaultAuthenticatorConfig(userDefinedFederatedAuthenticatorConfig);