Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: upgrade to keycloak 23.0.x version, using http request of action… #18

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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?

Expand Down
9 changes: 5 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>fr.redfroggy.keycloak</groupId>
<artifactId>keycloak-verify-email-by-code</artifactId>
<version>22.0.0-SNAPSHOT</version>
<version>23.0.0-SNAPSHOT</version>

<name>${project.groupId}:${project.artifactId}</name>
<description>Action to verify email by code for Keycloak</description>
Expand Down Expand Up @@ -53,12 +53,12 @@
<maven.source.plugin.version>3.3.0</maven.source.plugin.version>
<maven.javadoc.plugin.version>3.5.0</maven.javadoc.plugin.version>

<keycloak.version>22.0.1</keycloak.version>
<keycloak.version>23.0.4</keycloak.version>
<jboss-logging.version>3.5.3.Final</jboss-logging.version>

<junit-jupiter.version>5.9.1</junit-jupiter.version>
<mockito.version>4.8.0</mockito.version>
<assertj.version>3.23.1</assertj.version>
<junit-jupiter.version>5.10.0</junit-jupiter.version>
<mockito.version>5.3.1</mockito.version>
<assertj.version>3.24.2</assertj.version>
</properties>

<build>
Expand Down
12 changes: 12 additions & 0 deletions realm-config/dev/redfroggy-realm.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "[email protected]",
"fromDisplayName": "",
"user": ""
},
"eventsEnabled": false,
"eventsListeners": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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";
Expand All @@ -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) {
Expand Down Expand Up @@ -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());
Expand All @@ -105,8 +110,7 @@ public void processAction(RequiredActionContext context) {
requiredActionChallenge(context);
return;
}

MultivaluedMap<String, String> formData = resteasyProvider.getContextData(HttpRequest.class).getDecodedFormParameters();
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
String emailCode = formData.getFirst(EMAIL_CODE);

if (!code.equals(emailCode)) {
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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");
Expand Down Expand Up @@ -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<String, String> params = new MultivaluedHashMap<>();
params.add("email_code", "code is not same");
Expand Down Expand Up @@ -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<String, String> params = new MultivaluedHashMap<>();
params.add("email_code", "code is valid");
Expand Down
Loading