001
014
015 package com.liferay.portlet.messageboards.pop;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.pop.MessageListener;
020 import com.liferay.portal.kernel.pop.MessageListenerException;
021 import com.liferay.portal.kernel.util.CharPool;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.ObjectValuePair;
024 import com.liferay.portal.kernel.util.PrefsPropsUtil;
025 import com.liferay.portal.kernel.util.PropsKeys;
026 import com.liferay.portal.kernel.util.StreamUtil;
027 import com.liferay.portal.kernel.util.StringUtil;
028 import com.liferay.portal.model.Company;
029 import com.liferay.portal.model.User;
030 import com.liferay.portal.security.auth.PrincipalException;
031 import com.liferay.portal.security.permission.PermissionCheckerUtil;
032 import com.liferay.portal.service.CompanyLocalServiceUtil;
033 import com.liferay.portal.service.ServiceContext;
034 import com.liferay.portal.service.UserLocalServiceUtil;
035 import com.liferay.portal.util.PortalUtil;
036 import com.liferay.portal.util.PortletKeys;
037 import com.liferay.portal.util.PropsValues;
038 import com.liferay.portlet.messageboards.NoSuchCategoryException;
039 import com.liferay.portlet.messageboards.NoSuchMessageException;
040 import com.liferay.portlet.messageboards.model.MBCategory;
041 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
042 import com.liferay.portlet.messageboards.model.MBMessage;
043 import com.liferay.portlet.messageboards.model.MBMessageConstants;
044 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
045 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
046 import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
047 import com.liferay.portlet.messageboards.util.MBMailMessage;
048 import com.liferay.portlet.messageboards.util.MBUtil;
049
050 import java.io.InputStream;
051
052 import java.util.List;
053
054 import javax.mail.Message;
055 import javax.mail.MessagingException;
056
057 import org.apache.commons.lang.time.StopWatch;
058
059
064 public class MessageListenerImpl implements MessageListener {
065
066 public boolean accept(String from, String recipient, Message message) {
067 try {
068 if (isAutoReply(message)) {
069 return false;
070 }
071
072 String messageId = getMessageId(recipient, message);
073
074 if ((messageId == null) ||
075 (!messageId.startsWith(
076 MBUtil.MESSAGE_POP_PORTLET_PREFIX, getOffset()))) {
077
078 return false;
079 }
080
081 Company company = getCompany(messageId);
082 long categoryId = getCategoryId(messageId);
083
084 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
085 categoryId);
086
087 if (category.getCompanyId() != company.getCompanyId()) {
088 return false;
089 }
090
091 if (_log.isDebugEnabled()) {
092 _log.debug("Check to see if user " + from + " exists");
093 }
094
095 String pop3User = PrefsPropsUtil.getString(
096 PropsKeys.MAIL_SESSION_MAIL_POP3_USER,
097 PropsValues.MAIL_SESSION_MAIL_POP3_USER);
098
099 if (from.equalsIgnoreCase(pop3User)) {
100 return false;
101 }
102
103 UserLocalServiceUtil.getUserByEmailAddress(
104 company.getCompanyId(), from);
105
106 return true;
107 }
108 catch (Exception e) {
109 if (_log.isErrorEnabled()) {
110 _log.error("Unable to process message: " + message, e);
111 }
112
113 return false;
114 }
115 }
116
117 public void deliver(String from, String recipient, Message message)
118 throws MessageListenerException {
119
120 List<ObjectValuePair<String, InputStream>> inputStreamOVPs = null;
121
122 try {
123 StopWatch stopWatch = null;
124
125 if (_log.isDebugEnabled()) {
126 stopWatch = new StopWatch();
127
128 stopWatch.start();
129
130 _log.debug("Deliver message from " + from + " to " + recipient);
131 }
132
133 String messageId = getMessageId(recipient, message);
134
135 Company company = getCompany(messageId);
136
137 if (_log.isDebugEnabled()) {
138 _log.debug("Message id " + messageId);
139 }
140
141 long groupId = 0;
142 long categoryId = getCategoryId(messageId);
143
144 try {
145 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
146 categoryId);
147
148 groupId = category.getGroupId();
149 }
150 catch (NoSuchCategoryException nsce) {
151 groupId = categoryId;
152 categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
153 }
154
155 if (_log.isDebugEnabled()) {
156 _log.debug("Group id " + groupId);
157 _log.debug("Category id " + categoryId);
158 }
159
160 User user = UserLocalServiceUtil.getUserByEmailAddress(
161 company.getCompanyId(), from);
162
163 long parentMessageId = getParentMessageId(recipient, message);
164
165 if (_log.isDebugEnabled()) {
166 _log.debug("Parent message id " + parentMessageId);
167 }
168
169 MBMessage parentMessage = null;
170
171 try {
172 if (parentMessageId > 0) {
173 parentMessage = MBMessageLocalServiceUtil.getMessage(
174 parentMessageId);
175 }
176 }
177 catch (NoSuchMessageException nsme) {
178
179
180
181
182 }
183
184 if (_log.isDebugEnabled()) {
185 _log.debug("Parent message " + parentMessage);
186 }
187
188 String subject = MBUtil.getSubjectWithoutMessageId(message);
189
190 MBMailMessage mbMailMessage = new MBMailMessage();
191
192 MBUtil.collectPartContent(message, mbMailMessage);
193
194 inputStreamOVPs = mbMailMessage.getInputStreamOVPs();
195
196 PermissionCheckerUtil.setThreadValues(user);
197
198 ServiceContext serviceContext = new ServiceContext();
199
200 serviceContext.setAddGroupPermissions(true);
201 serviceContext.setAddGuestPermissions(true);
202 serviceContext.setLayoutFullURL(
203 PortalUtil.getLayoutFullURL(
204 groupId, PortletKeys.MESSAGE_BOARDS));
205 serviceContext.setScopeGroupId(groupId);
206
207 if (parentMessage == null) {
208 MBMessageServiceUtil.addMessage(
209 groupId, categoryId, subject, mbMailMessage.getBody(),
210 MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false,
211 0.0, true, serviceContext);
212 }
213 else {
214 MBMessageServiceUtil.addMessage(
215 parentMessage.getMessageId(), subject,
216 mbMailMessage.getBody(), MBMessageConstants.DEFAULT_FORMAT,
217 inputStreamOVPs, false, 0.0, true, serviceContext);
218 }
219
220 if (_log.isDebugEnabled()) {
221 _log.debug(
222 "Delivering message takes " + stopWatch.getTime() + " ms");
223 }
224 }
225 catch (PrincipalException pe) {
226 if (_log.isDebugEnabled()) {
227 _log.debug("Prevented unauthorized post from " + from);
228 }
229
230 throw new MessageListenerException(pe);
231 }
232 catch (Exception e) {
233 _log.error(e, e);
234
235 throw new MessageListenerException(e);
236 }
237 finally {
238 if (inputStreamOVPs != null) {
239 for (ObjectValuePair<String, InputStream> inputStreamOVP :
240 inputStreamOVPs) {
241
242 InputStream inputStream = inputStreamOVP.getValue();
243
244 StreamUtil.cleanUp(inputStream);
245 }
246 }
247
248 PermissionCheckerUtil.setThreadValues(null);
249 }
250 }
251
252 public String getId() {
253 return MessageListenerImpl.class.getName();
254 }
255
256 protected long getCategoryId(String recipient) {
257 int pos = recipient.indexOf(CharPool.AT);
258
259 String target = recipient.substring(
260 MBUtil.MESSAGE_POP_PORTLET_PREFIX.length() + getOffset(), pos);
261
262 String[] parts = StringUtil.split(target, CharPool.PERIOD);
263
264 return GetterUtil.getLong(parts[0]);
265 }
266
267 protected Company getCompany(String messageId) throws Exception {
268 int pos =
269 messageId.indexOf(CharPool.AT) +
270 PropsValues.POP_SERVER_SUBDOMAIN.length() + 1;
271
272 if (PropsValues.POP_SERVER_SUBDOMAIN.length() > 0) {
273 pos++;
274 }
275
276 int endPos = messageId.indexOf(CharPool.GREATER_THAN, pos);
277
278 if (endPos == -1) {
279 endPos = messageId.length();
280 }
281
282 String mx = messageId.substring(pos, endPos);
283
284 return CompanyLocalServiceUtil.getCompanyByMx(mx);
285 }
286
287 protected String getMessageId(String recipient, Message message)
288 throws Exception {
289
290 if (PropsValues.POP_SERVER_SUBDOMAIN.length() > 0) {
291 return recipient;
292 }
293 else {
294 return MBUtil.getParentMessageIdString(message);
295 }
296 }
297
298 protected int getOffset() {
299 if (PropsValues.POP_SERVER_SUBDOMAIN.length() == 0) {
300 return 1;
301 }
302
303 return 0;
304 }
305
306 protected long getParentMessageId(String recipient, Message message)
307 throws Exception {
308
309 if (!StringUtil.startsWith(
310 recipient, MBUtil.MESSAGE_POP_PORTLET_PREFIX)) {
311
312 return MBUtil.getParentMessageId(message);
313 }
314
315 int pos = recipient.indexOf(CharPool.AT);
316
317 if (pos < 0) {
318 return MBUtil.getParentMessageId(message);
319 }
320
321 String target = recipient.substring(
322 MBUtil.MESSAGE_POP_PORTLET_PREFIX.length(), pos);
323
324 String[] parts = StringUtil.split(target, CharPool.PERIOD);
325
326 long parentMessageId = 0;
327
328 if (parts.length == 2) {
329 parentMessageId = GetterUtil.getLong(parts[1]);
330 }
331
332 if (parentMessageId > 0) {
333 return parentMessageId;
334 }
335
336 return MBUtil.getParentMessageId(message);
337 }
338
339 protected boolean isAutoReply(Message message) throws MessagingException {
340 String[] autoReply = message.getHeader("X-Autoreply");
341
342 if ((autoReply != null) && (autoReply.length > 0)) {
343 return true;
344 }
345
346 String[] autoReplyFrom = message.getHeader("X-Autoreply-From");
347
348 if ((autoReplyFrom != null) && (autoReplyFrom.length > 0)) {
349 return true;
350 }
351
352 String[] mailAutoReply = message.getHeader("X-Mail-Autoreply");
353
354 if ((mailAutoReply != null) && (mailAutoReply.length > 0)) {
355 return true;
356 }
357
358 return false;
359 }
360
361 private static Log _log = LogFactoryUtil.getLog(MessageListenerImpl.class);
362
363 }