Skip to content

Commit

Permalink
Update APIs to support custom authentication management.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thisara-Welmilla committed Dec 2, 2024
1 parent b959007 commit 0f33431
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public ApplicationAuthenticatorService getApplicationAuthenticatorService() {
*
* @param applicationAuthenticatorService ApplicationAuthenticatorService.
*/
public void setApplicationCommonService(ApplicationAuthenticatorService applicationAuthenticatorService) {
public void setApplicationAuthenticatorService(ApplicationAuthenticatorService applicationAuthenticatorService) {

AuthenticatorsServiceHolder.getInstance().applicationAuthenticatorService = applicationAuthenticatorService;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ private Constants() {
public static final String AUTHENTICATOR_ERROR_PREFIX = "AUT-";
public static final String FEDERATED_AUTHENTICATORS = "federatedAuthenticators";
public static final String AUTHENTICATOR_PATH_COMPONENT = "/authenticators";
public static final String CONFIGS_AUTHENTICATOR_PATH_COMPONENT = "/configs/authenticators";
public static final String PATH_SEPERATOR = "/";
public static final String PAGE_LINK_REL_NEXT = "next";
public static final String PAGE_LINK_REL_PREVIOUS = "previous";
Expand Down Expand Up @@ -70,8 +71,10 @@ public enum ErrorMessage {
"Filter needs to be in the format <attribute>+<operation>+<value>. Eg: tag+eq+2FA"),
ERROR_CODE_UNSUPPORTED_FILTER_ATTRIBUTE("60002", "Unsupported filter attribute.",
"The filter attribute '%s' is not supported."),
ERROR_CODE_ENDPOINT_CONFIG("60003", "Unsupported filter attribute.",
"The filter attribute '%s' is not supported."),
ERROR_CODE_INVALID_ENDPOINT_CONFIG("60003", "Invalid endpoint configuration provided.",
"Invalid endpoint configuration is provided for the authenticator %s."),
ERROR_CODE_ERROR_AUTHENTICATOR_NOT_FOUND("60004", "Authenticator not found.",
"Authenticator not found by the given name: %s."),

ERROR_CODE_ERROR_LISTING_AUTHENTICATORS("65001", "Unable to list the existing authenticators.",
"Server encountered an error while listing the authenticators."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,30 @@ public class AuthenticatorsApi {
@Autowired
private AuthenticatorsApiService delegate;

@Valid
@POST
@Path("/custom")
@Consumes({ "application/json" })
@Produces({ "application/json" })
@ApiOperation(value = "Create a new user defined local authenticator. ", notes = "This API provides the capability to create a new user defined local authenticator. <br> <b>Permission required:</b> <br> * /permission/admin/manage/custom_authenticator/create <br> <b>Scope required:</b> <br> * internal_custom_authenticator_create <br> ", response = Authenticator.class, authorizations = {
@Authorization(value = "BasicAuth"),
@Authorization(value = "OAuth2", scopes = {

})
}, tags={ "User defined local authenticators", })
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Successful response", response = Authenticator.class),
@ApiResponse(code = 400, message = "Bad Request", response = Error.class),
@ApiResponse(code = 401, message = "Unauthorized", response = Void.class),
@ApiResponse(code = 403, message = "Forbidden", response = Void.class),
@ApiResponse(code = 409, message = "Conflict", response = Error.class),
@ApiResponse(code = 500, message = "Server Error", response = Error.class)
})
public Response addUserDefinedLocalAuthenticator(@ApiParam(value = "This represents the user defined local authenticator to be created." ,required=true) @Valid UserDefinedLocalAuthenticatorCreation userDefinedLocalAuthenticatorCreation) {

return delegate.addUserDefinedLocalAuthenticator(userDefinedLocalAuthenticatorCreation );
}

@Valid
@GET

Expand Down Expand Up @@ -93,30 +117,6 @@ public Response authenticatorsMetaTagsGet() {
return delegate.authenticatorsMetaTagsGet();
}

@Valid
@POST
@Path("/custom")
@Consumes({ "application/json" })
@Produces({ "application/json" })
@ApiOperation(value = "Create a new user defined local authenticator. ", notes = "This API provides the capability to create a new user defined local authenticator. <br> <b>Permission required:</b> <br> * /permission/admin/manage/custom_authenticator/create <br> <b>Scope required:</b> <br> * internal_custom_authenticator_create <br> ", response = Authenticator.class, authorizations = {
@Authorization(value = "BasicAuth"),
@Authorization(value = "OAuth2", scopes = {

})
}, tags={ "User defined local authenticators", })
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Successful response", response = Authenticator.class),
@ApiResponse(code = 400, message = "Bad Request", response = Error.class),
@ApiResponse(code = 401, message = "Unauthorized", response = Void.class),
@ApiResponse(code = 403, message = "Forbidden", response = Void.class),
@ApiResponse(code = 409, message = "Conflict", response = Error.class),
@ApiResponse(code = 500, message = "Server Error", response = Error.class)
})
public Response addUserDefinedLocalAuthenticator(@ApiParam(value = "This represents the user defined local authenticator to be created." ,required=true) @Valid UserDefinedLocalAuthenticatorCreation userDefinedLocalAuthenticatorCreation) {

return delegate.addUserDefinedLocalAuthenticator(userDefinedLocalAuthenticatorCreation );
}

@Valid
@DELETE
@Path("/custom/{authenticator-id}")
Expand Down Expand Up @@ -166,7 +166,7 @@ public Response getConnectedAppsOfLocalAuthenticator(@ApiParam(value = "ID of an
}

@Valid
@PATCH
@PUT
@Path("/custom/{authenticator-id}")
@Consumes({ "application/json" })
@Produces({ "application/json" })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@

public interface AuthenticatorsApiService {

public Response addUserDefinedLocalAuthenticator(UserDefinedLocalAuthenticatorCreation userDefinedLocalAuthenticatorCreation);

public Response authenticatorsGet(String filter, Integer limit, Integer offset);

public Response authenticatorsMetaTagsGet();

public Response addUserDefinedLocalAuthenticator(UserDefinedLocalAuthenticatorCreation userDefinedLocalAuthenticatorCreation);

public Response deleteUserDefinedLocalAuthenticator(String authenticatorId);

public Response getConnectedAppsOfLocalAuthenticator(String authenticatorId, Integer limit, Integer offset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
public class UserDefinedLocalAuthenticatorCreation {

private String name;
private String id;
private String displayName;
private Boolean isEnabled;

Expand Down Expand Up @@ -97,6 +98,24 @@ public void setName(String name) {
this.name = name;
}

/**
**/
public UserDefinedLocalAuthenticatorCreation id(String id) {

this.id = id;
return this;
}

@ApiModelProperty(example = "Q3VzdG9tQXV0aGVudGljYXRvcg==", value = "")
@JsonProperty("id")
@Valid
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}

/**
**/
public UserDefinedLocalAuthenticatorCreation displayName(String displayName) {
Expand Down Expand Up @@ -224,6 +243,7 @@ public boolean equals(java.lang.Object o) {
}
UserDefinedLocalAuthenticatorCreation userDefinedLocalAuthenticatorCreation = (UserDefinedLocalAuthenticatorCreation) o;
return Objects.equals(this.name, userDefinedLocalAuthenticatorCreation.name) &&
Objects.equals(this.id, userDefinedLocalAuthenticatorCreation.id) &&
Objects.equals(this.displayName, userDefinedLocalAuthenticatorCreation.displayName) &&
Objects.equals(this.isEnabled, userDefinedLocalAuthenticatorCreation.isEnabled) &&
Objects.equals(this.authenticationType, userDefinedLocalAuthenticatorCreation.authenticationType) &&
Expand All @@ -234,7 +254,7 @@ public boolean equals(java.lang.Object o) {

@Override
public int hashCode() {
return Objects.hash(name, displayName, isEnabled, authenticationType, image, description, endpoint);
return Objects.hash(name, id, displayName, isEnabled, authenticationType, image, description, endpoint);
}

@Override
Expand All @@ -244,6 +264,7 @@ public String toString() {
sb.append("class UserDefinedLocalAuthenticatorCreation {\n");

sb.append(" name: ").append(toIndentedString(name)).append("\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" displayName: ").append(toIndentedString(displayName)).append("\n");
sb.append(" isEnabled: ").append(toIndentedString(isEnabled)).append("\n");
sb.append(" authenticationType: ").append(toIndentedString(authenticationType)).append("\n");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
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.base.AuthenticatorPropertyConstants;
import org.wso2.carbon.identity.base.AuthenticatorPropertyConstants.DefinedByType;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.core.model.ExpressionNode;
Expand Down Expand Up @@ -214,12 +213,10 @@ public Authenticator addUserDefinedLocalAuthenticator(
UserDefinedLocalAuthenticatorConfig createdConfig = AuthenticatorsServiceHolder.getInstance()
.getApplicationAuthenticatorService().addUserDefinedLocalAuthenticator(
LocalAuthenticatorConfigBuilderFactory.build(config),
AuthenticatorPropertyConstants.AuthenticationType.valueOf(config.getAuthenticationType()
.toString()), CarbonContext.getThreadLocalCarbonContext().getTenantDomain());
CarbonContext.getThreadLocalCarbonContext().getTenantDomain());
return LocalAuthenticatorConfigBuilderFactory.build(createdConfig);
} catch (AuthenticatorMgtException e) {
throw handleAuthenticatorException(e, Constants.ErrorMessage
.ERROR_CODE_ERROR_RETRIEVING_IDP_CONNECTED_APPS, config.getName());
throw handleAuthenticatorException(e);
}
}

Expand All @@ -231,11 +228,11 @@ public Authenticator addUserDefinedLocalAuthenticator(
public void deleteUserDefinedLocalAuthenticator(String authenticatorId) {

try {
AuthenticatorsServiceHolder.getInstance().getApplicationAuthenticatorService().deleteUserDefinedLocalAuthenticator(
authenticatorId, CarbonContext.getThreadLocalCarbonContext().getTenantDomain());
AuthenticatorsServiceHolder.getInstance().getApplicationAuthenticatorService()
.deleteUserDefinedLocalAuthenticator(authenticatorId,
CarbonContext.getThreadLocalCarbonContext().getTenantDomain());
} catch (AuthenticatorMgtException e) {
throw handleAuthenticatorException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_RETRIEVING_IDP_CONNECTED_APPS,
authenticatorId);
throw handleAuthenticatorException(e);
}
}

Expand All @@ -256,16 +253,15 @@ public Authenticator updateUserDefinedLocalAuthenticator(
.getApplicationAuthenticatorService().getLocalAuthenticatorByName(authenticatorName, tenantDomain);
if (existingAuthenticator == null) {
throw handleException(Response.Status.NOT_FOUND,
Constants.ErrorMessage.ERROR_CODE_ERROR_RETRIEVING_IDP_CONNECTED_APPS, authenticatorName);
Constants.ErrorMessage.ERROR_CODE_ERROR_AUTHENTICATOR_NOT_FOUND, authenticatorName);
}
UserDefinedLocalAuthenticatorConfig updatedConfig = AuthenticatorsServiceHolder.getInstance()
.getApplicationAuthenticatorService().updateUserDefinedLocalAuthenticator(
LocalAuthenticatorConfigBuilderFactory.build(config, existingAuthenticator),
tenantDomain);
return LocalAuthenticatorConfigBuilderFactory.build(updatedConfig);
} catch (AuthenticatorMgtException e) {
throw handleAuthenticatorException(e, Constants.ErrorMessage.ERROR_CODE_ERROR_RETRIEVING_IDP_CONNECTED_APPS,
authenticatorId);
throw handleAuthenticatorException(e);
}
}

Expand Down Expand Up @@ -989,17 +985,15 @@ private APIError handleIdPException(IdentityProviderManagementException e,
* in the response.
*
* @param e IdentityProviderManagementException.
* @param errorEnum Error information.
* @return APIError.
*/
private APIError handleAuthenticatorException(AuthenticatorMgtException e,
Constants.ErrorMessage errorEnum, String data) {
private APIError handleAuthenticatorException(AuthenticatorMgtException e) {

ErrorResponse errorResponse;
ErrorResponse errorResponse = new ErrorResponse.Builder().withCode(e.getErrorCode()).withMessage(e.getMessage())
.withDescription(e.getDescription()).build();
Response.Status status;

if (e instanceof AuthenticatorMgtClientException) {
errorResponse = getErrorBuilder(errorEnum, data).build(log, e.getMessage());
if (e.getErrorCode() != null) {
String errorCode = e.getErrorCode();
errorCode =
Expand All @@ -1009,9 +1003,7 @@ private APIError handleAuthenticatorException(AuthenticatorMgtException e,
}
errorResponse.setDescription(e.getMessage());
status = Response.Status.BAD_REQUEST;

} else if (e instanceof AuthenticatorMgtServerException) {
errorResponse = getErrorBuilder(errorEnum, data).build(log, e, errorEnum.getDescription());
if (e.getErrorCode() != null) {
String errorCode = e.getErrorCode();
errorCode =
Expand All @@ -1022,7 +1014,6 @@ private APIError handleAuthenticatorException(AuthenticatorMgtException e,
errorResponse.setDescription(e.getMessage());
status = Response.Status.INTERNAL_SERVER_ERROR;
} else {
errorResponse = getErrorBuilder(errorEnum, data).build(log, e, errorEnum.getDescription());
status = Response.Status.INTERNAL_SERVER_ERROR;
}
return new APIError(status, errorResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@
import java.util.NoSuchElementException;
import java.util.stream.Collectors;

import static org.wso2.carbon.identity.api.server.authenticators.common.Constants.AUTHENTICATOR_PATH_COMPONENT;
import static org.wso2.carbon.identity.api.server.authenticators.common.Constants.ErrorMessage.ERROR_CODE_ENDPOINT_CONFIG;
import static org.wso2.carbon.identity.api.server.authenticators.common.Constants.CONFIGS_AUTHENTICATOR_PATH_COMPONENT;
import static org.wso2.carbon.identity.api.server.authenticators.common.Constants.ErrorMessage.ERROR_CODE_INVALID_ENDPOINT_CONFIG;
import static org.wso2.carbon.identity.api.server.common.Constants.V1_API_PATH_COMPONENT;
import static org.wso2.carbon.identity.api.server.common.Util.base64URLEncode;

/**
* The factory class for building user defined local authenticator configuration related models.
Expand All @@ -54,12 +55,14 @@ public static Authenticator build(UserDefinedLocalAuthenticatorConfig config) {

Authenticator authenticator = new Authenticator();
authenticator.setName(config.getName());
authenticator.setId(base64URLEncode(config.getName()));
authenticator.setDisplayName(config.getDisplayName());
authenticator.setIsEnabled(config.isEnabled());
authenticator.setDefinedBy(Authenticator.DefinedByEnum.USER);
authenticator.setType(Authenticator.TypeEnum.LOCAL);
authenticator.setTags(Arrays.asList(config.getTags()));
authenticator.setSelf(ContextLoader.buildURIForBody(String.format(V1_API_PATH_COMPONENT +
AUTHENTICATOR_PATH_COMPONENT + "/%s", config.getName())).toString());
CONFIGS_AUTHENTICATOR_PATH_COMPONENT + "/%s", config.getName())).toString());

return authenticator;
}
Expand All @@ -77,6 +80,8 @@ public static UserDefinedLocalAuthenticatorConfig build(UserDefinedLocalAuthenti
UserDefinedLocalAuthenticatorConfig authConfig = new UserDefinedLocalAuthenticatorConfig(
AuthenticatorPropertyConstants.AuthenticationType.valueOf(
config.getAuthenticationType().toString()));
authConfig.setAuthenticationType(AuthenticatorPropertyConstants.AuthenticationType.valueOf(
config.getAuthenticationType().toString()));
authConfig.setName(config.getName());
authConfig.setDisplayName(config.getDisplayName());
authConfig.setEnabled(config.getIsEnabled());
Expand Down Expand Up @@ -119,7 +124,7 @@ private static UserDefinedAuthenticatorEndpointConfig buildEndpointConfig(Endpoi
Map.Entry::getKey, entry -> entry.getValue().toString())));
return endpointConfigBuilder.build();
} catch (NoSuchElementException e) {
Constants.ErrorMessage error = ERROR_CODE_ENDPOINT_CONFIG;
Constants.ErrorMessage error = ERROR_CODE_INVALID_ENDPOINT_CONFIG;
throw new AuthenticatorMgtClientException(error.getCode(), error.getMessage(), error.getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ paths:
description: This represents the user defined local authenticator to be created.
required: true
/authenticators/custom/{authenticator-id}:
patch:
put:
tags:
- User defined local authenticators
summary: |
Expand Down Expand Up @@ -381,6 +381,9 @@ components:
name:
type: string
example: CustomAuthenticator
id:
type: string
example: Q3VzdG9tQXV0aGVudGljYXRvcg==
displayName:
type: string
example: Custom auth
Expand Down

0 comments on commit 0f33431

Please sign in to comment.