1
22
23 package com.liferay.portlet.messageboards.smtp;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
27 import com.liferay.portal.kernel.smtp.MessageListener;
28 import com.liferay.portal.kernel.smtp.MessageListenerException;
29 import com.liferay.portal.kernel.util.GetterUtil;
30 import com.liferay.portal.kernel.util.StringPool;
31 import com.liferay.portal.kernel.util.StringUtil;
32 import com.liferay.portal.model.Company;
33 import com.liferay.portal.model.User;
34 import com.liferay.portal.security.auth.PrincipalException;
35 import com.liferay.portal.security.permission.PermissionCheckerUtil;
36 import com.liferay.portal.service.CompanyLocalServiceUtil;
37 import com.liferay.portal.service.UserLocalServiceUtil;
38 import com.liferay.portal.util.PropsUtil;
39 import com.liferay.portlet.messageboards.NoSuchMessageException;
40 import com.liferay.portlet.messageboards.model.MBCategory;
41 import com.liferay.portlet.messageboards.model.MBMessage;
42 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
43 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
44 import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
45 import com.liferay.portlet.messageboards.util.MBUtil;
46 import com.liferay.util.mail.JavaMailUtil;
47 import com.liferay.util.mail.MailEngine;
48
49 import java.io.IOException;
50 import java.io.InputStream;
51
52 import javax.mail.BodyPart;
53 import javax.mail.MessagingException;
54 import javax.mail.Part;
55 import javax.mail.internet.MimeMessage;
56 import javax.mail.internet.MimeMultipart;
57
58 import org.apache.commons.lang.time.StopWatch;
59 import org.apache.commons.logging.Log;
60 import org.apache.commons.logging.LogFactory;
61
62
69 public class MessageListenerImpl implements MessageListener {
70
71 public boolean accept(String from, String recipient) {
72 try {
73 if (!recipient.startsWith(MBUtil.SMTP_PORTLET_PREFIX)) {
74 return false;
75 }
76
77 Company company = getCompany(recipient);
78 long categoryId = getCategoryId(recipient);
79
80 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
81 categoryId);
82
83 if (category.getCompanyId() != company.getCompanyId()) {
84 return false;
85 }
86
87 if (_log.isDebugEnabled()) {
88 _log.debug("Check to see if user " + from + " exists");
89 }
90
91 UserLocalServiceUtil.getUserByEmailAddress(
92 company.getCompanyId(), from);
93
94 return true;
95 }
96 catch (Exception e) {
97 if (_log.isWarnEnabled()) {
98 _log.warn("Mail rejected", e);
99 }
100
101 return false;
102 }
103 }
104
105 public void deliver(String from, String recipient, InputStream data)
106 throws MessageListenerException {
107
108 try {
109 StopWatch stopWatch = null;
110
111 if (_log.isDebugEnabled()) {
112 stopWatch = new StopWatch();
113
114 stopWatch.start();
115
116 _log.debug(
117 "Deliver message from " + from + " to " + recipient);
118 }
119
120 Company company = getCompany(recipient);
121 long categoryId = getCategoryId(recipient);
122
123 if (_log.isDebugEnabled()) {
124 _log.debug("Category id " + categoryId);
125 }
126
127 User user = UserLocalServiceUtil.getUserByEmailAddress(
128 company.getCompanyId(), from);
129
130 MimeMessage message = new MimeMessage(
131 MailEngine.getSession(), data);
132
133 long parentMessageId = getParentMessageId(recipient, message);
134
135 if (_log.isDebugEnabled()) {
136 _log.debug("Parent message id " + parentMessageId);
137 }
138
139 MBMessage parentMessage = null;
140
141 try {
142 if (parentMessageId > 0) {
143 parentMessage = MBMessageLocalServiceUtil.getMessage(
144 parentMessageId);
145 }
146 }
147 catch (NoSuchMessageException nsme) {
148
149
152 }
153
154 if (_log.isDebugEnabled()) {
155 _log.debug("Parent message " + parentMessage);
156 }
157
158 MBMailMessage collector = new MBMailMessage();
159
160 collectPartContent(message, collector);
161
162 PermissionCheckerUtil.setThreadValues(user);
163
164 if (parentMessage == null) {
165 MBMessageServiceUtil.addMessage(
166 categoryId, message.getSubject(), collector.getBody(),
167 collector.getFiles(), false, 0.0, null, true, true);
168 }
169 else {
170 MBMessageServiceUtil.addMessage(
171 categoryId, parentMessage.getThreadId(),
172 parentMessage.getMessageId(), message.getSubject(),
173 collector.getBody(), collector.getFiles(), false, 0.0, null,
174 true, true);
175 }
176
177 if (_log.isDebugEnabled()) {
178 _log.debug(
179 "Delivering message takes " + stopWatch.getTime() + " ms");
180 }
181 }
182 catch (PrincipalException pe) {
183 if (_log.isDebugEnabled()) {
184 _log.debug("Prevented unauthorized post from " + from);
185 }
186
187 throw new MessageListenerException(pe);
188 }
189 catch (Exception e) {
190 _log.error(e, e);
191
192 throw new MessageListenerException(e);
193 }
194 }
195
196 public String getId() {
197 return MessageListenerImpl.class.getName();
198 }
199
200 protected void collectMultipartContent(
201 MimeMultipart multipart, MBMailMessage collector)
202 throws IOException, MessagingException {
203
204 for (int i = 0; i < multipart.getCount(); i++) {
205 BodyPart part = multipart.getBodyPart(i);
206
207 collectPartContent(part, collector);
208 }
209 }
210
211 protected void collectPartContent(Part part, MBMailMessage collector)
212 throws IOException, MessagingException {
213
214 Object partContent = part.getContent();
215
216 String contentType = part.getContentType().toLowerCase();
217
218 if ((part.getDisposition() != null) &&
219 (part.getDisposition().equalsIgnoreCase(MimeMessage.ATTACHMENT))) {
220
221 if (_log.isDebugEnabled()) {
222 _log.debug("Processing attachment");
223 }
224
225 byte[] bytes = null;
226
227 if (partContent instanceof String) {
228 bytes = ((String)partContent).getBytes();
229 }
230 else if (partContent instanceof InputStream) {
231 bytes = JavaMailUtil.getBytes(part);
232 }
233
234 collector.addFile(part.getFileName(), bytes);
235 }
236 else {
237 if (partContent instanceof MimeMultipart) {
238 collectMultipartContent((MimeMultipart)partContent, collector);
239 }
240 else if (partContent instanceof String) {
241 if (contentType.startsWith("text/html")) {
242 collector.setHtmlBody((String)partContent);
243 }
244 else {
245 collector.setPlainBody((String)partContent);
246 }
247 }
248 }
249 }
250
251 protected long getCategoryId(String recipient) {
252 int pos = recipient.indexOf(StringPool.AT);
253
254 String target = recipient.substring(
255 MBUtil.SMTP_PORTLET_PREFIX.length(), pos);
256
257 String[] parts = StringUtil.split(target, ".");
258
259 long categoryId = GetterUtil.getLong(parts[0]);
260
261 return categoryId;
262 }
263
264 protected Company getCompany(String recipient)
265 throws PortalException, SystemException {
266
267 int pos = recipient.indexOf(StringPool.AT);
268
269 String smtpServerSubdomain = PropsUtil.get(
270 PropsUtil.SMTP_SERVER_SUBDOMAIN);
271
272 String mx = recipient.substring(
273 pos + smtpServerSubdomain.length() + 2);
274
275 return CompanyLocalServiceUtil.getCompanyByMx(mx);
276 }
277
278 protected long getParentMessageId(String recipient, MimeMessage message)
279 throws MessagingException {
280
281
283 int pos = recipient.indexOf(StringPool.AT);
284
285 String target = recipient.substring(
286 MBUtil.SMTP_PORTLET_PREFIX.length(), pos);
287
288 String[] parts = StringUtil.split(target, ".");
289
290 long parentMessageId = 0;
291
292 if (parts.length == 2) {
293 parentMessageId = GetterUtil.getLong(parts[1]);
294 }
295
296 if (parentMessageId > 0) {
297 return parentMessageId;
298 }
299
300
305 String parentHeader = null;
306
307 String[] references = message.getHeader("References");
308
309 if ((references != null) && (references.length > 0)) {
310 parentHeader = references[0].substring(
311 references[0].lastIndexOf("<"));
312 }
313
314 if (parentHeader == null) {
315 String[] inReplyToHeaders = message.getHeader("In-Reply-To");
316
317 if ((inReplyToHeaders != null) &&
318 (inReplyToHeaders.length > 0)) {
319
320 parentHeader = inReplyToHeaders[0];
321 }
322 }
323
324 if (parentHeader != null) {
325 if (_log.isDebugEnabled()) {
326 _log.debug("Parent header " + parentHeader);
327 }
328
329 if (parentMessageId == -1) {
330 parentMessageId = MBUtil.getMessageId(parentHeader);
331 }
332
333 if (_log.isDebugEnabled()) {
334 _log.debug("Previous message id " + parentMessageId);
335 }
336 }
337
338 return parentMessageId;
339 }
340
341 private static Log _log = LogFactory.getLog(MessageListenerImpl.class);
342
343 }