From 1a479318e62a349b4ab771aca54556213072eb21 Mon Sep 17 00:00:00 2001 From: dej Date: Fri, 26 Jan 2024 23:04:26 +0100 Subject: [PATCH] fix: upgrade to keycloak 23.0.x version, using http request of action required context --- README.md | 2 +- docker-compose.yml | 9 ++--- pom.xml | 10 +++--- realm-config/dev/redfroggy-realm.json | 12 +++++++ .../requiredactions/VerifyEmailByCode.java | 36 +++++++------------ .../VerifyEmailByCodeTest.java | 23 +++--------- 6 files changed, 39 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index c6c7302..1c491a0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This [Keycloak](https://www.keycloak.org) plugin adds a required action to verif ## Compatibility -The version 21.0.x of this plugin is compatible with Keycloak `21.0.x` and higher. +The version 23.0.x of this plugin is compatible with Keycloak `23.0.x` and higher. ## How to install? diff --git a/docker-compose.yml b/docker-compose.yml index 689e83b..ee1769c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,19 +1,20 @@ version: '3.8' services: keycloak: - image: quay.io/keycloak/keycloak:22.0 - command: [ 'start-dev --import-realm', + image: quay.io/keycloak/keycloak:23.0 + command: [ 'start-dev', + '--import-realm', '--debug', '--spi-required-action-VERIFY_EMAIL_CODE-code-length=5' ] volumes: - ./realm-config/local:/opt/keycloak/data/import - - ./target/keycloak-verify-email-by-code-22.0.0-SNAPSHOT.jar:/opt/keycloak/providers/keycloak-verify-email-by-code.jar + - ./target/keycloak-verify-email-by-code-23.0.0-SNAPSHOT.jar:/opt/keycloak/providers/keycloak-verify-email-by-code.jar environment: - KC_DB=dev-file - KEYCLOAK_ADMIN=admin - KEYCLOAK_ADMIN_PASSWORD=admin - DEBUG=true - - KC_LOG_LEVEL=debug + - KC_LOG_LEVEL=info - KC_FEATURES=scripts - KC_HTTP_PORT=9080 - KC_HTTPS_PORT=9443 diff --git a/pom.xml b/pom.xml index a0a6510..41ed7f1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ fr.redfroggy.keycloak keycloak-verify-email-by-code - 22.0.0-SNAPSHOT + 23.0.0-SNAPSHOT ${project.groupId}:${project.artifactId} Action to verify email by code for Keycloak @@ -53,12 +53,12 @@ 3.3.0 3.5.0 - 22.0.1 + 23.0.4 3.5.3.Final - 5.9.1 - 4.8.0 - 3.23.1 + 5.10.0 + 5.3.1 + 3.24.2 diff --git a/realm-config/dev/redfroggy-realm.json b/realm-config/dev/redfroggy-realm.json index d0afe97..29798d9 100644 --- a/realm-config/dev/redfroggy-realm.json +++ b/realm-config/dev/redfroggy-realm.json @@ -1266,6 +1266,18 @@ "strictTransportSecurity": "max-age=31536000; includeSubDomains" }, "smtpServer": { + "replyToDisplayName": "", + "starttls": "false", + "auth": "false", + "envelopeFrom": "", + "ssl": "false", + "password": "", + "port": "1025", + "host": "mailhog", + "replyTo": "", + "from": "contact@redfroggy.fr", + "fromDisplayName": "", + "user": "" }, "eventsEnabled": false, "eventsListeners": [ diff --git a/src/main/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCode.java b/src/main/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCode.java index 47fdfa7..d367991 100644 --- a/src/main/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCode.java +++ b/src/main/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCode.java @@ -21,13 +21,10 @@ import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.UriBuilderException; import org.jboss.logging.Logger; -import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.Config; import org.keycloak.authentication.RequiredActionContext; import org.keycloak.authentication.RequiredActionFactory; import org.keycloak.authentication.RequiredActionProvider; -import org.keycloak.common.util.Resteasy; -import org.keycloak.common.util.ResteasyProvider; import org.keycloak.common.util.SecretGenerator; import org.keycloak.email.EmailException; import org.keycloak.email.EmailTemplateProvider; @@ -56,7 +53,6 @@ * @version $Revision: 1 $ */ public class VerifyEmailByCode implements RequiredActionProvider, RequiredActionFactory, ServerInfoAwareProviderFactory { - private static final Logger logger = Logger.getLogger(VerifyEmailByCode.class); public static final String VERIFY_EMAIL_CODE = "VERIFY_EMAIL_CODE"; public static final String EMAIL_CODE = "email_code"; public static final String INVALID_CODE = "VerifyEmailInvalidCode"; @@ -65,10 +61,20 @@ public class VerifyEmailByCode implements RequiredActionProvider, RequiredAction public static final String CONFIG_CODE_SYMBOLS = "code-symbols"; public static final int DEFAULT_CODE_LENGTH = 8; public static final String DEFAULT_CODE_SYMBOLS = String.valueOf(SecretGenerator.ALPHANUM); + private static final Logger logger = Logger.getLogger(VerifyEmailByCode.class); private int codeLength; private String codeSymbols; - private ResteasyProvider resteasyProvider; + private static void createFormChallenge(RequiredActionContext context, FormMessage errorMessage) { + LoginFormsProvider loginFormsProvider = context.form(); + if (Objects.nonNull(errorMessage)) { + loginFormsProvider = loginFormsProvider.addError(new FormMessage(EMAIL_CODE, INVALID_CODE)); + } + Response challenge = loginFormsProvider + .setAttribute("user", new ProfileBean(context.getUser())) + .createForm(LOGIN_VERIFY_EMAIL_CODE_TEMPLATE); + context.challenge(challenge); + } @Override public void evaluateTriggers(RequiredActionContext context) { @@ -96,7 +102,6 @@ public void requiredActionChallenge(RequiredActionContext context) { sendVerifyEmailAndCreateForm(context); } - @Override public void processAction(RequiredActionContext context) { EventBuilder event = context.getEvent().clone().event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, context.getUser().getEmail()); @@ -105,8 +110,7 @@ public void processAction(RequiredActionContext context) { requiredActionChallenge(context); return; } - - MultivaluedMap formData = resteasyProvider.getContextData(HttpRequest.class).getDecodedFormParameters(); + MultivaluedMap formData = context.getHttpRequest().getDecodedFormParameters(); String emailCode = formData.getFirst(EMAIL_CODE); if (!code.equals(emailCode)) { @@ -120,27 +124,11 @@ public void processAction(RequiredActionContext context) { context.success(); } - private static void createFormChallenge(RequiredActionContext context, FormMessage errorMessage) { - LoginFormsProvider loginFormsProvider = context.form(); - if (Objects.nonNull(errorMessage)) { - loginFormsProvider = loginFormsProvider.addError(new FormMessage(EMAIL_CODE, INVALID_CODE)); - } - Response challenge = loginFormsProvider - .setAttribute("user", new ProfileBean(context.getUser())) - .createForm(LOGIN_VERIFY_EMAIL_CODE_TEMPLATE); - context.challenge(challenge); - } - @Override public RequiredActionProvider create(KeycloakSession session) { - setResteasyProvider(Resteasy.getProvider()); return this; } - void setResteasyProvider(ResteasyProvider resteasyProvider) { - this.resteasyProvider = resteasyProvider; - } - @Override public void init(Config.Scope config) { codeLength = config.getInt(CONFIG_CODE_LENGTH, DEFAULT_CODE_LENGTH); diff --git a/src/test/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCodeTest.java b/src/test/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCodeTest.java index 04bc8b3..3f8c515 100644 --- a/src/test/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCodeTest.java +++ b/src/test/java/fr/redfroggy/keycloak/requiredactions/VerifyEmailByCodeTest.java @@ -3,12 +3,10 @@ import jakarta.ws.rs.core.MultivaluedHashMap; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; -import org.jboss.resteasy.spi.HttpRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.keycloak.Config; import org.keycloak.authentication.RequiredActionContext; -import org.keycloak.common.util.ResteasyProvider; import org.keycloak.email.EmailException; import org.keycloak.email.EmailTemplateProvider; import org.keycloak.email.freemarker.beans.ProfileBean; @@ -17,6 +15,7 @@ import org.keycloak.events.EventBuilder; import org.keycloak.events.EventType; import org.keycloak.forms.login.LoginFormsProvider; +import org.keycloak.http.HttpRequest; import org.keycloak.models.KeycloakContext; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -33,38 +32,28 @@ @ExtendWith({MockitoExtension.class}) class VerifyEmailByCodeTest { + private final VerifyEmailByCode action = new VerifyEmailByCode(); @Mock private RealmModel realm; - @Mock private UserModel user; - @Mock private KeycloakSession session; - @Mock private EventBuilder event; - @Mock private AuthenticationSessionModel authSession; - @Mock private LoginFormsProvider form; - @Mock private EmailTemplateProvider templateProvider; - @Mock private Response response; - @Mock private RequiredActionContext requiredActionContext; - @Mock private Config.Scope config; - private final VerifyEmailByCode action = new VerifyEmailByCode(); - @Test public void shouldReturnGetId() { assertThat(action.getId()).isEqualTo("VERIFY_EMAIL_CODE"); @@ -256,10 +245,8 @@ public void shouldChallengeWithErrorOnProcessActionWhenCodeIsNotValid() { when(requiredActionContext.getAuthenticationSession()).thenReturn(authSession); when(authSession.getAuthNote(VerifyEmailByCode.VERIFY_EMAIL_CODE)).thenReturn("code is valid"); - ResteasyProvider resteasyProvider = mock(ResteasyProvider.class); - action.setResteasyProvider(resteasyProvider); HttpRequest request = mock(HttpRequest.class); - when(resteasyProvider.getContextData(HttpRequest.class)).thenReturn(request); + when(requiredActionContext.getHttpRequest()).thenReturn(request); MultivaluedMap params = new MultivaluedHashMap<>(); params.add("email_code", "code is not same"); @@ -294,10 +281,8 @@ public void shouldSuccessOnProcessActionWhenCodeIsValid() { when(requiredActionContext.getAuthenticationSession()).thenReturn(authSession); when(authSession.getAuthNote(VerifyEmailByCode.VERIFY_EMAIL_CODE)).thenReturn("code is valid"); - ResteasyProvider resteasyProvider = mock(ResteasyProvider.class); - action.setResteasyProvider(resteasyProvider); HttpRequest request = mock(HttpRequest.class); - when(resteasyProvider.getContextData(HttpRequest.class)).thenReturn(request); + when(requiredActionContext.getHttpRequest()).thenReturn(request); MultivaluedMap params = new MultivaluedHashMap<>(); params.add("email_code", "code is valid");