1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.kernel.mail;
23
24 import org.apache.commons.lang3.StringUtils;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import java.util.Date;
29 import java.util.Properties;
30
31 import javax.mail.MessagingException;
32 import javax.mail.Session;
33 import javax.mail.Transport;
34 import javax.mail.internet.MimeMessage;
35
36
37
38
39 public class BaseSmtpService {
40
41
42 private static final Logger logger = LoggerFactory.getLogger(BaseSmtpService.class);
43
44
45 protected enum Mode {
46 production, test
47 };
48
49
50 protected static final String OPT_MAIL_PREFIX = "mail.";
51
52
53 protected static final String OPT_MAIL_TRANSPORT = "mail.transport.protocol";
54
55
56 protected static final String OPT_MAIL_HOST_SUFFIX = ".host";
57
58
59 protected static final String OPT_MAIL_PORT_SUFFIX = ".port";
60
61
62 protected static final String OPT_MAIL_TLS_ENABLE_SUFFIX = ".starttls.enable";
63
64
65 protected static final String OPT_MAIL_AUTH_SUFFIX = ".auth";
66
67
68 protected static final String OPT_MAIL_USER = "mail.user";
69
70
71 protected static final String OPT_MAIL_PASSWORD = "mail.password";
72
73
74 protected static final String OPT_MAIL_FROM = "mail.from";
75
76
77 protected static final String OPT_MAIL_DEBUG = "mail.debug";
78
79
80 private static final String DEFAULT_MAIL_TRANSPORT = "smtp";
81
82
83 private static final int DEFAULT_MAIL_PORT = 25;
84
85
86 protected String mailTransport = DEFAULT_MAIL_TRANSPORT;
87
88
89 private boolean productionMode = true;
90
91
92 private String host = null;
93
94
95 private int port = DEFAULT_MAIL_PORT;
96
97
98 private String user = null;
99
100
101 private String password = null;
102
103
104 private boolean debug = false;
105
106
107 private boolean ssl = false;
108
109
110 private String sender = null;
111
112
113 private Properties mailProperties = new Properties();
114
115
116 private Session defaultMailSession = null;
117
118 public void setProductionMode(boolean mode) {
119 this.productionMode = mode;
120 }
121
122 public boolean isProductionMode() {
123 return productionMode;
124 }
125
126 public void setHost(String host) {
127 this.host = host;
128 }
129
130 public void setMailTransport(String mailTransport) {
131 this.mailTransport = mailTransport;
132 }
133
134 public void setPort(Integer port) {
135 this.port = port;
136 }
137
138 public void setUser(String user) {
139 this.user = user;
140 }
141
142 public void setPassword(String password) {
143 this.password = password;
144 }
145
146 public void setDebug(boolean debug) {
147 this.debug = debug;
148 }
149
150 public void setSender(String sender) {
151 this.sender = sender;
152 }
153
154 public String getSender() {
155 return this.sender;
156 }
157
158 public void setSsl(boolean ssl) {
159 this.ssl = ssl;
160 }
161
162 public void configure() {
163 mailProperties.clear();
164 defaultMailSession = null;
165
166 if (!("smtp".equals(mailTransport) || "smtps".equals(mailTransport))) {
167 if (mailTransport != null) {
168 logger.warn("'{}' procotol not supported. Reverting to default: '{}'", mailTransport, DEFAULT_MAIL_TRANSPORT);
169 }
170 logger.debug("Mail transport protocol defaults to '{}'", DEFAULT_MAIL_TRANSPORT);
171 mailProperties.put(OPT_MAIL_TRANSPORT, DEFAULT_MAIL_TRANSPORT);
172 } else {
173 logger.debug("Mail transport protocol is '{}'", mailTransport);
174 mailProperties.put(OPT_MAIL_TRANSPORT, mailTransport);
175 }
176
177 mailProperties.put(OPT_MAIL_PREFIX + mailTransport + OPT_MAIL_HOST_SUFFIX, host);
178 logger.debug("Mail host is {}", host);
179
180 mailProperties.put(OPT_MAIL_PREFIX + mailTransport + OPT_MAIL_PORT_SUFFIX, port);
181 logger.debug("Mail server port is '{}'", port);
182
183
184 String propName = OPT_MAIL_PREFIX + mailTransport + OPT_MAIL_AUTH_SUFFIX;
185 if (StringUtils.isNotBlank(user)) {
186 mailProperties.put(OPT_MAIL_USER, user);
187 mailProperties.put(propName, Boolean.toString(true));
188 logger.debug("Mail user is '{}'", user);
189 } else {
190 mailProperties.put(propName, Boolean.toString(false));
191 logger.debug("Sending mails to {} without authentication", host);
192 }
193
194 if (StringUtils.isNotBlank(password)) {
195 mailProperties.put(OPT_MAIL_PASSWORD, password);
196 logger.debug("Mail password set");
197 }
198
199 if (StringUtils.isNotBlank(sender)) {
200 mailProperties.put(OPT_MAIL_FROM, sender);
201 logger.debug("Mail sender is '{}'", sender);
202 } else {
203 logger.debug("Mail sender defaults not set");
204 }
205
206 mailProperties.put(OPT_MAIL_PREFIX + mailTransport + OPT_MAIL_TLS_ENABLE_SUFFIX, ssl);
207 if (ssl) {
208 logger.debug("TLS over SMTP is enabled");
209 } else {
210 logger.debug("TLS over SMTP is disabled");
211 }
212
213 mailProperties.put(OPT_MAIL_DEBUG, Boolean.toString(debug));
214 logger.debug("Mail debugging is {}", debug ? "enabled" : "disabled");
215
216 logger.info("Mail service configured with {}", host);
217 Properties props = getSession().getProperties();
218 for (String key : props.stringPropertyNames()) {
219 logger.info("{}: {}", key, props.getProperty(key));
220 }
221 }
222
223
224
225
226
227
228 public Session getSession() {
229 if (defaultMailSession == null) {
230 defaultMailSession = Session.getInstance(mailProperties);
231 }
232 return defaultMailSession;
233 }
234
235
236
237
238
239
240 public MimeMessage createMessage() {
241 return new MimeMessage(getSession());
242 }
243
244
245
246
247
248
249
250
251
252 public void send(MimeMessage message) throws MessagingException {
253 message.setSentDate(new Date());
254 if (!productionMode) {
255 logger.debug("Skipping sending of message {} due to test mode", message);
256 return;
257 }
258 Transport t = getSession().getTransport(mailTransport);
259 ClassLoader cl = Thread.currentThread().getContextClassLoader();
260 try {
261 Thread.currentThread().setContextClassLoader(javax.mail.Session.class.getClassLoader());
262 if (user != null) {
263 t.connect(user, password);
264 } else {
265 t.connect();
266 }
267 t.sendMessage(message, message.getAllRecipients());
268 } finally {
269 Thread.currentThread().setContextClassLoader(cl);
270 t.close();
271 }
272 }
273
274 }