use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.
the class RuleManager method applyRulesToIncomingMessage.
/**
* Adds a message to a mailbox. If filter rules exist, processes
* the filter rules. Otherwise, files to <tt>Inbox</tt> or <tt>Spam</tt>.
*
* @param allowFilterToMountpoint if <tt>false</tt>, rules
* @return the list of message id's that were added, or an empty list.
*/
public static List<ItemId> applyRulesToIncomingMessage(OperationContext octxt, Mailbox mailbox, ParsedMessage pm, int size, String recipient, LmtpEnvelope env, DeliveryContext sharedDeliveryCtxt, int incomingFolderId, boolean noICal, boolean allowFilterToMountpoint) throws ServiceException {
List<ItemId> addedMessageIds = null;
IncomingMessageHandler handler = new IncomingMessageHandler(octxt, sharedDeliveryCtxt, mailbox, recipient, pm, size, incomingFolderId, noICal);
ZimbraMailAdapter mailAdapter = new ZimbraMailAdapter(mailbox, handler);
mailAdapter.setEnvelope(env);
mailAdapter.setAllowFilterToMountpoint(allowFilterToMountpoint);
String[] filters = { ADMIN_FILTER_RULES_BEFORE_CACHE_KEY, FILTER_RULES_CACHE_KEY, ADMIN_FILTER_RULES_AFTER_CACHE_KEY };
try {
boolean applyRules = true;
Account account = mailbox.getAccount();
for (String filter : filters) {
// Determine whether to apply rules
Node node = getRulesNode(account, filter);
if (null == node) {
applyRules = false;
}
if (SpamHandler.isSpam(handler.getMimeMessage()) && !account.getBooleanAttr(Provisioning.A_zimbraSpamApplyUserFilters, false)) {
// Don't apply user filters to spam by default
applyRules = false;
break;
}
if (applyRules) {
if (filter.equals(FILTER_RULES_CACHE_KEY)) {
mailAdapter.setUserScriptExecuting(true);
}
boolean proceed = evaluateScript(mailAdapter, node);
if (!proceed) {
continue;
}
if (mailAdapter.isStop()) {
break;
}
mailAdapter.resetValues();
mailAdapter.resetCapabilities();
}
}
if (applyRules) {
mailAdapter.executeAllActions();
addedMessageIds = mailAdapter.getAddedMessageIds();
}
} catch (ErejectException ex) {
throw DeliveryServiceException.DELIVERY_REJECTED(ex.getMessage(), ex);
} catch (Exception e) {
ZimbraLog.filter.warn("An error occurred while processing filter rules. Filing message to %s.", handler.getDefaultFolderPath(), e);
} catch (TokenMgrError e) {
// Workaround for bug 19576. Certain parse errors can cause JavaCC to throw an Error
// instead of an Exception. Woo.
ZimbraLog.filter.warn("An error occurred while processing filter rules. Filing message to %s.", handler.getDefaultFolderPath(), e);
}
if (addedMessageIds == null) {
// Filter rules were not processed. File to the default folder.
Message msg = mailAdapter.keep(KeepType.IMPLICIT_KEEP);
addedMessageIds = new ArrayList<ItemId>(1);
addedMessageIds.add(new ItemId(msg));
}
return addedMessageIds;
}
use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.
the class ErejectTest method testThatSenderRcdUnDeliveredEmail.
/*
* applyRulesToIncomingMessage() should throw an exception to cancel the message delivery.
* No message is delivered.
*
* The following error will be logged:
* ERROR - Evaluation failed. Reason: 'ereject' action refuses delivery of a message. Sieve rule evaluation is cancelled
*/
@Test
public void testThatSenderRcdUnDeliveredEmail() {
Account acct1 = null;
Mailbox mbox1 = null;
Account acct2 = null;
Mailbox mbox2 = null;
try {
acct1 = Provisioning.getInstance().get(Key.AccountBy.name, "test@zimbra.com");
mbox1 = MailboxManager.getInstance().getMailboxByAccount(acct1);
RuleManager.clearCachedRules(acct1);
acct2 = Provisioning.getInstance().get(Key.AccountBy.name, "test2@zimbra.com");
mbox2 = MailboxManager.getInstance().getMailboxByAccount(acct2);
LmtpEnvelope env = new LmtpEnvelope();
LmtpAddress sender = new LmtpAddress("<test2@zimbra.com>", new String[] { "BODY", "SIZE" }, null);
LmtpAddress recipient = new LmtpAddress("<test@zimbra.com>", null, null);
env.setSender(sender);
env.addLocalRecipient(recipient);
acct1.setMailSieveScript(filterScript);
RuleManager.applyRulesToIncomingMessage(new OperationContext(mbox1), mbox1, new ParsedMessage(sampleBaseMsg.getBytes(), false), 0, acct1.getName(), env, new DeliveryContext(), Mailbox.ID_FOLDER_INBOX, true);
} catch (DeliveryServiceException e) {
if (e.getCause() instanceof ErejectException) {
try {
List<Integer> items = mbox1.getItemIds(null, Mailbox.ID_FOLDER_INBOX).getIds(MailItem.Type.MESSAGE);
Assert.assertEquals(null, items);
} catch (Exception ex) {
ex.printStackTrace();
fail("No exception should be thrown: " + ex.getMessage());
}
} else {
fail("No exception other than DeliveryServiceException/ErejectException should be thrown: " + e.getMessage());
}
} catch (Exception e) {
fail("No exception should be thrown: " + e.getMessage());
}
}
use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.
the class ZimbraMailAdapter method executeActions.
@Override
public void executeActions() throws SieveException {
try {
handler.beforeFiltering();
String messageId = Mime.getMessageID(handler.getMimeMessage());
// the script contains a single discard action, JSieve returns an empty list.
if (getActions().size() == 0) {
ZimbraLog.filter.info("Discarding message with Message-ID %s from %s", messageId, Mime.getSender(handler.getMimeMessage()));
handler.discard();
return;
}
List<Action> deliveryActions = getDeliveryActions();
if (deliveryActions.isEmpty()) {
// i.e. no keep/fileinto/redirect actions
if (getReplyNotifyRejectActions().isEmpty()) {
// if only flag/tag actions are present, we keep the message even if discard
// action is present
keep(KeepType.EXPLICIT_KEEP);
} else if (!discardActionPresent) {
// else if reply/notify/reject/ereject actions are present and there's no discard, do sort
// of implicit keep
keep(KeepType.EXPLICIT_KEEP);
}
} else {
ListIterator<Action> li = deliveryActions.listIterator(deliveryActions.size());
while (li.hasPrevious()) {
Action lastDeliveryAction = li.previous();
if (lastDeliveryAction instanceof ActionFileInto) {
ActionFileInto lastFileIntoAction = (ActionFileInto) lastDeliveryAction;
if (lastFileIntoAction.isCopy() && !discardActionPresent) {
keep(KeepType.EXPLICIT_KEEP);
}
break;
} else if (lastDeliveryAction instanceof ActionRedirect) {
ActionRedirect lastRedirectAction = (ActionRedirect) lastDeliveryAction;
if (lastRedirectAction.isCopy() && !discardActionPresent) {
keep(KeepType.EXPLICIT_KEEP);
}
break;
}
}
}
for (Action action : actions) {
if (action instanceof ActionKeep) {
if (context == null) {
ZimbraLog.filter.warn("SieveContext has unexpectedly not been set");
keep(KeepType.IMPLICIT_KEEP);
} else if (context.getCommandStateManager().isImplicitKeep()) {
// implicit keep: this means that none of the user's rules have been matched
// we need to check system spam filter to see if the mail is spam
keep(KeepType.IMPLICIT_KEEP);
} else {
keep(KeepType.EXPLICIT_KEEP);
}
} else if (action instanceof ActionFileInto) {
ActionFileInto fileinto = (ActionFileInto) action;
String folderPath = fileinto.getDestination();
folderPath = FilterUtil.replaceVariables(this, folderPath);
try {
if (!allowFilterToMountpoint && isMountpoint(mailbox, folderPath)) {
ZimbraLog.filter.info("Filing to mountpoint \"%s\" is not allowed. Filing to the default folder instead.", folderPath);
keep(KeepType.EXPLICIT_KEEP);
} else {
fileInto(folderPath);
}
} catch (ServiceException e) {
ZimbraLog.filter.info("Unable to file message to %s. Filing to %s instead.", folderPath, handler.getDefaultFolderPath(), e);
keep(KeepType.EXPLICIT_KEEP);
}
} else if (action instanceof ActionRedirect) {
// redirect mail to another address
ActionRedirect redirect = (ActionRedirect) action;
String addr = redirect.getAddress();
addr = FilterUtil.replaceVariables(this, addr);
ZimbraLog.filter.info("Redirecting message to %s.", addr);
try {
handler.redirect(addr);
} catch (Exception e) {
ZimbraLog.filter.warn("Unable to redirect to %s. Filing message to %s.", addr, handler.getDefaultFolderPath(), e);
keep(KeepType.EXPLICIT_KEEP);
}
} else if (action instanceof ActionReply) {
// reply to mail
ActionReply reply = (ActionReply) action;
ZimbraLog.filter.debug("Replying to message");
try {
String replyStrg = FilterUtil.replaceVariables(this, reply.getBodyTemplate());
handler.reply(replyStrg);
} catch (Exception e) {
ZimbraLog.filter.warn("Unable to reply.", e);
keep(KeepType.EXPLICIT_KEEP);
}
} else if (action instanceof ActionNotify) {
ActionNotify notify = (ActionNotify) action;
ZimbraLog.filter.debug("Sending notification message to %s.", notify.getEmailAddr());
try {
handler.notify(FilterUtil.replaceVariables(this, notify.getEmailAddr()), FilterUtil.replaceVariables(this, notify.getSubjectTemplate()), FilterUtil.replaceVariables(this, notify.getBodyTemplate()), notify.getMaxBodyBytes(), notify.getOrigHeaders());
} catch (Exception e) {
ZimbraLog.filter.warn("Unable to notify.", e);
keep(KeepType.EXPLICIT_KEEP);
}
} else if (action instanceof ActionReject) {
ActionReject reject = (ActionReject) action;
ZimbraLog.filter.debug("Refusing delivery of a message: %s", reject.getMessage());
try {
String msg = FilterUtil.replaceVariables(this, reject.getMessage());
handler.reject(msg, envelope);
handler.discard();
} catch (Exception e) {
ZimbraLog.filter.info("Unable to reject.", e);
keep(KeepType.EXPLICIT_KEEP);
}
} else if (action instanceof ActionEreject) {
ActionEreject ereject = (ActionEreject) action;
ZimbraLog.filter.debug("Refusing delivery of a message at the protocol level");
try {
handler.ereject(envelope);
} catch (ErejectException e) {
// 'ereject' action executed
throw e;
} catch (Exception e) {
ZimbraLog.filter.warn("Unable to ereject.", e);
}
} else if (action instanceof ActionNotifyMailto) {
ActionNotifyMailto notifyMailto = (ActionNotifyMailto) action;
ZimbraLog.filter.debug("Sending RFC 5435/5436 compliant notification message to %s.", notifyMailto.getMailto());
try {
handler.notifyMailto(envelope, notifyMailto.getFrom(), notifyMailto.getImportance(), notifyMailto.getOptions(), notifyMailto.getMessage(), notifyMailto.getMailto(), notifyMailto.getMailtoParams());
} catch (Exception e) {
ZimbraLog.filter.warn("Unable to notify (mailto).", e);
keep(KeepType.EXPLICIT_KEEP);
}
}
}
handler.afterFiltering();
} catch (ServiceException e) {
throw new ZimbraSieveException(e);
}
}
use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.
the class ErejectTest method test.
/*
* applyRulesToIncomingMessage() should throw an exception to cancel the message delivery.
* No message is delivered.
*
* The following error will be logged:
* ERROR - Evaluation failed. Reason: 'ereject' action refuses delivery of a message. Sieve rule evaluation is cancelled
*/
@Test
public void test() {
Account acct1 = null;
Mailbox mbox1 = null;
boolean isPassed = false;
try {
acct1 = Provisioning.getInstance().get(Key.AccountBy.name, "test@zimbra.com");
mbox1 = MailboxManager.getInstance().getMailboxByAccount(acct1);
RuleManager.clearCachedRules(acct1);
LmtpEnvelope env = new LmtpEnvelope();
LmtpAddress sender = new LmtpAddress("<test2@zimbra.com>", new String[] { "BODY", "SIZE" }, null);
LmtpAddress recipient = new LmtpAddress("<test@zimbra.com>", null, null);
env.setSender(sender);
env.addLocalRecipient(recipient);
acct1.setMailSieveScript(filterScript);
RuleManager.applyRulesToIncomingMessage(new OperationContext(mbox1), mbox1, new ParsedMessage(sampleBaseMsg.getBytes(), false), 0, acct1.getName(), env, new DeliveryContext(), Mailbox.ID_FOLDER_INBOX, true);
} catch (DeliveryServiceException e) {
if (e.getCause() instanceof ErejectException) {
try {
List<Integer> items = mbox1.getItemIds(null, Mailbox.ID_FOLDER_INBOX).getIds(MailItem.Type.MESSAGE);
Assert.assertEquals(null, items);
isPassed = true;
} catch (Exception ex) {
fail("No exception should be thrown: " + ex.getMessage());
}
} else {
fail("No exception other than DeliveryServiceException/ErejectException should be thrown: " + e.getMessage());
}
} catch (Exception e) {
fail("No exception should be thrown: " + e.getMessage());
}
if (!isPassed) {
fail("DeliveryServiceException/ErejectException should have been thrown, but no exception is thrown");
}
}
use of com.zimbra.cs.filter.jsieve.ErejectException in project zm-mailbox by Zimbra.
the class ZimbraMailAdapter method executeActionErejectInternal.
private void executeActionErejectInternal(Action action) throws ErejectException {
ActionEreject ereject = (ActionEreject) action;
ZimbraLog.filter.debug("Refusing delivery of a message at the protocol level");
try {
handler.ereject(envelope);
} catch (ErejectException e) {
// 'ereject' action executed
throw e;
} catch (Exception e) {
ZimbraLog.filter.warn("Unable to ereject.", e);
}
}
Aggregations