about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/cmd_ac.c3
-rw-r--r--src/command/cmd_defs.c14
-rw-r--r--src/command/cmd_funcs.c8
-rw-r--r--src/command/cmd_funcs.h1
-rw-r--r--src/config/preferences.c3
-rw-r--r--src/config/preferences.h1
-rw-r--r--src/ui/console.c10
-rw-r--r--src/ui/ui.h1
-rw-r--r--src/xmpp/message.c22
-rw-r--r--tests/unittests/ui/stub_ui.c6
10 files changed, 68 insertions, 1 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index 77cd1adc..a4d61c30 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -1672,7 +1672,8 @@ _cmd_ac_complete_params(ProfWin* window, const char* const input, gboolean previ
 
     // autocomplete boolean settings
     gchar* boolean_choices[] = { "/beep", "/states", "/outtype", "/flash", "/splash",
-                                 "/history", "/vercheck", "/privileges", "/wrap", "/carbons", "/os", "/slashguard", "/mam" };
+                                 "/history", "/vercheck", "/privileges", "/wrap",
+                                 "/carbons", "/os", "/slashguard", "/mam", "/silence" };
 
     for (int i = 0; i < ARRAY_SIZE(boolean_choices); i++) {
         result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice, previous, NULL);
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index 63cb8780..16efea21 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -2622,6 +2622,20 @@ static struct cmd_t command_defs[] = {
       CMD_NOEXAMPLES
     },
 
+    { "/silence",
+      parse_args, 1, 1, &cons_silence_setting,
+      CMD_NOSUBFUNCS
+      CMD_MAINFUNC(cmd_silence)
+      CMD_TAGS(
+              CMD_TAG_CHAT)
+      CMD_SYN(
+              "/silence on|off")
+      CMD_DESC(
+              "Let's you silence all message attempts from people who are not in your roster.")
+      CMD_NOARGS
+      CMD_NOEXAMPLES
+    },
+
     // NEXT-COMMAND (search helper)
 };
 
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index 9b092939..073abde0 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -9505,3 +9505,11 @@ cmd_editor(ProfWin* window, const char* const command, gchar** args)
     }
     return TRUE;
 }
+
+gboolean
+cmd_silence(ProfWin* window, const char* const command, gchar** args)
+{
+    _cmd_set_boolean_preference(args[0], command, "Block all messages from JIDs that are not in the roster", PREF_SILENCE_NON_ROSTER);
+
+    return TRUE;
+}
diff --git a/src/command/cmd_funcs.h b/src/command/cmd_funcs.h
index aadcb55f..54cc6e78 100644
--- a/src/command/cmd_funcs.h
+++ b/src/command/cmd_funcs.h
@@ -246,5 +246,6 @@ gboolean cmd_executable_urlsave(ProfWin* window, const char* const command, gcha
 gboolean cmd_executable_editor(ProfWin* window, const char* const command, gchar** args);
 gboolean cmd_mam(ProfWin* window, const char* const command, gchar** args);
 gboolean cmd_editor(ProfWin* window, const char* const command, gchar** args);
+gboolean cmd_silence(ProfWin* window, const char* const command, gchar** args);
 
 #endif
diff --git a/src/config/preferences.c b/src/config/preferences.c
index 3e1ba585..4b24d46b 100644
--- a/src/config/preferences.c
+++ b/src/config/preferences.c
@@ -1916,6 +1916,7 @@ _get_group(preference_t pref)
     case PREF_TLS_CERTPATH:
     case PREF_CORRECTION_ALLOW:
     case PREF_MAM:
+    case PREF_SILENCE_NON_ROSTER:
         return PREF_GROUP_CONNECTION;
     case PREF_OTR_LOG:
     case PREF_OTR_POLICY:
@@ -2198,6 +2199,8 @@ _get_key(preference_t pref)
         return "url.save.cmd";
     case PREF_COMPOSE_EDITOR:
         return "compose.editor";
+    case PREF_SILENCE_NON_ROSTER:
+        return "silence.incoming.nonroster";
     default:
         return NULL;
     }
diff --git a/src/config/preferences.h b/src/config/preferences.h
index d8573349..f7474c1f 100644
--- a/src/config/preferences.h
+++ b/src/config/preferences.h
@@ -176,6 +176,7 @@ typedef enum {
     PREF_URL_OPEN_CMD,
     PREF_URL_SAVE_CMD,
     PREF_COMPOSE_EDITOR,
+    PREF_SILENCE_NON_ROSTER,
 } preference_t;
 
 typedef struct prof_alias_t
diff --git a/src/ui/console.c b/src/ui/console.c
index 4cb041a8..f7963a27 100644
--- a/src/ui/console.c
+++ b/src/ui/console.c
@@ -2179,6 +2179,16 @@ cons_mam_setting(void)
 }
 
 void
+cons_silence_setting(void)
+{
+    if (prefs_get_boolean(PREF_SILENCE_NON_ROSTER)) {
+        cons_show("Block all messages from JIDs that are not in the roster (/silence)    : ON");
+    } else {
+        cons_show("Block all messages from JIDs that are not in the roster (/silence)    : OFF");
+    }
+}
+
+void
 cons_show_connection_prefs(void)
 {
     cons_show("Connection preferences:");
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 441c9adf..dc2fc497 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -328,6 +328,7 @@ void cons_correction_setting(void);
 void cons_executable_setting(void);
 void cons_slashguard_setting(void);
 void cons_mam_setting(void);
+void cons_silence_setting(void);
 void cons_show_contact_online(PContact contact, Resource* resource, GDateTime* last_activity);
 void cons_show_contact_offline(PContact contact, char* resource, char* status);
 void cons_theme_properties(void);
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index e14ae07d..a8613ef9 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -94,6 +94,7 @@ static gboolean _handle_mam(xmpp_stanza_t* const stanza);
 static void _handle_pubsub(xmpp_stanza_t* const stanza, xmpp_stanza_t* const event);
 static gboolean _handle_form(xmpp_stanza_t* const stanza);
 static gboolean _handle_jingle_message(xmpp_stanza_t* const stanza);
+static gboolean _should_ignore_based_on_silence(xmpp_stanza_t* const stanza);
 
 #ifdef HAVE_LIBGPGME
 static xmpp_stanza_t* _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text);
@@ -171,6 +172,11 @@ _message_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* con
     } else if (type == NULL || g_strcmp0(type, STANZA_TYPE_CHAT) == 0 || g_strcmp0(type, STANZA_TYPE_NORMAL) == 0) {
         // type: chat, normal (==NULL)
 
+        // ignore all messages from JIDs that are not in roster, if 'silence' is set
+        if (_should_ignore_based_on_silence(stanza)) {
+            return 1;
+        }
+
         // XEP-0353: Jingle Message Initiation
         if (_handle_jingle_message(stanza)) {
             return 1;
@@ -1687,3 +1693,19 @@ _handle_jingle_message(xmpp_stanza_t* const stanza)
     }
     return FALSE;
 }
+
+static gboolean
+_should_ignore_based_on_silence(xmpp_stanza_t* const stanza)
+{
+    if (prefs_get_boolean(PREF_SILENCE_NON_ROSTER)) {
+        const char* const from = xmpp_stanza_get_from(stanza);
+        Jid* from_jid = jid_create(from);
+        PContact contact = roster_get_contact(from_jid->barejid);
+        jid_destroy(from_jid);
+        if (!contact) {
+            log_debug("[Silence] Ignoring message from: %s", from);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
diff --git a/tests/unittests/ui/stub_ui.c b/tests/unittests/ui/stub_ui.c
index 1cae8bde..edacc80a 100644
--- a/tests/unittests/ui/stub_ui.c
+++ b/tests/unittests/ui/stub_ui.c
@@ -1125,6 +1125,12 @@ void
 cons_mam_setting(void)
 {
 }
+
+void
+cons_silence_setting(void)
+{
+}
+
 void
 cons_show_bookmarks_ignore(gchar** list, gsize len)
 {