Skip to content

Commit

Permalink
Add SslBundle support to MailSender
Browse files Browse the repository at this point in the history
  • Loading branch information
ruifigueira committed Mar 20, 2024
1 parent e3f8c34 commit e9b7527
Show file tree
Hide file tree
Showing 12 changed files with 451 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ public class MailProperties {
*/
private String jndiName;

/**
* SSL configuration.
*/
private final Ssl ssl = new Ssl();

public String getHost() {
return this.host;
}
Expand Down Expand Up @@ -136,4 +141,41 @@ public String getJndiName() {
return this.jndiName;
}

public Ssl getSsl() {
return this.ssl;
}

public static class Ssl {

/**
* Whether to enable SSL support.
* If enabled, {@code mail.smtp.ssl.enable} property is set to {@code true}.
*/
private Boolean enabled;

/**
* SSL bundle name.
* If not null, {@code mail.smtp.ssl.socketFactory} property is set to a
* {@code SSLSocketFactory} obtained from the corresponding SSL bundle.
*/
private String bundle;

public boolean isEnabled() {
return (this.enabled != null) ? this.enabled : this.bundle != null;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public String getBundle() {
return this.bundle;
}

public void setBundle(String bundle) {
this.bundle = bundle;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
import java.util.Map;
import java.util.Properties;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.MailSender;
Expand All @@ -38,6 +41,12 @@
@ConditionalOnProperty(prefix = "spring.mail", name = "host")
class MailSenderPropertiesConfiguration {

private final ObjectProvider<SslBundles> sslBundles;

MailSenderPropertiesConfiguration(ObjectProvider<SslBundles> sslBundles) {
this.sslBundles = sslBundles;
}

@Bean
@ConditionalOnMissingBean(JavaMailSender.class)
JavaMailSenderImpl mailSender(MailProperties properties) {
Expand All @@ -57,8 +66,16 @@ private void applyProperties(MailProperties properties, JavaMailSenderImpl sende
if (properties.getDefaultEncoding() != null) {
sender.setDefaultEncoding(properties.getDefaultEncoding().name());
}
if (!properties.getProperties().isEmpty()) {
sender.setJavaMailProperties(asProperties(properties.getProperties()));
Properties javaMailProperties = asProperties(properties.getProperties());
if (properties.getSsl().isEnabled()) {
javaMailProperties.setProperty("mail.smtp.ssl.enable", "true");
}
if (properties.getSsl().getBundle() != null) {
SslBundle sslBundle = this.sslBundles.getObject().getBundle(properties.getSsl().getBundle());
javaMailProperties.put("mail.smtp.ssl.socketFactory", sslBundle.createSslContext().getSocketFactory());
}
if (!javaMailProperties.isEmpty()) {
sender.setJavaMailProperties(javaMailProperties);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* 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
*
* https://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.springframework.boot.autoconfigure.mail;

import java.time.Duration;

import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.MountableFile;

import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.testcontainers.MaildevContainer;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.web.client.RestClient;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Integration tests for {@link MailSenderAutoConfiguration}.
*
* @author Rui Figueira
*/
@Testcontainers(disabledWithoutDocker = true)
class MailSenderAutoConfigurationIntegrationTests {

@Container
static final MaildevContainer maildev = new MaildevContainer()
.withCA(MountableFile.forClasspathResource("/org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt"))
.withIncomingSecure()
.withIncomingCert(
MountableFile.forClasspathResource("/org/springframework/boot/autoconfigure/mail/ssl/test-server.crt"))
.withIncomingKey(
MountableFile.forClasspathResource("/org/springframework/boot/autoconfigure/mail/ssl/test-server.key"));

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MailSenderAutoConfiguration.class, SslAutoConfiguration.class,
RestClientAutoConfiguration.class));

@Test
void sendSecuredEmail() {
this.contextRunner.withPropertyValues("spring.mail.host:" + maildev.getHost(),
"spring.mail.port:" + maildev.getSmtpPort(), "spring.mail.ssl.enabled:true",
"spring.mail.ssl.bundle:test-bundle",
"spring.ssl.bundle.pem.test-bundle.truststore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-ca.crt",
"spring.ssl.bundle.pem.test-bundle.keystore.certificate=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.crt",
"spring.ssl.bundle.pem.test-bundle.keystore.private-key=classpath:org/springframework/boot/autoconfigure/mail/ssl/test-client.key")
.run((context) -> {
JavaMailSenderImpl mailSender = context.getBean(JavaMailSenderImpl.class);
RestClient restClient = context.getBean(RestClient.Builder.class).baseUrl(maildev.getWebUrl()).build();

SimpleMailMessage msg = new SimpleMailMessage();
msg.setFrom("[email protected]");
msg.setTo("[email protected]");
msg.setSubject("Hello World!");
msg.setText("Hi there!");
mailSender.send(msg);

Awaitility.await().atMost(Duration.ofSeconds(5)).ignoreExceptions().untilAsserted(() -> {
MailInfo[] mails = getAllMails(restClient);
assertThat(mails).isNotEmpty();
assertThat(mails[0].subject).isEqualTo("Hello World!");
});
});
}

private static MailInfo[] getAllMails(RestClient restClient) {
// https://github.com/maildev/maildev/blob/v2.1.0/docs/rest.md
return restClient.get().uri("/email").retrieve().body(MailInfo[].class);
}

record MailInfo(String subject) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Properties;

import javax.naming.Context;
import javax.net.ssl.SSLSocketFactory;

import jakarta.mail.Session;
import org.junit.jupiter.api.AfterEach;
Expand All @@ -29,6 +30,7 @@
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jndi.JndiPropertiesHidingClassLoader;
import org.springframework.boot.autoconfigure.jndi.TestableInitialContextFactory;
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -49,8 +51,9 @@
*/
class MailSenderAutoConfigurationTests {

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
AutoConfigurations.of(MailSenderAutoConfiguration.class, MailSenderValidatorAutoConfiguration.class));
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MailSenderAutoConfiguration.class,
MailSenderValidatorAutoConfiguration.class, SslAutoConfiguration.class));

private ClassLoader threadContextClassLoader;

Expand Down Expand Up @@ -240,6 +243,32 @@ void connectionOnStartupNotCalled() {
});
}

@Test
void sslEnabled() {
this.contextRunner.withPropertyValues("spring.mail.host:localhost", "spring.mail.ssl.enabled:true")
.run((context) -> {
assertThat(context).hasSingleBean(JavaMailSenderImpl.class);
JavaMailSenderImpl mailSender = context.getBean(JavaMailSenderImpl.class);
assertThat(mailSender.getJavaMailProperties()).containsEntry("mail.smtp.ssl.enable", "true");
});
}

@Test
void sslBundle() {
this.contextRunner
.withPropertyValues("spring.mail.host:localhost", "spring.mail.ssl.bundle:test-bundle",
"spring.ssl.bundle.jks.test-bundle.keystore.location:classpath:test.jks",
"spring.ssl.bundle.jks.test-bundle.keystore.password:secret",
"spring.ssl.bundle.jks.test-bundle.key.password:password")
.run((context) -> {
assertThat(context).hasSingleBean(JavaMailSenderImpl.class);
JavaMailSenderImpl mailSender = context.getBean(JavaMailSenderImpl.class);
assertThat(mailSender.getJavaMailProperties()).doesNotContainKey("mail.smtp.ssl.enable");
Object property = mailSender.getJavaMailProperties().get("mail.smtp.ssl.socketFactory");
assertThat(property).isInstanceOf(SSLSocketFactory.class);
});
}

private Session configureJndiSession(String name) {
Properties properties = new Properties();
Session session = Session.getDefaultInstance(properties);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFhjCCA26gAwIBAgIUERZP46qinK0dKmJzlCsoD/k1nWYwDQYJKoZIhvcNAQEL
BQAwOzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDEeMBwGA1UEAwwVQ2VydGlm
aWNhdGUgQXV0aG9yaXR5MB4XDTIzMDUwMTIwNDkxMFoXDTMzMDQyODIwNDkxMFow
OzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDEeMBwGA1UEAwwVQ2VydGlmaWNh
dGUgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApWYo
UQjDY98oVOO5HOjheWeBN+C6gozg4aPY0VdRDTKmZ5SzNjuYtX6jsd8e5UF+ceeL
Aw9E3FAKG80F/81c6mtFhFUNUaBCbK2/+igs+Ae6r42i6iLImvgYLbZ0rGpPwszT
KGlwyobsI8n1bRFrVRdtGWVfn3Dfc5k/+dnZ03kOpViv/gd/xNWMcMOlj64F1s8L
6Nx9bfeJvOcsX+5qMiy/B6dZS0lkvXZISJbFhvX/+5Tb/vkP41AnrYff8hO8OBs+
G2srr2xNAIcgNBSjedDVUaRO+a2WHdX/1fHOlNqz335XMo79FOqRWDCZET3YW36A
hqiSPPiDq8AA7hmVxnq7vxWo/qclaqVuk5Dxp+ZD7d8deSGehTPajeCZCDtNhw6C
jtlU8v/LdwMRhqZp5/fjDlOEkutFh6B/aMjq3ZPYQad4MtQixDifgEs4iwnIMoVS
Wqpn24qn0qddfP0Y00U1F79UuJ2cJpyqdjtMRvbdNv6udWhD0rtrjdLvGFDOryzD
W7xQD2NLWW0IC9YNuXR0FzrJFFqWBW+lfF1u1PdW7ITFtUhj8RcIZZgUS/w1Yh8/
d6ja18UROEgiJ/Isgvl8sNTe2oNQK9HM6XtyEif5G5J7cv5FAH3si98My5h+rKq9
AMGfQLtDOM+Ivg7D63iiuxB57Rq91xCsKCC2QNECAwEAAaOBgTB/MB0GA1UdDgQW
BBQuNq1dmybivJy6XnHIFBYqEfqtMDAfBgNVHSMEGDAWgBQuNq1dmybivJy6XnHI
FBYqEfqtMDAPBgNVHRMBAf8EBTADAQH/MCwGA1UdEQQlMCOCC2V4YW1wbGUuY29t
gglsb2NhbGhvc3SCCTEyNy4wLjAuMTANBgkqhkiG9w0BAQsFAAOCAgEAJFpeqQB9
pJLn4idrp7M1lSCrBJu2tu2UsOVcKTGZ3uqgKgKa+bn0kw9yN1CMISLSOV9B1Zt5
/+2U24/9iC1nGIzEpk2uQ2GwGaxFsy38gP6FF+UFltEvLbhfHWZ/j8gWQhTRQ/sT
TMd0L0CysmDswoEHcuNgdX+V4WVchPqdHTxp5qLM3GRas5JCuNcVi+vFEWCQsYRh
iTpsCEVfRsVJKUvPKVLR8PSEjSt8S+SQjIuTVWSmdG358uRVxpBzAzMwz9sQw4G6
Rv3S4LaQpWXUyHVYM1OxQz0fhEug5qgSR75GTFwG1oVd5rdk7iK/J3WbRJZ9FcKx
ipZ3jdl5mmI6p87OjgQVtUInv8KK88AhJmypBXaHE64nn8+YUsh/ud6+Vr8vyMPK
TZJivCtVKoX+nd3Zb3qX2YGORKQmn4GPX551FCk1CFOa+qlGfXtfqV2Z9LEQmqx3
ygqVnmSf34oTz04sSMdK7m3ULqLyv3RFJJ4F+VsHHAEdJYO+v/GdGz/0FA7ZZ4t+
7r1qY7uK4NSMRBn+DGlUL9oVp26uss/Qvi1WTI0g9W1YImxYSlaR0tm9jZQckirm
KMLMDyGJFvHqR8LRa3DU6L5pU99LxZSHRxBAY6oexKSYWt7BSE1kwaL3Exjg/RG/
ap5/GNJS1STNnbgq5TtWUbvZcXuhuBe8ClI=
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEGjCCAgKgAwIBAgIUCNvMLf/1EZcO6R9L/PQVWN8agbkwDQYJKoZIhvcNAQEL
BQAwOzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDEeMBwGA1UEAwwVQ2VydGlm
aWNhdGUgQXV0aG9yaXR5MB4XDTIzMDUwMTIwNDkxMFoXDTI0MDQzMDIwNDkxMFow
LzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDESMBAGA1UEAwwJbG9jYWxob3N0
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzP5NGFAhk6hAVr3YshRJ
YGxS2IGphFaq/c99QZQ62JbcSwceFo0p8Px9JiaT38n7NejEy6t6U0PQP2B9r3pJ
p0RwplvITLd1lp96DdMQeGXKa2rqJ62u9//u/XxFboVU6QYC90Pnqi6sRWejKEI8
Yowg6erjNMCQiIAKqhWPfdsJOxf79102gdahuTT8A89p551u7a84oTRtX4fLksP2
x0BVFb0/Dirz5ngwm6YHpN+8z7BYIyj4dLzzFjaqU1gptxtGygap1GtD1X9fJ61l
k6K8vMww4+/zYOoGratUTNeKHOvvXf9SnjoqyMTvJFyTX+5snkyL81q3+XgXJOYL
ZQIDAQABoyIwIDALBgNVHQ8EBAMCBaAwEQYJYIZIAYb4QgEBBAQDAgeAMA0GCSqG
SIb3DQEBCwUAA4ICAQAq5Em7EVkGhPgIMDmxhm398Kv8OivFxX6x5aGnJ+m8+mZV
+wrkjRvpqN/+CtTsid2q4+qYdlov8hJ2oxwVhfnrF5b7Xj7caC2FJifPXPiaMogT
5VI4uCABBuVQR0kDtnPF8bRiTWCKC3DC84GqMp0cUs3Qyf1dLcjhcc9dSROn00y8
/qmIz8roJ2esnqG12rTGdIAaWSgBCMKFjrV8YmxLf+z72VHSx6uC5CARG+UYa5Mu
vga0Q77QmwSstKBvGUBtvzQoML3/UFCikdfOxDgvJbr8Q0yEEw8hK7vGZLaj00zB
U4B5+DfV285RW09ihp2YMxuz3mL2tM5++RYJphB9/VTN3/f+geKt2pPA3Rkk11Ug
LP3NdpT5ZnQL9ehtmIExk2NVBi+RmGCcP7KcMtlq44FdyRF7p6qdg/Eq5n/sOMxQ
DnamgWDQltm6cuZ49haCXLZIbfqM2cHARIw/Sv3Dgd9SSDL2pooWI2U82fQ9A71q
u/hUlNDZm0v51IfgzJcbAtlAYd2OVlgCkkkFtbgdOaQUShIkcCKcpxtgQzpynNMO
DJoO41VXpMzBN7/ppVi0JrF7RkaXGeoNsqfvcmjQEuXUOluge2q8kHDf7gEUddKa
ijPHtkFQF2ujCGr/AVYjCMSlOk5WhRh8ZVxN0KbiWZJUN8akX4gU4KIpTe1big==
-----END CERTIFICATE-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAzP5NGFAhk6hAVr3YshRJYGxS2IGphFaq/c99QZQ62JbcSwce
Fo0p8Px9JiaT38n7NejEy6t6U0PQP2B9r3pJp0RwplvITLd1lp96DdMQeGXKa2rq
J62u9//u/XxFboVU6QYC90Pnqi6sRWejKEI8Yowg6erjNMCQiIAKqhWPfdsJOxf7
9102gdahuTT8A89p551u7a84oTRtX4fLksP2x0BVFb0/Dirz5ngwm6YHpN+8z7BY
Iyj4dLzzFjaqU1gptxtGygap1GtD1X9fJ61lk6K8vMww4+/zYOoGratUTNeKHOvv
Xf9SnjoqyMTvJFyTX+5snkyL81q3+XgXJOYLZQIDAQABAoIBAFNG/Arkgr95mqmi
dmXh1+1UFFPgWP1qOAzkPf5mOYHDx7qzKYX/0woTiMP26BwB8gv0g/45q3goFHGq
wWSISWOqahkrMDP6U8rc/rifBhHjSFhbFsUHygz17CEOWyaLA/OmfY32CCcazuFj
OOUiA2YFh1mAEs1bbVwGqE5wc9qsZtBlJxudSWtSZoJuFECDNqLfQXkJ39KnKhp4
D337nOR/xww81202mlfF/vvhRMfUIUS2Ij9USndp9huBHFSxf1mYjD1ljjx6U7el
new8TPf76J7nuy/6SxZ9wF6P2dk/eQcN5AnIcDGq0WzS3VcJc/KG/+maflCvH0dB
SLfx4AECgYEA7e+5/UhWZ62BfF1/Nat95+t+bh8UYN8gPEUos7oS/cUrme7YAPQT
MTWNulpmgGCRDxeXU9XBaPGyF7cU5bx28sK64ZUe8D1ySgGpVeSEQtjCLFEf6eat
801TQVNaH2WlDZTm+Onfr7ppFN1pLrBY+83m9TDJd6v4qHsvtNkcx38CgYEA3I5U
OvvoTEj8+Xc0U296NU+aWJLNrkDH6lFtdXsLyoumxh0DDbKSw8ia28Z5+8tz0mdB
33sIsnnsQ+83YoiXyopM9GFZdZH3luKrXgOGH8QFygJI8xGqqcLjeWNkW0b0KCkv
AoiedqOOmCdRMUfy3v5irH+4O90ZmW6VxNKbfxsCgYEAtjjFOQwAWHCR3TwBo4nN
6CL7dbzJr5LSLjZNAK/9wWoShVZdCQXj+OjpvRFktOa/0U4g7+yhrgyEdxMYpwUa
F7s4wnCg/B4i/Difhg93l3ZH5wbOKSUojU/n9fyu5aLDsE4cQf9i90MNHRSgbEhU
Law4OAmAEe2bhvSoyZkJKGMCgYBgW25BNr0OVvTuqD2cFh/2Goj8GWbysiqlHF4N
7WwBWXHLK/Ghklq8XnAJhHTWpNQ9IA+Pa1kpYErwgxpXWgW23yUvvzguPU9GBFGK
CVAXoLRGxSjJyPYepJ5s8hduKVmSEiwPl1Bj1KD/qG24cg6RjeHeKw56WOZOOhoE
m16D8QKBgBHXU31OJ2KMDnwjsMW2SlpYKoIQlJyTg3qvN7gu+ZGo5B7hviqh5wN1
y577N/NT9No8qGNEGTZl35hkyw8DmB4RAZp7G1qbVCGszUBt/vS6Guv82/EgMVo2
ZgiQBkI1kEOtj5LMVBfOKTRBEpyAm5fSZ+eQtSIc5LCbQ8aEvio4
-----END RSA PRIVATE KEY-----

0 comments on commit e9b7527

Please sign in to comment.