Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add service layer support to manage the user defined local authenticators #6071

Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,20 @@

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.constant.AuthenticatorMgtErrorConstants.ErrorMessages;
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.AuthenticatorMgtClientException;
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.util.UserDefinedLocalAuthenticatorValidator;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.AuthenticationType;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -31,10 +42,15 @@
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 @@ -47,10 +63,30 @@ public static ApplicationAuthenticatorService getInstance() {
return instance;
}

/**
* This returns only SYSTEM defined local authenticators.
*
* @return Retrieved LocalAuthenticatorConfig.
*/
@Deprecated
public List<LocalAuthenticatorConfig> getLocalAuthenticators() {
return this.localAuthenticators;
}

/**
* This returns both SYSTEM and USER defined local authenticators.
*
* @return Retrieved LocalAuthenticatorConfig.
*/
public List<LocalAuthenticatorConfig> getLocalAuthenticators(String tenantDomain)
throws AuthenticatorMgtException {

List<LocalAuthenticatorConfig> userDefinedAuthenticators =
CACHE_BACKED_DAO.getAllUserDefinedLocalAuthenticator(IdentityTenantUtil.getTenantId(tenantDomain));
userDefinedAuthenticators.addAll(localAuthenticators);
return userDefinedAuthenticators;
}

public List<FederatedAuthenticatorConfig> getFederatedAuthenticators() {
return this.federatedAuthenticators;
}
Expand All @@ -59,6 +95,14 @@ 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
public LocalAuthenticatorConfig getLocalAuthenticatorByName(String name) {
for (LocalAuthenticatorConfig localAuthenticator : localAuthenticators) {
if (localAuthenticator.getName().equals(name)) {
Expand All @@ -68,6 +112,28 @@ 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 Down Expand Up @@ -121,4 +187,108 @@ public void removeRequestPathAuthenticator(RequestPathAuthenticatorConfig authen
requestPathAuthenticators.remove(authenticator);
}
}

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

LocalAuthenticatorConfig config = getLocalAuthenticatorByName(authenticatorConfig.getName(), tenantDomain);
if (config != null) {
ErrorMessages error = ErrorMessages.ERROR_AUTHENTICATOR_ALREADY_EXIST;
throw new AuthenticatorMgtClientException(error.getCode(), error.getMessage(),
String.format(error.getDescription(), authenticatorConfig.getName()));
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved
}
authenticatorValidator.validateAuthenticatorName(authenticatorConfig.getName());
authenticatorValidator.validateForBlank("Display name", authenticatorConfig.getDisplayName());
authenticatorValidator.validateDefinedByType(authenticatorConfig.getDefinedByType());

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

/**
* Update 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 updating the authenticator configuration.
*/
public LocalAuthenticatorConfig updateUserDefinedLocalAuthenticator(LocalAuthenticatorConfig authenticatorConfig,
String tenantDomain) throws AuthenticatorMgtException {

LocalAuthenticatorConfig 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 {

LocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator(authenticatorName, tenantDomain);
authenticatorValidator.validateDefinedByType(existingConfig.getDefinedByType());
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved

CACHE_BACKED_DAO.deleteUserDefinedLocalAuthenticator(authenticatorName,
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 LocalAuthenticatorConfig.
* @throws AuthenticatorMgtException If an error occurs while retrieving the authenticator configuration.
*/
public LocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenticatorName, String tenantDomain)
throws AuthenticatorMgtException {

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

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

return config;

}

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

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

if (existingAuthenticatorConfig == null) {
ErrorMessages error = ErrorMessages.ERROR_NOT_FOUND_AUTHENTICATOR;
throw new AuthenticatorMgtClientException(error.getCode(), error.getMessage(),
String.format(error.getDescription(), authenticatorName));
}

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

/**
* Constants for authenticator configuration management service.
*/
public class AuthenticatorMgtErrorConstants {
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved

/**
* Error messages.
*/
public enum ErrorMessages {

// Client errors.
ERROR_NOT_FOUND_AUTHENTICATOR("60001", "No Authenticator found.",
"No Authenticator found by given authenticator name: %s."),
ERROR_OP_ON_SYSTEM_AUTHENTICATOR("60002", "No operations allowed on system authenticators.",
"Do not allow to perform any operation on system defined authenticator: %s."),
ERROR_AUTHENTICATOR_ALREADY_EXIST("60003", "An authenticator already exists.",
"As authenticator already exists for the given name: %s."),
ERROR_INVALID_AUTHENTICATOR_NAME("60004", "Authenticator name is invalid.",
"The provided authenticator name %s is not in the expected format %s."),
ERROR_BLANK_FIELD_VALUE("60004", "Invalid empty or blank value.",
"Value for %s should not be empty or blank."),

// Server errors.
ERROR_WHILE_ADDING_AUTHENTICATOR("65001", "Error while adding authenticator.",
"Error while persisting authenticator from the system."),
ERROR_WHILE_UPDATING_AUTHENTICATOR("65002", "Error while updating authenticator.",
"Error while updating authenticator from the system."),
ERROR_WHILE_RETRIEVING_AUTHENTICATOR_BY_NAME("65003", "Error while retrieving authenticator.",
"Error while retrieving authenticator from the system."),
ERROR_WHILE_DELETING_AUTHENTICATOR("65004", "Error while deleting authenticator.",
"Error while deleting authenticator from the system."),;

private final String code;
private final String message;
private final String description;

ErrorMessages(String code, String message, String description) {

this.code = code;
this.message = message;
this.description = description;
}

public String getCode() {

return code;
}

public String getMessage() {

return message;
}

public String getDescription() {

return description;
}
}
}
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