From 31ebd6ab1cb464c66b1555e5d78896a46d092cc9 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 30 Jun 2021 23:42:32 +0200 Subject: [PATCH 1/4] Add XEP-0377: Spam Reporting Report and block: `/blocked add someone@domain.org report-abuse This is not nice` `/blocked add someone@domain.org report-spam This is not nice` Regular block: `/blocked add someone@domain.org` Implement https://github.com/profanity-im/profanity/issues/1434 --- src/command/cmd_defs.c | 5 +++-- src/command/cmd_funcs.c | 42 ++++++++++++++++++++++++++++++++--------- src/xmpp/blocking.c | 27 +++++++++++++++++++++++++- src/xmpp/stanza.h | 4 ++++ src/xmpp/xmpp.h | 9 ++++++++- 5 files changed, 74 insertions(+), 13 deletions(-) diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index e04ba2a1..83714717 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -420,7 +420,7 @@ static struct cmd_t command_defs[] = { }, { "/blocked", - parse_args, 0, 2, NULL, + parse_args_with_freetext, 0, 4, NULL, CMD_NOSUBFUNCS CMD_MAINFUNC(cmd_blocked) CMD_TAGS( @@ -428,7 +428,7 @@ static struct cmd_t command_defs[] = { CMD_TAG_CHAT) CMD_SYN( "/blocked", - "/blocked add []", + "/blocked add [] [report-abuse|report-spam []", "/blocked remove ") CMD_DESC( "Manage blocked users (XEP-0191), calling with no arguments shows the current list of blocked users. " @@ -438,6 +438,7 @@ static struct cmd_t command_defs[] = { { "remove ", "Remove the specified Jabber ID from the blocked list." }) CMD_EXAMPLES( "/blocked add hel@helheim.edda", + "/blocked add hel@helheim.edda report-spam", "/blocked add profanity@rooms.dismail.de/spammy-user") }, diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index e1108982..094e6527 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -3014,17 +3014,41 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args) if (g_strcmp0(args[0], "add") == 0) { char* jid = args[1]; - if (jid == NULL && (window->type == WIN_CHAT)) { - ProfChatWin* chatwin = (ProfChatWin*)window; - jid = chatwin->barejid; + char* msg = NULL; + blocked_report br = BLOCKED_NO_REPORT; + + // /blocked add jid or /blocked add (in window) + if (g_strv_length(args) < 3) { + if (jid == NULL && (window->type == WIN_CHAT)) { + ProfChatWin* chatwin = (ProfChatWin*)window; + jid = chatwin->barejid; + } + + if (jid == NULL) { + cons_bad_cmd_usage(command); + return TRUE; + } + + } else { + if (args[2] && g_strcmp0(args[2], "report-abuse") == 0) { + br = BLOCKED_REPORT_ABUSE; + } else if (args[2] && g_strcmp0(args[2], "report-abuse") == 0) { + br = BLOCKED_REPORT_SPAM; + } else { + cons_bad_cmd_usage(command); + return TRUE; + } + + if (!connection_supports(XMPP_FEATURE_SPAM_REPORTING)) { + cons_show("Spam reporting not supported by server."); + return TRUE; + } + + msg = args[3]; } - if (jid == NULL) { - cons_bad_cmd_usage(command); - return TRUE; - } - - gboolean res = blocked_add(jid); + // args[3] is optional message + gboolean res = blocked_add(jid, br, msg); if (!res) { cons_show("User %s already blocked.", jid); } diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c index 34614679..b16f95cb 100644 --- a/src/xmpp/blocking.c +++ b/src/xmpp/blocking.c @@ -109,7 +109,7 @@ blocked_ac_reset(void) } gboolean -blocked_add(char* jid) +blocked_add(char* jid, blocked_report reportkind, const char* const message) { GList* found = g_list_find_custom(blocked, jid, (GCompareFunc)g_strcmp0); if (found) { @@ -129,6 +129,31 @@ blocked_add(char* jid) xmpp_stanza_set_name(item, STANZA_NAME_ITEM); xmpp_stanza_set_attribute(item, STANZA_ATTR_JID, jid); + if (reportkind != BLOCKED_NO_REPORT) { + xmpp_stanza_t* report = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(report, STANZA_NAME_REPORT); + if (reportkind == BLOCKED_REPORT_ABUSE) { + xmpp_stanza_set_attribute(report, STANZA_ATTR_REASON, STANZA_REPORTING_ABUSE); + } else { + xmpp_stanza_set_attribute(report, STANZA_ATTR_REASON, STANZA_REPORTING_SPAM); + } + + if (message) { + xmpp_stanza_t* text = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(text, STANZA_NAME_TEXT); + + xmpp_stanza_t* txt = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(txt, message); + + xmpp_stanza_add_child(text, txt); + xmpp_stanza_add_child(report, text); + xmpp_stanza_release(txt); + } + + xmpp_stanza_add_child(item, report); + xmpp_stanza_release(report); + } + xmpp_stanza_add_child(block, item); xmpp_stanza_release(item); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index aeddf6a2..47560ce0 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -122,6 +122,7 @@ #define STANZA_NAME_AFTER "after" #define STANZA_NAME_USERNAME "username" #define STANZA_NAME_PROPOSE "propose" +#define STANZA_NAME_REPORT "report" // error conditions #define STANZA_NAME_BAD_REQUEST "bad-request" @@ -245,6 +246,9 @@ #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" +#define STANZA_REPORTING_ABUSE "urn:xmpp:reporting:abuse" +#define STANZA_REPORTING_SPAM "urn:xmpp:reporting:spam" + typedef struct caps_stanza_t { char* hash; diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 003c3e07..61c7a642 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -70,6 +70,7 @@ #define XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY "urn:xmpp:avatar:metadata+notify" #define XMPP_FEATURE_LAST_MESSAGE_CORRECTION "urn:xmpp:message-correct:0" #define XMPP_FEATURE_MAM2 "urn:xmpp:mam:2" +#define XMPP_FEATURE_SPAM_REPORTING "urn:xmpp:reporting:1" typedef enum { JABBER_CONNECTING, @@ -89,6 +90,12 @@ typedef enum { INVITE_MEDIATED } jabber_invite_t; +typedef enum { + BLOCKED_NO_REPORT, + BLOCKED_REPORT_ABUSE, + BLOCKED_REPORT_SPAM +} blocked_report; + typedef struct bookmark_t { char* barejid; @@ -286,7 +293,7 @@ void roster_send_add_new(const char* const barejid, const char* const name); void roster_send_remove(const char* const barejid); GList* blocked_list(void); -gboolean blocked_add(char* jid); +gboolean blocked_add(char* jid, blocked_report reportkind, const char* const message); gboolean blocked_remove(char* jid); char* blocked_ac_find(const char* const search_str, gboolean previous, void* context); void blocked_ac_reset(void); From 7f737a3b47f348e327bdf4de9af692f3668beb2c Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 1 Jul 2021 10:36:52 +0200 Subject: [PATCH 2/4] Mention feature details when not supported So that we will get aware of a version mismatch. --- src/command/cmd_funcs.c | 10 +++++----- src/xmpp/iq.c | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 094e6527..eeb860e9 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -3008,7 +3008,7 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args) } if (!connection_supports(XMPP_FEATURE_BLOCKING)) { - cons_show("Blocking not supported by server."); + cons_show("Blocking (%s) not supported by server.", XMPP_FEATURE_BLOCKING); return TRUE; } @@ -3040,7 +3040,7 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args) } if (!connection_supports(XMPP_FEATURE_SPAM_REPORTING)) { - cons_show("Spam reporting not supported by server."); + cons_show("Spam reporting (%s) not supported by server.", XMPP_FEATURE_SPAM_REPORTING); return TRUE; } @@ -6521,7 +6521,7 @@ cmd_ping(ProfWin* window, const char* const command, gchar** args) } if (args[0] == NULL && connection_supports(XMPP_FEATURE_PING) == FALSE) { - cons_show("Server does not support ping requests."); + cons_show("Server does not support ping requests (%s).", XMPP_FEATURE_PING); return TRUE; } @@ -8126,7 +8126,7 @@ cmd_command_list(ProfWin* window, const char* const command, gchar** args) } if (connection_supports(XMPP_FEATURE_COMMANDS) == FALSE) { - cons_show("Server does not support ad hoc commands."); + cons_show("Server does not support ad hoc commands (%s).", XMPP_FEATURE_COMMANDS); return TRUE; } @@ -8182,7 +8182,7 @@ cmd_command_exec(ProfWin* window, const char* const command, gchar** args) } if (connection_supports(XMPP_FEATURE_COMMANDS) == FALSE) { - cons_show("Server does not support ad hoc commands."); + cons_show("Server does not support ad hoc commands (%s).", XMPP_FEATURE_COMMANDS); return TRUE; } diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 19b620e2..42571b9c 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1385,7 +1385,7 @@ _autoping_timed_send(xmpp_conn_t* const conn, void* const userdata) if (connection_supports(XMPP_FEATURE_PING) == FALSE) { log_warning("Server doesn't advertise %s feature, disabling autoping.", XMPP_FEATURE_PING); prefs_set_autoping(0); - cons_show_error("Server ping not supported, autoping disabled."); + cons_show_error("Server ping not supported (%s), autoping disabled.", XMPP_FEATURE_PING); xmpp_conn_t* conn = connection_get_conn(); xmpp_timed_handler_delete(conn, _autoping_timed_send); return 1; @@ -2586,7 +2586,7 @@ iq_mam_request(ProfChatWin* win) { if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) { log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2); - cons_show_error("Server doesn't support MAM."); + cons_show_error("Server doesn't support MAM (%s).", XMPP_FEATURE_MAM2); return; } From 2f533c5da4c77af2d661101bae05e8c9a4d9784c Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 1 Jul 2021 10:38:38 +0200 Subject: [PATCH 3/4] Adjust test stub of blocking command --- tests/unittests/xmpp/stub_xmpp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index ba72024c..4ecb8f79 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -547,7 +547,7 @@ blocked_list(void) } gboolean -blocked_add(char* jid) +blocked_add(char* jid, blocked_report reportkind, const char* const message) { return TRUE; } From 1d845c9ffb2a3575fa7edded00a7309016997a91 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 1 Jul 2021 10:53:11 +0200 Subject: [PATCH 4/4] Reorder /blocked commands Instead of `/blocked add [] [report-abuse|report-spam []` have: * /blocked add [] [] (like before) * /blocked report-abuse [] [] * /blocked report-spam [] [] --- src/command/cmd_ac.c | 2 ++ src/command/cmd_defs.c | 15 +++++++++----- src/command/cmd_funcs.c | 46 ++++++++++++++++++++++------------------- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 6b46d079..77cd1adc 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -951,6 +951,8 @@ cmd_ac_init(void) blocked_ac = autocomplete_new(); autocomplete_add(blocked_ac, "add"); autocomplete_add(blocked_ac, "remove"); + autocomplete_add(blocked_ac, "report-abuse"); + autocomplete_add(blocked_ac, "report-spam"); clear_ac = autocomplete_new(); autocomplete_add(clear_ac, "persist_history"); diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 83714717..63cb8780 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -420,7 +420,7 @@ static struct cmd_t command_defs[] = { }, { "/blocked", - parse_args_with_freetext, 0, 4, NULL, + parse_args_with_freetext, 0, 3, NULL, CMD_NOSUBFUNCS CMD_MAINFUNC(cmd_blocked) CMD_TAGS( @@ -428,17 +428,22 @@ static struct cmd_t command_defs[] = { CMD_TAG_CHAT) CMD_SYN( "/blocked", - "/blocked add [] [report-abuse|report-spam []", + "/blocked add []", + "/blocked report-abuse [] []", + "/blocked report-spam [] []", "/blocked remove ") CMD_DESC( "Manage blocked users (XEP-0191), calling with no arguments shows the current list of blocked users. " - "To blog a certain user in a MUC use the following as jid: room@conference.example.org/spammy-user") + "To blog a certain user in a MUC use the following as jid: room@conference.example.org/spammy-user" + "It is also possible to block and report (XEP-0377) a user with the report-abuse and report-spam commands.") CMD_ARGS( { "add []", "Block the specified Jabber ID. If in a chat window and no jid is specified, the current recipient will be blocked." }, - { "remove ", "Remove the specified Jabber ID from the blocked list." }) + { "remove ", "Remove the specified Jabber ID from the blocked list." }, + { "report-abuse []", "Report the jid as abuse with an optional message to the service operator." }, + { "report-spam []", "Report the jid as spam with an optional message to the service operator." }) CMD_EXAMPLES( "/blocked add hel@helheim.edda", - "/blocked add hel@helheim.edda report-spam", + "/blocked report-spam hel@helheim.edda Very annoying guy", "/blocked add profanity@rooms.dismail.de/spammy-user") }, diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index eeb860e9..9b092939 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -3012,10 +3012,10 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args) return TRUE; } + blocked_report br = BLOCKED_NO_REPORT; + if (g_strcmp0(args[0], "add") == 0) { char* jid = args[1]; - char* msg = NULL; - blocked_report br = BLOCKED_NO_REPORT; // /blocked add jid or /blocked add (in window) if (g_strv_length(args) < 3) { @@ -3028,27 +3028,9 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args) cons_bad_cmd_usage(command); return TRUE; } - - } else { - if (args[2] && g_strcmp0(args[2], "report-abuse") == 0) { - br = BLOCKED_REPORT_ABUSE; - } else if (args[2] && g_strcmp0(args[2], "report-abuse") == 0) { - br = BLOCKED_REPORT_SPAM; - } else { - cons_bad_cmd_usage(command); - return TRUE; - } - - if (!connection_supports(XMPP_FEATURE_SPAM_REPORTING)) { - cons_show("Spam reporting (%s) not supported by server.", XMPP_FEATURE_SPAM_REPORTING); - return TRUE; - } - - msg = args[3]; } - // args[3] is optional message - gboolean res = blocked_add(jid, br, msg); + gboolean res = blocked_add(jid, br, NULL); if (!res) { cons_show("User %s already blocked.", jid); } @@ -3070,6 +3052,28 @@ cmd_blocked(ProfWin* window, const char* const command, gchar** args) return TRUE; } + if (strncmp(args[0], "report-", 7) == 0) { + if (args[1] && g_strcmp0(args[0], "report-abuse") == 0) { + br = BLOCKED_REPORT_ABUSE; + } else if (args[1] && g_strcmp0(args[0], "report-spam") == 0) { + br = BLOCKED_REPORT_SPAM; + } else { + cons_bad_cmd_usage(command); + return TRUE; + } + + if (!connection_supports(XMPP_FEATURE_SPAM_REPORTING)) { + cons_show("Spam reporting (%s) not supported by server.", XMPP_FEATURE_SPAM_REPORTING); + return TRUE; + } + + // args[3] is an optional message + gboolean res = blocked_add(args[1], br, args[3]); + if (!res) { + cons_show("User %s already blocked.", args[1]); + } + } + GList* blocked = blocked_list(); GList* curr = blocked; if (curr) {