public DemoApplication(@Context ServletContext servletContext) { super(servletContext); KeycloakSession session = factory.createSession(); session.getTransaction().begin(); install(new RealmManager(session)); session.getTransaction().commit(); }
public void run() { final ArrayList<LoginEvent> events = new ArrayList<LoginEvent>(TRANSACTION_SIZE + 1); while (run) { try { LoginEvent take = queue.poll(2, TimeUnit.SECONDS); if (take == null) { continue; } try { events.add(take); queue.drainTo(events, TRANSACTION_SIZE); for (LoginEvent event : events) { if (event instanceof FailedLogin) { logFailure(event); } else { logSuccess(event); } } Collections.sort( events); // we sort to avoid deadlock due to ordered updates. Maybe I'm overthinking // this. KeycloakSession session = factory.createSession(); try { for (LoginEvent event : events) { if (event instanceof FailedLogin) { failure(session, event); } } session.getTransaction().commit(); } catch (Exception e) { session.getTransaction().rollback(); throw e; } finally { for (LoginEvent event : events) { if (event instanceof FailedLogin) { ((FailedLogin) event).latch.countDown(); } } events.clear(); session.close(); } } catch (Exception e) { logger.error("Failed processing event", e); } } catch (InterruptedException e) { break; } finally { shutdownLatch.countDown(); } } }
/** * Delete execution * * @param execution Execution id */ @Path("/executions/{executionId}") @DELETE @NoCache public void removeExecution(@PathParam("executionId") String execution) { auth.requireManage(); AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution); if (model == null) { session.getTransaction().setRollbackOnly(); throw new NotFoundException("Illegal execution"); } AuthenticationFlowModel parentFlow = getParentFlow(model); if (parentFlow.isBuiltIn()) { throw new BadRequestException("It is illegal to remove execution from a built in flow"); } if (model.getFlowId() != null) { AuthenticationFlowModel nonTopLevelFlow = realm.getAuthenticationFlowById(model.getFlowId()); realm.removeAuthenticationFlow(nonTopLevelFlow); } realm.removeAuthenticatorExecution(model); adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); }
/** * Lower execution's priority * * @param execution Execution id */ @Path("/executions/{executionId}/lower-priority") @POST @NoCache public void lowerPriority(@PathParam("executionId") String execution) { auth.requireManage(); AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution); if (model == null) { session.getTransaction().setRollbackOnly(); throw new NotFoundException("Illegal execution"); } AuthenticationFlowModel parentFlow = getParentFlow(model); if (parentFlow.isBuiltIn()) { throw new BadRequestException("It is illegal to modify execution in a built in flow"); } List<AuthenticationExecutionModel> executions = getSortedExecutions(parentFlow); int i = 0; for (i = 0; i < executions.size(); i++) { if (executions.get(i).getId().equals(model.getId())) { break; } } if (i + 1 >= executions.size()) return; AuthenticationExecutionModel next = executions.get(i + 1); int tmp = model.getPriority(); model.setPriority(next.getPriority()); realm.updateAuthenticatorExecution(model); next.setPriority(tmp); realm.updateAuthenticatorExecution(next); adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success(); }
/** * Raise execution's priority * * @param execution Execution id */ @Path("/executions/{executionId}/raise-priority") @POST @NoCache public void raisePriority(@PathParam("executionId") String execution) { auth.requireManage(); AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution); if (model == null) { session.getTransaction().setRollbackOnly(); throw new NotFoundException("Illegal execution"); } AuthenticationFlowModel parentFlow = getParentFlow(model); if (parentFlow.isBuiltIn()) { throw new BadRequestException("It is illegal to modify execution in a built in flow"); } List<AuthenticationExecutionModel> executions = getSortedExecutions(parentFlow); AuthenticationExecutionModel previous = null; for (AuthenticationExecutionModel exe : executions) { if (exe.getId().equals(model.getId())) { break; } previous = exe; } if (previous == null) return; int tmp = previous.getPriority(); previous.setPriority(model.getPriority()); realm.updateAuthenticatorExecution(previous); model.setPriority(tmp); realm.updateAuthenticatorExecution(model); adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).success(); }
/** * 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(); } }
protected void setupKeycloak() { KeycloakSession session = server.getKeycloakSessionFactory().createSession(); session.getTransaction().begin(); try { RealmManager manager = new RealmManager(session); RealmModel adminstrationRealm = manager.getRealm(Config.getAdminRealm()); configure(manager, adminstrationRealm); session.getTransaction().commit(); } finally { session.close(); } }
/** * Update the user * * @param id User id * @param rep * @return */ @Path("{id}") @PUT @Consumes(MediaType.APPLICATION_JSON) public Response updateUser(final @PathParam("id") String id, final UserRepresentation rep) { auth.requireManage(); try { UserModel user = session.users().getUserById(id, realm); if (user == null) { throw new NotFoundException("User not found"); } Set<String> attrsToRemove; if (rep.getAttributes() != null) { attrsToRemove = new HashSet<>(user.getAttributes().keySet()); attrsToRemove.removeAll(rep.getAttributes().keySet()); } else { attrsToRemove = Collections.emptySet(); } if (rep.isEnabled() != null && rep.isEnabled()) { UsernameLoginFailureModel failureModel = session.sessions().getUserLoginFailure(realm, rep.getUsername().toLowerCase()); if (failureModel != null) { failureModel.clearFailures(); } } updateUserFromRep(user, rep, attrsToRemove, realm, session); adminEvent .operation(OperationType.UPDATE) .resourcePath(uriInfo) .representation(rep) .success(); if (session.getTransaction().isActive()) { session.getTransaction().commit(); } return Response.noContent().build(); } catch (ModelDuplicateException e) { return ErrorResponse.exists("User exists with same username or email"); } catch (ModelReadOnlyException re) { return ErrorResponse.exists("User is read only!"); } }
/** * Create a new user * * <p>Username must be unique. * * @param uriInfo * @param rep * @return */ @POST @Consumes(MediaType.APPLICATION_JSON) public Response createUser(final @Context UriInfo uriInfo, final UserRepresentation rep) { auth.requireManage(); // Double-check duplicated username and email here due to federation if (session.users().getUserByUsername(rep.getUsername(), realm) != null) { return ErrorResponse.exists("User exists with same username"); } if (rep.getEmail() != null && session.users().getUserByEmail(rep.getEmail(), realm) != null) { return ErrorResponse.exists("User exists with same email"); } try { UserModel user = session.users().addUser(realm, rep.getUsername()); Set<String> emptySet = Collections.emptySet(); updateUserFromRep(user, rep, emptySet, realm, session); adminEvent .operation(OperationType.CREATE) .resourcePath(uriInfo, user.getId()) .representation(rep) .success(); if (session.getTransaction().isActive()) { session.getTransaction().commit(); } return Response.created(uriInfo.getAbsolutePathBuilder().path(user.getId()).build()).build(); } catch (ModelDuplicateException e) { if (session.getTransaction().isActive()) { session.getTransaction().setRollbackOnly(); } return ErrorResponse.exists("User exists with same username or email"); } }
/** * Update execution with new configuration * * @param execution Execution id * @param json JSON with new configuration * @return */ @Path("/executions/{executionId}/config") @POST @NoCache @Consumes(MediaType.APPLICATION_JSON) public Response newExecutionConfig( @PathParam("executionId") String execution, AuthenticatorConfigRepresentation json) { auth.requireManage(); AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution); if (model == null) { session.getTransaction().setRollbackOnly(); throw new NotFoundException("Illegal execution"); } AuthenticatorConfigModel config = RepresentationToModel.toModel(json); config = realm.addAuthenticatorConfig(config); model.setAuthenticatorConfig(config.getId()); realm.updateAuthenticatorExecution(model); json.setId(config.getId()); adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(json).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build(); }