Skip to content

Commit

Permalink
Add support for managing custom federated authenticators.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thisara-Welmilla committed Nov 5, 2024
1 parent 80fa63d commit e887bdf
Show file tree
Hide file tree
Showing 8 changed files with 374 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
<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.action.management</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ public class FederatedAuthenticatorConfig implements Serializable {
@XmlElement(name = "DefinedBy")
protected DefinedByType definedByType;

public FederatedAuthenticatorConfig() {

definedByType = DefinedByType.SYSTEM;
}

public static FederatedAuthenticatorConfig build(OMElement federatedAuthenticatorConfigOM) {

if (federatedAuthenticatorConfigOM == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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.model;

import org.wso2.carbon.identity.action.management.model.EndpointConfig;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.AuthenticationType;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType;

/**
* Verification authenticator configuration.
*/
public class UserDefinedFederatedAuthenticatorConfig extends FederatedAuthenticatorConfig {

private static final String TAG_2FA = "2FA";
private static final String TAG_CUSTOM = "CUSTOM";

protected EndpointConfig endpointConfig;

public UserDefinedFederatedAuthenticatorConfig(AuthenticationType type) {

definedByType = DefinedByType.USER;
if (AuthenticationType.VERIFICATION == type) {
setTags(new String[]{TAG_CUSTOM, TAG_2FA});
} else {
setTags(new String[]{TAG_CUSTOM});
}
}

/**
* Get the endpoint config of the Local authenticator config.
*
* @return DefinedByType
*/
public EndpointConfig getEndpointConfig() {

return endpointConfig;
}

/**
* Set the defined by type of the Local authenticator config.
*
* @param endpointConfig The endpoint config of the local authenticator config.
*/
public void setEndpointConfig(EndpointConfig endpointConfig) {

this.endpointConfig = endpointConfig;
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.identity.action.management.ActionManagementService;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants;
import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService;
Expand Down Expand Up @@ -490,4 +491,21 @@ protected void unsetClaimMetaMgtService(ClaimMetadataManagementService claimMeta

IdpMgtServiceComponentHolder.getInstance().setClaimMetadataManagementService(null);
}

@Reference(
name = "action.management.service",
service = ActionManagementService.class,
cardinality = ReferenceCardinality.MANDATORY,
policy = ReferencePolicy.DYNAMIC,
unbind = "unsetActionManagementService"
)
protected void setActionManagementService(ActionManagementService actionManagementService) {

IdpMgtServiceComponentHolder.getInstance().setActionManagementService(actionManagementService);
}

protected void unsetActionManagementService(ActionManagementService actionManagementService) {

IdpMgtServiceComponentHolder.getInstance().setActionManagementService(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.wso2.carbon.idp.mgt.internal;

import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.identity.action.management.ActionManagementService;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants;
import org.wso2.carbon.identity.claim.metadata.mgt.ClaimMetadataManagementService;
Expand Down Expand Up @@ -53,7 +54,6 @@ public static IdpMgtServiceComponentHolder getInstance() {
private volatile List<ConnectorConfig> identityConnectorConfigList = new ArrayList<>();
private RoleManagementService roleManagementService;
private ClaimMetadataManagementService claimMetadataManagementService;
private SecretsProcessor<IdentityProvider> idpSecretsProcessorService;

private List<MetadataConverter> metadataConverters = new ArrayList<>();

Expand Down Expand Up @@ -155,4 +155,14 @@ public void setClaimMetadataManagementService(ClaimMetadataManagementService cla

this.claimMetadataManagementService = claimMetadataManagementService;
}

public ActionManagementService getActionManagementService() {

return actionManagementService;
}

public void setActionManagementService(ActionManagementService actionManagementService) {

this.actionManagementService = actionManagementService;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* 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.idp.mgt.util;

import org.wso2.carbon.identity.action.management.ActionManagementService;
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.model.FederatedAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.Property;
import org.wso2.carbon.identity.application.common.model.UserDefinedFederatedAuthenticatorConfig;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants;
import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
import org.wso2.carbon.idp.mgt.IdentityProviderManagementServerException;
import org.wso2.carbon.idp.mgt.internal.IdpMgtServiceComponentHolder;

import static org.wso2.carbon.idp.mgt.util.IdPManagementConstants.ErrorMessage.ERROR_CODE_ASSOCIATED_ACTION_MGT;

/**
* This class responsible for managing authenticator endpoint configurations as the actions associated.
*/
public class AuthenticatorEndpointConfigurationManager {

private final String ACTION_ID_PROPERTY = "actionId";

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

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

try {
UserDefinedFederatedAuthenticatorConfig castedConfig = (UserDefinedFederatedAuthenticatorConfig) config;
Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService().addAction(Action.ActionTypes.AUTHENTICATION.toString(),
buildActionToCreate(castedConfig.getName(), castedConfig.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 IdentityProviderManagementServerException(ERROR_CODE_ASSOCIATED_ACTION_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 federated application authenticator configuration to be updated.
* @param oldConfig The current federated application authenticator configuration.
* @param tenantId The id of Tenant domain.
*
* @throws IdentityProviderManagementServerException If an error occurs while updating associated action.
*/
public void updateEndpointConfigurations(FederatedAuthenticatorConfig newConfig, FederatedAuthenticatorConfig oldConfig,
int tenantId) throws IdentityProviderManagementServerException {

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

String actionId = getActionIdFromProperty(oldConfig.getProperties());
try {
UserDefinedFederatedAuthenticatorConfig castedConfig = (UserDefinedFederatedAuthenticatorConfig) newConfig;
IdpMgtServiceComponentHolder.getInstance().getActionManagementService().updateAction(
Action.ActionTypes.AUTHENTICATION.toString(), actionId, buildActionToUpdate(
castedConfig.getEndpointConfig()), IdentityTenantUtil.getTenantDomain(tenantId));
} catch (ActionMgtException e) {
throw new IdentityProviderManagementServerException(ERROR_CODE_ASSOCIATED_ACTION_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 federated application authenticator configuration.
* @param tenantId The id of Tenant domain.
*
* @throws IdentityProviderManagementServerException If an error occurs retrieving updating associated action.
*/
public FederatedAuthenticatorConfig resolveEndpointConfigurations(FederatedAuthenticatorConfig config,
int tenantId) throws IdentityProviderManagementServerException {

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

String actionId = getActionIdFromProperty(config.getProperties());
try {
UserDefinedFederatedAuthenticatorConfig castedConfig = (UserDefinedFederatedAuthenticatorConfig) config;
Action action = IdpMgtServiceComponentHolder.getInstance().getActionManagementService()
.getActionByActionId(Action.ActionTypes.AUTHENTICATION.toString(),
actionId, IdentityTenantUtil.getTenantDomain(tenantId));
castedConfig.setEndpointConfig(action.getEndpoint());
return castedConfig;
} catch (ActionMgtException e) {
throw new IdentityProviderManagementServerException(ERROR_CODE_ASSOCIATED_ACTION_MGT.getCode(),
String.format("Error occurred retrieving associated action with id %s for the authenticator %s",
actionId, config.getName()), e);
}
}

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

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

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

public FederatedAuthenticatorConfig createFederatedAuthenticatorConfig(AuthenticatorPropertyConstants.DefinedByType
definedByType) {

if (definedByType == AuthenticatorPropertyConstants.DefinedByType.SYSTEM) {
return new FederatedAuthenticatorConfig();
}

return new UserDefinedFederatedAuthenticatorConfig(
AuthenticatorPropertyConstants.AuthenticationType.Identification);
}

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 federated" +
"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) throws IdentityProviderManagementServerException {
for (Property property : properties) {
if (ACTION_ID_PROPERTY.equals(property.getName())) {
return property.getValue();
}
}
throw new IdentityProviderManagementServerException(String.format("No action id found from the property."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,8 @@ public enum ErrorMessage {
"applications of Identity Provider with resource ID: %s."),
ERROR_CODE_VALIDATING_OUTBOUND_PROVISIONING_ROLES("IDP-65008", "Error while validating " +
"the outbound provisioning roles"),
ERROR_CODE_RETRIEVING_IDP_GROUPS("IDP-65009", "Error while retrieving IDP groups");
ERROR_CODE_RETRIEVING_IDP_GROUPS("IDP-65009", "Error while retrieving IDP groups"),
ERROR_CODE_ASSOCIATED_ACTION_MGT("IDP-65010", "Error occurred with associated action management."),;

private final String code;
private final String message;
Expand Down

0 comments on commit e887bdf

Please sign in to comment.