Improvements for openapi annotations in AuthenticationManagementResource

Closes #29788

Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
rmartinc 2024-06-06 13:11:04 +02:00 committed by Marek Posolda
parent 6067f93984
commit 760e01b9db
2 changed files with 71 additions and 15 deletions

View file

@ -908,6 +908,19 @@ public class ModelToRepresentation {
return rep;
}
public static AuthenticationExecutionRepresentation toRepresentation(AuthenticationExecutionModel model) {
AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation();
rep.setId(model.getId());
rep.setAuthenticatorConfig(model.getAuthenticatorConfig());
rep.setAuthenticator(model.getAuthenticator());
rep.setFlowId(model.getFlowId());
rep.setAuthenticatorFlow(model.isAuthenticatorFlow());
rep.setRequirement(model.getRequirement().name());
rep.setPriority(model.getPriority());
rep.setParentFlow(model.getParentFlow());
return rep;
}
public static AuthenticatorConfigRepresentation toRepresentation(AuthenticatorConfigModel model) {
AuthenticatorConfigRepresentation rep = new AuthenticatorConfigRepresentation();
rep.setId(model.getId());

View file

@ -91,8 +91,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
import org.keycloak.utils.RequiredActionHelper;
import org.keycloak.utils.ReservedCharValidator;
@ -121,6 +119,7 @@ public class AuthenticationManagementResource {
* Get form providers
*
* Returns a stream of form providers.
* @return
*/
@Path("/form-providers")
@GET
@ -138,6 +137,7 @@ public class AuthenticationManagementResource {
* Get authenticator providers
*
* Returns a stream of authenticator providers.
* @return
*/
@Path("/authenticator-providers")
@GET
@ -155,6 +155,7 @@ public class AuthenticationManagementResource {
* Get client authenticator providers
*
* Returns a stream of client authenticator providers.
* @return
*/
@Path("/client-authenticator-providers")
@GET
@ -193,6 +194,7 @@ public class AuthenticationManagementResource {
* Get form action providers
*
* Returns a stream of form action providers.
* @return
*/
@Path("/form-action-providers")
@GET
@ -212,6 +214,7 @@ public class AuthenticationManagementResource {
* Get authentication flows
*
* Returns a stream of authentication flows.
* @return
*/
@Path("/flows")
@GET
@ -239,6 +242,7 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Create a new authentication flow")
@APIResponse(responseCode = "201", description = "Created")
public Response createFlow(@Parameter( description = "Authentication flow representation") AuthenticationFlowRepresentation flow) {
auth.realm().requireManageRealm();
@ -289,6 +293,7 @@ public class AuthenticationManagementResource {
/**
* Update an authentication flow
*
* @param id The flow id
* @param flow Authentication flow representation
* @return
*/
@ -299,7 +304,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Update an authentication flow")
public Response updateFlow(@PathParam("id") String id, AuthenticationFlowRepresentation flow) {
@APIResponse(responseCode = "204", description = "No Content")
public void updateFlow(@PathParam("id") String id, AuthenticationFlowRepresentation flow) {
auth.realm().requireManageRealm();
AuthenticationFlowRepresentation existingFlow = getFlow(id);
@ -340,7 +346,6 @@ public class AuthenticationManagementResource {
flow.setId(existingFlow.getId());
realm.updateAuthenticationFlow(RepresentationToModel.toModel(flow));
adminEvent.operation(OperationType.UPDATE).resourcePath(session.getContext().getUri()).representation(flow).success();
return Response.accepted(flow).build();
}
/**
@ -353,6 +358,7 @@ public class AuthenticationManagementResource {
@NoCache
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Delete an authentication flow")
@APIResponse(responseCode = "204", description = "No Content")
public void deleteFlow(@Parameter(description = "Flow id") @PathParam("id") String id) {
auth.realm().requireManageRealm();
@ -379,6 +385,7 @@ public class AuthenticationManagementResource {
*
* @param flowAlias Name of the existing authentication flow
* @param data JSON containing 'newName' attribute
* @return
*/
@Path("/flows/{flowAlias}/copy")
@POST
@ -386,6 +393,7 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Copy existing authentication flow under a new name The new name is given as 'newName' attribute of the passed JSON object")
@APIResponse(responseCode = "201", description = "Created")
public Response copy(@Parameter(description="name of the existing authentication flow") @PathParam("flowAlias") String flowAlias, Map<String, String> data) {
auth.realm().requireManageRealm();
@ -441,7 +449,7 @@ public class AuthenticationManagementResource {
AuthenticatorConfigModel config = configManager.getAuthenticatorConfig(realm, execution.getAuthenticatorConfig());
if (config == null) {
logger.debugf("Authentication execution with id [%s] not found", config.getId());
logger.debugf("Authentication execution configuration with id [%s] not found", execution.getAuthenticatorConfig());
throw new IllegalStateException("Authentication execution configuration not found");
}
@ -472,6 +480,7 @@ public class AuthenticationManagementResource {
*
* @param flowAlias Alias of parent authentication flow
* @param data New authentication flow / execution JSON data containing 'alias', 'type', 'provider', 'priority', and 'description' attributes
* @return
*/
@Path("/flows/{flowAlias}/executions/flow")
@POST
@ -479,6 +488,7 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Add new flow with new execution to existing flow")
@APIResponse(responseCode = "201", description = "Created")
public Response addExecutionFlow(@Parameter(description = "Alias of parent authentication flow") @PathParam("flowAlias") String flowAlias, @Parameter(description = "New authentication flow / execution JSON data containing 'alias', 'type', 'provider', 'priority', and 'description' attributes") Map<String, Object> data) {
auth.realm().requireManageRealm();
@ -536,6 +546,7 @@ public class AuthenticationManagementResource {
*
* @param flowAlias Alias of parent flow
* @param data New execution JSON data containing 'provider' and 'priority' (optional) attribute
* @return
*/
@Path("/flows/{flowAlias}/executions/execution")
@POST
@ -543,6 +554,7 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary="Add new authentication execution to a flow")
@APIResponse(responseCode = "201", description = "Created")
public Response addExecutionToFlow(@Parameter(description = "Alias of parent flow") @PathParam("flowAlias") String flowAlias, @Parameter(description = "New execution JSON data containing 'provider' and 'priority' (optional) attribute") Map<String, Object> data) {
auth.realm().requireManageRealm();
@ -619,6 +631,7 @@ public class AuthenticationManagementResource {
* Get authentication executions for a flow
*
* @param flowAlias Flow alias
* @return The list of executions
*/
@Path("/flows/{flowAlias}/executions")
@GET
@ -626,20 +639,20 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Get authentication executions for a flow")
public Response getExecutions(@Parameter(description = "Flow alias") @PathParam("flowAlias") String flowAlias) {
public List<AuthenticationExecutionInfoRepresentation> getExecutions(@Parameter(description = "Flow alias") @PathParam("flowAlias") String flowAlias) {
auth.realm().requireViewRealm();
AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
if (flow == null) {
logger.debug("flow not found: " + flowAlias);
return Response.status(NOT_FOUND).build();
throw new NotFoundException("Flow not found");
}
List<AuthenticationExecutionInfoRepresentation> result = new LinkedList<>();
int level = 0;
recurseExecutions(flow, result, level);
return Response.ok(result).build();
return result;
}
public void recurseExecutions(AuthenticationFlowModel flow, List<AuthenticationExecutionInfoRepresentation> result, int level) {
@ -721,6 +734,7 @@ public class AuthenticationManagementResource {
* Update authentication executions of a Flow
* @param flowAlias Flow alias
* @param rep AuthenticationExecutionInfoRepresentation
* @return
*/
@Path("/flows/{flowAlias}/executions")
@PUT
@ -729,7 +743,8 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Update authentication executions of a Flow")
public Response updateExecutions(@Parameter(description = "Flow alias") @PathParam("flowAlias") String flowAlias, @Parameter(description = "AuthenticationExecutionInfoRepresentation") AuthenticationExecutionInfoRepresentation rep) {
@APIResponse(responseCode = "204", description = "No Content")
public void updateExecutions(@Parameter(description = "Flow alias") @PathParam("flowAlias") String flowAlias, @Parameter(description = "AuthenticationExecutionInfoRepresentation") AuthenticationExecutionInfoRepresentation rep) {
auth.realm().requireManageRealm();
AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
@ -756,11 +771,13 @@ public class AuthenticationManagementResource {
if (updateExecution) {
realm.updateAuthenticatorExecution(model);
adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(session.getContext().getUri()).representation(rep).success();
return Response.accepted(flow).build();
return;
}
//executions can't have name and description updated
if (rep.getAuthenticationFlow() == null) { return Response.accepted(flow).build();}
if (rep.getAuthenticationFlow() == null) {
return;
}
//check if updating a correct flow
AuthenticationFlowModel checkFlow = realm.getAuthenticationFlowById(rep.getFlowId());
@ -792,11 +809,12 @@ public class AuthenticationManagementResource {
//update the flow
realm.updateAuthenticationFlow(checkFlow);
adminEvent.operation(OperationType.UPDATE).resource(ResourceType.AUTH_EXECUTION).resourcePath(session.getContext().getUri()).representation(rep).success();
return Response.accepted(flow).build();
}
/**
* Get Single Execution
* @param executionId The execution id
* @return
*/
@Path("/executions/{executionId}")
@GET
@ -804,7 +822,7 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Get Single Execution")
public Response getExecution(final @PathParam("executionId") String executionId) {
public AuthenticationExecutionRepresentation getExecution(final @PathParam("executionId") String executionId) {
//http://localhost:8080/auth/admin/realms/master/authentication/executions/cf26211b-9e68-4788-b754-1afd02e59d7f
auth.realm().requireManageRealm();
@ -814,13 +832,14 @@ public class AuthenticationManagementResource {
throw new NotFoundException("Illegal execution");
}
return Response.ok(model.get()).build();
return ModelToRepresentation.toRepresentation(model.get());
}
/**
* Add new authentication execution
*
* @param execution JSON model describing authentication execution
* @return
*/
@Path("/executions")
@POST
@ -828,6 +847,7 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Add new authentication execution")
@APIResponse(responseCode = "201", description = "Created")
public Response addExecution(@Parameter(description = "JSON model describing authentication execution") AuthenticationExecutionRepresentation execution) {
auth.realm().requireManageRealm();
@ -958,6 +978,7 @@ public class AuthenticationManagementResource {
@NoCache
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Delete execution")
@APIResponse(responseCode = "204", description = "No Content")
public void removeExecution(@Parameter(description = "Execution id") @PathParam("executionId") String execution) {
auth.realm().requireManageRealm();
@ -996,6 +1017,7 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Update execution with new configuration")
@APIResponse(responseCode = "201", description = "Created")
public Response newExecutionConfig(@Parameter(description = "Execution id") @PathParam("executionId") String execution, @Parameter(description = "JSON with new configuration") AuthenticatorConfigRepresentation json) {
auth.realm().requireManageRealm();
@ -1025,6 +1047,7 @@ public class AuthenticationManagementResource {
*
* @param execution Execution id
* @param id Configuration id
* @return
* @deprecated Use rather {@link #getAuthenticatorConfig(String)}
*/
@Path("/executions/{executionId}/config/{id}")
@ -1033,6 +1056,7 @@ public class AuthenticationManagementResource {
@NoCache
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Get execution's configuration", deprecated = true)
@Deprecated
public AuthenticatorConfigRepresentation getAuthenticatorConfig(@Parameter(description = "Execution id") @PathParam("executionId") String execution, @Parameter(description = "Configuration id") @PathParam("id") String id) {
auth.realm().requireViewRealm();
@ -1048,6 +1072,7 @@ public class AuthenticationManagementResource {
* Get unregistered required actions
*
* Returns a stream of unregistered required actions.
* @return
*/
@Path("unregistered-required-actions")
@GET
@ -1117,6 +1142,7 @@ public class AuthenticationManagementResource {
* Get required actions
*
* Returns a stream of required actions.
* @return
*/
@Path("required-actions")
@GET
@ -1145,6 +1171,7 @@ public class AuthenticationManagementResource {
/**
* Get required action for alias
* @param alias Alias of required action
* @return The required action representation
*/
@Path("required-actions/{alias}")
@GET
@ -1174,6 +1201,7 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Update required action")
@APIResponse(responseCode = "204", description = "No Content")
public void updateRequiredAction(@Parameter(description = "Alias of required action") @PathParam("alias") String alias, @Parameter(description = "JSON describing new state of required action") RequiredActionProviderRepresentation rep) {
auth.realm().requireManageRealm();
@ -1203,6 +1231,7 @@ public class AuthenticationManagementResource {
@DELETE
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Delete required action")
@APIResponse(responseCode = "204", description = "No Content")
public void removeRequiredAction(@Parameter(description = "Alias of required action") @PathParam("alias") String alias) {
auth.realm().requireManageRealm();
@ -1290,6 +1319,8 @@ public class AuthenticationManagementResource {
/**
* Get required actions provider's configuration description
* @param alias The alias of the required action
* @return The required action configuration representation
*/
@Path("required-actions/{alias}/config-description")
@GET
@ -1318,6 +1349,7 @@ public class AuthenticationManagementResource {
/**
* Get the configuration of the RequiredAction provider in the current Realm.
* @param alias Provider id
* @return The required action configuration representation
*/
@Path("required-actions/{alias}/config")
@GET
@ -1350,6 +1382,7 @@ public class AuthenticationManagementResource {
@NoCache
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Delete RequiredAction configuration")
@APIResponse(responseCode = "204", description = "No Content")
public void removeRequiredActionConfig(@Parameter(description = "Alias of required action") @PathParam("alias") String alias) {
auth.realm().requireManageRealm();
@ -1381,6 +1414,7 @@ public class AuthenticationManagementResource {
@NoCache
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Update RequiredAction configuration")
@APIResponse(responseCode = "204", description = "No Content")
public void updateRequiredActionConfig(@Parameter(description = "Alias of required action") @PathParam("alias") String alias, @Parameter(description = "JSON describing new state of required action configuration") RequiredActionConfigRepresentation rep) {
auth.realm().requireManageRealm();
@ -1410,6 +1444,8 @@ public class AuthenticationManagementResource {
/**
* Get authenticator provider's configuration description
* @param providerId The authenticator provider id
* @return The authenticator configuration representation
*/
@Path("config-description/{providerId}")
@GET
@ -1450,6 +1486,7 @@ public class AuthenticationManagementResource {
/**
* Get configuration descriptions for all clients
* @return
*/
@Path("per-client-config-description")
@GET
@ -1474,6 +1511,7 @@ public class AuthenticationManagementResource {
/**
* Create new authenticator configuration
* @param rep JSON describing new authenticator configuration
* @return
* @deprecated Use {@link #newExecutionConfig(String, AuthenticatorConfigRepresentation)} instead
*/
@Path("config")
@ -1482,6 +1520,8 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Create new authenticator configuration", deprecated = true)
@APIResponse(responseCode = "201", description = "Created")
@Deprecated
public Response createAuthenticatorConfig(@Parameter(description = "JSON describing new authenticator configuration") AuthenticatorConfigRepresentation rep) {
auth.realm().requireManageRealm();
@ -1495,6 +1535,7 @@ public class AuthenticationManagementResource {
/**
* Get authenticator configuration
* @param id Configuration id
* @return The authenticator configuration representation
*/
@Path("config/{id}")
@GET
@ -1522,6 +1563,7 @@ public class AuthenticationManagementResource {
@NoCache
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Delete authenticator configuration")
@APIResponse(responseCode = "204", description = "No Content")
public void removeAuthenticatorConfig(@Parameter(description = "Configuration id") @PathParam("id") String id) {
auth.realm().requireManageRealm();
@ -1553,6 +1595,7 @@ public class AuthenticationManagementResource {
@NoCache
@Tag(name = KeycloakOpenAPI.Admin.Tags.AUTHENTICATION_MANAGEMENT)
@Operation( summary = "Update authenticator configuration")
@APIResponse(responseCode = "204", description = "No Content")
public void updateAuthenticatorConfig(@Parameter(description = "Configuration id") @PathParam("id") String id, @Parameter(description = "JSON describing new state of authenticator configuration") AuthenticatorConfigRepresentation rep) {
auth.realm().requireManageRealm();