From f6fc5b62584ca13e6f27795bd3c06f0d45c8f3b8 Mon Sep 17 00:00:00 2001 From: Lukas Hanusovsky <61745358+lhanusov@users.noreply.github.com> Date: Mon, 3 Mar 2025 09:31:47 +0100 Subject: [PATCH] [Test framework MVP] SMTPConnectionTest + SMTPConnectionVaultTest (#35230) * [Test framework MVP] SMTPConnectionTest - mv Signed-off-by: Lukas Hanusovsky * [Test framework MVP] SMTPConnectionTest + SMTPConnectionVaultTest Signed-off-by: Lukas Hanusovsky --------- Signed-off-by: Lukas Hanusovsky --- .../testframework/mail/MailServer.java | 4 + .../tests/admin/SMTPConnectionTest.java | 161 ++++++++++++++++++ .../tests/admin/SMTPConnectionVaultTest.java | 87 ++++++++++ .../partialexport/PartialExportTest.java | 2 +- .../partialexport-testrealm.json | 0 .../tests/admin/vault/default_smtp__password | 1 + .../testsuite/admin/SMTPConnectionTest.java | 155 ----------------- .../admin/SMTPConnectionVaultTest.java | 15 -- 8 files changed, 254 insertions(+), 171 deletions(-) create mode 100644 tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionTest.java create mode 100644 tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionVaultTest.java rename tests/base/src/test/resources/{export => org/keycloak/tests/admin/partialexport}/partialexport-testrealm.json (100%) create mode 100644 tests/base/src/test/resources/org/keycloak/tests/admin/vault/default_smtp__password delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionTest.java delete mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionVaultTest.java diff --git a/test-framework/email-server/src/main/java/org/keycloak/testframework/mail/MailServer.java b/test-framework/email-server/src/main/java/org/keycloak/testframework/mail/MailServer.java index 0f4983733f6..64e83942cf3 100644 --- a/test-framework/email-server/src/main/java/org/keycloak/testframework/mail/MailServer.java +++ b/test-framework/email-server/src/main/java/org/keycloak/testframework/mail/MailServer.java @@ -21,6 +21,10 @@ public class MailServer extends ManagedTestResource { greenMail.stop(); } + public void credentials(String username, String password) { + greenMail.setUser(username, password); + } + public MimeMessage[] getReceivedMessages() { return greenMail.getReceivedMessages(); } diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionTest.java new file mode 100644 index 00000000000..ebce3a53caa --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionTest.java @@ -0,0 +1,161 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.tests.admin; + +import org.junit.jupiter.api.Test; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.models.AdminRoles; +import org.keycloak.models.Constants; +import org.keycloak.representations.idm.RealmRepresentation; + +import jakarta.mail.internet.MimeMessage; +import jakarta.ws.rs.core.Response; +import org.keycloak.testframework.annotations.InjectAdminClient; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.mail.MailServer; +import org.keycloak.testframework.mail.annotations.InjectMailServer; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.realm.RealmConfig; +import org.keycloak.testframework.realm.RealmConfigBuilder; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static org.keycloak.representations.idm.ComponentRepresentation.SECRET_VALUE; + +/** + * @author Bruno Oliveira + */ +@KeycloakIntegrationTest +public class SMTPConnectionTest { + + @InjectRealm(config = SMTPRealmWithClientAndUser.class) + private ManagedRealm managedRealm; + + @InjectAdminClient(mode = InjectAdminClient.Mode.MANAGED_REALM, client = "myclient", user = "myadmin") + private Keycloak adminClient; + + @InjectMailServer + private MailServer mailServer; + + @Test + public void testWithNullSettings() throws Exception { + Response response = adminClient.realms().realm(managedRealm.getName()).testSMTPConnection(settings(null, null, null, null, null, null, null, null)); + assertStatus(response, 500); + } + + @Test + public void testWithProperSettings() throws Exception { + Response response = adminClient.realms().realm(managedRealm.getName()).testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", null, null, null, null, null)); + assertStatus(response, 204); + assertMailReceived(); + } + + @Test + public void testWithAuthEnabledCredentialsEmpty() throws Exception { + Response response = adminClient.realms().realm(managedRealm.getName()).testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, null, null)); + assertStatus(response, 500); + } + + @Test + public void testWithAuthEnabledValidCredentials() throws Exception { + String password = "admin"; + + mailServer.credentials("admin@localhost", password); + Response response = adminClient.realms().realm(managedRealm.getName()).testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, "admin@localhost", password)); + assertStatus(response, 204); + } + + @Test + public void testAuthEnabledAndSavedCredentials() throws Exception { + String password = "admin"; + RealmResource realm = adminClient.realms().realm(managedRealm.getName()); + + RealmRepresentation realmRep = realm.toRepresentation(); + realmRep.setSmtpServer(smtpMap("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, + "admin@localhost", password, null, null)); + managedRealm.updateWithCleanup(r -> r.update(realmRep)); + + mailServer.credentials("admin@localhost", password); + Response response = realm.testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, + "admin@localhost", SECRET_VALUE)); + assertStatus(response, 204); + } + + private Map settings(String host, String port, String from, String auth, String ssl, String starttls, + String username, String password) throws Exception { + return smtpMap(host, port, from, auth, ssl, starttls, username, password, "", ""); + } + + private Map smtpMap(String host, String port, String from, String auth, String ssl, String starttls, + String username, String password, String replyTo, String envelopeFrom) { + Map config = new HashMap<>(); + config.put("host", host); + config.put("port", port); + config.put("from", from); + config.put("auth", auth); + config.put("ssl", ssl); + config.put("starttls", starttls); + config.put("user", username); + config.put("password", password); + config.put("replyTo", replyTo); + config.put("envelopeFrom", envelopeFrom); + return config; + } + + private void assertStatus(Response response, int status) { + assertEquals(status, response.getStatus()); + response.close(); + } + + private void assertMailReceived() { + if (mailServer.getReceivedMessages().length == 1) { + try { + MimeMessage message = mailServer.getReceivedMessages()[0]; + assertEquals("[KEYCLOAK] - SMTP test message", message.getSubject()); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + fail("E-mail was not received"); + } + } + + public static class SMTPRealmWithClientAndUser implements RealmConfig { + + @Override + public RealmConfigBuilder configure(RealmConfigBuilder realm) { + realm.addClient("myclient") + .secret("mysecret") + .directAccessGrants(); + + realm.addUser("myadmin") + .name("My", "Admin") + .email("admin@localhost") + .emailVerified() + .password("myadmin") + .clientRoles(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN); + + return realm; + } + } +} diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionVaultTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionVaultTest.java new file mode 100644 index 00000000000..0d13b4773d8 --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/tests/admin/SMTPConnectionVaultTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.keycloak.tests.admin; + +import jakarta.ws.rs.core.Response; +import org.junit.jupiter.api.Test; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.testframework.annotations.InjectAdminClient; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.mail.MailServer; +import org.keycloak.testframework.mail.annotations.InjectMailServer; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.server.KeycloakServerConfig; +import org.keycloak.testframework.server.KeycloakServerConfigBuilder; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@KeycloakIntegrationTest(config = SMTPConnectionVaultTest.SMTPVaultConfig.class) +public class SMTPConnectionVaultTest { + + @InjectRealm(config = SMTPConnectionTest.SMTPRealmWithClientAndUser.class) + private ManagedRealm managedRealm; + + @InjectAdminClient(mode = InjectAdminClient.Mode.MANAGED_REALM, client = "myclient", user = "myadmin") + private Keycloak adminClient; + + @InjectMailServer + private MailServer mailServer; + + @Test + public void testWithAuthEnabledValidCredentials() throws Exception { + // The value of password must match the value of vaultPassword stored in the vault file: resources/vault/default_smtp__password. + // Prefix default in the file default_smtp__password is the name of the managed realm. + String password = "admin"; + String vaultPassword = "${vault.smtp_password}"; + + mailServer.credentials("admin@localhost", password); + + Map settings = new HashMap<>(); + settings.put("host", "127.0.0.1"); + settings.put("port", "3025"); + settings.put("from", "auto@keycloak.org"); + settings.put("auth", "true"); + settings.put("ssl", null); + settings.put("starttls", null); + settings.put("user", "admin@localhost"); + settings.put("password", vaultPassword); + settings.put("replyTo", ""); + settings.put("envelopeFrom", ""); + + Response response = adminClient.realms().realm(managedRealm.getName()).testSMTPConnection(settings); + assertEquals(204, response.getStatus()); + response.close(); + } + + public static class SMTPVaultConfig implements KeycloakServerConfig { + + @Override + public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) { + URL url = SMTPConnectionVaultTest.class.getResource("vault"); + if (url == null) { + throw new RuntimeException("Unable to find the vault folder in the classpath for the default_smtp__password file!"); + } + return config.option("vault", "file").option("vault-dir", url.getPath()); + } + } +} diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/partialexport/PartialExportTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/partialexport/PartialExportTest.java index 6b744792215..54d5a4618be 100644 --- a/tests/base/src/test/java/org/keycloak/tests/admin/partialexport/PartialExportTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/admin/partialexport/PartialExportTest.java @@ -46,7 +46,7 @@ public class PartialExportTest { @BeforeEach public void initializeRealm() { - RealmRepresentation realmRepresentation = loadJson(PartialExportTest.class.getResourceAsStream("/export/partialexport-testrealm.json"), RealmRepresentation.class); + RealmRepresentation realmRepresentation = loadJson(PartialExportTest.class.getResourceAsStream("partialexport-testrealm.json"), RealmRepresentation.class); adminClient.realms().create(realmRepresentation); } diff --git a/tests/base/src/test/resources/export/partialexport-testrealm.json b/tests/base/src/test/resources/org/keycloak/tests/admin/partialexport/partialexport-testrealm.json similarity index 100% rename from tests/base/src/test/resources/export/partialexport-testrealm.json rename to tests/base/src/test/resources/org/keycloak/tests/admin/partialexport/partialexport-testrealm.json diff --git a/tests/base/src/test/resources/org/keycloak/tests/admin/vault/default_smtp__password b/tests/base/src/test/resources/org/keycloak/tests/admin/vault/default_smtp__password new file mode 100644 index 00000000000..f77b00407e0 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/admin/vault/default_smtp__password @@ -0,0 +1 @@ +admin \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionTest.java deleted file mode 100644 index 814159ffb71..00000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.testsuite.admin; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.keycloak.admin.client.resource.RealmResource; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.util.GreenMailRule; -import org.keycloak.testsuite.util.UserBuilder; - -import jakarta.mail.internet.MimeMessage; -import jakarta.ws.rs.core.Response; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.keycloak.representations.idm.ComponentRepresentation.SECRET_VALUE; - -/** - * @author Bruno Oliveira - */ -public class SMTPConnectionTest extends AbstractKeycloakTest { - - public final String SMTP_PASSWORD = setSmtpPassword(); - - @Rule - public GreenMailRule greenMailRule = new GreenMailRule(); - private RealmResource realm; - - @Override - public void addTestRealms(List testRealms) { - } - - public String setSmtpPassword() { - return "admin"; - } - - @Before - public void before() { - realm = adminClient.realm("master"); - List admin = realm.users().search("admin", 0, 1); - UserRepresentation user = UserBuilder.edit(admin.get(0)).email("admin@localhost").build(); - realm.users().get(user.getId()).update(user); - } - - private Map settings(String host, String port, String from, String auth, String ssl, String starttls, - String username, String password) throws Exception { - return smtpMap(host, port, from, auth, ssl, starttls, username, password, "", ""); - } - - private Map smtpMap(String host, String port, String from, String auth, String ssl, String starttls, - String username, String password, String replyTo, String envelopeFrom) { - Map config = new HashMap<>(); - config.put("host", host); - config.put("port", port); - config.put("from", from); - config.put("auth", auth); - config.put("ssl", ssl); - config.put("starttls", starttls); - config.put("user", username); - config.put("password", password); - config.put("replyTo", replyTo); - config.put("envelopeFrom", envelopeFrom); - return config; - } - - @Test - public void testWithNullSettings() throws Exception { - Response response = realm.testSMTPConnection(settings(null, null, null, null, null, null, - null, null)); - assertStatus(response, 500); - } - - @Test - public void testWithProperSettings() throws Exception { - Response response = realm.testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", null, null, null, - null, null)); - assertStatus(response, 204); - assertMailReceived(); - } - - @Test - public void testWithAuthEnabledCredentialsEmpty() throws Exception { - Response response = realm.testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, - null, null)); - assertStatus(response, 500); - } - - @Test - public void testWithAuthEnabledValidCredentials() throws Exception { - greenMailRule.credentials("admin@localhost", "admin"); - Response response = realm.testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, - "admin@localhost", SMTP_PASSWORD)); - assertStatus(response, 204); - } - - @Test - public void testAuthEnabledAndSavedCredentials() throws Exception { - RealmRepresentation realmRep = realm.toRepresentation(); - Map oldSmtp = realmRep.getSmtpServer(); - try { - realmRep.setSmtpServer(smtpMap("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, - "admin@localhost", SMTP_PASSWORD, null, null)); - realm.update(realmRep); - - greenMailRule.credentials("admin@localhost", "admin"); - Response response = realm.testSMTPConnection(settings("127.0.0.1", "3025", "auto@keycloak.org", "true", null, null, - "admin@localhost", SECRET_VALUE)); - assertStatus(response, 204); - } finally { - // Revert SMTP back - realmRep.setSmtpServer(oldSmtp); - realm.update(realmRep); - } - } - - private void assertStatus(Response response, int status) { - assertEquals(status, response.getStatus()); - response.close(); - } - - private void assertMailReceived() { - if (greenMailRule.getReceivedMessages().length == 1) { - try { - MimeMessage message = greenMailRule.getReceivedMessages()[0]; - assertEquals("[KEYCLOAK] - SMTP test message", message.getSubject()); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - fail("E-mail was not received"); - } - } -} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionVaultTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionVaultTest.java deleted file mode 100644 index a4cc775e854..00000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/SMTPConnectionVaultTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.keycloak.testsuite.admin; - -import org.keycloak.testsuite.arquillian.annotation.EnableVault; - -/** - * @author Martin Kanis - */ -@EnableVault -public class SMTPConnectionVaultTest extends SMTPConnectionTest { - - @Override - public String setSmtpPassword() { - return "${vault.smtp_password}"; - } -} \ No newline at end of file