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

Provide support for managing the user defined local authenticators #6172

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@
<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.testutil</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.framework</groupId>
<artifactId>org.wso2.carbon.identity.action.management</artifactId>
Expand Down Expand Up @@ -90,7 +105,11 @@
org.apache.axiom.*; version="${axiom.osgi.version.range}",
org.apache.commons.logging; version="${import.package.version.commons.logging}",
org.apache.commons.lang; version="${commons-lang.wso2.osgi.version.range}",
org.osgi.framework; version="${osgi.framework.imp.pkg.version.range}",
org.osgi.service.component; version="${osgi.service.component.imp.pkg.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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,43 @@

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.AuthenticatorManagementDAO;
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;
import static org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants.Authenticator.DISPLAY_NAME;

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

private static volatile ApplicationAuthenticatorService instance;
private static final Log LOG = LogFactory.getLog(ApplicationAuthenticatorService.class);
private static final AuthenticatorManagementDAO 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 +71,18 @@ public List<LocalAuthenticatorConfig> getLocalAuthenticators() {
return this.localAuthenticators;
}

/**
* This returns user defined local authenticators.
*
* @param tenantDomain Tenant domain.
* @return Retrieved LocalAuthenticatorConfig.
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved
*/
public List<UserDefinedLocalAuthenticatorConfig> getAllUserDefinedLocalAuthenticators(String tenantDomain)
throws AuthenticatorMgtException {

return dao.getAllUserDefinedLocalAuthenticators(IdentityTenantUtil.getTenantId(tenantDomain));
}

public List<FederatedAuthenticatorConfig> getFederatedAuthenticators() {
return this.federatedAuthenticators;
}
Expand All @@ -59,6 +91,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 +110,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 @@ -86,8 +149,18 @@ public RequestPathAuthenticatorConfig getRequestPathAuthenticatorByName(String n
return null;
}

/**
* Add a system defined Local Application Authenticator configuration.
*
* @param authenticator The Local Application Authenticator configuration.
*/
public void addLocalAuthenticator(LocalAuthenticatorConfig authenticator) {
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved

Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved
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 +194,94 @@ 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());

return 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);
if (existingConfig == null) {
throw buildClientException(AuthenticatorMgtError.ERROR_NOT_FOUND_AUTHENTICATOR,
authenticatorConfig.getName());
}

authenticatorValidator.validateForBlank(DISPLAY_NAME, authenticatorConfig.getDisplayName());

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

Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved
UserDefinedLocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator(
authenticatorName, tenantDomain);
if (existingConfig == null) {
return;
}

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 {

return dao.getUserDefinedLocalAuthenticator(
authenticatorName, IdentityTenantUtil.getTenantId(tenantDomain));
}

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

return dao.getUserDefinedLocalAuthenticator(authenticatorName, IdentityTenantUtil.getTenantId(tenantDomain));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.cache;

import org.wso2.carbon.identity.core.cache.BaseCache;
import org.wso2.carbon.utils.CarbonUtils;

/**
* Cache for the user defined local application authenticator configurations.
*/
public class AuthenticatorCache extends BaseCache<AuthenticatorCacheKey, AuthenticatorCacheEntry> {

private static final String CACHE_NAME = "AuthenticatorCache";
private static final AuthenticatorCache INSTANCE = new AuthenticatorCache();

private AuthenticatorCache() {

super(CACHE_NAME);
}

/**
* Get Authenticator cache by the name instance.
*
* @return Authenticator cache by name instance.
*/
public static AuthenticatorCache getInstance() {

CarbonUtils.checkSecurity();
return INSTANCE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.cache;

import org.wso2.carbon.identity.application.common.model.UserDefinedLocalAuthenticatorConfig;
import org.wso2.carbon.identity.core.cache.CacheEntry;

/**
* Cache Entry for the user defined local application authenticator configurations.
*/
public class AuthenticatorCacheEntry extends CacheEntry {

private static final long serialVersionUID = -6234723984328871924L;

private UserDefinedLocalAuthenticatorConfig authenticatorConfig;
Thisara-Welmilla marked this conversation as resolved.
Show resolved Hide resolved

public AuthenticatorCacheEntry(UserDefinedLocalAuthenticatorConfig authenticatorConfig) {

this.authenticatorConfig = authenticatorConfig;
}

public UserDefinedLocalAuthenticatorConfig getAuthenticatorConfig() {

return authenticatorConfig;
}

public void setAuthenticatorConfig(UserDefinedLocalAuthenticatorConfig authenticatorConfig) {

this.authenticatorConfig = authenticatorConfig;
}
}
Loading
Loading