Skip to content

Commit

Permalink
Add service layer support for the custom local auth extensions.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thisara-Welmilla committed Nov 13, 2024
1 parent 4a85b28 commit 5a98250
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
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;
Expand Down Expand Up @@ -198,8 +199,9 @@ public void removeRequestPathAuthenticator(RequestPathAuthenticatorConfig authen
* @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 {
public UserDefinedLocalAuthenticatorConfig createUserDefinedLocalAuthenticator(
UserDefinedLocalAuthenticatorConfig authenticatorConfig, AuthenticationType type, String tenantDomain)
throws AuthenticatorMgtException {

LocalAuthenticatorConfig config = getLocalAuthenticatorByName(authenticatorConfig.getName(), tenantDomain);
if (config != null) {
Expand All @@ -221,13 +223,14 @@ public LocalAuthenticatorConfig createUserDefinedLocalAuthenticator(LocalAuthent
* @param authenticatorConfig The Local Application Authenticator configuration.
* @param tenantDomain Tenant Domain.
*
* @return Updated LocalAuthenticatorConfig.
* @return Updated UserDefinedLocalAuthenticatorConfig.
* @throws AuthenticatorMgtException If an error occurs while updating the authenticator configuration.
*/
public LocalAuthenticatorConfig updateUserDefinedLocalAuthenticator(LocalAuthenticatorConfig authenticatorConfig,
String tenantDomain) throws AuthenticatorMgtException {
public UserDefinedLocalAuthenticatorConfig updateUserDefinedLocalAuthenticator(
UserDefinedLocalAuthenticatorConfig authenticatorConfig, String tenantDomain)
throws AuthenticatorMgtException {

LocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator(
UserDefinedLocalAuthenticatorConfig existingConfig = resolveExistingAuthenticator(
authenticatorConfig.getName(), tenantDomain);
authenticatorValidator.validateDefinedByType(existingConfig.getDefinedByType());
authenticatorValidator.validateForBlank("Display name", authenticatorConfig.getDisplayName());
Expand All @@ -247,7 +250,8 @@ public LocalAuthenticatorConfig updateUserDefinedLocalAuthenticator(LocalAuthent
public void deleteUserDefinedLocalAuthenticator(String authenticatorName, String tenantDomain)
throws AuthenticatorMgtException {

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

CACHE_BACKED_DAO.deleteUserDefinedLocalAuthenticator(authenticatorName,
Expand All @@ -260,14 +264,14 @@ public void deleteUserDefinedLocalAuthenticator(String authenticatorName, String
* @param authenticatorName Name of Local Application Authenticator configuration to be deleted.
* @param tenantDomain Tenant domain.
*
* @return Retrieved LocalAuthenticatorConfig.
* @return Retrieved UserDefinedLocalAuthenticatorConfig.
* @throws AuthenticatorMgtException If an error occurs while retrieving the authenticator configuration.
*/
public LocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenticatorName, String tenantDomain)
throws AuthenticatorMgtException {
public UserDefinedLocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenticatorName,
String tenantDomain) throws AuthenticatorMgtException {

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

if (config != null && !config.getDefinedByType().equals(DefinedByType.USER)) {
return null;
Expand All @@ -277,11 +281,11 @@ public LocalAuthenticatorConfig getUserDefinedLocalAuthenticator(String authenti

}

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

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

if (existingAuthenticatorConfig == null) {
ErrorMessages error = ErrorMessages.ERROR_NOT_FOUND_AUTHENTICATOR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ public enum ErrorMessages {
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 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;
Expand Down
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);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* 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.util;

import org.wso2.carbon.identity.action.management.exception.ActionMgtException;
import org.wso2.carbon.identity.action.management.model.Action;
import org.wso2.carbon.identity.action.management.model.EndpointConfig;
import org.wso2.carbon.identity.application.common.exception.AuthenticatorEndpointConfigServerException;
import org.wso2.carbon.identity.application.common.model.Property;
import org.wso2.carbon.identity.application.common.model.UserDefinedAuthenticatorEndpointConfig;
import org.wso2.carbon.identity.application.common.model.UserDefinedLocalAuthenticatorConfig;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static org.wso2.carbon.identity.application.common.constant.AuthenticatorMgtErrorConstants
.ErrorMessages.ERROR_CODE_ENDPOINT_CONFIG_MGT;

/**
* This class responsible for managing authenticator endpoint configurations for the user defined Local
* authenticators.
*/
public class UserDefinedLocalAuthenticatorEndpointConfigManager {

private static final String ACTION_ID_PROPERTY = "actionId";

/**
* Create a new action for given endpoint configurations of the user defined authenticator.
*
* @param config The Local application authenticator configuration.
* @param tenantId The id of Tenant domain.
* @throws AuthenticatorEndpointConfigServerException If an error occurs while adding the action.
*/
public void addEndpointConfigurations(UserDefinedLocalAuthenticatorConfig config, int tenantId)
throws AuthenticatorEndpointConfigServerException {

try {
Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService()
.addAction(Action.ActionTypes.AUTHENTICATION.getPathParam(),
buildActionToCreate(config.getName(), config.getEndpointConfig().getEndpointConfig()),
IdentityTenantUtil.getTenantDomain(tenantId));
Property endpointProperty = new Property();
endpointProperty.setName(ACTION_ID_PROPERTY);
endpointProperty.setValue(action.getId());
config.setProperties(new Property[]{endpointProperty});
} catch (ActionMgtException e) {
throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(),
"Error occurred while adding associated action for the authenticator:" + config.getName(), e);
}
}

/**
* Updated associated action for given updated endpoint configurations of the user defined authenticator.
*
* @param newConfig The Local application authenticator configuration to be updated.
* @param oldConfig The current Local application authenticator configuration.
* @param tenantId The id of Tenant domain.
* @throws AuthenticatorEndpointConfigServerException If an error occurs while updating associated action.
*/
public void updateEndpointConfigurations(UserDefinedLocalAuthenticatorConfig newConfig,
UserDefinedLocalAuthenticatorConfig oldConfig, int tenantId)
throws AuthenticatorEndpointConfigServerException {

String actionId = getActionIdFromProperty(oldConfig.getProperties(), oldConfig.getName());
try {
IdpMgtServiceComponentHolder.getInstance().getActionManagementService()
.updateAction(Action.ActionTypes.AUTHENTICATION.getPathParam(),
actionId,
buildActionToUpdate(newConfig.getEndpointConfig().getEndpointConfig()),
IdentityTenantUtil.getTenantDomain(tenantId));
newConfig.setProperties(oldConfig.getProperties());
} catch (ActionMgtException e) {
throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(),
String.format("Error occurred while updating associated action with id %s for the authenticator %s",
actionId, oldConfig.getName()), e);
}
}

/**
* Retrieve associated action of the user defined authenticator.
*
* @param config The Local application authenticator configuration.
* @param tenantId The id of Tenant domain.
* @return Local authenticator with endpoint configurations resolved.
* @throws AuthenticatorEndpointConfigServerException If an error occurs retrieving updating associated action.
*/
public UserDefinedLocalAuthenticatorConfig resolveEndpointConfigurations(UserDefinedLocalAuthenticatorConfig config,
int tenantId) throws AuthenticatorEndpointConfigServerException {

String actionId = getActionIdFromProperty(config.getProperties(), config.getName());
try {
Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService()
.getActionByActionId(Action.ActionTypes.AUTHENTICATION.getPathParam(),
actionId,
IdentityTenantUtil.getTenantDomain(tenantId));

config.setEndpointConfig(buildUserDefinedAuthenticatorEndpointConfig(action.getEndpoint()));
return config;
} catch (ActionMgtException e) {
throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(),
String.format("Error occurred retrieving associated action with id %s for the authenticator %s",
actionId, config.getName()), e);
}
}

private UserDefinedAuthenticatorEndpointConfig buildUserDefinedAuthenticatorEndpointConfig(
EndpointConfig endpointConfig) {

UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder endpointConfigBuilder =
new UserDefinedAuthenticatorEndpointConfig.UserDefinedAuthenticatorEndpointConfigBuilder();
endpointConfigBuilder.uri(endpointConfig.getUri());
endpointConfigBuilder.authenticationType(endpointConfig.getAuthentication().getType().getName());
Map<String, String> propMap = new HashMap<>();
endpointConfig.getAuthentication().getProperties()
.forEach(prop -> propMap.put(prop.getName(), prop.getValue()));
endpointConfigBuilder.authenticationProperties(propMap);
return endpointConfigBuilder.build();
}

/**
* Delete associated action of the user defined authenticator.
*
* @param config The Local application authenticator configuration.
* @param tenantId The id of Tenant domain.
*
* @throws AuthenticatorEndpointConfigServerException If an error occurs while deleting associated action.
*/
public void deleteEndpointConfigurations(UserDefinedLocalAuthenticatorConfig config, int tenantId) throws
AuthenticatorEndpointConfigServerException {

if (config.getDefinedByType() == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) {
return;
}

String actionId = getActionIdFromProperty(config.getProperties(), config.getName());
try {
IdpMgtServiceComponentHolder.getInstance().getActionManagementService()
.deleteAction(Action.ActionTypes.AUTHENTICATION.getPathParam(),
actionId,
IdentityTenantUtil.getTenantDomain(tenantId));
} catch (ActionMgtException e) {
throw new AuthenticatorEndpointConfigServerException(ERROR_CODE_ENDPOINT_CONFIG_MGT.getCode(),
String.format("Error occurred while deleting associated action with id %s for the authenticator %s",
actionId, config.getName()), e);
}
}

private Action buildActionToCreate(String authenticatorName, EndpointConfig endpointConfig) {

Action.ActionRequestBuilder actionRequestBuilder = new Action.ActionRequestBuilder();
actionRequestBuilder.name(authenticatorName);
actionRequestBuilder.description(String.format("This is the action associated to the user defined Local" +
"authenticator %s.", authenticatorName));
actionRequestBuilder.endpoint(endpointConfig);

return actionRequestBuilder.build();
}

private Action buildActionToUpdate(EndpointConfig endpointConfig) {

Action.ActionRequestBuilder actionRequestBuilder = new Action.ActionRequestBuilder();
actionRequestBuilder.endpoint(endpointConfig);

return actionRequestBuilder.build();
}

private String getActionIdFromProperty(Property[] properties, String authenticatorName)
throws AuthenticatorEndpointConfigServerException {

return Arrays.stream(properties)
.filter(property -> ACTION_ID_PROPERTY.equals(property.getName()))
.map(Property::getValue)
.findFirst()
.orElseThrow(() -> new AuthenticatorEndpointConfigServerException(
"No action Id was found in the properties of the authenticator configurations for" +
" the authenticator: " + authenticatorName));
}
}
Loading

0 comments on commit 5a98250

Please sign in to comment.