Skip to content

Commit

Permalink
Add support for managing custom federated authenticators.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thisara-Welmilla committed Nov 4, 2024
1 parent 80fa63d commit bddbeb2
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.central.log.mgt</artifactId>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.action.management</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,7 @@
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.database.utils.jdbc.exceptions.DataAccessException;
import org.wso2.carbon.identity.application.common.model.Claim;
import org.wso2.carbon.identity.application.common.model.ClaimConfig;
import org.wso2.carbon.identity.application.common.model.ClaimMapping;
import org.wso2.carbon.identity.application.common.model.FederatedAssociationConfig;
import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.IdPGroup;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.model.IdentityProviderProperty;
import org.wso2.carbon.identity.application.common.model.JustInTimeProvisioningConfig;
import org.wso2.carbon.identity.application.common.model.LocalRole;
import org.wso2.carbon.identity.application.common.model.PermissionsAndRoleConfig;
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.*;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationManagementUtil;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType;
Expand All @@ -62,6 +49,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;
Expand Down Expand Up @@ -125,6 +113,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
Expand Down Expand Up @@ -1138,7 +1128,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"));

Expand All @@ -1149,7 +1141,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());
Expand All @@ -1170,6 +1161,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.
Expand Down Expand Up @@ -1327,6 +1319,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);

Expand Down Expand Up @@ -1416,6 +1410,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);
Expand Down Expand Up @@ -1461,6 +1456,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);
Expand Down Expand Up @@ -3981,6 +3977,8 @@ 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) {
Expand Down Expand Up @@ -4310,6 +4308,8 @@ 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 (ConnectorException e) {
Expand Down Expand Up @@ -4374,17 +4374,22 @@ 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);
} finally {
Expand All @@ -4405,6 +4410,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);
Expand All @@ -4422,14 +4428,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) {
Expand All @@ -4441,6 +4450,8 @@ 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 (SecretManagementException e) {
Expand All @@ -4456,8 +4467,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));
Expand All @@ -4473,11 +4485,15 @@ 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);
Expand All @@ -4490,8 +4506,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 " +
Expand All @@ -4510,10 +4527,14 @@ 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);
Expand Down
Loading

0 comments on commit bddbeb2

Please sign in to comment.