Search in sources :

Example 16 with FilterAction

use of com.zimbra.soap.mail.type.FilterAction in project zm-mailbox by Zimbra.

the class SoapToSieve method handleAction.

private String handleAction(FilterAction action, boolean isAdminScript) throws ServiceException {
    if (action instanceof FilterAction.KeepAction) {
        return "keep";
    } else if (action instanceof FilterAction.DiscardAction) {
        return "discard";
    } else if (action instanceof FilterAction.FileIntoAction) {
        FilterAction.FileIntoAction fileinto = (FilterAction.FileIntoAction) action;
        String folderPath = fileinto.getFolder();
        boolean copy = fileinto.isCopy();
        if (StringUtil.isNullOrEmpty(folderPath)) {
            throw ServiceException.INVALID_REQUEST("Missing folderPath", null);
        }
        if (copy) {
            return String.format("fileinto :copy \"%s\"", FilterUtil.escape(folderPath));
        } else {
            return String.format("fileinto \"%s\"", FilterUtil.escape(folderPath));
        }
    } else if (action instanceof FilterAction.TagAction) {
        FilterAction.TagAction tag = (FilterAction.TagAction) action;
        String tagName = tag.getTag();
        if (StringUtil.isNullOrEmpty(tagName)) {
            throw ServiceException.INVALID_REQUEST("Missing tag", null);
        }
        return String.format("tag \"%s\"", FilterUtil.escape(tagName));
    } else if (action instanceof FilterAction.FlagAction) {
        FilterAction.FlagAction flag = (FilterAction.FlagAction) action;
        String flagName = flag.getFlag();
        if (StringUtil.isNullOrEmpty(flagName)) {
            throw ServiceException.INVALID_REQUEST("Missing flag", null);
        }
        return String.format("flag \"%s\"", Sieve.Flag.valueOf(flagName));
    } else if (action instanceof FilterAction.RedirectAction) {
        FilterAction.RedirectAction redirect = (FilterAction.RedirectAction) action;
        String address = redirect.getAddress();
        boolean copy = redirect.isCopy();
        if (StringUtil.isNullOrEmpty(address)) {
            throw ServiceException.INVALID_REQUEST("Missing address", null);
        }
        if (copy) {
            return String.format("redirect :copy \"%s\"", FilterUtil.escape(address));
        } else {
            return String.format("redirect \"%s\"", FilterUtil.escape(address));
        }
    } else if (action instanceof FilterAction.ReplyAction) {
        FilterAction.ReplyAction reply = (FilterAction.ReplyAction) action;
        String content = reply.getContent();
        if (StringUtil.isNullOrEmpty(content)) {
            throw ServiceException.INVALID_REQUEST("Missing reply content", null);
        }
        return new StringBuilder("reply text:\r\n").append(getDotStuffed(content)).append("\r\n.\r\n").toString();
    } else if (action instanceof FilterAction.NotifyAction) {
        FilterAction.NotifyAction notify = (FilterAction.NotifyAction) action;
        String emailAddr = notify.getAddress();
        if (StringUtil.isNullOrEmpty(emailAddr)) {
            throw ServiceException.INVALID_REQUEST("Missing address", null);
        }
        String subjectTemplate = Strings.nullToEmpty(notify.getSubject());
        String bodyTemplate = Strings.nullToEmpty(notify.getContent());
        int maxBodyBytes = MoreObjects.firstNonNull(notify.getMaxBodySize(), -1);
        String origHeaders = Strings.nullToEmpty(notify.getOrigHeaders());
        if (!subjectTemplate.isEmpty() && containsSubjectHeader(origHeaders)) {
            throw ServiceException.INVALID_REQUEST("subject conflict", null);
        }
        return new StringBuilder("notify ").append(StringUtil.enclose(FilterUtil.escape(emailAddr), '"')).append(' ').append(StringUtil.enclose(subjectTemplate, '"')).append(' ').append("text:\r\n").append(getDotStuffed(bodyTemplate)).append("\r\n.\r\n").append(maxBodyBytes < 0 ? "" : " " + maxBodyBytes).append(origHeaders.isEmpty() ? "" : " " + getSieveMultiValue(origHeaders)).toString();
    } else if (action instanceof FilterAction.RFCCompliantNotifyAction) {
        FilterAction.RFCCompliantNotifyAction notify = (FilterAction.RFCCompliantNotifyAction) action;
        String from = notify.getFrom();
        String importance = Strings.nullToEmpty(notify.getImportance());
        String options = Strings.nullToEmpty(notify.getOptions());
        String message = Strings.nullToEmpty(notify.getMessage());
        String method = Strings.nullToEmpty(notify.getMethod());
        if (StringUtil.isNullOrEmpty(method)) {
            throw ServiceException.INVALID_REQUEST("Missing notification mechanism", null);
        }
        StringBuilder filter = new StringBuilder("notify ");
        if (!from.isEmpty()) {
            filter.append(":from ").append(StringUtil.enclose(FilterUtil.escape(from), '"')).append(' ');
        }
        if (!importance.isEmpty()) {
            filter.append(":importance ").append(StringUtil.enclose(importance, '"')).append(' ');
        }
        if (!options.isEmpty()) {
            filter.append(":options ").append(StringUtil.enclose(options, '"')).append(' ');
        }
        if (!message.isEmpty()) {
            filter.append(":message ").append(StringUtil.enclose(message, '"')).append(' ');
        }
        if (method.indexOf("\n") < 0) {
            filter.append(StringUtil.enclose(method, '"'));
        } else {
            filter.append("text:\r\n").append(method).append("\r\n.\r\n");
        }
        return filter.toString();
    } else if (action instanceof FilterAction.StopAction) {
        return "stop";
    } else if (action instanceof FilterAction.RejectAction) {
        FilterAction.RejectAction rejectAction = (FilterAction.RejectAction) action;
        return handleRejectAction(rejectAction);
    } else if (action instanceof FilterAction.ErejectAction) {
        FilterAction.ErejectAction erejectAction = (FilterAction.ErejectAction) action;
        return handleRejectAction(erejectAction);
    } else if (action instanceof FilterAction.LogAction) {
        FilterAction.LogAction logAction = (FilterAction.LogAction) action;
        StringBuilder sb = new StringBuilder();
        sb.append("log");
        FilterAction.LogAction.LogLevel level = logAction.getLevel();
        if (level != null) {
            if (!(FilterAction.LogAction.LogLevel.fatal == level || FilterAction.LogAction.LogLevel.error == level || FilterAction.LogAction.LogLevel.warn == level || FilterAction.LogAction.LogLevel.info == level || FilterAction.LogAction.LogLevel.debug == level || FilterAction.LogAction.LogLevel.trace == level)) {
                String message = "Invalid log action: Invalid log level found: " + level.toString();
                throw ServiceException.PARSE_ERROR(message, null);
            }
            sb.append(" :").append(level.toString());
        }
        sb.append(" \"").append(logAction.getContent()).append("\"");
        return sb.toString();
    } else if (action instanceof FilterAction.AddheaderAction) {
        if (!isAdminScript) {
            throw ServiceException.PARSE_ERROR("Invalid addheader action: addheader action is not allowed in user scripts", null);
        }
        FilterAction.AddheaderAction addheaderAction = (FilterAction.AddheaderAction) action;
        if (StringUtil.isNullOrEmpty(addheaderAction.getHeaderName()) || StringUtil.isNullOrEmpty(addheaderAction.getHeaderValue())) {
            throw ServiceException.PARSE_ERROR("Invalid addheader action: Missing headerName or headerValue", null);
        }
        StringBuilder sb = new StringBuilder();
        sb.append("addheader");
        if (addheaderAction.getLast() != null && addheaderAction.getLast()) {
            sb.append(" :last");
        }
        sb.append(" \"").append(addheaderAction.getHeaderName()).append("\"");
        sb.append(" \"").append(addheaderAction.getHeaderValue()).append("\"");
        return sb.toString();
    } else if (action instanceof FilterAction.ReplaceheaderAction) {
        if (!isAdminScript) {
            throw ServiceException.PARSE_ERROR("Invalid replaceheader action: replaceheader action is not allowed in user scripts", null);
        }
        FilterAction.ReplaceheaderAction replaceheaderAction = (FilterAction.ReplaceheaderAction) action;
        replaceheaderAction.validateReplaceheaderAction();
        StringBuilder sb = new StringBuilder();
        sb.append("replaceheader");
        if (replaceheaderAction.getLast() != null && replaceheaderAction.getLast()) {
            sb.append(" :last");
        }
        if (replaceheaderAction.getOffset() != null) {
            sb.append(" :index ").append(replaceheaderAction.getOffset());
        }
        if (!StringUtil.isNullOrEmpty(replaceheaderAction.getNewName())) {
            sb.append(" :newname ").append("\"").append(replaceheaderAction.getNewName()).append("\"");
        }
        if (!StringUtil.isNullOrEmpty(replaceheaderAction.getNewValue())) {
            sb.append(" :newvalue ").append("\"").append(replaceheaderAction.getNewValue()).append("\"");
        }
        EditheaderTest test = replaceheaderAction.getTest();
        if (test.getCount() != null && test.getCount()) {
            sb.append(" :count");
        } else if (test.getValue() != null && test.getValue()) {
            sb.append(" :value");
        }
        if (!StringUtil.isNullOrEmpty(test.getRelationalComparator())) {
            sb.append(" \"").append(test.getRelationalComparator()).append("\"");
        }
        if (!StringUtil.isNullOrEmpty(test.getComparator())) {
            sb.append(" :comparator ").append("\"").append(test.getComparator()).append("\"");
        }
        if (!StringUtil.isNullOrEmpty(test.getMatchType())) {
            sb.append(" :").append(test.getMatchType());
        }
        if (!StringUtil.isNullOrEmpty(test.getHeaderName())) {
            sb.append(" \"").append(test.getHeaderName()).append("\"");
        }
        List<String> headerValues = test.getHeaderValue();
        if (headerValues != null && !headerValues.isEmpty()) {
            if (headerValues.size() > 1) {
                sb.append(" [");
            }
            boolean first = true;
            for (String value : headerValues) {
                if (first) {
                    first = false;
                } else {
                    sb.append(",");
                }
                sb.append(" \"").append(value).append("\"");
            }
            if (headerValues.size() > 1) {
                sb.append(" ]");
            }
        }
        return sb.toString();
    } else if (action instanceof FilterAction.DeleteheaderAction) {
        if (!isAdminScript) {
            throw ServiceException.PARSE_ERROR("Invalid deleteheader action: deleteheader action is not allowed in user scripts", null);
        }
        FilterAction.DeleteheaderAction deleteheaderAction = (FilterAction.DeleteheaderAction) action;
        deleteheaderAction.validateDeleteheaderAction();
        StringBuilder sb = new StringBuilder();
        sb.append("deleteheader");
        if (deleteheaderAction.getLast() != null && deleteheaderAction.getLast()) {
            sb.append(" :last");
        }
        if (deleteheaderAction.getOffset() != null) {
            sb.append(" :index ").append(deleteheaderAction.getOffset());
        }
        EditheaderTest test = deleteheaderAction.getTest();
        if (test.getCount() != null && test.getCount()) {
            sb.append(" :count");
        } else if (test.getValue() != null && test.getValue()) {
            sb.append(" :value");
        }
        if (!StringUtil.isNullOrEmpty(test.getRelationalComparator())) {
            sb.append(" \"").append(test.getRelationalComparator()).append("\"");
        }
        if (!StringUtil.isNullOrEmpty(test.getComparator())) {
            sb.append(" :comparator ").append("\"").append(test.getComparator()).append("\"");
        }
        if (!StringUtil.isNullOrEmpty(test.getMatchType())) {
            sb.append(" :").append(test.getMatchType());
        }
        if (!StringUtil.isNullOrEmpty(test.getHeaderName())) {
            sb.append(" \"").append(test.getHeaderName()).append("\"");
        }
        List<String> headerValues = test.getHeaderValue();
        if (headerValues != null && !headerValues.isEmpty()) {
            if (headerValues.size() > 1) {
                sb.append(" [");
            }
            boolean first = true;
            for (String value : headerValues) {
                if (first) {
                    first = false;
                } else {
                    sb.append(",");
                }
                sb.append(" \"").append(value).append("\"");
            }
            if (headerValues.size() > 1) {
                sb.append(" ]");
            }
        }
        return sb.toString();
    } else {
        ZimbraLog.soap.debug("Ignoring unexpected action: %s", action);
    }
    return null;
}
Also used : List(java.util.List) EditheaderTest(com.zimbra.soap.mail.type.EditheaderTest) FilterAction(com.zimbra.soap.mail.type.FilterAction)

Example 17 with FilterAction

use of com.zimbra.soap.mail.type.FilterAction in project zm-mailbox by Zimbra.

the class SoapToSieve method handleNest.

// Constructing nested rule block with base indents which is for entire block.
private String handleNest(String baseIndents, NestedRule currentNestedRule, boolean isAdminScript) throws ServiceException {
    StringBuilder nestedIfBlock = new StringBuilder();
    FilterVariables filterVariables = currentNestedRule.getFilterVariables();
    nestedIfBlock.append(handleVariables(filterVariables, baseIndents));
    Sieve.Condition childCondition = Sieve.Condition.fromString(currentNestedRule.getFilterTests().getCondition());
    if (childCondition == null) {
        childCondition = Sieve.Condition.allof;
    }
    // assuming no disabled_if for child tests so far
    nestedIfBlock.append(baseIndents).append("if ");
    nestedIfBlock.append(childCondition).append(" (");
    // Handle tests
    // sort by index
    Map<Integer, String> index2childTest = new TreeMap<Integer, String>();
    for (FilterTest childTest : currentNestedRule.getFilterTests().getTests()) {
        String childResult = handleTest(childTest);
        if (childResult != null) {
            FilterUtil.addToMap(index2childTest, childTest.getIndex(), childResult);
        }
    }
    Joiner.on(",\n  " + baseIndents).appendTo(nestedIfBlock, index2childTest.values());
    nestedIfBlock.append(") {\n");
    // Handle actions
    // sort by index
    Map<Integer, String> index2childAction = new TreeMap<Integer, String>();
    List<FilterAction> childActions = currentNestedRule.getFilterActions();
    String variables = "";
    if (childActions != null) {
        for (FilterAction childAction : childActions) {
            if (childAction instanceof FilterVariables) {
                FilterVariables var = (FilterVariables) childAction;
                variables = handleVariables(var, baseIndents + "    ");
            } else {
                String childResult = handleAction(childAction, isAdminScript);
                if (childResult != null) {
                    FilterUtil.addToMap(index2childAction, childAction.getIndex(), childResult);
                }
            }
        }
        for (String childAction : index2childAction.values()) {
            nestedIfBlock.append(baseIndents);
            nestedIfBlock.append("    ").append(childAction).append(END_OF_LINE);
        }
        if (!variables.isEmpty()) {
            nestedIfBlock.append(variables);
        }
    }
    // Handle nest
    if (currentNestedRule.getChild() != null) {
        nestedIfBlock.append(handleNest(baseIndents + "    ", currentNestedRule.getChild(), isAdminScript));
    }
    if (childActions == null && currentNestedRule.getChild() == null) {
        // If there is no more nested rule, there should be at least one action.
        throw ServiceException.INVALID_REQUEST("Missing action", null);
    }
    nestedIfBlock.append(baseIndents);
    nestedIfBlock.append("}\n");
    return nestedIfBlock.toString();
}
Also used : FilterTest(com.zimbra.soap.mail.type.FilterTest) Sieve(com.zimbra.common.filter.Sieve) TreeMap(java.util.TreeMap) FilterVariables(com.zimbra.soap.mail.type.FilterVariables) FilterAction(com.zimbra.soap.mail.type.FilterAction)

Example 18 with FilterAction

use of com.zimbra.soap.mail.type.FilterAction in project zm-mailbox by Zimbra.

the class ModifyFilterRulesTest method testBug92309_SetIncomingXMLRules_EmptyAddress.

/**
 * Bug 92309: text "null" was set to To/Cc/From field
 *
 * When the To, Cc, or From field in the message filter rule
 * composing dialogue window is left empty, ZWC automatically
 * put a text "null" to the filed.  This test case tests that
 * the text "null" will not be set if the To/Cc/From field
 * is empty.
 */
@Test
public void testBug92309_SetIncomingXMLRules_EmptyAddress() {
    try {
        Account account = Provisioning.getInstance().getAccount(MockProvisioning.DEFAULT_ACCOUNT_ID);
        RuleManager.clearCachedRules(account);
        // Construct a filter rule with 'address' test whose value is empty (null)
        FilterRule rule = new FilterRule("testSetIncomingXMLRules_EmptyAddress", true);
        FilterTest.AddressTest test = new FilterTest.AddressTest();
        test.setHeader("to");
        test.setStringComparison("is");
        test.setPart("all");
        test.setValue(null);
        test.setIndex(0);
        FilterTests tests = new FilterTests("anyof");
        tests.addTest(test);
        FilterAction action = new FilterAction.KeepAction();
        action.setIndex(0);
        rule.setFilterTests(tests);
        rule.addFilterAction(action);
        List<FilterRule> filterRuleList = new ArrayList<FilterRule>();
        filterRuleList.add(rule);
        // When the ModifyFilterRulesRequest is submitted from the Web client,
        // eventually this RuleManager.setIncomingXMLRules is called to convert
        // the request in JSON to the SIEVE rule text.
        RuleManager.setIncomingXMLRules(account, filterRuleList);
        // Verify that the saved zimbraMailSieveScript
        String sieve = account.getMailSieveScript();
        int result = sieve.indexOf("address :all :is :comparator \"i;ascii-casemap\" [\"to\"] \"\"");
        Assert.assertNotSame(-1, result);
    } catch (Exception e) {
        fail("No exception should be thrown" + e);
    }
}
Also used : Account(com.zimbra.cs.account.Account) ArrayList(java.util.ArrayList) FilterRule(com.zimbra.soap.mail.type.FilterRule) ServiceException(com.zimbra.common.service.ServiceException) FilterTest(com.zimbra.soap.mail.type.FilterTest) FilterTests(com.zimbra.soap.mail.type.FilterTests) FilterAction(com.zimbra.soap.mail.type.FilterAction) FilterTest(com.zimbra.soap.mail.type.FilterTest) Test(org.junit.Test)

Example 19 with FilterAction

use of com.zimbra.soap.mail.type.FilterAction in project zm-mailbox by Zimbra.

the class GetFilterRulesAdminTest method testSieveToSoapReplaceheaderActionBasic.

/**
 ************replaceheader**************
 */
// TODO: start writing unit tests
@Test
public void testSieveToSoapReplaceheaderActionBasic() throws ServiceException {
    RuleManager.clearCachedRules(account);
    String script = "require [\"editheader\", \"variables\"];\n" + "# rule1\n" + "replaceheader :newvalue \"[new] ${1}\" \"X-My-Header\" \"xyz\";";
    account.setAdminSieveScriptBefore(script);
    List<FilterRule> filterRules = RuleManager.getAdminRulesAsXML(account, FilterType.INCOMING, AdminFilterType.BEFORE);
    Assert.assertEquals(filterRules.size(), 1);
    FilterRule filterRule = filterRules.get(0);
    Assert.assertEquals("rule1", filterRule.getName());
    Assert.assertTrue(filterRule.isActive());
    Assert.assertEquals(1, filterRule.getFilterActions().size());
    FilterAction filterAction = filterRule.getFilterActions().get(0);
    Assert.assertTrue(filterAction instanceof FilterAction.ReplaceheaderAction);
    FilterAction.ReplaceheaderAction action = (FilterAction.ReplaceheaderAction) filterAction;
    Assert.assertNull(action.getLast());
    Assert.assertNull(action.getOffset());
    Assert.assertNull(action.getNewName());
    Assert.assertEquals("[new] ${1}", action.getNewValue());
    EditheaderTest test = action.getTest();
    Assert.assertEquals("i;ascii-casemap", test.getComparator());
    Assert.assertEquals("is", test.getMatchType());
    Assert.assertNull(test.getRelationalComparator());
    Assert.assertNull(test.getCount());
    Assert.assertNull(test.getValue());
    Assert.assertEquals("X-My-Header", test.getHeaderName());
    List<String> values = test.getHeaderValue();
    Assert.assertEquals(1, values.size());
    Assert.assertEquals("xyz", values.get(0));
}
Also used : FilterRule(com.zimbra.soap.mail.type.FilterRule) EditheaderTest(com.zimbra.soap.mail.type.EditheaderTest) FilterAction(com.zimbra.soap.mail.type.FilterAction) EditheaderTest(com.zimbra.soap.mail.type.EditheaderTest) Test(org.junit.Test)

Example 20 with FilterAction

use of com.zimbra.soap.mail.type.FilterAction in project zm-mailbox by Zimbra.

the class GetFilterRulesAdminTest method testSieveToSoapAddheaderActionWithoutLast.

/**
 ************addheader**************
 */
@Test
public void testSieveToSoapAddheaderActionWithoutLast() throws ServiceException {
    RuleManager.clearCachedRules(account);
    String script = "# rule1\n" + "require [\"editheader\"];\n" + "addheader \"X-My-Header\" \"Test Value\";";
    account.setAdminSieveScriptBefore(script);
    List<FilterRule> filterRules = RuleManager.getAdminRulesAsXML(account, FilterType.INCOMING, AdminFilterType.BEFORE);
    Assert.assertEquals(filterRules.size(), 1);
    FilterRule rule = filterRules.get(0);
    Assert.assertTrue(rule.isActive());
    Assert.assertEquals(rule.getName(), "rule1");
    Assert.assertEquals(rule.getActionCount(), 1);
    FilterAction filterAction = rule.getFilterActions().get(0);
    Assert.assertTrue(filterAction instanceof FilterAction.AddheaderAction);
    FilterAction.AddheaderAction action = (FilterAction.AddheaderAction) filterAction;
    Assert.assertEquals(action.getHeaderName(), "X-My-Header");
    Assert.assertEquals(action.getHeaderValue(), "Test Value");
    Assert.assertNull(action.getLast());
}
Also used : FilterRule(com.zimbra.soap.mail.type.FilterRule) FilterAction(com.zimbra.soap.mail.type.FilterAction) EditheaderTest(com.zimbra.soap.mail.type.EditheaderTest) Test(org.junit.Test)

Aggregations

FilterAction (com.zimbra.soap.mail.type.FilterAction)30 FilterRule (com.zimbra.soap.mail.type.FilterRule)24 Test (org.junit.Test)23 EditheaderTest (com.zimbra.soap.mail.type.EditheaderTest)19 FilterTest (com.zimbra.soap.mail.type.FilterTest)10 FilterTests (com.zimbra.soap.mail.type.FilterTests)8 FilterVariables (com.zimbra.soap.mail.type.FilterVariables)5 Sieve (com.zimbra.common.filter.Sieve)4 TreeMap (java.util.TreeMap)4 ServiceException (com.zimbra.common.service.ServiceException)3 Account (com.zimbra.cs.account.Account)3 ArrayList (java.util.ArrayList)3 Element (com.zimbra.common.soap.Element)2 JSONElement (com.zimbra.common.soap.Element.JSONElement)2 XMLElement (com.zimbra.common.soap.Element.XMLElement)2 GetFilterRulesResponse (com.zimbra.soap.mail.message.GetFilterRulesResponse)2 NestedRule (com.zimbra.soap.mail.type.NestedRule)2 XmlAnyElement (javax.xml.bind.annotation.XmlAnyElement)2 XmlElement (javax.xml.bind.annotation.XmlElement)2 List (java.util.List)1