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;
}
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();
}
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);
}
}
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));
}
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());
}
Aggregations