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 @@ -91,6 +91,8 @@
org.apache.commons.logging; version="${import.package.version.commons.logging}",
org.apache.commons.lang; version="${commons-lang.wso2.osgi.version.range}",
org.apache.commons.collections; version="${commons-collections.wso2.osgi.version.range}",
org.wso2.carbon.database.utils.jdbc; version="${org.wso2.carbon.database.utils.version.range}",
org.wso2.carbon.database.utils.jdbc.exceptions; version="${org.wso2.carbon.database.utils.version.range}",

org.apache.axis2.*; version="${axis2.osgi.version.range}",

Expand All @@ -106,6 +108,9 @@
org.wso2.carbon.identity.core.util; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.core.cache; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.central.log.mgt.*; version="${carbon.identity.package.import.version.range}",
org.wso2.carbon.identity.action.management.*; version="${carbon.identity.package.import.version.range}",
org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}",
org.osgi.service.component; version="${osgi.service.component.imp.pkg.version.range}",

com.fasterxml.jackson.annotation; version="${com.fasterxml.jackson.annotation.version.range}"
</Import-Package>
Expand Down
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());
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved

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,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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* 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 exception.
*/
public class AuthenticatorMgtException extends Exception {

private String errorCode;
private String description;

public AuthenticatorMgtException(String message) {

super(message);
}

public AuthenticatorMgtException(String message, String errorCode, Throwable cause) {

super(message, cause);
this.errorCode = errorCode;
}

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

super(message);
this.errorCode = errorCode;
this.description = description;
}

public AuthenticatorMgtException(String message, String description, String errorCode, Throwable cause) {

super(message, cause);
this.errorCode = errorCode;
this.description = description;
}

public String getErrorCode() {

return this.errorCode;
}

public String getDescription() {

return this.description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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 server exception.
*/
public class AuthenticatorMgtServerException extends AuthenticatorMgtException {

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

super(message, errorCode, description);
}

public AuthenticatorMgtServerException(String errorCode, String message, String description,
Throwable cause) {

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