1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.mail.internal.configuration

File DefaultMailSenderConfiguration.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

24
66
12
1
321
186
26
0.39
5.5
12
2.17

Classes

Class Line # Actions
DefaultMailSenderConfiguration 53 66 0% 26 1
0.9901960599%
 

Contributing tests

This file is covered by 20 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.mail.internal.configuration;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.InputStream;
24    import java.util.ArrayList;
25    import java.util.List;
26    import java.util.Properties;
27   
28    import javax.inject.Inject;
29    import javax.inject.Named;
30    import javax.inject.Singleton;
31   
32    import org.apache.commons.lang.exception.ExceptionUtils;
33    import org.apache.commons.lang3.StringUtils;
34    import org.slf4j.Logger;
35    import org.xwiki.component.annotation.Component;
36    import org.xwiki.configuration.ConfigurationSource;
37    import org.xwiki.mail.MailSenderConfiguration;
38   
39    /**
40    * Gets the Mail Sending configuration. The configuration is checked in the following order:
41    * <ul>
42    * <li>Look in Mail.MailConfig in the current wiki</li>
43    * <li>[Backward compatibility] Look in (current space).XWikiPreferences in the current wiki</li>
44    * <li>[Backward compatibility] Look in XWiki.XWikiPreferences in the current wiki</li>
45    * <li>Look in the xwiki properties file</li>
46    * </ul>
47    *
48    * @version $Id: 5cf91c6bd1457bc57f610563f947408a43d40da8 $
49    * @since 6.1M2
50    */
51    @Component
52    @Singleton
 
53    public class DefaultMailSenderConfiguration implements MailSenderConfiguration
54    {
55    /**
56    * Java Mail SMTP property for the protocol.
57    */
58    public static final String JAVAMAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol";
59   
60    /**
61    * Java Mail SMTP property for the host.
62    */
63    public static final String JAVAMAIL_SMTP_HOST = "mail.smtp.host";
64   
65    /**
66    * Java Mail SMTP property for the server port.
67    */
68    public static final String JAVAMAIL_SMTP_PORT = "mail.smtp.port";
69   
70    /**
71    * Java Mail SMTP property for the username.
72    */
73    public static final String JAVAMAIL_SMTP_USERNAME = "mail.smtp.user";
74   
75    /**
76    * Java Mail SMTP property for the from email address.
77    */
78    public static final String JAVAMAIL_SMTP_FROM = "mail.smtp.from";
79   
80    /**
81    * Java Mail SMTP property for specifying that we are authenticating.
82    */
83    public static final String JAVAMAIL_SMTP_AUTH = "mail.smtp.auth";
84   
85    /**
86    * Prefix for configuration keys for the Mail Sending module.
87    */
88    private static final String PREFIX = "mail.sender.";
89   
90    private static final int DEFAULT_PORT = 25;
91   
92    /**
93    * By default we wait 8 seconds between each mail in order to throttle the mail sending and not be considered as
94    * a spammer by mail servers.
95    */
96    private static final long DEFAULT_SEND_WAIT_TIME = 8 * 1000L;
97   
98    private static final String FROM_PROPERTY = "from";
99    private static final String BCC_PROPERTY = "bcc";
100    private static final String HOST_PROPERTY = "host";
101    private static final String PORT_PROPERTY = "port";
102    private static final String USERNAME_PROPERTY = "username";
103    private static final String PASSWORD_PROPERTY = "password";
104    private static final String PROPERTIES_PROPERTY = "properties";
105    private static final String SEND_WAIT_TIME = "sendWaitTime";
106   
107    @Inject
108    private Logger logger;
109   
110    @Inject
111    @Named("mailsend")
112    private ConfigurationSource mailConfigSource;
113   
114    @Inject
115    @Named("documents")
116    private ConfigurationSource documentsSource;
117   
118    @Inject
119    @Named("xwikiproperties")
120    private ConfigurationSource xwikiPropertiesSource;
121   
 
122  38 toggle @Override
123    public String getHost()
124    {
125  38 String host;
126   
127    // First, look in the document sources
128  38 host = this.mailConfigSource.getProperty(HOST_PROPERTY,
129    this.documentsSource.getProperty("smtp_server", String.class));
130   
131    // If not found, look in the xwiki properties source
132  38 if (host == null) {
133  21 host = this.xwikiPropertiesSource.getProperty(PREFIX + HOST_PROPERTY, "localhost");
134    }
135   
136  38 return host;
137    }
138   
 
139  40 toggle @Override
140    public int getPort()
141    {
142  40 Integer port = null;
143   
144    // First, look in the document sources
145  40 String portAsString = this.documentsSource.getProperty("smtp_port");
146  40 if (!StringUtils.isEmpty(portAsString)) {
147  1 try {
148  1 port = this.mailConfigSource.getProperty(PORT_PROPERTY, Integer.parseInt(portAsString));
149    } catch (NumberFormatException e) {
150  0 port = DEFAULT_PORT;
151    }
152    } else {
153  39 port = this.mailConfigSource.getProperty(PORT_PROPERTY, Integer.class);
154    }
155   
156    // If not found, look in the xwiki properties source
157  40 if (port == null) {
158  22 port = this.xwikiPropertiesSource.getProperty(PREFIX + PORT_PROPERTY, DEFAULT_PORT);
159    }
160   
161  40 return port;
162    }
163   
 
164  113 toggle @Override
165    public String getUsername()
166    {
167  113 String username;
168   
169    // First, look in the document sources
170  113 username = this.mailConfigSource.getProperty(USERNAME_PROPERTY,
171    this.documentsSource.getProperty("smtp_server_username", String.class));
172   
173    // If not found, look in the xwiki properties source
174  113 if (username == null) {
175  112 username = this.xwikiPropertiesSource.getProperty(PREFIX + USERNAME_PROPERTY, String.class);
176    }
177   
178  113 return username;
179    }
180   
 
181  2 toggle @Override
182    public String getPassword()
183    {
184  2 String password;
185   
186    // First, look in the document sources
187  2 password = this.mailConfigSource.getProperty(PASSWORD_PROPERTY,
188    this.documentsSource.getProperty("smtp_server_password", String.class));
189   
190    // If not found, look in the xwiki properties source
191  2 if (password == null) {
192  1 password = this.xwikiPropertiesSource.getProperty(PREFIX + PASSWORD_PROPERTY, String.class);
193    }
194   
195  2 return password;
196    }
197   
 
198  8 toggle @Override
199    public List<String> getBCCAddresses()
200    {
201  8 List<String> bccAddresses = new ArrayList<>();
202   
203    // First, look in the document source
204  8 String bccAsString = this.mailConfigSource.getProperty(BCC_PROPERTY, String.class);
205   
206    // If not found, look in the xwiki properties source
207  8 if (bccAsString == null) {
208  7 bccAsString = this.xwikiPropertiesSource.getProperty(PREFIX + BCC_PROPERTY, String.class);
209    }
210   
211    // Convert into a list (if property is found and not null)
212  8 if (bccAsString != null) {
213  1 for (String address : StringUtils.split(bccAsString, ',')) {
214  2 bccAddresses.add(StringUtils.trim(address));
215    }
216    }
217   
218  8 return bccAddresses;
219    }
220   
 
221  74 toggle @Override
222    public String getFromAddress()
223    {
224  74 String from;
225   
226    // First, look in the document sources
227  74 from = this.mailConfigSource.getProperty(FROM_PROPERTY,
228    this.documentsSource.getProperty("admin_email", String.class));
229   
230    // If not found, look in the xwiki properties source
231  74 if (from == null) {
232  71 from = this.xwikiPropertiesSource.getProperty(PREFIX + FROM_PROPERTY, String.class);
233    }
234   
235  74 return from;
236    }
237   
 
238  42 toggle @Override
239    public Properties getAdditionalProperties()
240    {
241  42 Properties properties;
242   
243    // First, look in the document sources
244  42 String extraPropertiesAsString = this.mailConfigSource.getProperty(PROPERTIES_PROPERTY,
245    this.documentsSource.getProperty("javamail_extra_props", String.class));
246   
247    // If not found, look in the xwiki properties source
248  42 if (extraPropertiesAsString == null) {
249  38 properties = this.xwikiPropertiesSource.getProperty(PREFIX + PROPERTIES_PROPERTY, Properties.class);
250    } else {
251    // The "javamail_extra_props" property is stored in a text area and thus we need to convert it to a Map.
252  4 InputStream is = new ByteArrayInputStream(extraPropertiesAsString.getBytes());
253  4 properties = new Properties();
254  4 try {
255  4 properties.load(is);
256    } catch (Exception e) {
257    // Will happen if the user has not used the right format, in which case we log a warning but discard
258    // the user values.
259  1 this.logger.warn("Error while parsing mail properties [{}]. Root cause [{}]. Ignoring configuration...",
260    extraPropertiesAsString, ExceptionUtils.getRootCauseMessage(e));
261    }
262    }
263   
264  42 return properties;
265    }
266   
 
267  43 toggle @Override
268    public Properties getAllProperties()
269    {
270  43 Properties properties = new Properties();
271  43 addProperty(properties, JAVAMAIL_TRANSPORT_PROTOCOL, "smtp");
272  43 addProperty(properties, JAVAMAIL_SMTP_HOST, getHost());
273  43 addProperty(properties, JAVAMAIL_SMTP_USERNAME, getUsername());
274  43 addProperty(properties, JAVAMAIL_SMTP_FROM, getFromAddress());
275  43 addProperty(properties, JAVAMAIL_SMTP_PORT, Integer.toString(getPort()));
276   
277    // If a username and a password have been provided consider we're authenticating against the SMTP server
278  43 if (usesAuthentication()) {
279  1 properties.put(JAVAMAIL_SMTP_AUTH, "true");
280    }
281   
282    // Add user-specified mail properties.
283    // Note: We're only supporting SMTP (and not SMTPS) at the moment, which means that for sending emails to a
284    // SMTP server requiring TLS the user will need to pass the "mail.smtp.starttls.enable=true" property and use
285    // the proper port for TLS (587 for Gmail for example, while port 465 is used for SMTPS/SSL).
286  43 properties.putAll(getAdditionalProperties());
287   
288  43 return properties;
289    }
290   
 
291  215 toggle private void addProperty(Properties properties, String key, String value)
292    {
293  215 if (value != null) {
294  137 properties.setProperty(key, value);
295    }
296    }
297   
 
298  83 toggle @Override
299    public boolean usesAuthentication()
300    {
301  83 return !StringUtils.isEmpty(getUsername()) && !StringUtils.isEmpty(getPassword());
302    }
303   
 
304  4 toggle @Override
305    public String getScriptServicePermissionCheckerHint()
306    {
307  4 return this.xwikiPropertiesSource.getProperty(PREFIX + "scriptServiceCheckerHint", "programmingrights");
308    }
309   
 
310  7 toggle @Override
311    public long getSendWaitTime()
312    {
313  7 Long waitTime = this.mailConfigSource.getProperty(SEND_WAIT_TIME);
314   
315  7 if (waitTime == null) {
316  1 waitTime = this.xwikiPropertiesSource.getProperty(PREFIX + SEND_WAIT_TIME, DEFAULT_SEND_WAIT_TIME);
317    }
318   
319  7 return waitTime;
320    }
321    }