diff --git a/forms/src/main/java/org/keycloak/forms/UrlBean.java b/forms/src/main/java/org/keycloak/forms/UrlBean.java index cb82aaa6ba..0fb83c0c34 100644 --- a/forms/src/main/java/org/keycloak/forms/UrlBean.java +++ b/forms/src/main/java/org/keycloak/forms/UrlBean.java @@ -108,8 +108,16 @@ public class UrlBean { } } - public String getPasswordResetUrl() { - return Urls.accountPasswordReset(baseURI, realm.getId()).toString(); + public String getLoginUpdatePasswordUrl() { + return Urls.loginActionUpdatePassword(baseURI, realm.getId()).toString(); + } + + public String getLoginUpdateTotpUrl() { + return Urls.loginActionUpdateTotp(baseURI, realm.getId()).toString(); + } + + public String getLoginUpdateProfileUrl() { + return Urls.loginActionUpdateProfile(baseURI, realm.getId()).toString(); } public String getSocialUrl() { @@ -124,8 +132,12 @@ public class UrlBean { return Urls.accountTotpRemove(baseURI, realm.getId()).toString(); } - public String getEmailVerificationUrl() { - return Urls.accountEmailVerification(baseURI, realm.getId()).toString(); + public String getLoginPasswordResetUrl() { + return Urls.loginPasswordReset(baseURI, realm.getId()).toString(); + } + + public String getLoginEmailVerificationUrl() { + return Urls.loginActionEmailVerification(baseURI, realm.getId()).toString(); } } diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl index 9b3cca5326..2b1c1c5c9a 100755 --- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl +++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-config-totp.ftl @@ -27,7 +27,7 @@
  • 3Enter the one-time-password provided by Google Authenticator below and click Submit to finish the setup.

    -
    +
    diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl index 60ae59a4cf..ad80199ed5 100755 --- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl +++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-reset-password.ftl @@ -21,7 +21,7 @@

    ${rb.getString('emailInstruction')}

    - +
    diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl index a9b1ed24fd..4db19119b4 100755 --- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl +++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-password.ftl @@ -11,7 +11,7 @@ <#elseif section = "form">
    - +
    diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl index fb9a8e47ba..2683d2f29d 100755 --- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl +++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-update-profile.ftl @@ -15,7 +15,7 @@ <#elseif section = "form">
    - + diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl index d92c349235..cff75f1086 100755 --- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl +++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login-verify-email.ftl @@ -20,7 +20,7 @@ Your account is not enabled. An email with instructions to verify your email address has been sent to you.

    Haven't received a verification code in your email? - Click here to re-send the email. + Click here to re-send the email.

    diff --git a/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl b/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl index 863118e86b..7e63046d97 100755 --- a/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl +++ b/forms/src/main/resources/META-INF/resources/forms/theme/default/login.ftl @@ -24,7 +24,7 @@
    -

    Forgot Password?

    +

    Forgot Password?

    diff --git a/services/src/main/java/org/keycloak/services/email/EmailSender.java b/services/src/main/java/org/keycloak/services/email/EmailSender.java index 93f59f9f74..6fd09075bf 100755 --- a/services/src/main/java/org/keycloak/services/email/EmailSender.java +++ b/services/src/main/java/org/keycloak/services/email/EmailSender.java @@ -79,7 +79,7 @@ public class EmailSender { } public void sendEmailVerification(UserModel user, RealmModel realm, AccessCodeEntry accessCode, UriInfo uriInfo) { - UriBuilder builder = Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "emailVerification"); + UriBuilder builder = Urls.loginActionEmailVerificationBuilder(uriInfo.getBaseUri()); builder.queryParam("key", accessCode.getId()); URI uri = builder.build(realm.getId()); @@ -103,7 +103,7 @@ public class EmailSender { } public void sendPasswordReset(UserModel user, RealmModel realm, AccessCodeEntry accessCode, UriInfo uriInfo) { - UriBuilder builder = Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "passwordPage"); + UriBuilder builder = Urls.loginPasswordResetBuilder(uriInfo.getBaseUri()); builder.queryParam("key", accessCode.getId()); URI uri = builder.build(realm.getId()); diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java index 2874971439..7f54e5232a 100755 --- a/services/src/main/java/org/keycloak/services/resources/AccountService.java +++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java @@ -98,8 +98,7 @@ public class AccountService { @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processAccountUpdate(final MultivaluedMap formData) { - AccessCodeEntry accessCodeEntry = getAccessCodeEntry(RequiredAction.UPDATE_PROFILE); - UserModel user = accessCodeEntry != null ? getUserFromAccessCode(accessCodeEntry) : getUserFromAuthManager(); + UserModel user = getUserFromAuthManager(); if (user == null) { return Response.status(Status.FORBIDDEN).build(); } @@ -108,60 +107,7 @@ public class AccountService { user.setLastName(formData.getFirst("lastName")); user.setEmail(formData.getFirst("email")); - user.removeRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE); - if (accessCodeEntry != null) { - accessCodeEntry.getRequiredActions().remove(UserModel.RequiredAction.UPDATE_PROFILE); - } - - if (accessCodeEntry != null) { - return redirectOauth(user, accessCodeEntry); - } else { - return Flows.forms(realm, request, uriInfo).setUser(user).forwardToAccount(); - } - } - - private UserModel getUserFromAccessCode(AccessCodeEntry accessCodeEntry) { - String loginName = accessCodeEntry.getUser().getLoginName(); - return realm.getUser(loginName); - } - - private UserModel getUserFromAuthManager() { - return authManager.authenticateIdentityCookie(realm, uriInfo, headers); - } - - private AccessCodeEntry getAccessCodeEntry(RequiredAction requiredAction) { - String code = uriInfo.getQueryParameters().getFirst(FormFlows.CODE); - if (code == null) { - return null; - } - - JWSInput input = new JWSInput(code, providers); - boolean verifiedCode = false; - try { - verifiedCode = RSAProvider.verify(input, realm.getPublicKey()); - } catch (Exception ignored) { - return null; - } - - if (!verifiedCode) { - return null; - } - - String key = input.readContent(String.class); - AccessCodeEntry accessCodeEntry = tokenManager.getAccessCode(key); - if (accessCodeEntry == null) { - return null; - } - - if (accessCodeEntry.isExpired()) { - return null; - } - - if (accessCodeEntry.getRequiredActions() == null || !accessCodeEntry.getRequiredActions().contains(requiredAction)) { - return null; - } - - return accessCodeEntry; + return Flows.forms(realm, request, uriInfo).setUser(user).forwardToAccount(); } @Path("totp-remove") @@ -177,8 +123,7 @@ public class AccountService { @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processTotpUpdate(final MultivaluedMap formData) { - AccessCodeEntry accessCodeEntry = getAccessCodeEntry(RequiredAction.CONFIGURE_TOTP); - UserModel user = accessCodeEntry != null ? getUserFromAccessCode(accessCodeEntry) : getUserFromAuthManager(); + UserModel user = getUserFromAuthManager(); if (user == null) { return Response.status(Status.FORBIDDEN).build(); } @@ -205,150 +150,39 @@ public class AccountService { credentials.setValue(formData.getFirst("totpSecret")); realm.updateCredential(user, credentials); - user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); - if (accessCodeEntry != null) { - accessCodeEntry.getRequiredActions().remove(UserModel.RequiredAction.CONFIGURE_TOTP); - } - user.setTotp(true); - if (accessCodeEntry != null) { - return redirectOauth(user, accessCodeEntry); - } else { - return Flows.forms(realm, request, uriInfo).setError("successTotp").setErrorType(FormFlows.ErrorType.SUCCESS) - .setUser(user).forwardToTotp(); - } - } - - @Path("password-reset") - @GET - public Response passwordReset() { - return Flows.forms(realm, request, uriInfo).forwardToPasswordReset(); - } - - @Path("password-reset") - @POST - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - public Response sendPasswordReset(final MultivaluedMap formData) { - String username = formData.getFirst("username"); - String email = formData.getFirst("email"); - - String scopeParam = uriInfo.getQueryParameters().getFirst("scope"); - String state = uriInfo.getQueryParameters().getFirst("state"); - String redirect = uriInfo.getQueryParameters().getFirst("redirect_uri"); - String clientId = uriInfo.getQueryParameters().getFirst("client_id"); - - UserModel client = realm.getUser(clientId); - if (client == null) { - return Flows.oauth(realm, request, uriInfo, authManager, tokenManager).forwardToSecurityFailure( - "Unknown login requester."); - } - if (!client.isEnabled()) { - return Flows.oauth(realm, request, uriInfo, authManager, tokenManager).forwardToSecurityFailure( - "Login requester not enabled."); - } - - UserModel user = realm.getUser(username); - if (user == null || !email.equals(user.getEmail())) { - return Flows.forms(realm, request, uriInfo).setError("emailError").forwardToPasswordReset(); - } - - Set requiredActions = new HashSet(user.getRequiredActions()); - requiredActions.add(RequiredAction.UPDATE_PASSWORD); - - AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, realm, client, user); - accessCode.setRequiredActions(requiredActions); - accessCode.setExpiration(System.currentTimeMillis() / 1000 + realm.getAccessCodeLifespanUserAction()); - - new EmailSender().sendPasswordReset(user, realm, accessCode, uriInfo); - - return Flows.forms(realm, request, uriInfo).setError("emailSent").setErrorType(FormFlows.ErrorType.SUCCESS) - .forwardToPasswordReset(); - } - - @Path("email-verification") - @GET - public Response emailVerification() { - if (uriInfo.getQueryParameters().containsKey("key")) { - AccessCodeEntry accessCode = tokenManager.getAccessCode(uriInfo.getQueryParameters().getFirst("key")); - if (accessCode == null || accessCode.isExpired() - || !accessCode.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL)) { - return Response.status(Status.FORBIDDEN).build(); - } - - String loginName = accessCode.getUser().getLoginName(); - UserModel user = realm.getUser(loginName); - user.setEmailVerified(true); - user.removeRequiredAction(RequiredAction.VERIFY_EMAIL); - - accessCode.getRequiredActions().remove(RequiredAction.VERIFY_EMAIL); - - return redirectOauth(user, accessCode); - } else { - AccessCodeEntry accessCode = getAccessCodeEntry(RequiredAction.VERIFY_EMAIL); - UserModel user = accessCode != null ? getUserFromAccessCode(accessCode) : null; - if (user == null) { - return Response.status(Status.FORBIDDEN).build(); - } - - return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode).setUser(user) - .forwardToAction(RequiredAction.VERIFY_EMAIL); - } - } - - private Response redirectOauth(UserModel user, AccessCodeEntry accessCode) { - if (accessCode == null) { - return null; - } - - Set requiredActions = user.getRequiredActions(); - if (!requiredActions.isEmpty()) { - return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode).setUser(user) - .forwardToAction(requiredActions.iterator().next()); - } else { - accessCode.setExpiration((System.currentTimeMillis() / 1000) + realm.getAccessCodeLifespan()); - return Flows.oauth(realm, request, uriInfo, authManager, tokenManager).redirectAccessCode(accessCode, - accessCode.getState(), accessCode.getRedirectUri()); - } + return Flows.forms(realm, request, uriInfo).setError("successTotp").setErrorType(FormFlows.ErrorType.SUCCESS) + .setUser(user).forwardToTotp(); } @Path("password") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processPasswordUpdate(final MultivaluedMap formData) { - AccessCodeEntry accessCode = getAccessCodeEntry(RequiredAction.UPDATE_PASSWORD); - UserModel user = accessCode != null ? getUserFromAccessCode(accessCode) : getUserFromAuthManager(); + UserModel user = getUserFromAuthManager(); if (user == null) { return Response.status(Status.FORBIDDEN).build(); } - boolean loginAction = accessCode != null; - FormFlows forms = Flows.forms(realm, request, uriInfo).setUser(user); String password = formData.getFirst("password"); String passwordNew = formData.getFirst("password-new"); String passwordConfirm = formData.getFirst("password-confirm"); - String error = null; - if (Validation.isEmpty(passwordNew)) { - error = Messages.MISSING_PASSWORD; + forms.setError(Messages.MISSING_PASSWORD).forwardToPassword(); } else if (!passwordNew.equals(passwordConfirm)) { - error = Messages.INVALID_PASSWORD_CONFIRM; + forms.setError(Messages.INVALID_PASSWORD_CONFIRM).forwardToPassword(); } - if (!loginAction) { - if (Validation.isEmpty(password)) { - error = Messages.MISSING_PASSWORD; - } else if (!realm.validatePassword(user, password)) { - error = Messages.INVALID_PASSWORD_EXISTING; - } + if (Validation.isEmpty(password)) { + forms.setError(Messages.MISSING_PASSWORD).forwardToPassword(); + } else if (!realm.validatePassword(user, password)) { + forms.setError(Messages.INVALID_PASSWORD_EXISTING).forwardToPassword(); } - if (error != null) { - return forms.setError(error).forwardToPassword(); - } UserCredentialModel credentials = new UserCredentialModel(); credentials.setType(CredentialRepresentation.PASSWORD); @@ -356,16 +190,7 @@ public class AccountService { realm.updateCredential(user, credentials); - user.removeRequiredAction(RequiredAction.UPDATE_PASSWORD); - if (accessCode != null) { - accessCode.getRequiredActions().remove(UserModel.RequiredAction.UPDATE_PASSWORD); - } - - if (accessCode != null) { - return redirectOauth(user, accessCode); - } else { - return Flows.forms(realm, request, uriInfo).setUser(user).forwardToPassword(); - } + return Flows.forms(realm, request, uriInfo).setUser(user).forwardToPassword(); } @Path("") @@ -404,21 +229,14 @@ public class AccountService { @Path("password") @GET public Response passwordPage() { - if (uriInfo.getQueryParameters().containsKey("key")) { - AccessCodeEntry accessCode = tokenManager.getAccessCode(uriInfo.getQueryParameters().getFirst("key")); - if (accessCode == null || accessCode.isExpired() - || !accessCode.getRequiredActions().contains(RequiredAction.UPDATE_PASSWORD)) { - return Response.status(Status.FORBIDDEN).build(); - } - - return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode) - .forwardToAction(RequiredAction.UPDATE_PASSWORD); - } else { - UserModel user = getUserFromAuthManager(); - if (user == null) { - return Response.status(Status.FORBIDDEN).build(); - } - return Flows.forms(realm, request, uriInfo).setUser(user).forwardToPassword(); + UserModel user = getUserFromAuthManager(); + if (user == null) { + return Response.status(Status.FORBIDDEN).build(); } + return Flows.forms(realm, request, uriInfo).setUser(user).forwardToPassword(); + } + + private UserModel getUserFromAuthManager() { + return authManager.authenticateIdentityCookie(realm, uriInfo, headers); } } diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java index ee344b8e92..214a814a8a 100755 --- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java +++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java @@ -29,6 +29,7 @@ import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserModel.RequiredAction; import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.services.email.EmailSender; import org.keycloak.services.managers.AccessCodeEntry; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.TokenManager; @@ -43,8 +44,8 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.*; -import javax.ws.rs.core.Response.Status; import javax.ws.rs.ext.Providers; +import java.util.HashSet; import java.util.Set; /** @@ -75,7 +76,7 @@ public class RequiredActionsService { this.tokenManager = tokenManager; } - @Path("") + @Path("profile") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response updateProfile(final MultivaluedMap formData) { @@ -98,7 +99,7 @@ public class RequiredActionsService { @Path("totp") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - public Response configureTotp(final MultivaluedMap formData) { + public Response updateTotp(final MultivaluedMap formData) { AccessCodeEntry accessCode = getAccessCodeEntry(RequiredAction.CONFIGURE_TOTP); if (accessCode == null) { return forwardToErrorPage(); @@ -129,39 +130,10 @@ public class RequiredActionsService { return redirectOauth(user, accessCode); } - - @Path("email-verification") - @GET - public Response emailVerification() { - if (uriInfo.getQueryParameters().containsKey("key")) { - AccessCodeEntry accessCode = tokenManager.getAccessCode(uriInfo.getQueryParameters().getFirst("key")); - if (accessCode == null || accessCode.isExpired() - || !accessCode.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL)) { - return forwardToErrorPage(); - } - - UserModel user = getUser(accessCode); - user.setEmailVerified(true); - - user.removeRequiredAction(RequiredAction.VERIFY_EMAIL); - accessCode.getRequiredActions().remove(RequiredAction.VERIFY_EMAIL); - - return redirectOauth(user, accessCode); - } else { - AccessCodeEntry accessCode = getAccessCodeEntry(RequiredAction.VERIFY_EMAIL); - if (accessCode == null) { - return forwardToErrorPage(); - } - - return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode).setUser(accessCode.getUser()) - .forwardToAction(RequiredAction.VERIFY_EMAIL); - } - } - @Path("password") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - public Response resetPassword(final MultivaluedMap formData) { + public Response updatePassword(final MultivaluedMap formData) { AccessCodeEntry accessCode = getAccessCodeEntry(RequiredAction.UPDATE_PASSWORD); if (accessCode == null) { return forwardToErrorPage(); @@ -198,6 +170,90 @@ public class RequiredActionsService { } } + + @Path("email-verification") + @GET + public Response emailVerification() { + if (uriInfo.getQueryParameters().containsKey("key")) { + AccessCodeEntry accessCode = tokenManager.getAccessCode(uriInfo.getQueryParameters().getFirst("key")); + if (accessCode == null || accessCode.isExpired() + || !accessCode.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL)) { + return forwardToErrorPage(); + } + + UserModel user = getUser(accessCode); + user.setEmailVerified(true); + + user.removeRequiredAction(RequiredAction.VERIFY_EMAIL); + accessCode.getRequiredActions().remove(RequiredAction.VERIFY_EMAIL); + + return redirectOauth(user, accessCode); + } else { + AccessCodeEntry accessCode = getAccessCodeEntry(RequiredAction.VERIFY_EMAIL); + if (accessCode == null) { + return forwardToErrorPage(); + } + + return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode).setUser(accessCode.getUser()) + .forwardToAction(RequiredAction.VERIFY_EMAIL); + } + } + + @Path("password-reset") + @GET + public Response passwordReset() { + if (uriInfo.getQueryParameters().containsKey("key")) { + AccessCodeEntry accessCode = tokenManager.getAccessCode(uriInfo.getQueryParameters().getFirst("key")); + if (accessCode == null || accessCode.isExpired() + || !accessCode.getRequiredActions().contains(RequiredAction.UPDATE_PASSWORD)) { + return forwardToErrorPage(); + } + return Flows.forms(realm, request, uriInfo).setAccessCode(accessCode).forwardToAction(RequiredAction.UPDATE_PASSWORD); + } else { + return Flows.forms(realm, request, uriInfo).forwardToPasswordReset(); + } + } + + @Path("password-reset") + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public Response sendPasswordReset(final MultivaluedMap formData) { + String username = formData.getFirst("username"); + String email = formData.getFirst("email"); + + String scopeParam = uriInfo.getQueryParameters().getFirst("scope"); + String state = uriInfo.getQueryParameters().getFirst("state"); + String redirect = uriInfo.getQueryParameters().getFirst("redirect_uri"); + String clientId = uriInfo.getQueryParameters().getFirst("client_id"); + + UserModel client = realm.getUser(clientId); + if (client == null) { + return Flows.oauth(realm, request, uriInfo, authManager, tokenManager).forwardToSecurityFailure( + "Unknown login requester."); + } + if (!client.isEnabled()) { + return Flows.oauth(realm, request, uriInfo, authManager, tokenManager).forwardToSecurityFailure( + "Login requester not enabled."); + } + + UserModel user = realm.getUser(username); + if (user == null || !email.equals(user.getEmail())) { + return Flows.forms(realm, request, uriInfo).setError("emailError").forwardToPasswordReset(); + } + + Set requiredActions = new HashSet(user.getRequiredActions()); + requiredActions.add(RequiredAction.UPDATE_PASSWORD); + + AccessCodeEntry accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, realm, client, user); + accessCode.setRequiredActions(requiredActions); + accessCode.setExpiration(System.currentTimeMillis() / 1000 + realm.getAccessCodeLifespanUserAction()); + + new EmailSender().sendPasswordReset(user, realm, accessCode, uriInfo); + + return Flows.forms(realm, request, uriInfo).setError("emailSent").setErrorType(FormFlows.ErrorType.SUCCESS) + .forwardToPasswordReset(); + } + private AccessCodeEntry getAccessCodeEntry(RequiredAction requiredAction) { String code = uriInfo.getQueryParameters().getFirst(FormFlows.CODE); if (code == null) { diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java index c8bfd0ec8b..d72e80d9d4 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -30,6 +30,7 @@ import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.container.ResourceContext; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; @@ -75,6 +76,8 @@ public class TokenService { @Context protected KeycloakTransaction transaction; + @Context + protected ResourceContext resourceContext; private ResourceAdminManager resourceAdminManager = new ResourceAdminManager(); @@ -219,7 +222,9 @@ public class TokenService { @Path("auth/request/login-actions") public RequiredActionsService getRequiredActionsService() { - return new RequiredActionsService(realm, tokenManager); + RequiredActionsService service = new RequiredActionsService(realm, tokenManager); + resourceContext.initResource(service); + return service; } private void isTotpConfigurationRequired(UserModel user) { diff --git a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java index b6a86a2cd4..200b746ea3 100755 --- a/services/src/main/java/org/keycloak/services/resources/flows/Urls.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/Urls.java @@ -35,7 +35,7 @@ public class Urls { return accountBase(baseUri).path(AccountService.class, "accessPage").build(realmId); } - public static UriBuilder accountBase(URI baseUri) { + private static UriBuilder accountBase(URI baseUri) { return realmBase(baseUri).path(RealmsResource.class, "getAccountService"); } @@ -59,12 +59,32 @@ public class Urls { return accountBase(baseUri).path(AccountService.class, "processTotpRemove").build(realmId); } - public static URI accountEmailVerification(URI baseUri, String realmId) { - return accountBase(baseUri).path(AccountService.class, "emailVerification").build(realmId); + public static URI loginActionUpdatePassword(URI baseUri, String realmId) { + return requiredActionsBase(baseUri).path(RequiredActionsService.class, "updatePassword").build(realmId); } - public static URI accountPasswordReset(URI baseUri, String realmId) { - return accountBase(baseUri).path(AccountService.class, "passwordReset").build(realmId); + public static URI loginActionUpdateTotp(URI baseUri, String realmId) { + return requiredActionsBase(baseUri).path(RequiredActionsService.class, "updateTotp").build(realmId); + } + + public static URI loginActionUpdateProfile(URI baseUri, String realmId) { + return requiredActionsBase(baseUri).path(RequiredActionsService.class, "updateProfile").build(realmId); + } + + public static URI loginActionEmailVerification(URI baseUri, String realmId) { + return loginActionEmailVerificationBuilder(baseUri).build(realmId); + } + + public static UriBuilder loginActionEmailVerificationBuilder(URI baseUri) { + return requiredActionsBase(baseUri).path(RequiredActionsService.class, "emailVerification"); + } + + public static URI loginPasswordReset(URI baseUri, String realmId) { + return loginPasswordResetBuilder(baseUri).build(realmId); + } + + public static UriBuilder loginPasswordResetBuilder(URI baseUri) { + return requiredActionsBase(baseUri).path(RequiredActionsService.class, "passwordReset"); } private static UriBuilder realmBase(URI baseUri) { @@ -120,11 +140,15 @@ public class Urls { .build(realmId); } - private static UriBuilder tokenBase(URI baseUri) { - return realmBase(baseUri).path(RealmsResource.class, "getTokenService"); - } - public static URI socialRegisterAction(URI baseUri, String realmId) { return socialBase(baseUri).path(SocialResource.class, "socialRegistration").build(realmId); } + + private static UriBuilder requiredActionsBase(URI baseUri) { + return tokenBase(baseUri).path(TokenService.class, "getRequiredActionsService"); + } + + private static UriBuilder tokenBase(URI baseUri) { + return realmBase(baseUri).path(RealmsResource.class, "getTokenService"); + } }