From 80692be12d4801639e58414c3c00b8c391d58c72 Mon Sep 17 00:00:00 2001 From: M66B Date: Mon, 15 Apr 2024 09:11:36 +0200 Subject: [PATCH] Added rule not header condition --- .../java/eu/faircode/email/EntityRule.java | 184 +++++++++--------- .../java/eu/faircode/email/FragmentRule.java | 4 + app/src/main/res/layout/fragment_rule.xml | 21 +- 3 files changed, 117 insertions(+), 92 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/EntityRule.java b/app/src/main/java/eu/faircode/email/EntityRule.java index ffc0b8b232..dbd4baea74 100644 --- a/app/src/main/java/eu/faircode/email/EntityRule.java +++ b/app/src/main/java/eu/faircode/email/EntityRule.java @@ -349,99 +349,15 @@ public class EntityRule { // Header JSONObject jheader = jcondition.optJSONObject("header"); if (jheader != null) { + boolean not = jheader.optBoolean("not"); String value = jheader.getString("value"); boolean regex = jheader.getBoolean("regex"); if (!regex && value.startsWith("$") && value.endsWith("$")) { - String keyword = value.substring(1, value.length() - 1); - - if ("$tls".equals(keyword)) { - if (!Boolean.TRUE.equals(message.tls)) - return false; - } else if ("$aligned".equals(keyword)) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - boolean native_dkim = prefs.getBoolean("native_dkim", false); - if (!native_dkim) - return false; - if (message.signedby == null) - return false; - if (message.from == null || message.from.length != 1) - return false; - String domain = UriHelper.getEmailDomain(((InternetAddress) message.from[0]).getAddress()); - if (domain == null) - return false; - boolean valid = false; - for (String signer : message.signedby.split(",")) - if (Objects.equals( - UriHelper.getRootDomain(context, signer), - UriHelper.getRootDomain(context, domain))) { - valid = true; - break; - } - if (!valid) - return false; - } else if ("$dkim".equals(keyword)) { - if (!Boolean.TRUE.equals(message.dkim)) - return false; - } else if ("$spf".equals(keyword)) { - if (!Boolean.TRUE.equals(message.spf)) - return false; - } else if ("$dmarc".equals(keyword)) { - if (!Boolean.TRUE.equals(message.dmarc)) - return false; - } else if ("$auth".equals(keyword)) { - if (!Boolean.TRUE.equals(message.auth)) - return false; - } else if ("$mx".equals(keyword)) { - if (!Boolean.TRUE.equals(message.mx)) - return false; - } else if ("$blocklist".equals(keyword)) { - if (!Boolean.FALSE.equals(message.blocklist)) - return false; - } else if ("$replydomain".equals(keyword)) { - if (!Boolean.TRUE.equals(message.reply_domain)) - return false; - } else if ("$nofrom".equals(keyword)) { - if (message.from != null && message.from.length > 0) - return false; - } else if ("$multifrom".equals(keyword)) { - if (message.from == null || message.from.length < 2) - return false; - } else if ("$automatic".equals(keyword)) { - if (!Boolean.TRUE.equals(message.auto_submitted)) - return false; - } else if ("$lowpriority".equals(keyword)) { - if (!EntityMessage.PRIORITIY_LOW.equals(message.priority)) - return false; - } else if ("$highpriority".equals(keyword)) { - if (!EntityMessage.PRIORITIY_HIGH.equals(message.priority)) - return false; - } else if ("$signed".equals(keyword)) { - if (!message.isSigned()) - return false; - } else if ("$encrypted".equals(keyword)) { - if (!message.isEncrypted()) - return false; - } else { - List keywords = new ArrayList<>(); - keywords.addAll(Arrays.asList(message.keywords)); - - if (message.ui_seen) - keywords.add("$seen"); - if (message.ui_answered) - keywords.add("$answered"); - if (message.ui_flagged) - keywords.add("$flagged"); - if (message.ui_deleted) - keywords.add("$deleted"); - if (message.infrastructure != null) - keywords.add('$' + message.infrastructure); - - if (!keywords.contains(keyword)) - return false; - } + if (matchKeywords(context, message, value) != not) + return false; } else { if (headers == null) { if (message.headers == null) @@ -459,7 +375,7 @@ public class EntityRule { break; } } - if (!matches) + if (matches == not) return false; } } @@ -566,6 +482,98 @@ public class EntityRule { return true; } + private static boolean matchKeywords(Context context, EntityMessage message, String value) { + String keyword = value.substring(1, value.length() - 1); + + if ("$tls".equals(keyword)) { + if (!Boolean.TRUE.equals(message.tls)) + return true; + } else if ("$aligned".equals(keyword)) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean native_dkim = prefs.getBoolean("native_dkim", false); + if (!native_dkim) + return true; + if (message.signedby == null) + return true; + if (message.from == null || message.from.length != 1) + return true; + String domain = UriHelper.getEmailDomain(((InternetAddress) message.from[0]).getAddress()); + if (domain == null) + return true; + boolean valid = false; + for (String signer : message.signedby.split(",")) + if (Objects.equals( + UriHelper.getRootDomain(context, signer), + UriHelper.getRootDomain(context, domain))) { + valid = true; + break; + } + if (!valid) + return true; + } else if ("$dkim".equals(keyword)) { + if (!Boolean.TRUE.equals(message.dkim)) + return true; + } else if ("$spf".equals(keyword)) { + if (!Boolean.TRUE.equals(message.spf)) + return true; + } else if ("$dmarc".equals(keyword)) { + if (!Boolean.TRUE.equals(message.dmarc)) + return true; + } else if ("$auth".equals(keyword)) { + if (!Boolean.TRUE.equals(message.auth)) + return true; + } else if ("$mx".equals(keyword)) { + if (!Boolean.TRUE.equals(message.mx)) + return true; + } else if ("$blocklist".equals(keyword)) { + if (!Boolean.FALSE.equals(message.blocklist)) + return true; + } else if ("$replydomain".equals(keyword)) { + if (!Boolean.TRUE.equals(message.reply_domain)) + return true; + } else if ("$nofrom".equals(keyword)) { + if (message.from != null && message.from.length > 0) + return true; + } else if ("$multifrom".equals(keyword)) { + if (message.from == null || message.from.length < 2) + return true; + } else if ("$automatic".equals(keyword)) { + if (!Boolean.TRUE.equals(message.auto_submitted)) + return true; + } else if ("$lowpriority".equals(keyword)) { + if (!EntityMessage.PRIORITIY_LOW.equals(message.priority)) + return true; + } else if ("$highpriority".equals(keyword)) { + if (!EntityMessage.PRIORITIY_HIGH.equals(message.priority)) + return true; + } else if ("$signed".equals(keyword)) { + if (!message.isSigned()) + return true; + } else if ("$encrypted".equals(keyword)) { + if (!message.isEncrypted()) + return true; + } else { + List keywords = new ArrayList<>(); + keywords.addAll(Arrays.asList(message.keywords)); + + if (message.ui_seen) + keywords.add("$seen"); + if (message.ui_answered) + keywords.add("$answered"); + if (message.ui_flagged) + keywords.add("$flagged"); + if (message.ui_deleted) + keywords.add("$deleted"); + if (message.infrastructure != null) + keywords.add('$' + message.infrastructure); + + if (!keywords.contains(keyword)) + return true; + } + + return false; + } + private boolean matches(Context context, EntityMessage message, String needle, String haystack, boolean regex) { boolean matched = false; if (needle != null && haystack != null) diff --git a/app/src/main/java/eu/faircode/email/FragmentRule.java b/app/src/main/java/eu/faircode/email/FragmentRule.java index 594425b628..7393f8e578 100644 --- a/app/src/main/java/eu/faircode/email/FragmentRule.java +++ b/app/src/main/java/eu/faircode/email/FragmentRule.java @@ -111,6 +111,7 @@ public class FragmentRule extends FragmentBase { private CheckBox cbAttachments; private EditText etMimeType; + private CheckBox cbHeaderNot; private EditText etHeader; private ImageButton ibHeader; private CheckBox cbHeader; @@ -310,6 +311,7 @@ public class FragmentRule extends FragmentBase { cbAttachments = view.findViewById(R.id.cbAttachments); etMimeType = view.findViewById(R.id.etMimeType); + cbHeaderNot = view.findViewById(R.id.cbHeaderNot); etHeader = view.findViewById(R.id.etHeader); ibHeader = view.findViewById(R.id.ibHeader); cbHeader = view.findViewById(R.id.cbHeader); @@ -1259,6 +1261,7 @@ public class FragmentRule extends FragmentBase { etMimeType.setText(jcondition.optString("mimetype")); etMimeType.setEnabled(cbAttachments.isChecked()); + cbHeaderNot.setChecked(jheader != null && jheader.optBoolean("not")); etHeader.setText(jheader == null ? null : jheader.getString("value")); cbHeader.setChecked(jheader != null && jheader.getBoolean("regex")); @@ -1665,6 +1668,7 @@ public class FragmentRule extends FragmentBase { String header = etHeader.getText().toString(); if (!TextUtils.isEmpty(header)) { JSONObject jheader = new JSONObject(); + jheader.put("not", cbHeaderNot.isChecked()); jheader.put("value", header); jheader.put("regex", cbHeader.isChecked()); jcondition.put("header", jheader); diff --git a/app/src/main/res/layout/fragment_rule.xml b/app/src/main/res/layout/fragment_rule.xml index 12f1ff3d5e..86517b47b8 100644 --- a/app/src/main/res/layout/fragment_rule.xml +++ b/app/src/main/res/layout/fragment_rule.xml @@ -455,15 +455,27 @@ app:layout_constraintTop_toBottomOf="@id/tvMimeType" /> + + + app:layout_constraintTop_toBottomOf="@id/cbHeaderNot" />