Skip to content

Commit

Permalink
Add authentication service layer for user def auth mgt.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thisara-Welmilla committed Dec 3, 2024
1 parent 5ef08cc commit b652192
Show file tree
Hide file tree
Showing 13 changed files with 993 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,41 @@

package org.wso2.carbon.identity.application.common;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.application.common.dao.impl.AuthenticatorManagementDAOImpl;
import org.wso2.carbon.identity.application.common.dao.impl.CacheBackedAuthenticatorMgtDAO;
import org.wso2.carbon.identity.application.common.exception.AuthenticatorMgtException;
import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.LocalAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.RequestPathAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.UserDefinedLocalAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.util.AuthenticatorMgtExceptionBuilder.AuthenticatorMgtError;
import org.wso2.carbon.identity.application.common.util.UserDefinedLocalAuthenticatorValidator;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;

import java.util.ArrayList;
import java.util.List;

import static org.wso2.carbon.identity.application.common.util.AuthenticatorMgtExceptionBuilder.buildClientException;
import static org.wso2.carbon.identity.application.common.util.AuthenticatorMgtExceptionBuilder.buildRuntimeServerException;

/**
* Application authenticator service.
*/
public class ApplicationAuthenticatorService {

private static volatile ApplicationAuthenticatorService instance;
private static final Log LOG = LogFactory.getLog(ApplicationAuthenticatorService.class);
private static final CacheBackedAuthenticatorMgtDAO CACHE_BACKED_DAO =
new CacheBackedAuthenticatorMgtDAO(new AuthenticatorManagementDAOImpl());

private List<LocalAuthenticatorConfig> localAuthenticators = new ArrayList<>();
private List<FederatedAuthenticatorConfig> federatedAuthenticators = new ArrayList<>();
private List<RequestPathAuthenticatorConfig> requestPathAuthenticators = new ArrayList<>();
private UserDefinedLocalAuthenticatorValidator authenticatorValidator =
new UserDefinedLocalAuthenticatorValidator();

public static ApplicationAuthenticatorService getInstance() {
if (instance == null) {
Expand All @@ -51,6 +69,17 @@ public List<LocalAuthenticatorConfig> getLocalAuthenticators() {
return this.localAuthenticators;
}

/**
* This returns user defined local authenticators.
*
* @return Retrieved LocalAuthenticatorConfig.
*/
public List<UserDefinedLocalAuthenticatorConfig> getUserDefinedLocalAuthenticators(String tenantDomain)
throws AuthenticatorMgtException {

return CACHE_BACKED_DAO.getAllUserDefinedLocalAuthenticator(IdentityTenantUtil.getTenantId(tenantDomain));
}

public List<FederatedAuthenticatorConfig> getFederatedAuthenticators() {
return this.federatedAuthenticators;
}
Expand All @@ -59,6 +88,16 @@ public List<RequestPathAuthenticatorConfig> getRequestPathAuthenticators() {
return this.requestPathAuthenticators;
}

/**
* This returns only SYSTEM defined local authenticator by name.
*
* @param name The name of the Local Application Authenticator configuration.
* @return Retrieved LocalAuthenticatorConfig.
*
* @deprecated It is recommended to use {@link #getLocalAuthenticatorByName(String, String)},
* which supports retrieving both USER and SYSTEM defined Local Application Authenticator configuration by name.
*/
@Deprecated
public LocalAuthenticatorConfig getLocalAuthenticatorByName(String name) {
for (LocalAuthenticatorConfig localAuthenticator : localAuthenticators) {
if (localAuthenticator.getName().equals(name)) {
Expand All @@ -68,6 +107,27 @@ public LocalAuthenticatorConfig getLocalAuthenticatorByName(String name) {
return null;
}

/**
* Retrieve both USER and SYSTEM defined Local Application Authenticator configuration by name.
*
* @param name The name of the Local Application Authenticator configuration.
* @param tenantDomain Tenant domain.
* @return Retrieved LocalAuthenticatorConfig.
* @throws AuthenticatorMgtException If an error occurs while retrieving the authenticator configuration by name.
*/
public LocalAuthenticatorConfig getLocalAuthenticatorByName(String name, String tenantDomain)
throws AuthenticatorMgtException {

/* First, check whether an authenticator by the given name is in the system defined authenticators list.
If not, check in user defined authenticators. */
for (LocalAuthenticatorConfig localAuthenticator : localAuthenticators) {
if (localAuthenticator.getName().equals(name)) {
return localAuthenticator;
}
}
return getUserDefinedLocalAuthenticator(name, tenantDomain);
}

public FederatedAuthenticatorConfig getFederatedAuthenticatorByName(String name) {
for (FederatedAuthenticatorConfig federatedAuthenticator : federatedAuthenticators) {
if (federatedAuthenticator.getName().equals(name)) {
Expand All @@ -87,7 +147,12 @@ public RequestPathAuthenticatorConfig getRequestPathAuthenticatorByName(String n
}

public void addLocalAuthenticator(LocalAuthenticatorConfig authenticator) {

if (authenticator != null) {
if (authenticator.getDefinedByType() != DefinedByType.SYSTEM) {
throw buildRuntimeServerException(
AuthenticatorMgtError.ERROR_CODE_INVALID_DEFINED_BY_AUTH_PROVIDED, null);
}
localAuthenticators.add(authenticator);
}
}
Expand Down Expand Up @@ -121,4 +186,103 @@ public void removeRequestPathAuthenticator(RequestPathAuthenticatorConfig authen
requestPathAuthenticators.remove(authenticator);
}
}

/**
* Create a user defined Local Application Authenticator configuration.
*
* @param authenticatorConfig The Local Application Authenticator configuration.
* @param tenantDomain Tenant domain.
* @return Updated LocalAuthenticatorConfig.
* @throws AuthenticatorMgtException If an error occurs while creating the authenticator configuration.
*/
public UserDefinedLocalAuthenticatorConfig addUserDefinedLocalAuthenticator(
UserDefinedLocalAuthenticatorConfig authenticatorConfig, String tenantDomain)
throws AuthenticatorMgtException {

LocalAuthenticatorConfig config = getLocalAuthenticatorByName(authenticatorConfig.getName(), tenantDomain);
if (config != null) {
throw buildClientException(AuthenticatorMgtError.ERROR_AUTHENTICATOR_ALREADY_EXIST,
authenticatorConfig.getName());
}
authenticatorValidator.validateAuthenticatorName(authenticatorConfig.getName());
authenticatorValidator.validateForBlank("Display name", authenticatorConfig.getDisplayName());
authenticatorValidator.validateDefinedByType(authenticatorConfig.getDefinedByType());

return CACHE_BACKED_DAO.addUserDefinedLocalAuthenticator(
authenticatorConfig, IdentityTenantUtil.getTenantId(tenantDomain));
}

/**
* Update a user defined Local Application Authenticator configuration.
*
* @param authenticatorConfig The Local Application Authenticator configuration.
* @param tenantDomain Tenant Domain.
* @return Updated UserDefinedLocalAuthenticatorConfig.
* @throws AuthenticatorMgtException If an error occurs while updating the authenticator configuration.
*/
public UserDefinedLocalAuthenticatorConfig updateUserDefinedLocalAuthenticator(
UserDefinedLocalAuthenticatorConfig authenticatorConfig, String tenantDomain)
throws AuthenticatorMgtException {

UserDefinedLocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator(
authenticatorConfig.getName(), tenantDomain);
authenticatorValidator.validateDefinedByType(existingConfig.getDefinedByType());
authenticatorValidator.validateForBlank("Display name", authenticatorConfig.getDisplayName());

return CACHE_BACKED_DAO.updateUserDefinedLocalAuthenticator(
existingConfig, authenticatorConfig, IdentityTenantUtil.getTenantId(tenantDomain));
}

/**
* Update a Local Application Authenticator configuration.
*
* @param authenticatorName Name of Local Application Authenticator configuration to be deleted.
* @param tenantDomain Tenant domain.
* @throws AuthenticatorMgtException If an error occurs while deleting the authenticator configuration.
*/
public void deleteUserDefinedLocalAuthenticator(String authenticatorName, String tenantDomain)
throws AuthenticatorMgtException {

UserDefinedLocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator(
authenticatorName, tenantDomain);
authenticatorValidator.validateDefinedByType(existingConfig.getDefinedByType());

CACHE_BACKED_DAO.deleteUserDefinedLocalAuthenticator(authenticatorName, existingConfig,
IdentityTenantUtil.getTenantId(tenantDomain));
}

/**
* Retrieve a Local Application Authenticator configuration by name.
*
* @param authenticatorName Name of Local Application Authenticator configuration to be deleted.
* @param tenantDomain Tenant domain.
* @return Retrieved UserDefinedLocalAuthenticatorConfig.
* @throws AuthenticatorMgtException If an error occurs while retrieving the authenticator configuration.
*/
public UserDefinedLocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenticatorName,
String tenantDomain) throws AuthenticatorMgtException {

UserDefinedLocalAuthenticatorConfig config = CACHE_BACKED_DAO.getUserDefinedLocalAuthenticator(
authenticatorName, IdentityTenantUtil.getTenantId(tenantDomain));

if (config != null && !config.getDefinedByType().equals(DefinedByType.USER)) {
return null;
}

return config;

}

private UserDefinedLocalAuthenticatorConfig resolveExistingAuthenticator(String authenticatorName,
String tenantDomain) throws AuthenticatorMgtException {

UserDefinedLocalAuthenticatorConfig existingAuthenticatorConfig = CACHE_BACKED_DAO.
getUserDefinedLocalAuthenticator(authenticatorName, IdentityTenantUtil.getTenantId(tenantDomain));

if (existingAuthenticatorConfig == null) {
throw buildClientException(AuthenticatorMgtError.ERROR_NOT_FOUND_AUTHENTICATOR, authenticatorName);
}

return existingAuthenticatorConfig;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.constant;

/**
* SQL constants for authenticator configuration management service.
*/
public class AuthenticatorMgtSQLConstants {

private AuthenticatorMgtSQLConstants() {

}

/**
* Column Names.
*/
public static class Column {

public static final String IDP_ID = "ID";
public static final String IDP_NAME = "IDP_NAME";
public static final String TENANT_ID = "TENANT_ID";
public static final String NAME = "NAME";
public static final String IS_ENABLED = "IS_ENABLED";
public static final String DEFINED_BY = "DEFINED_BY";
public static final String AUTHENTICATION_TYPE = "AUTHENTICATION_TYPE";
public static final String DISPLAY_NAME = "DISPLAY_NAME";
public static final String ID = "ID";
public static final String AUTHENTICATOR_ID = "AUTHENTICATOR_ID";
public static final String PROPERTY_KEY = "PROPERTY_KEY";
public static final String PROPERTY_VALUE = "PROPERTY_VALUE";
public static final String IS_SECRET = "IS_SECRET";

private Column() {

}
}

/**
* Queries.
*/
public static class Query {

public static final String ADD_AUTHENTICATOR_SQL = "INSERT INTO IDP_AUTHENTICATOR " +
"(TENANT_ID, IDP_ID, NAME, IS_ENABLED, DEFINED_BY, AUTHENTICATION_TYPE, DISPLAY_NAME) VALUES" +
" (:TENANT_ID;, (SELECT ID FROM IDP WHERE IDP.NAME = :IDP_NAME; AND IDP.TENANT_ID = :TENANT_ID;), " +
":NAME;, :IS_ENABLED;, :DEFINED_BY;, :AUTHENTICATION_TYPE;, :DISPLAY_NAME;);";
public static final String UPDATE_AUTHENTICATOR_SQL = "UPDATE IDP_AUTHENTICATOR SET IS_ENABLED = " +
":IS_ENABLED;, DISPLAY_NAME = :DISPLAY_NAME; WHERE NAME = :NAME; AND TENANT_ID = :TENANT_ID;";
public static final String GET_AUTHENTICATOR_SQL = "SELECT * FROM IDP_AUTHENTICATOR WHERE NAME = :NAME; " +
" AND TENANT_ID = :TENANT_ID;";
public static final String GET_ALL_USER_DEFINED_AUTHENTICATOR_SQL = "SELECT * FROM IDP_AUTHENTICATOR " +
"WHERE DEFINED_BY = :DEFINED_BY; AND TENANT_ID = :TENANT_ID;";
public static final String DELETE_AUTHENTICATOR_SQL = "DELETE FROM IDP_AUTHENTICATOR WHERE NAME = :NAME; " +
" AND TENANT_ID = :TENANT_ID;";
public static final String GET_AUTHENTICATOR_ID_SQL = "SELECT ID FROM IDP_AUTHENTICATOR " +
"WHERE NAME = :NAME; AND TENANT_ID = :TENANT_ID;";
public static final String ADD_AUTHENTICATOR_PROP_SQL = "INSERT INTO IDP_AUTHENTICATOR_PROPERTY " +
"(AUTHENTICATOR_ID, TENANT_ID, PROPERTY_KEY, PROPERTY_VALUE, IS_SECRET) VALUES " +
"(:AUTHENTICATOR_ID;, :TENANT_ID;, :PROPERTY_KEY;, :PROPERTY_VALUE;, :IS_SECRET;);";
public static final String DELETE_AUTHENTICATOR_PROP_SQL = "DELETE FROM IDP_AUTHENTICATOR_PROPERTY " +
"WHERE AUTHENTICATOR_ID = :AUTHENTICATOR_ID; AND TENANT_ID = :TENANT_ID;";
public static final String GET_AUTHENTICATOR_PROP_SQL = "SELECT PROPERTY_KEY, PROPERTY_VALUE, IS_SECRET" +
" FROM IDP_AUTHENTICATOR_PROPERTY " +
"WHERE AUTHENTICATOR_ID = :AUTHENTICATOR_ID; AND TENANT_ID = :TENANT_ID;";

private Query() {

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.carbon.identity.application.common.exception;

/**
* Authenticator configuration management client exception.
*/
public class AuthenticatorMgtClientException extends AuthenticatorMgtException {

public AuthenticatorMgtClientException(String errorCode, String message, String description) {

super(message, description, errorCode);
}
}
Loading

0 comments on commit b652192

Please sign in to comment.