From 06482fdaefc2ae8651bcdd719936cb9c7bcfb10f Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 1 Jul 2021 18:02:03 +0200 Subject: [PATCH] Add option to only allow messages from jids in roster `/silence on` will throw away all messages (type: chat, normal) that come from jids that are not in the roster. Implement https://github.com/profanity-im/profanity/issues/955 --- src/command/cmd_ac.c | 3 ++- src/command/cmd_defs.c | 14 ++++++++++++++ src/command/cmd_funcs.c | 8 ++++++++ src/command/cmd_funcs.h | 1 + src/config/preferences.c | 3 +++ src/config/preferences.h | 1 + src/ui/console.c | 10 ++++++++++ src/ui/ui.h | 1 + src/xmpp/message.c | 22 ++++++++++++++++++++++ 9 files changed, 62 insertions(+), 1 deletion(-) 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 @@ -2178,6 +2178,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) { 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; +}