UPDATE_EMAIL action token handling should allow the user to resume its navigation to the redirect uri
Signed-off-by: Réda Housni Alaoui <reda-alaoui@hey.com>
This commit is contained in:
parent
b3321cb26e
commit
67718c653a
4 changed files with 33 additions and 3 deletions
|
@ -30,17 +30,24 @@ public class UpdateEmailActionToken extends DefaultActionToken {
|
||||||
private String newEmail;
|
private String newEmail;
|
||||||
@JsonProperty("logoutSessions")
|
@JsonProperty("logoutSessions")
|
||||||
private Boolean logoutSessions;
|
private Boolean logoutSessions;
|
||||||
|
@JsonProperty("reduri")
|
||||||
|
private String redirectUri;
|
||||||
|
|
||||||
public UpdateEmailActionToken(String userId, int absoluteExpirationInSecs, String oldEmail, String newEmail, String clientId) {
|
public UpdateEmailActionToken(String userId, int absoluteExpirationInSecs, String oldEmail, String newEmail, String clientId) {
|
||||||
this(userId, absoluteExpirationInSecs, oldEmail, newEmail, clientId, null);
|
this(userId, absoluteExpirationInSecs, oldEmail, newEmail, clientId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UpdateEmailActionToken(String userId, int absoluteExpirationInSecs, String oldEmail, String newEmail, String clientId, Boolean logoutSessions){
|
public UpdateEmailActionToken(String userId, int absoluteExpirationInSecs, String oldEmail, String newEmail, String clientId, Boolean logoutSessions){
|
||||||
|
this(userId, absoluteExpirationInSecs, oldEmail, newEmail, clientId, logoutSessions, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UpdateEmailActionToken(String userId, int absoluteExpirationInSecs, String oldEmail, String newEmail, String clientId, Boolean logoutSessions, String redirectUri){
|
||||||
super(userId, TOKEN_TYPE, absoluteExpirationInSecs, null);
|
super(userId, TOKEN_TYPE, absoluteExpirationInSecs, null);
|
||||||
this.oldEmail = oldEmail;
|
this.oldEmail = oldEmail;
|
||||||
this.newEmail = newEmail;
|
this.newEmail = newEmail;
|
||||||
this.issuedFor = clientId;
|
this.issuedFor = clientId;
|
||||||
this.logoutSessions = Boolean.TRUE.equals(logoutSessions)? true : null;
|
this.logoutSessions = Boolean.TRUE.equals(logoutSessions)? true : null;
|
||||||
|
this.redirectUri = redirectUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UpdateEmailActionToken(){
|
private UpdateEmailActionToken(){
|
||||||
|
@ -70,4 +77,12 @@ public class UpdateEmailActionToken extends DefaultActionToken {
|
||||||
public void setLogoutSessions(Boolean logoutSessions) {
|
public void setLogoutSessions(Boolean logoutSessions) {
|
||||||
this.logoutSessions = Boolean.TRUE.equals(logoutSessions)? true : null;
|
this.logoutSessions = Boolean.TRUE.equals(logoutSessions)? true : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getRedirectUri() {
|
||||||
|
return redirectUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedirectUri(String redirectUri) {
|
||||||
|
this.redirectUri = redirectUri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ import org.keycloak.forms.login.LoginFormsProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.FormMessage;
|
import org.keycloak.models.utils.FormMessage;
|
||||||
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
import org.keycloak.protocol.oidc.utils.RedirectUtils;
|
||||||
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.messages.Messages;
|
import org.keycloak.services.messages.Messages;
|
||||||
import org.keycloak.services.validation.Validation;
|
import org.keycloak.services.validation.Validation;
|
||||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||||
|
@ -88,7 +91,12 @@ public class UpdateEmailActionTokenHandler extends AbstractActionTokenHandler<Up
|
||||||
user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
user.removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
||||||
tokenContext.getAuthenticationSession().removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
tokenContext.getAuthenticationSession().removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
|
||||||
|
|
||||||
return forms.setAttribute("messageHeader", forms.getMessage("emailUpdatedTitle")).setSuccess("emailUpdated", newEmail)
|
AuthenticationSessionModel authSession = tokenContext.getAuthenticationSession();
|
||||||
|
String redirectUri = RedirectUtils.verifyRedirectUri(tokenContext.getSession(), token.getRedirectUri(), authSession.getClient());
|
||||||
|
|
||||||
|
return forms.setAttribute("messageHeader", forms.getMessage("emailUpdatedTitle"))
|
||||||
|
.setAttribute("pageRedirectUri", redirectUri)
|
||||||
|
.setSuccess("emailUpdated", newEmail)
|
||||||
.createInfoPage();
|
.createInfoPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class UpdateEmail implements RequiredActionProvider, RequiredActionFactor
|
||||||
AuthenticationSessionModel authenticationSession = context.getAuthenticationSession();
|
AuthenticationSessionModel authenticationSession = context.getAuthenticationSession();
|
||||||
|
|
||||||
UpdateEmailActionToken actionToken = new UpdateEmailActionToken(user.getId(), Time.currentTime() + validityInSecs,
|
UpdateEmailActionToken actionToken = new UpdateEmailActionToken(user.getId(), Time.currentTime() + validityInSecs,
|
||||||
oldEmail, newEmail, authenticationSession.getClient().getClientId(), logoutSessions);
|
oldEmail, newEmail, authenticationSession.getClient().getClientId(), logoutSessions, authenticationSession.getRedirectUri());
|
||||||
|
|
||||||
String link = Urls
|
String link = Urls
|
||||||
.actionTokenBuilder(uriInfo.getBaseUri(), actionToken.serialize(session, realm, uriInfo),
|
.actionTokenBuilder(uriInfo.getBaseUri(), actionToken.serialize(session, realm, uriInfo),
|
||||||
|
|
|
@ -26,6 +26,7 @@ import jakarta.mail.MessagingException;
|
||||||
import jakarta.mail.internet.MimeMessage;
|
import jakarta.mail.internet.MimeMessage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import org.jboss.arquillian.graphene.page.Page;
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
|
@ -43,6 +44,7 @@ import org.keycloak.testsuite.pages.InfoPage;
|
||||||
import org.keycloak.testsuite.util.GreenMailRule;
|
import org.keycloak.testsuite.util.GreenMailRule;
|
||||||
import org.keycloak.testsuite.util.MailUtils;
|
import org.keycloak.testsuite.util.MailUtils;
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
|
||||||
public class RequiredActionUpdateEmailTestWithVerificationTest extends AbstractRequiredActionUpdateEmailTest {
|
public class RequiredActionUpdateEmailTestWithVerificationTest extends AbstractRequiredActionUpdateEmailTest {
|
||||||
|
|
||||||
|
@ -66,6 +68,8 @@ public class RequiredActionUpdateEmailTestWithVerificationTest extends AbstractR
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void changeEmailUsingRequiredAction(String newEmail, boolean logoutOtherSessions) throws Exception {
|
protected void changeEmailUsingRequiredAction(String newEmail, boolean logoutOtherSessions) throws Exception {
|
||||||
|
String redirectUri = OAuthClient.APP_ROOT + "/auth?nonce=" + UUID.randomUUID();
|
||||||
|
oauth.redirectUri(redirectUri);
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
|
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
@ -86,6 +90,9 @@ public class RequiredActionUpdateEmailTestWithVerificationTest extends AbstractR
|
||||||
|
|
||||||
infoPage.assertCurrent();
|
infoPage.assertCurrent();
|
||||||
assertEquals("The account email has been successfully updated to new@localhost.", infoPage.getInfo());
|
assertEquals("The account email has been successfully updated to new@localhost.", infoPage.getInfo());
|
||||||
|
infoPage.clickBackToApplicationLink();
|
||||||
|
WaitUtils.waitForPageToLoad();
|
||||||
|
assertEquals(redirectUri, driver.getCurrentUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateEmail(boolean logoutOtherSessions) throws Exception {
|
private void updateEmail(boolean logoutOtherSessions) throws Exception {
|
||||||
|
|
Loading…
Reference in a new issue