keycloak-uncached

Merge pull request #2934 from fkiss/master-truststore KEYCLOAK-2283

6/17/2016 9:05:38 AM

Details

pom.xml 7(+7 -0)

diff --git a/pom.xml b/pom.xml
index 082891b..0e2b3ff 100755
--- a/pom.xml
+++ b/pom.xml
@@ -102,6 +102,7 @@
         <picketlink.version>2.7.0.Final</picketlink.version>
         <selenium.version>2.35.0</selenium.version>
         <xml-apis.version>1.4.01</xml-apis.version>
+        <subethasmtp.version>3.1.7</subethasmtp.version>
 
         <!-- Maven Plugins -->
         <embedmongo.plugin.version>0.1.12</embedmongo.plugin.version>
@@ -432,6 +433,12 @@
                 <version>${greenmail.version}</version>
                 <scope>test</scope>
             </dependency>
+            <dependency>
+                <groupId>org.subethamail</groupId>
+                <artifactId>subethasmtp</artifactId>
+                <version>${subethasmtp.version}</version>
+                <scope>test</scope>
+            </dependency>
 
             <!-- Apache DS -->
             <dependency>
diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml
index ef8a64d..8a77396 100644
--- a/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml
+++ b/testsuite/integration-arquillian/servers/auth-server/jboss/pom.xml
@@ -277,6 +277,84 @@
                             </execution>
                         </executions>
                     </plugin>
+                    <plugin>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-keystore</id>
+                                <phase>process-resources</phase>
+                                <goals>
+                                    <goal>copy-resources</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${auth.server.home}/standalone/configuration</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>${common.resources}/keystore</directory>
+                                            <includes>
+                                                <include>keycloak.jks</include>
+                                                <include>keycloak.truststore</include>
+                                            </includes>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <version>1.8</version>
+                        <executions>
+                            <execution>
+                                <id>inject-truststore-into-keycloak-server-json</id>
+                                <phase>process-resources</phase>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <target>
+                                        <ant antfile="../build-truststore.xml" inheritRefs="true">
+                                            <target name="inject-truststore"/>
+                                        </ant>
+                                    </target>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <dependencies>
+                            <dependency>
+                                <groupId>ant-contrib</groupId>
+                                <artifactId>ant-contrib</artifactId>
+                                <version>1.0b3</version>
+                                <exclusions>
+                                    <exclusion>
+                                        <groupId>ant</groupId>
+                                        <artifactId>ant</artifactId>
+                                    </exclusion>
+                                </exclusions>
+                            </dependency>
+                            <dependency>
+                                <groupId>org.apache.ant</groupId>
+                                <artifactId>ant-apache-bsf</artifactId>
+                                <version>1.9.3</version>
+                            </dependency>
+                            <dependency>
+                                <groupId>org.apache.bsf</groupId>
+                                <artifactId>bsf-api</artifactId>
+                                <version>3.1</version>
+                            </dependency>
+                            <dependency>
+                                <groupId>rhino</groupId>
+                                <artifactId>js</artifactId>
+                                <version>1.7R2</version>
+                            </dependency>
+                            <dependency>
+                                <groupId>org.keycloak</groupId>
+                                <artifactId>keycloak-core</artifactId>
+                                <version>${project.version}</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
                 </plugins>
             </build>
         </profile>
@@ -615,12 +693,12 @@
                 <session.cache.owners>1</session.cache.owners>
                 <offline.session.cache.owners>1</offline.session.cache.owners>
                 <login.failure.cache.owners>1</login.failure.cache.owners>
-                
+
                 <load.metric>simple</load.metric>
                 <!-- The default value 'simple' configures mod-cluster with simple-load-provider.
                 Any other value configures it with dynamic-load-provider using the particular `load.metric`.
                 Supported metrics: https://docs.jboss.org/mod_cluster/1.2.0/html/java.AS7config.html#LoadMetric -->
-                
+
             </properties>
             <build>
                 <pluginManagement>
@@ -723,7 +801,7 @@
                 </pluginManagement>
             </build>
         </profile>
-        
+
         <profile>
             <id>admin</id>
             <build>
diff --git a/testsuite/integration-arquillian/tests/base/pom.xml b/testsuite/integration-arquillian/tests/base/pom.xml
index ee6ad1b..11cf4d6 100644
--- a/testsuite/integration-arquillian/tests/base/pom.xml
+++ b/testsuite/integration-arquillian/tests/base/pom.xml
@@ -68,6 +68,11 @@
             <scope>compile</scope>
         </dependency>
         <dependency>
+            <groupId>org.subethamail</groupId>
+            <artifactId>subethasmtp</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
             <groupId>com.icegreen</groupId>
             <artifactId>greenmail</artifactId>
             <scope>compile</scope>
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java
index e566b41..848a9fa 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/auth/page/login/VerifyEmail.java
@@ -28,9 +28,17 @@ public class VerifyEmail extends Authenticate {
 
     @FindBy(xpath = "//div[@id='kc-form-wrapper']/p")
     private WebElement instruction;
-    
+
+    @FindBy(id = "kc-error-message")
+    private WebElement error;
+
     public String getInstructionMessage() {
         waitUntilElement(instruction).is().present();
         return instruction.getText();
     }
+
+    public String getErrorMessage() {
+        waitUntilElement(error).is().present();
+        return error.getText();
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java
index 5110e4c..50c8ed3 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MailServerConfiguration.java
@@ -25,4 +25,6 @@ public class MailServerConfiguration {
     public static final String FROM = "server@mail.test";
     public static final String HOST = "localhost";
     public static final String PORT = "3025";
+    public static final String PORT_SSL = "3465";
+    public static final String STARTTLS = "true";
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerFactoryImpl.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerFactoryImpl.java
new file mode 100644
index 0000000..67a2e43
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerFactoryImpl.java
@@ -0,0 +1,86 @@
+package org.keycloak.testsuite.util;
+
+import org.subethamail.smtp.MessageContext;
+import org.subethamail.smtp.MessageHandler;
+import org.subethamail.smtp.MessageHandlerFactory;
+import org.subethamail.smtp.RejectException;
+
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.MimeMessage;
+import java.io.*;
+import java.util.Properties;
+
+
+public class MessageHandlerFactoryImpl implements MessageHandlerFactory {
+
+    MimeMessage message;
+
+    public MessageHandler create(MessageContext ctx) {
+        return new Handler(ctx);
+    }
+
+    class Handler implements MessageHandler {
+        MessageContext ctx;
+
+
+
+        public Handler(MessageContext ctx) {
+            this.ctx = ctx;
+        }
+
+        public void from(String from) throws RejectException {
+            System.out.println("FROM:" + from);
+        }
+
+        public void recipient(String recipient) throws RejectException {
+            System.out.println("RECIPIENT:" + recipient);
+        }
+
+        public void data(InputStream data) throws IOException {
+            String rawMail = this.convertStreamToString(data);
+
+            Session session = Session.getDefaultInstance(new Properties());
+            InputStream is = new ByteArrayInputStream(rawMail.getBytes());
+            try
+            {
+                message = new MimeMessage(session, is);
+                setMessage(message);
+            }
+            catch (MessagingException e)
+            {
+                e.printStackTrace();
+            }
+        }
+
+        public void done() {
+            System.out.println("Finished");
+        }
+
+        public String convertStreamToString(InputStream is) {
+            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+            StringBuilder sb = new StringBuilder();
+
+            String line = null;
+            try {
+                while ((line = reader.readLine()) != null) {
+                    sb.append(line + "\n");
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            return sb.toString();
+        }
+
+
+
+    }
+
+    public MimeMessage getMessage(){
+        return message;
+    }
+
+    public  void setMessage(MimeMessage msg){
+        this.message = msg;
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerImpl.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerImpl.java
new file mode 100644
index 0000000..ec6d430
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/MessageHandlerImpl.java
@@ -0,0 +1,37 @@
+package org.keycloak.testsuite.util;
+
+import org.jboss.logging.Logger;
+import org.subethamail.smtp.MessageContext;
+import org.subethamail.smtp.MessageHandler;
+
+import java.io.InputStream;
+
+public class MessageHandlerImpl implements MessageHandler {
+    MessageContext context;
+
+    private static final Logger log = Logger.getLogger(MessageHandlerImpl.class);
+
+    MessageHandlerImpl(MessageContext context) {
+        this.context = context;
+    }
+
+    @Override
+    public void from(String from) {
+        log.info("FROM: ${from}");
+    }
+
+    @Override
+    public void recipient(String recipient) {
+        log.info("RECIPIENT: ${recipient}");
+    }
+
+    @Override
+    public void data(InputStream data) {
+        log.info("DATA");
+    }
+
+    @Override
+    public void done() {
+        log.info("DONE");
+    }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java
new file mode 100644
index 0000000..499e387
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/account/TrustStoreEmailTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.account;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.junit.After;
+import org.junit.Test;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
+
+import org.keycloak.testsuite.TestRealmKeycloakTest;
+import org.keycloak.testsuite.auth.page.AuthRealm;
+import org.keycloak.testsuite.auth.page.account.AccountManagement;
+import org.keycloak.testsuite.auth.page.login.OIDCLogin;
+import org.keycloak.testsuite.auth.page.login.VerifyEmail;
+import org.keycloak.testsuite.util.*;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.keycloak.testsuite.util.MailAssert.assertEmailAndGetUrl;
+import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
+
+
+/**
+ *
+ * @author fkiss
+ */
+public class TrustStoreEmailTest extends TestRealmKeycloakTest {
+
+    @Page
+    protected OIDCLogin testRealmLoginPage;
+
+    @Page
+    protected AuthRealm testRealmPage;
+
+    @Page
+    protected AccountManagement accountManagement;
+
+    @Page
+    private VerifyEmail testRealmVerifyEmailPage;
+
+    private UserRepresentation user;
+
+    @Override
+    public void configureTestRealm(RealmRepresentation testRealm) {
+        log.info("enable verify email and configure smtp server to run with ssl in test realm");
+
+        user = findUserInRealmRep(testRealm, "test-user@localhost");
+        testRealm.setSmtpServer(SslMailServer.getServerConfiguration());
+        testRealm.setVerifyEmail(true);
+    }
+
+
+    @Override
+    public void setDefaultPageUriParameters() {
+        super.setDefaultPageUriParameters();
+        testRealmPage.setAuthRealm("test");
+        testRealmVerifyEmailPage.setAuthRealm(testRealmPage);
+        accountManagement.setAuthRealm(testRealmPage);
+        testRealmLoginPage.setAuthRealm(testRealmPage);
+    }
+
+    @After
+    public void afterTrustStoreEmailTest() {
+        SslMailServer.stop();
+    }
+
+
+    @Test
+    public void verifyEmailWithSslEnabled() {
+        SslMailServer.startWithSsl(this.getClass().getClassLoader().getResource(SslMailServer.PRIVATE_KEY).getFile());
+        accountManagement.navigateTo();
+        testRealmLoginPage.form().login(user.getUsername(), "password");
+
+        assertEquals("You need to verify your email address to activate your account.",
+                testRealmVerifyEmailPage.getFeedbackText());
+
+        String verifyEmailUrl = assertEmailAndGetUrl(MailServerConfiguration.FROM, user.getEmail(),
+                "Someone has created a Test account with this email address.", true);
+
+        log.info("navigating to url from email: " + verifyEmailUrl);
+
+        driver.navigate().to(verifyEmailUrl);
+
+        assertCurrentUrlStartsWith(accountManagement);
+        accountManagement.signOut();
+        testRealmLoginPage.form().login(user);
+        assertCurrentUrlStartsWith(accountManagement);
+    }
+
+    @Test
+    public void verifyEmailWithSslWrongCertificate() {
+        SslMailServer.startWithSsl(this.getClass().getClassLoader().getResource(SslMailServer.INVALID_KEY).getFile());
+        accountManagement.navigateTo();
+        loginPage.form().login(user);
+
+        assertEquals("Failed to send email, please try again later.\n" +
+                        "« Back to Application",
+                testRealmVerifyEmailPage.getErrorMessage());
+    }
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java
index 93ae0cc..ac90ea8 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/MailAssert.java
@@ -30,11 +30,15 @@ public class MailAssert {
 
     private static final Logger log = Logger.getLogger(MailAssert.class);
     
-    public static String assertEmailAndGetUrl(String from, String recipient, String content) {
+    public static String assertEmailAndGetUrl(String from, String recipient, String content, Boolean sslEnabled) {
 
         try {
-            MimeMessage message = MailServer.getLastReceivedMessage();
-            assertNotNull("There is no received email.", message);
+            MimeMessage message;
+            if (sslEnabled){
+                message= SslMailServer.getLastReceivedMessage();
+            } else {
+                message = MailServer.getLastReceivedMessage();
+            }            assertNotNull("There is no received email.", message);
             assertEquals(recipient, message.getRecipients(RecipientType.TO)[0].toString());
             assertEquals(from, message.getFrom()[0].toString());
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SslMailServer.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SslMailServer.java
new file mode 100644
index 0000000..0088e42
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/SslMailServer.java
@@ -0,0 +1,151 @@
+/*
+ * 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.util;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.*;
+import java.security.*;
+import java.security.cert.CertificateException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.mail.internet.MimeMessage;
+import javax.net.ssl.*;
+
+import org.jboss.logging.Logger;
+import org.subethamail.smtp.server.SMTPServer;
+
+import static org.keycloak.testsuite.util.MailServerConfiguration.*;
+import static org.keycloak.testsuite.util.MailServerConfiguration.PORT_SSL;
+import static org.keycloak.testsuite.util.MailServerConfiguration.STARTTLS;
+
+public class SslMailServer {
+
+    private static final Logger log = Logger.getLogger(MailServer.class);
+
+    public static final String PRIVATE_KEY = "keystore/keycloak.jks";
+
+    public static final String TRUSTED_CERTIFICATE = "keystore/keycloak.truststore";
+
+    //private key tested with invalid certificate
+    public static final String INVALID_KEY = "keystore/email_invalid.jks";
+
+    private static MessageHandlerFactoryImpl messageHandlerFactory = new MessageHandlerFactoryImpl();
+
+    private static SMTPServer smtpServer;
+
+    private static Map<String, String> serverConfiguration = new HashMap<>();
+
+
+    public static void start() {
+        smtpServer = new SMTPServer(messageHandlerFactory);
+        smtpServer.setHostName(HOST);
+        smtpServer.setPort(Integer.parseInt(PORT));
+        smtpServer.start();
+
+        log.info("Started mail server (" + smtpServer.getHostName() + ":" + smtpServer.getPort() + ")");
+    }
+
+    public static void stop() {
+        if (smtpServer != null) {
+            log.info("Stopping mail server (" + smtpServer.getHostName() + ":" + smtpServer.getPort() + ")");
+            // Suppress error from SubEthaSmtp on shutdown
+            Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+                @Override
+                public void uncaughtException(Thread t, Throwable e) {
+                    if (!(e.getCause() instanceof SocketException && e.getStackTrace()[0].getClassName()
+                            .equals("org.subethamail.smtp.server.Session"))) {
+                        log.error("Exception in thread \"" + t.getName() + "\" ");
+                        log.error(e.getMessage(), e);
+                    }
+                }
+            });
+            smtpServer.stop();
+        }
+    }
+
+    public static void startWithSsl(String privateKey){
+        InputStream keyStoreIS = null;
+        try {
+            keyStoreIS = new FileInputStream(privateKey);
+            char[] keyStorePassphrase = "secret".toCharArray();
+            KeyStore ksKeys = null;
+            ksKeys = KeyStore.getInstance("JKS");
+            ksKeys.load(keyStoreIS, keyStorePassphrase);
+
+            // KeyManager decides which key material to use.
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+            kmf.init(ksKeys, keyStorePassphrase);
+
+            // Trust store for client authentication.
+            InputStream trustStoreIS = new FileInputStream(String.valueOf(MailServer.class.getClassLoader().getResource(TRUSTED_CERTIFICATE).getFile()));
+            char[] trustStorePassphrase = "secret".toCharArray();
+            KeyStore ksTrust = KeyStore.getInstance("JKS");
+            ksTrust.load(trustStoreIS, trustStorePassphrase);
+
+            // TrustManager decides which certificate authorities to use.
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+            tmf.init(ksTrust);
+
+            final SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+            smtpServer = new SMTPServer(messageHandlerFactory) {
+                @Override
+                public SSLSocket createSSLSocket(Socket socket) throws IOException {
+                    InetSocketAddress remoteAddress =
+                            (InetSocketAddress) socket.getRemoteSocketAddress();
+                    SSLSocketFactory sf = sslContext.getSocketFactory();
+                    SSLSocket s = (SSLSocket) (sf.createSocket(
+                            socket, remoteAddress.getHostName(), socket.getPort(), true));
+
+                    // we are a server
+                    s.setUseClientMode(false);
+
+                    // select protocols and cipher suites
+                    s.setEnabledProtocols(s.getSupportedProtocols());
+                    s.setEnabledCipherSuites(s.getSupportedCipherSuites());
+                    return s;
+                }
+            };
+        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyManagementException | CertificateException e) {
+            throw new RuntimeException(e);
+        }
+
+        smtpServer.setHostName(HOST);
+        smtpServer.setPort(Integer.parseInt(PORT_SSL));
+        smtpServer.setEnableTLS(true);
+        smtpServer.start();
+
+        log.info("Started mail server (" + smtpServer.getHostName() + ":" + smtpServer.getPort() + ")");
+    }
+
+    public static Map<String, String> getServerConfiguration() {
+        serverConfiguration.put("from", FROM);
+        serverConfiguration.put("host", HOST);
+        serverConfiguration.put("port", PORT_SSL);
+        serverConfiguration.put("starttls", STARTTLS);
+        return serverConfiguration;
+    }
+
+    public static MimeMessage getLastReceivedMessage() throws InterruptedException {
+        return messageHandlerFactory.getMessage();
+    }
+}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/email_invalid.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/email_invalid.jks
new file mode 100644
index 0000000..e940f19
Binary files /dev/null and b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/email_invalid.jks differ
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.jks b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.jks
new file mode 100644
index 0000000..81570ab
Binary files /dev/null and b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.jks differ
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.truststore b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.truststore
new file mode 100644
index 0000000..2df5170
Binary files /dev/null and b/testsuite/integration-arquillian/tests/base/src/test/resources/keystore/keycloak.truststore differ
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
index 78479d7..c37291d 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
@@ -121,10 +121,10 @@
 
     "truststore": {
         "file": {
-            "file": "${keycloak.truststore.file:src/main/keystore/keycloak.truststore}",
+            "file": "${keycloak.truststore.file:src/test/resources/keystore/keycloak.truststore}",
             "password": "${keycloak.truststore.password:secret}",
             "hostname-verification-policy": "${keycloak.truststore.policy:WILDCARD}",
-            "disabled": "${keycloak.truststore.disabled:true}"
+            "disabled": "${keycloak.truststore.disabled:false}"
         }
     }
 }
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index c3b3ccd..2773015 100755
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -736,6 +736,16 @@
                         </exclusion>
                     </exclusions>
                 </dependency>
+                <dependency>
+                    <groupId>org.subethamail</groupId>
+                    <artifactId>subethasmtp</artifactId>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>org.slf4j</groupId>
+                            <artifactId>slf4j-api</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
 
                 <!-- Keycloak deps for tests -->