Skip to content

Commit

Permalink
MAILET-115 Move message altering from AbstractRedirect to AlteredMail…
Browse files Browse the repository at this point in the history
…Utils
  • Loading branch information
Antoine Duprat authored and chibenwa committed Jan 11, 2017
1 parent fe3a35e commit 6bffadb
Show file tree
Hide file tree
Showing 12 changed files with 419 additions and 196 deletions.
Expand Up @@ -18,6 +18,8 @@
****************************************************************/ ****************************************************************/
package org.apache.james.transport.mailets.utils; package org.apache.james.transport.mailets.utils;


import java.util.Enumeration;

import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;


Expand Down Expand Up @@ -68,4 +70,17 @@ private String chooseSubject(String newSubject, String originalSubject) {
return Optional.fromNullable(newSubject).or(originalSubject); return Optional.fromNullable(newSubject).or(originalSubject);
} }


/**
* Utility method for obtaining a string representation of a Message's
* headers
*/
public String getMessageHeaders() throws MessagingException {
@SuppressWarnings("unchecked")
Enumeration<String> heads = message.getAllHeaderLines();
StringBuilder headBuffer = new StringBuilder(1024);
while (heads.hasMoreElements()) {
headBuffer.append(heads.nextElement()).append("\r\n");
}
return headBuffer.toString();
}
} }
Expand Up @@ -19,14 +19,14 @@


package org.apache.james.transport.mailets.utils; package org.apache.james.transport.mailets.utils;


import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat; import static org.assertj.guava.api.Assertions.assertThat;


import java.util.Properties; import java.util.Properties;


import javax.mail.Session; import javax.mail.Session;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;


import org.apache.james.transport.mailets.utils.MimeMessageUtils;
import org.apache.mailet.base.test.FakeMail; import org.apache.mailet.base.test.FakeMail;
import org.junit.Test; import org.junit.Test;


Expand Down Expand Up @@ -133,4 +133,23 @@ public void buildNewSubjectShouldReplaceSubjectWithPrefixWhenSubjectIsEmpty() th


assertThat(newSubject).contains(prefix); assertThat(newSubject).contains(prefix);
} }

@Test
public void getMessageHeadersShouldReturnEmptyStringWhenNoHeaders() throws Exception {
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
String messageHeaders = new MimeMessageUtils(message).getMessageHeaders();

assertThat(messageHeaders).isEmpty();
}

@Test
public void getMessageHeadersShouldHeadersWhenSome() throws Exception {
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
message.addHeader("first", "value");
message.addHeader("second", "value2");
String messageHeaders = new MimeMessageUtils(message).getMessageHeaders();

String expectedHeaders = "first: value\r\nsecond: value2\r\n";
assertThat(messageHeaders).isEqualTo(expectedHeaders);
}
} }
Expand Up @@ -136,7 +136,7 @@ protected String[] getAllowedInitParameters() {
} }


@Override @Override
protected String getMessage(Mail originalMail) throws MessagingException { public String getMessage(Mail originalMail) throws MessagingException {
return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail); return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail);
} }


Expand Down
Expand Up @@ -129,7 +129,7 @@ protected String[] getAllowedInitParameters() {
} }


@Override @Override
protected String getMessage(Mail originalMail) throws MessagingException { public String getMessage(Mail originalMail) throws MessagingException {
return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail); return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail);
} }


Expand Down Expand Up @@ -376,7 +376,7 @@ private MimeBodyPart createAttachedOriginal(Mail originalMail, TypeCode attachme
MimeMessage originalMessage = originalMail.getMessage(); MimeMessage originalMessage = originalMail.getMessage();


if (attachmentType.equals(TypeCode.HEADS)) { if (attachmentType.equals(TypeCode.HEADS)) {
part.setContent(getMessageHeaders(originalMessage), "text/plain"); part.setContent(new MimeMessageUtils(originalMessage).getMessageHeaders(), "text/plain");
part.setHeader("Content-Type", "text/rfc822-headers"); part.setHeader("Content-Type", "text/rfc822-headers");
} else { } else {
part.setContent(originalMessage, "message/rfc822"); part.setContent(originalMessage, "message/rfc822");
Expand Down
Expand Up @@ -106,7 +106,7 @@ protected String[] getAllowedInitParameters() {
} }


@Override @Override
protected String getMessage(Mail originalMail) throws MessagingException { public String getMessage(Mail originalMail) throws MessagingException {
return getInitParameters().getMessage(); return getInitParameters().getMessage();
} }


Expand Down
Expand Up @@ -143,7 +143,7 @@ protected String[] getAllowedInitParameters() {
} }


@Override @Override
protected String getMessage(Mail originalMail) throws MessagingException { public String getMessage(Mail originalMail) throws MessagingException {
return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail); return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail);
} }


Expand Down
Expand Up @@ -143,7 +143,7 @@ protected String[] getAllowedInitParameters() {
} }


@Override @Override
protected String getMessage(Mail originalMail) throws MessagingException { public String getMessage(Mail originalMail) throws MessagingException {
return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail); return new NotifyMailetsMessage().generateMessage(getInitParameters().getMessage(), originalMail);
} }


Expand Down
Expand Up @@ -315,7 +315,7 @@ protected String[] getAllowedInitParameters() {
} }


@Override @Override
protected String getMessage(Mail originalMail) throws MessagingException { public String getMessage(Mail originalMail) throws MessagingException {
return getInitParameters().getMessage(); return getInitParameters().getMessage();
} }


Expand Down
Expand Up @@ -308,7 +308,7 @@ protected String[] getAllowedInitParameters() {
} }


@Override @Override
protected String getMessage(Mail originalMail) throws MessagingException { public String getMessage(Mail originalMail) throws MessagingException {
return getInitParameters().getMessage(); return getInitParameters().getMessage();
} }


Expand Down
Expand Up @@ -19,29 +19,22 @@


package org.apache.james.transport.mailets.redirect; package org.apache.james.transport.mailets.redirect;


import java.io.ByteArrayOutputStream;
import java.util.Enumeration;
import java.util.List; import java.util.List;


import javax.inject.Inject; import javax.inject.Inject;
import javax.mail.BodyPart;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;


import org.apache.james.core.MailImpl; import org.apache.james.core.MailImpl;
import org.apache.james.core.MimeMessageUtil;
import org.apache.james.dnsservice.api.DNSService; import org.apache.james.dnsservice.api.DNSService;
import org.apache.james.transport.mailets.Redirect; import org.apache.james.transport.mailets.Redirect;
import org.apache.james.transport.mailets.utils.MimeMessageModifier; import org.apache.james.transport.mailets.utils.MimeMessageModifier;
import org.apache.james.transport.util.SpecialAddressesUtils; import org.apache.james.transport.util.SpecialAddressesUtils;
import org.apache.mailet.Mail; import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress; import org.apache.mailet.MailAddress;
import org.apache.mailet.base.GenericMailet; import org.apache.mailet.base.GenericMailet;
import org.apache.mailet.base.RFC2822Headers;


import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
Expand Down Expand Up @@ -147,7 +140,6 @@


public abstract class AbstractRedirect extends GenericMailet { public abstract class AbstractRedirect extends GenericMailet {


private static final char LINE_BREAK = '\n';
public static final List<String> REVERSE_PATH_ALLOWED_SPECIALS = ImmutableList.of("postmaster", "sender", "null", "unaltered"); public static final List<String> REVERSE_PATH_ALLOWED_SPECIALS = ImmutableList.of("postmaster", "sender", "null", "unaltered");
public static final List<String> SENDER_ALLOWED_SPECIALS = ImmutableList.of("postmaster", "sender", "unaltered"); public static final List<String> SENDER_ALLOWED_SPECIALS = ImmutableList.of("postmaster", "sender", "unaltered");


Expand All @@ -168,7 +160,7 @@ public void setDNSService(DNSService dns) {
* *
* @return {@link #getMessage()} * @return {@link #getMessage()}
*/ */
protected abstract String getMessage(Mail originalMail) throws MessagingException; public abstract String getMessage(Mail originalMail) throws MessagingException;


/** /**
* Gets the <code>recipients</code> property. Returns the collection of * Gets the <code>recipients</code> property. Returns the collection of
Expand Down Expand Up @@ -388,7 +380,11 @@ public void service(Mail originalMail) throws MessagingException {
newMail.setMessage(new MimeMessage(Session.getDefaultInstance(System.getProperties(), null))); newMail.setMessage(new MimeMessage(Session.getDefaultInstance(System.getProperties(), null)));


// handle the new message if altered // handle the new message if altered
buildAlteredMessage(newMail, originalMail); AlteredMailUtils.builder()
.mailet(this)
.originalMail(originalMail)
.build()
.buildAlteredMessage(newMail);


} else { } else {
// if we need the original, create a copy of this message to // if we need the original, create a copy of this message to
Expand Down Expand Up @@ -447,183 +443,6 @@ protected void updateHeaders() throws MessagingException {


protected abstract MimeMessageModifier getMimeMessageModifier(Mail newMail, Mail originalMail) throws MessagingException; protected abstract MimeMessageModifier getMimeMessageModifier(Mail newMail, Mail originalMail) throws MessagingException;


/**
* Utility method for obtaining a string representation of a Message's
* headers
*/
protected String getMessageHeaders(MimeMessage message) throws MessagingException {
@SuppressWarnings("unchecked")
Enumeration<String> heads = message.getAllHeaderLines();
StringBuilder headBuffer = new StringBuilder(1024);
while (heads.hasMoreElements()) {
headBuffer.append(heads.nextElement().toString()).append("\r\n");
}
return headBuffer.toString();
}

/**
* Utility method for obtaining a string representation of a Message's body
*/
private String getMessageBody(MimeMessage message) throws Exception {
ByteArrayOutputStream bodyOs = new ByteArrayOutputStream();
MimeMessageUtil.writeMessageBodyTo(message, bodyOs);
return bodyOs.toString();
}

/**
* Builds the message of the newMail in case it has to be altered.
*
* @param originalMail the original Mail object
* @param newMail the Mail object to build
*/
protected void buildAlteredMessage(Mail newMail, Mail originalMail) throws MessagingException {

MimeMessage originalMessage = originalMail.getMessage();
MimeMessage newMessage = newMail.getMessage();

// Copy the relevant headers
copyRelevantHeaders(originalMessage, newMessage);

String head = getMessageHeaders(originalMessage);
try {
// Create the message body
MimeMultipart multipart = new MimeMultipart("mixed");

// Create the message
MimeMultipart mpContent = new MimeMultipart("alternative");
mpContent.addBodyPart(getBodyPart(originalMail, originalMessage, head));

MimeBodyPart contentPartRoot = new MimeBodyPart();
contentPartRoot.setContent(mpContent);

multipart.addBodyPart(contentPartRoot);

if (getInitParameters().isDebug()) {
log("attachmentType:" + getInitParameters().getAttachmentType());
}
if (!getInitParameters().getAttachmentType().equals(TypeCode.NONE)) {
multipart.addBodyPart(getAttachmentPart(originalMail, originalMessage, head));
}

if (getInitParameters().isAttachError() && originalMail.getErrorMessage() != null) {
multipart.addBodyPart(getErrorPart(originalMail));
}
newMail.getMessage().setContent(multipart);
newMail.getMessage().setHeader(RFC2822Headers.CONTENT_TYPE, multipart.getContentType());

} catch (Exception ioe) {
throw new MessagingException("Unable to create multipart body", ioe);
}
}

private BodyPart getBodyPart(Mail originalMail, MimeMessage originalMessage, String head) throws MessagingException, Exception {
MimeBodyPart part = new MimeBodyPart();
part.setText(getText(originalMail, originalMessage, head));
part.setDisposition("inline");
return part;
}

private MimeBodyPart getAttachmentPart(Mail originalMail, MimeMessage originalMessage, String head) throws MessagingException, Exception {
MimeBodyPart attachmentPart = new MimeBodyPart();
switch (getInitParameters().getAttachmentType()) {
case HEADS:
attachmentPart.setText(head);
break;
case BODY:
try {
attachmentPart.setText(getMessageBody(originalMessage));
} catch (Exception e) {
attachmentPart.setText("body unavailable");
}
break;
case ALL:
attachmentPart.setText(head + "\r\nMessage:\r\n" + getMessageBody(originalMessage));
break;
case MESSAGE:
attachmentPart.setContent(originalMessage, "message/rfc822");
break;
case NONE:
break;
case UNALTERED:
break;
}
if ((originalMessage.getSubject() != null) && (originalMessage.getSubject().trim().length() > 0)) {
attachmentPart.setFileName(originalMessage.getSubject().trim());
} else {
attachmentPart.setFileName("No Subject");
}
attachmentPart.setDisposition("Attachment");
return attachmentPart;
}

private MimeBodyPart getErrorPart(Mail originalMail) throws MessagingException {
MimeBodyPart errorPart = new MimeBodyPart();
errorPart.setContent(originalMail.getErrorMessage(), "text/plain");
errorPart.setHeader(RFC2822Headers.CONTENT_TYPE, "text/plain");
errorPart.setFileName("Reasons");
errorPart.setDisposition(javax.mail.Part.ATTACHMENT);
return errorPart;
}

private String getText(Mail originalMail, MimeMessage originalMessage, String head) throws MessagingException {
StringBuilder builder = new StringBuilder();

String messageText = getMessage(originalMail);
if (messageText != null) {
builder.append(messageText)
.append(LINE_BREAK);
}

if (getInitParameters().isDebug()) {
log("inline:" + getInitParameters().getInLineType());
}
boolean all = false;
switch (getInitParameters().getInLineType()) {
case ALL:
all = true;
case HEADS:
builder.append("Message Headers:")
.append(LINE_BREAK)
.append(head)
.append(LINE_BREAK);
if (!all) {
break;
}
case BODY:
appendBody(builder, originalMessage);
break;
case NONE:
break;
case MESSAGE:
break;
case UNALTERED:
break;
}
return builder.toString();
}

private void appendBody(StringBuilder builder, MimeMessage originalMessage) {
builder.append("Message:")
.append(LINE_BREAK);
try {
builder.append(getMessageBody(originalMessage))
.append(LINE_BREAK);
} catch (Exception e) {
builder.append("body unavailable")
.append(LINE_BREAK);
}
}

private void copyRelevantHeaders(MimeMessage originalMessage, MimeMessage newMessage) throws MessagingException {
@SuppressWarnings("unchecked")
Enumeration<String> headerEnum = originalMessage.getMatchingHeaderLines(
new String[] { RFC2822Headers.DATE, RFC2822Headers.FROM, RFC2822Headers.REPLY_TO, RFC2822Headers.TO,
RFC2822Headers.SUBJECT, RFC2822Headers.RETURN_PATH });
while (headerEnum.hasMoreElements()) {
newMessage.addHeaderLine(headerEnum.nextElement());
}
}

/** /**
* <p> * <p>
* Checks if a sender domain of <i>mail</i> is valid. * Checks if a sender domain of <i>mail</i> is valid.
Expand Down

0 comments on commit 6bffadb

Please sign in to comment.