@Path("email-verification") @GET public Response emailVerification( @QueryParam("code") String code, @QueryParam("key") String key) { event.event(EventType.VERIFY_EMAIL); if (key != null) { Checks checks = new Checks(); if (!checks.verifyCode(key, ClientSessionModel.Action.VERIFY_EMAIL.name())) { return checks.response; } ClientSessionCode accessCode = checks.clientCode; ClientSessionModel clientSession = accessCode.getClientSession(); UserSessionModel userSession = clientSession.getUserSession(); UserModel user = userSession.getUser(); initEvent(clientSession); user.setEmailVerified(true); user.removeRequiredAction(RequiredAction.VERIFY_EMAIL); event.event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, user.getEmail()).success(); String actionCookieValue = getActionCookie(); if (actionCookieValue == null || !actionCookieValue.equals(userSession.getId())) { session.sessions().removeClientSession(realm, clientSession); return session .getProvider(LoginFormsProvider.class) .setSuccess(Messages.EMAIL_VERIFIED) .createInfoPage(); } event = event.clone().removeDetail(Details.EMAIL).event(EventType.LOGIN); return AuthenticationManager.nextActionAfterAuthentication( session, userSession, clientSession, clientConnection, request, uriInfo, event); } else { Checks checks = new Checks(); if (!checks.verifyCode(code, ClientSessionModel.Action.VERIFY_EMAIL.name())) { return checks.response; } ClientSessionCode accessCode = checks.clientCode; ClientSessionModel clientSession = accessCode.getClientSession(); UserSessionModel userSession = clientSession.getUserSession(); initEvent(clientSession); createActionCookie(realm, uriInfo, clientConnection, userSession.getId()); return session .getProvider(LoginFormsProvider.class) .setClientSessionCode(accessCode.getCode()) .setUser(userSession.getUser()) .createResponse(RequiredAction.VERIFY_EMAIL); } }
/** * Send a update account email to the user * * <p>An email contains a link the user can click to perform a set of required actions. The * redirectUri and clientId parameters are optional. The default for the redirect is the account * client. * * @param id User is * @param redirectUri Redirect uri * @param clientId Client id * @param actions required actions the user needs to complete * @return */ @Path("{id}/execute-actions-email") @PUT @Consumes(MediaType.APPLICATION_JSON) public Response executeActionsEmail( @PathParam("id") String id, @QueryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM) String redirectUri, @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId, List<String> actions) { auth.requireManage(); UserModel user = session.users().getUserById(id, realm); if (user == null) { return ErrorResponse.error("User not found", Response.Status.NOT_FOUND); } if (user.getEmail() == null) { return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST); } ClientSessionModel clientSession = createClientSession(user, redirectUri, clientId); for (String action : actions) { clientSession.addRequiredAction(action); } ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession); accessCode.setAction(ClientSessionModel.Action.EXECUTE_ACTIONS.name()); try { UriBuilder builder = Urls.executeActionsBuilder(uriInfo.getBaseUri()); builder.queryParam("key", accessCode.getCode()); String link = builder.build(realm.getName()).toString(); long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction()); this.session .getProvider(EmailTemplateProvider.class) .setRealm(realm) .setUser(user) .sendExecuteActions(link, expiration); // audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, // accessCode.getCodeId()).success(); adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success(); return Response.ok().build(); } catch (EmailException e) { logger.failedToSendActionsEmail(e); return ErrorResponse.error( "Failed to send execute actions email", Response.Status.INTERNAL_SERVER_ERROR); } }
@Override public Response authenticated(UserSessionModel userSession, ClientSessionCode accessCode) { ClientSessionModel clientSession = accessCode.getClientSession(); setupResponseTypeAndMode(clientSession); String redirect = clientSession.getRedirectUri(); OIDCRedirectUriBuilder redirectUri = OIDCRedirectUriBuilder.fromUri(redirect, responseMode); String state = clientSession.getNote(OIDCLoginProtocol.STATE_PARAM); logger.debugv("redirectAccessCode: state: {0}", state); if (state != null) redirectUri.addParam(OAuth2Constants.STATE, state); // Standard or hybrid flow if (responseType.hasResponseType(OIDCResponseType.CODE)) { accessCode.setAction(ClientSessionModel.Action.CODE_TO_TOKEN.name()); redirectUri.addParam(OAuth2Constants.CODE, accessCode.getCode()); } // Implicit or hybrid flow if (responseType.isImplicitOrHybridFlow()) { TokenManager tokenManager = new TokenManager(); AccessTokenResponse res = tokenManager .responseBuilder( realm, clientSession.getClient(), event, session, userSession, clientSession) .generateAccessToken() .generateIDToken() .build(); if (responseType.hasResponseType(OIDCResponseType.ID_TOKEN)) { redirectUri.addParam("id_token", res.getIdToken()); } if (responseType.hasResponseType(OIDCResponseType.TOKEN)) { redirectUri.addParam("access_token", res.getToken()); redirectUri.addParam("token_type", res.getTokenType()); redirectUri.addParam("session-state", res.getSessionState()); redirectUri.addParam("expires_in", String.valueOf(res.getExpiresIn())); } redirectUri.addParam("not-before-policy", String.valueOf(res.getNotBeforePolicy())); } return redirectUri.build(); }
@Path("federated-identity-update") @GET public Response processFederatedIdentityUpdate( @QueryParam("action") String action, @QueryParam("provider_id") String providerId, @QueryParam("stateChecker") String stateChecker) { if (auth == null) { return login("identity"); } require(AccountRoles.MANAGE_ACCOUNT); csrfCheck(stateChecker); UserModel user = auth.getUser(); if (Validation.isEmpty(providerId)) { setReferrerOnPage(); return account .setError(Messages.MISSING_IDENTITY_PROVIDER) .createResponse(AccountPages.FEDERATED_IDENTITY); } AccountSocialAction accountSocialAction = AccountSocialAction.getAction(action); if (accountSocialAction == null) { setReferrerOnPage(); return account .setError(Messages.INVALID_FEDERATED_IDENTITY_ACTION) .createResponse(AccountPages.FEDERATED_IDENTITY); } boolean hasProvider = false; for (IdentityProviderModel model : realm.getIdentityProviders()) { if (model.getAlias().equals(providerId)) { hasProvider = true; } } if (!hasProvider) { setReferrerOnPage(); return account .setError(Messages.IDENTITY_PROVIDER_NOT_FOUND) .createResponse(AccountPages.FEDERATED_IDENTITY); } if (!user.isEnabled()) { setReferrerOnPage(); return account .setError(Messages.ACCOUNT_DISABLED) .createResponse(AccountPages.FEDERATED_IDENTITY); } switch (accountSocialAction) { case ADD: String redirectUri = UriBuilder.fromUri( Urls.accountFederatedIdentityPage(uriInfo.getBaseUri(), realm.getName())) .build() .toString(); try { ClientSessionModel clientSession = auth.getClientSession(); ClientSessionCode clientSessionCode = new ClientSessionCode(realm, clientSession); clientSessionCode.setAction(ClientSessionModel.Action.AUTHENTICATE.name()); clientSession.setRedirectUri(redirectUri); clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString()); return Response.temporaryRedirect( Urls.identityProviderAuthnRequest( this.uriInfo.getBaseUri(), providerId, realm.getName(), clientSessionCode.getCode())) .build(); } catch (Exception spe) { setReferrerOnPage(); return account .setError(Messages.IDENTITY_PROVIDER_REDIRECT_ERROR) .createResponse(AccountPages.FEDERATED_IDENTITY); } case REMOVE: FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm); if (link != null) { // Removing last social provider is not possible if you don't have other possibility to // authenticate if (session.users().getFederatedIdentities(user, realm).size() > 1 || user.getFederationLink() != null || isPasswordSet(user)) { session.users().removeFederatedIdentity(realm, user, providerId); logger.debugv( "Social provider {0} removed successfully from user {1}", providerId, user.getUsername()); event .event(EventType.REMOVE_FEDERATED_IDENTITY) .client(auth.getClient()) .user(auth.getUser()) .detail(Details.USERNAME, link.getUserId() + "@" + link.getIdentityProvider()) .success(); setReferrerOnPage(); return account .setSuccess(Messages.IDENTITY_PROVIDER_REMOVED) .createResponse(AccountPages.FEDERATED_IDENTITY); } else { setReferrerOnPage(); return account .setError(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER) .createResponse(AccountPages.FEDERATED_IDENTITY); } } else { setReferrerOnPage(); return account .setError(Messages.FEDERATED_IDENTITY_NOT_ACTIVE) .createResponse(AccountPages.FEDERATED_IDENTITY); } default: throw new IllegalArgumentException(); } }