/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.message.boards.internal.pop;
import com.liferay.message.boards.kernel.model.MBCategory;
import com.liferay.message.boards.kernel.model.MBCategoryConstants;
import com.liferay.message.boards.kernel.model.MBMessage;
import com.liferay.message.boards.kernel.model.MBMessageConstants;
import com.liferay.message.boards.kernel.service.MBCategoryLocalService;
import com.liferay.message.boards.kernel.service.MBMessageLocalService;
import com.liferay.message.boards.kernel.service.MBMessageService;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.pop.MessageListener;
import com.liferay.portal.kernel.pop.MessageListenerException;
import com.liferay.portal.kernel.portlet.PortletProvider;
import com.liferay.portal.kernel.portlet.PortletProviderUtil;
import com.liferay.portal.kernel.security.auth.PrincipalException;
import com.liferay.portal.kernel.service.CompanyLocalService;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.UserLocalService;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.Http;
import com.liferay.portal.kernel.util.ObjectValuePair;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PrefsPropsUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.StreamUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.security.permission.PermissionCheckerUtil;
import com.liferay.portal.util.PropsValues;
import com.liferay.portlet.messageboards.util.MBMailMessage;
import com.liferay.portlet.messageboards.util.MBUtil;
import java.io.InputStream;
import java.util.List;
import javax.mail.Message;
import javax.mail.MessagingException;
import org.apache.commons.lang.time.StopWatch;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Brian Wing Shun Chan
* @author Jorge Ferrer
* @author Michael C. Han
*/
@Component(immediate = true, service = MessageListener.class)
public class MessageListenerImpl implements MessageListener {
@Override
public boolean accept(String from, String recipient, Message message) {
try {
if (isAutoReply(message)) {
return false;
}
String messageIdString = getMessageIdString(recipient, message);
if ((messageIdString == null) ||
!messageIdString.startsWith(
MBUtil.MESSAGE_POP_PORTLET_PREFIX,
MBUtil.getMessageIdStringOffset())) {
return false;
}
Company company = getCompany(messageIdString);
long categoryId = MBUtil.getCategoryId(messageIdString);
MBCategory category = _mbCategoryLocalService.getCategory(
categoryId);
if ((category.getCompanyId() != company.getCompanyId()) &&
!category.isRoot()) {
return false;
}
if (_log.isDebugEnabled()) {
_log.debug("Check to see if user " + from + " exists");
}
String pop3User = PrefsPropsUtil.getString(
PropsKeys.MAIL_SESSION_MAIL_POP3_USER,
PropsValues.MAIL_SESSION_MAIL_POP3_USER);
if (StringUtil.equalsIgnoreCase(from, pop3User)) {
return false;
}
_userLocalService.getUserByEmailAddress(
company.getCompanyId(), from);
return true;
}
catch (Exception e) {
_log.error("Unable to process message: " + message, e);
return false;
}
}
@Override
public void deliver(String from, String recipient, Message message)
throws MessageListenerException {
List<ObjectValuePair<String, InputStream>> inputStreamOVPs = null;
try {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
if (_log.isDebugEnabled()) {
_log.debug("Deliver message from " + from + " to " + recipient);
}
String messageIdString = getMessageIdString(recipient, message);
Company company = getCompany(messageIdString);
if (_log.isDebugEnabled()) {
_log.debug("Message id " + messageIdString);
}
long parentMessageId = MBUtil.getMessageId(messageIdString);
if (_log.isDebugEnabled()) {
_log.debug("Parent message id " + parentMessageId);
}
MBMessage parentMessage = null;
if (parentMessageId > 0) {
parentMessage = _mbMessageLocalService.fetchMBMessage(
parentMessageId);
}
if (_log.isDebugEnabled()) {
_log.debug("Parent message " + parentMessage);
}
long groupId = 0;
long categoryId = MBUtil.getCategoryId(messageIdString);
MBCategory category = _mbCategoryLocalService.fetchMBCategory(
categoryId);
if (category == null) {
categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
if (parentMessage != null) {
groupId = parentMessage.getGroupId();
}
}
else {
groupId = category.getGroupId();
}
if (_log.isDebugEnabled()) {
_log.debug("Group id " + groupId);
_log.debug("Category id " + categoryId);
}
User user = _userLocalService.getUserByEmailAddress(
company.getCompanyId(), from);
String subject = null;
if (parentMessage != null) {
subject = MBUtil.getSubjectForEmail(parentMessage);
}
MBMailMessage mbMailMessage = new MBMailMessage();
MBUtil.collectPartContent(message, mbMailMessage);
inputStreamOVPs = mbMailMessage.getInputStreamOVPs();
PermissionCheckerUtil.setThreadValues(user);
ServiceContext serviceContext = new ServiceContext();
serviceContext.setAttribute("propagatePermissions", Boolean.TRUE);
String portletId = PortletProviderUtil.getPortletId(
MBMessage.class.getName(), PortletProvider.Action.VIEW);
serviceContext.setLayoutFullURL(
_portal.getLayoutFullURL(
groupId, portletId,
StringUtil.equalsIgnoreCase(
Http.HTTPS, PropsValues.WEB_SERVER_PROTOCOL)));
serviceContext.setScopeGroupId(groupId);
if (parentMessage == null) {
_mbMessageService.addMessage(
groupId, categoryId, subject, mbMailMessage.getBody(),
MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false,
0.0, true, serviceContext);
}
else {
_mbMessageService.addMessage(
parentMessage.getMessageId(), subject,
mbMailMessage.getBody(), MBMessageConstants.DEFAULT_FORMAT,
inputStreamOVPs, false, 0.0, true, serviceContext);
}
if (_log.isDebugEnabled()) {
_log.debug(
"Delivering message takes " + stopWatch.getTime() + " ms");
}
}
catch (PrincipalException pe) {
if (_log.isDebugEnabled()) {
_log.debug("Prevented unauthorized post from " + from);
}
throw new MessageListenerException(pe);
}
catch (Exception e) {
_log.error(e, e);
throw new MessageListenerException(e);
}
finally {
if (inputStreamOVPs != null) {
for (ObjectValuePair<String, InputStream> inputStreamOVP :
inputStreamOVPs) {
InputStream inputStream = inputStreamOVP.getValue();
StreamUtil.cleanUp(inputStream);
}
}
PermissionCheckerUtil.setThreadValues(null);
}
}
@Override
public String getId() {
return MessageListenerImpl.class.getName();
}
protected Company getCompany(String messageIdString) throws Exception {
int pos =
messageIdString.indexOf(CharPool.AT) +
PropsValues.POP_SERVER_SUBDOMAIN.length() + 1;
if (PropsValues.POP_SERVER_SUBDOMAIN.length() > 0) {
pos++;
}
int endPos = messageIdString.indexOf(CharPool.GREATER_THAN, pos);
if (endPos == -1) {
endPos = messageIdString.length();
}
String mx = messageIdString.substring(pos, endPos);
return _companyLocalService.getCompanyByMx(mx);
}
protected String getMessageIdString(String recipient, Message message)
throws Exception {
if (PropsValues.POP_SERVER_SUBDOMAIN.length() > 0) {
return recipient;
}
else {
return MBUtil.getParentMessageIdString(message);
}
}
protected boolean isAutoReply(Message message) throws MessagingException {
String[] autoReply = message.getHeader("X-Autoreply");
if (ArrayUtil.isNotEmpty(autoReply)) {
return true;
}
String[] autoReplyFrom = message.getHeader("X-Autoreply-From");
if (ArrayUtil.isNotEmpty(autoReplyFrom)) {
return true;
}
String[] mailAutoReply = message.getHeader("X-Mail-Autoreply");
if (ArrayUtil.isNotEmpty(mailAutoReply)) {
return true;
}
return false;
}
@Reference(unbind = "-")
protected void setCompanyLocalService(
CompanyLocalService companyLocalService) {
_companyLocalService = companyLocalService;
}
@Reference(unbind = "-")
protected void setMBCategoryLocalService(
MBCategoryLocalService mbCategoryLocalService) {
_mbCategoryLocalService = mbCategoryLocalService;
}
@Reference(unbind = "-")
protected void setMBMessageLocalService(
MBMessageLocalService mbMessageLocalService) {
_mbMessageLocalService = mbMessageLocalService;
}
@Reference(unbind = "-")
protected void setMBMessageService(MBMessageService mbMessageService) {
_mbMessageService = mbMessageService;
}
@Reference(unbind = "-")
protected void setUserLocalService(UserLocalService userLocalService) {
_userLocalService = userLocalService;
}
private static final Log _log = LogFactoryUtil.getLog(
MessageListenerImpl.class);
private CompanyLocalService _companyLocalService;
private MBCategoryLocalService _mbCategoryLocalService;
private MBMessageLocalService _mbMessageLocalService;
private MBMessageService _mbMessageService;
@Reference
private Portal _portal;
private UserLocalService _userLocalService;
}