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

Open
wants to merge 4 commits into
base: custom-local-auth-extensions
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,21 @@

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.model.UserDefinedLocalAuthenticatorConfig;
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 +43,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 +64,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 +96,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 +113,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 +188,111 @@ 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 UserDefinedLocalAuthenticatorConfig createUserDefinedLocalAuthenticator(
UserDefinedLocalAuthenticatorConfig 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()));
}
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 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,
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) {
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,81 @@
/*
* 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 {

/**
* 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."),
ERROR_CODE_ENDPOINT_CONFIG_MGT("65005", "Error while managing endpoint configurations.",
"Error while managing endpoint configurations for the user defined local authenticator %s."),;

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,35 @@
/*
* 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;

/**
* Exception class for user defined local authenticator endpoint configurations related exceptions.
*/
public class AuthenticatorEndpointConfigServerException extends AuthenticatorMgtServerException{

public AuthenticatorEndpointConfigServerException(String message) {

super(message);
}

public AuthenticatorEndpointConfigServerException(String errorCode, String message, Throwable throwable) {

super(errorCode, message, throwable);
}
}
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