/** * Copy existing authentication flow under a new name * * <p>The new name is given as 'newName' attribute of the passed JSON object * * @param flowAlias Name of the existing authentication flow * @param data JSON containing 'newName' attribute */ @Path("/flows/{flowAlias}/copy") @POST @NoCache @Consumes(MediaType.APPLICATION_JSON) public Response copy(@PathParam("flowAlias") String flowAlias, Map<String, String> data) { auth.requireManage(); String newName = data.get("newName"); if (realm.getFlowByAlias(newName) != null) { return Response.status(Response.Status.CONFLICT).build(); } AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias); if (flow == null) { logger.debug("flow not found: " + flowAlias); return Response.status(NOT_FOUND).build(); } AuthenticationFlowModel copy = new AuthenticationFlowModel(); copy.setAlias(newName); copy.setDescription(flow.getDescription()); copy.setProviderId(flow.getProviderId()); copy.setBuiltIn(false); copy.setTopLevel(flow.isTopLevel()); copy = realm.addAuthenticationFlow(copy); copy(newName, flow, copy); data.put("id", copy.getId()); adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success(); return Response.status(201).build(); }
/** * Update authentication executions of a flow * * @param flowAlias Flow alias * @param rep */ @Path("/flows/{flowAlias}/executions") @PUT @NoCache @Consumes(MediaType.APPLICATION_JSON) public void updateExecutions( @PathParam("flowAlias") String flowAlias, AuthenticationExecutionInfoRepresentation rep) { auth.requireManage(); AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias); if (flow == null) { logger.debug("flow not found: " + flowAlias); throw new NotFoundException("flow not found"); } AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(rep.getId()); if (model == null) { session.getTransaction().setRollbackOnly(); throw new NotFoundException("Illegal execution"); } if (!model.getRequirement().name().equals(rep.getRequirement())) { model.setRequirement(AuthenticationExecutionModel.Requirement.valueOf(rep.getRequirement())); realm.updateAuthenticatorExecution(model); adminEvent .operation(OperationType.UPDATE) .resourcePath(uriInfo) .representation(rep) .success(); } }
/** * Create a new authentication flow * * @param flow Authentication flow representation * @return */ @Path("/flows") @POST @NoCache @Consumes(MediaType.APPLICATION_JSON) public Response createFlow(AuthenticationFlowRepresentation flow) { auth.requireManage(); if (flow.getAlias() == null || flow.getAlias().isEmpty()) { return ErrorResponse.exists("Failed to create flow with empty alias name"); } if (realm.getFlowByAlias(flow.getAlias()) != null) { return ErrorResponse.exists("Flow " + flow.getAlias() + " already exists"); } AuthenticationFlowModel createdModel = realm.addAuthenticationFlow(RepresentationToModel.toModel(flow)); flow.setId(createdModel.getId()); adminEvent .operation(OperationType.CREATE) .resourcePath(uriInfo, createdModel.getId()) .representation(flow) .success(); return Response.status(201).build(); }
/** * Add new flow with new execution to existing flow * * @param flowAlias Alias of parent authentication flow * @param data New authentication flow / execution JSON data containing 'alias', 'type', * 'provider', and 'description' attributes */ @Path("/flows/{flowAlias}/executions/flow") @POST @NoCache @Consumes(MediaType.APPLICATION_JSON) public void addExecutionFlow(@PathParam("flowAlias") String flowAlias, Map<String, String> data) { auth.requireManage(); AuthenticationFlowModel parentFlow = realm.getFlowByAlias(flowAlias); if (parentFlow == null) { throw new BadRequestException("Parent flow doesn't exists"); } String alias = data.get("alias"); String type = data.get("type"); String provider = data.get("provider"); String description = data.get("description"); AuthenticationFlowModel newFlow = realm.getFlowByAlias(alias); if (newFlow != null) { throw new BadRequestException("New flow alias name already exists"); } newFlow = new AuthenticationFlowModel(); newFlow.setAlias(alias); newFlow.setDescription(description); newFlow.setProviderId(type); newFlow = realm.addAuthenticationFlow(newFlow); AuthenticationExecutionModel execution = new AuthenticationExecutionModel(); execution.setParentFlow(parentFlow.getId()); execution.setFlowId(newFlow.getId()); execution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED); execution.setAuthenticatorFlow(true); execution.setAuthenticator(provider); execution.setPriority(getNextPriority(parentFlow)); execution = realm.addAuthenticatorExecution(execution); data.put("id", execution.getId()); adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success(); }
/** * Add new authentication execution to a flow * * @param flowAlias Alias of parent flow * @param data New execution JSON data containing 'provider' attribute */ @Path("/flows/{flowAlias}/executions/execution") @POST @NoCache @Consumes(MediaType.APPLICATION_JSON) public void addExecution(@PathParam("flowAlias") String flowAlias, Map<String, String> data) { auth.requireManage(); AuthenticationFlowModel parentFlow = realm.getFlowByAlias(flowAlias); if (parentFlow == null) { throw new BadRequestException("Parent flow doesn't exists"); } if (parentFlow.isBuiltIn()) { throw new BadRequestException("It is illegal to add execution to a built in flow"); } String provider = data.get("provider"); // make sure provider is one of the registered providers ProviderFactory f; if (parentFlow.getProviderId().equals(AuthenticationFlow.CLIENT_FLOW)) { f = session .getKeycloakSessionFactory() .getProviderFactory(ClientAuthenticator.class, provider); } else if (parentFlow.getProviderId().equals(AuthenticationFlow.FORM_FLOW)) { f = session.getKeycloakSessionFactory().getProviderFactory(FormAction.class, provider); } else { f = session.getKeycloakSessionFactory().getProviderFactory(Authenticator.class, provider); } if (f == null) { throw new BadRequestException("No authentication provider found for id: " + provider); } AuthenticationExecutionModel execution = new AuthenticationExecutionModel(); execution.setParentFlow(parentFlow.getId()); execution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED); execution.setAuthenticatorFlow(false); execution.setAuthenticator(provider); execution.setPriority(getNextPriority(parentFlow)); execution = realm.addAuthenticatorExecution(execution); data.put("id", execution.getId()); adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(data).success(); }
/** * Get authentication executions for a flow * * @param flowAlias Flow alias */ @Path("/flows/{flowAlias}/executions") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) public Response getExecutions(@PathParam("flowAlias") String flowAlias) { auth.requireView(); AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias); if (flow == null) { logger.debug("flow not found: " + flowAlias); return Response.status(NOT_FOUND).build(); } List<AuthenticationExecutionInfoRepresentation> result = new LinkedList<>(); int level = 0; recurseExecutions(flow, result, level); return Response.ok(result).build(); }