From 609d05366c00670c176c842a19be760ad54f384b Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 20 Nov 2016 02:09:34 +0000 Subject: [PATCH] Use server features for account muc service issue #878 --- src/command/cmd_ac.c | 1 + src/command/cmd_defs.c | 8 +- src/command/cmd_funcs.c | 51 ++++++++---- src/config/account.c | 55 ++++++------- src/config/accounts.c | 102 ++++++++++++++---------- src/config/accounts.h | 1 + src/xmpp/connection.c | 4 + src/xmpp/connection.h | 1 - src/xmpp/xmpp.h | 2 + tests/functionaltests/functionaltests.c | 1 - tests/functionaltests/test_muc.c | 15 ---- tests/functionaltests/test_muc.h | 1 - tests/functionaltests/test_rooms.c | 2 +- tests/unittests/config/stub_accounts.c | 1 + 14 files changed, 133 insertions(+), 112 deletions(-) diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 2d3209d5..be198e2a 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -360,6 +360,7 @@ cmd_ac_init(void) autocomplete_add(account_clear_ac, "pgpkeyid"); autocomplete_add(account_clear_ac, "startscript"); autocomplete_add(account_clear_ac, "theme"); + autocomplete_add(account_clear_ac, "muc"); account_default_ac = autocomplete_new(); autocomplete_add(account_default_ac, "set"); diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 34400ae3..3c2be4db 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1989,7 +1989,8 @@ static struct cmd_t command_defs[] = "/account clear port", "/account clear otr", "/account clear pgpkeyid", - "/account clear startscript") + "/account clear startscript", + "/account clean muc") CMD_DESC( "Commands for creating and managing accounts. " "Calling with no arguments will display information for the current account.") @@ -2012,7 +2013,7 @@ static struct cmd_t command_defs[] = { "set resource ", "The resource to be used for this account, defaults to 'profanity'." }, { "set password ", "Password for the account, note this is currently stored in plaintext if set." }, { "set eval_password ", "Shell command evaluated to retrieve password for the account. Can be used to retrieve password from keyring." }, - { "set muc ", "The default MUC chat service to use, defaults to 'conference.' where the domain part is from the account JID." }, + { "set muc ", "The default MUC chat service to use, defaults to the servers disco info response." }, { "set nick ", "The default nickname to use when joining chat rooms." }, { "set otr ", "Override global OTR policy for this account, see /otr." }, { "set pgpkeyid ", "Set the ID of the PGP key for this account, see /pgp." }, @@ -2028,7 +2029,8 @@ static struct cmd_t command_defs[] = { "clear otr", "Remove the OTR policy setting for this account." }, { "clear pgpkeyid", "Remove pgpkeyid associated with this account." }, { "clear startscript", "Remove startscript associated with this account." }, - { "clear theme", "Clear the theme setting for the account, the global theme will be used." }) + { "clear theme", "Clear the theme setting for the account, the global theme will be used." }, + { "clear muc", "Remove the default MUC service setting."}) CMD_EXAMPLES( "/account add me", "/account set me jid me@chatty", diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 145752ca..08570e96 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -959,6 +959,10 @@ cmd_account_clear(ProfWin *window, const char *const command, gchar **args) accounts_clear_theme(account_name); cons_show("Removed theme for account %s", account_name); cons_show(""); + } else if (strcmp(property, "muc") == 0) { + accounts_clear_muc(account_name); + cons_show("Removed MUC service for account %s", account_name); + cons_show(""); } else { cons_show("Invalid property: %s", property); cons_show(""); @@ -3426,17 +3430,20 @@ cmd_join(ProfWin *window, const char *const command, gchar **args) if (args[0] == NULL) { char *account_name = session_get_account_name(); ProfAccount *account = accounts_get_account(account_name); + if (account->muc_service) { + GString *room_str = g_string_new(""); + char *uuid = connection_create_uuid(); + g_string_append_printf(room_str, "private-chat-%s@%s", uuid, account->muc_service); + connection_free_uuid(uuid); - GString *room_str = g_string_new(""); - char *uuid = connection_create_uuid(); - g_string_append_printf(room_str, "private-chat-%s@%s", uuid, account->muc_service); - connection_free_uuid(uuid); + presence_join_room(room_str->str, account->muc_nick, NULL); + muc_join(room_str->str, account->muc_nick, NULL, FALSE); - presence_join_room(room_str->str, account->muc_nick, NULL); - muc_join(room_str->str, account->muc_nick, NULL, FALSE); - - g_string_free(room_str, TRUE); - account_free(account); + g_string_free(room_str, TRUE); + account_free(account); + } else { + cons_show("Account MUC service property not found."); + } return TRUE; } @@ -3451,7 +3458,6 @@ cmd_join(ProfWin *window, const char *const command, gchar **args) char *room = NULL; char *nick = NULL; char *passwd = NULL; - GString *room_str = g_string_new(""); char *account_name = session_get_account_name(); ProfAccount *account = accounts_get_account(account_name); @@ -3460,11 +3466,18 @@ cmd_join(ProfWin *window, const char *const command, gchar **args) room = args[0]; // server not supplied (room), use account preference - } else { + } else if (account->muc_service) { + GString *room_str = g_string_new(""); g_string_append(room_str, args[0]); g_string_append(room_str, "@"); g_string_append(room_str, account->muc_service); room = room_str->str; + g_string_free(room_str, FALSE); + + // no account preference + } else { + cons_show("Account MUC service property not found."); + return TRUE; } // Additional args supplied @@ -3502,7 +3515,6 @@ cmd_join(ProfWin *window, const char *const command, gchar **args) } jid_destroy(room_arg); - g_string_free(room_str, TRUE); account_free(account); return TRUE; @@ -4307,14 +4319,19 @@ cmd_rooms(ProfWin *window, const char *const command, gchar **args) return TRUE; } - if (args[0] == NULL) { - ProfAccount *account = accounts_get_account(session_get_account_name()); - iq_room_list_request(account->muc_service); - account_free(account); - } else { + if (args[0]) { iq_room_list_request(args[0]); + return TRUE; } + ProfAccount *account = accounts_get_account(session_get_account_name()); + if (account->muc_service) { + iq_room_list_request(account->muc_service); + } else { + cons_show("Account MUC service property not found."); + } + account_free(account); + return TRUE; } diff --git a/src/config/account.c b/src/config/account.c index 3e8c8cf1..40b91224 100644 --- a/src/config/account.c +++ b/src/config/account.c @@ -115,17 +115,10 @@ account_new(const gchar *const name, const gchar *const jid, new_account->priority_xa = priority_xa; new_account->priority_dnd = priority_dnd; - if (muc_service == NULL) { - GString *g_muc_service = g_string_new("conference."); - Jid *jidp = jid_create(new_account->jid); - g_string_append(g_muc_service, jidp->domainpart); - - new_account->muc_service = g_muc_service->str; - - g_string_free(g_muc_service, FALSE); - jid_destroy(jidp); - } else { + if (muc_service) { new_account->muc_service = strdup(muc_service); + } else { + new_account->muc_service = NULL; } if (muc_nick == NULL) { @@ -224,25 +217,27 @@ account_eval_password(ProfAccount *account) void account_free(ProfAccount *account) { - if (account) { - free(account->name); - free(account->jid); - free(account->password); - free(account->eval_password); - free(account->resource); - free(account->server); - free(account->last_presence); - free(account->login_presence); - free(account->muc_service); - free(account->muc_nick); - free(account->otr_policy); - free(account->pgp_keyid); - free(account->startscript); - free(account->theme); - free(account->tls_policy); - g_list_free_full(account->otr_manual, g_free); - g_list_free_full(account->otr_opportunistic, g_free); - g_list_free_full(account->otr_always, g_free); - free(account); + if (account == NULL) { + return; } + + free(account->name); + free(account->jid); + free(account->password); + free(account->eval_password); + free(account->resource); + free(account->server); + free(account->last_presence); + free(account->login_presence); + free(account->muc_service); + free(account->muc_nick); + free(account->otr_policy); + free(account->pgp_keyid); + free(account->startscript); + free(account->theme); + free(account->tls_policy); + g_list_free_full(account->otr_manual, g_free); + g_list_free_full(account->otr_opportunistic, g_free); + g_list_free_full(account->otr_always, g_free); + free(account); } diff --git a/src/config/accounts.c b/src/config/accounts.c index 96168b5b..233a5aa8 100644 --- a/src/config/accounts.c +++ b/src/config/accounts.c @@ -133,46 +133,46 @@ accounts_add(const char *account_name, const char *altdomain, const int port, co } } - // doesn't yet exist - if (!g_key_file_has_group(accounts, account_name)) { - g_key_file_set_boolean(accounts, account_name, "enabled", TRUE); - g_key_file_set_string(accounts, account_name, "jid", barejid); - g_key_file_set_string(accounts, account_name, "resource", resource); - if (altdomain) { - g_key_file_set_string(accounts, account_name, "server", altdomain); - } - if (port != 0) { - g_key_file_set_integer(accounts, account_name, "port", port); - } - if (tls_policy) { - g_key_file_set_string(accounts, account_name, "tls.policy", tls_policy); - } - - Jid *jidp = jid_create(barejid); - GString *muc_service = g_string_new("conference."); - g_string_append(muc_service, jidp->domainpart); - g_key_file_set_string(accounts, account_name, "muc.service", muc_service->str); - g_string_free(muc_service, TRUE); - if (jidp->localpart == NULL) { - g_key_file_set_string(accounts, account_name, "muc.nick", jidp->domainpart); - } else { - g_key_file_set_string(accounts, account_name, "muc.nick", jidp->localpart); - } - jid_destroy(jidp); - - g_key_file_set_string(accounts, account_name, "presence.last", "online"); - g_key_file_set_string(accounts, account_name, "presence.login", "online"); - g_key_file_set_integer(accounts, account_name, "priority.online", 0); - g_key_file_set_integer(accounts, account_name, "priority.chat", 0); - g_key_file_set_integer(accounts, account_name, "priority.away", 0); - g_key_file_set_integer(accounts, account_name, "priority.xa", 0); - g_key_file_set_integer(accounts, account_name, "priority.dnd", 0); - - _save_accounts(); - autocomplete_add(all_ac, account_name); - autocomplete_add(enabled_ac, account_name); + if (g_key_file_has_group(accounts, account_name)) { + jid_destroy(jid); + return; } + g_key_file_set_boolean(accounts, account_name, "enabled", TRUE); + g_key_file_set_string(accounts, account_name, "jid", barejid); + g_key_file_set_string(accounts, account_name, "resource", resource); + if (altdomain) { + g_key_file_set_string(accounts, account_name, "server", altdomain); + } + if (port != 0) { + g_key_file_set_integer(accounts, account_name, "port", port); + } + if (tls_policy) { + g_key_file_set_string(accounts, account_name, "tls.policy", tls_policy); + } + + Jid *jidp = jid_create(barejid); + + if (jidp->localpart == NULL) { + g_key_file_set_string(accounts, account_name, "muc.nick", jidp->domainpart); + } else { + g_key_file_set_string(accounts, account_name, "muc.nick", jidp->localpart); + } + + jid_destroy(jidp); + + g_key_file_set_string(accounts, account_name, "presence.last", "online"); + g_key_file_set_string(accounts, account_name, "presence.login", "online"); + g_key_file_set_integer(accounts, account_name, "priority.online", 0); + g_key_file_set_integer(accounts, account_name, "priority.chat", 0); + g_key_file_set_integer(accounts, account_name, "priority.away", 0); + g_key_file_set_integer(accounts, account_name, "priority.xa", 0); + g_key_file_set_integer(accounts, account_name, "priority.dnd", 0); + + _save_accounts(); + autocomplete_add(all_ac, account_name); + autocomplete_add(enabled_ac, account_name); + jid_destroy(jid); } @@ -223,7 +223,18 @@ accounts_get_account(const char *const name) int priority_xa = g_key_file_get_integer(accounts, name, "priority.xa", NULL); int priority_dnd = g_key_file_get_integer(accounts, name, "priority.dnd", NULL); - gchar *muc_service = g_key_file_get_string(accounts, name, "muc.service", NULL); + gchar *muc_service = NULL; + if (g_key_file_has_key(accounts, name, "muc.service", NULL)) { + muc_service = g_key_file_get_string(accounts, name, "muc.service", NULL); + } else { + jabber_conn_status_t conn_status = connection_get_status(); + if (conn_status == JABBER_CONNECTED) { + char* conf_jid = connection_jid_for_feature(XMPP_FEATURE_MUC); + if (conf_jid) { + muc_service = strdup(conf_jid); + } + } + } gchar *muc_nick = g_key_file_get_string(accounts, name, "muc.nick", NULL); gchar *otr_policy = NULL; @@ -416,10 +427,6 @@ accounts_set_jid(const char *const account_name, const char *const value) g_key_file_set_string(accounts, account_name, "resource", jid->resourcepart); } - GString *muc_service = g_string_new("conference."); - g_string_append(muc_service, jid->domainpart); - g_key_file_set_string(accounts, account_name, "muc.service", muc_service->str); - g_string_free(muc_service, TRUE); if (jid->localpart == NULL) { g_key_file_set_string(accounts, account_name, "muc.nick", jid->domainpart); } else { @@ -568,6 +575,15 @@ accounts_clear_theme(const char *const account_name) } } +void +accounts_clear_muc(const char *const account_name) +{ + if (accounts_account_exists(account_name)) { + g_key_file_remove_key(accounts, account_name, "muc.service", NULL); + _save_accounts(); + } +} + void accounts_clear_otr(const char *const account_name) { diff --git a/src/config/accounts.h b/src/config/accounts.h index 7524c65e..6c6cb1c9 100644 --- a/src/config/accounts.h +++ b/src/config/accounts.h @@ -93,6 +93,7 @@ void accounts_clear_otr(const char *const account_name); void accounts_clear_pgp_keyid(const char *const account_name); void accounts_clear_script_start(const char *const account_name); void accounts_clear_theme(const char *const account_name); +void accounts_clear_muc(const char *const account_name); void accounts_add_otr_policy(const char *const account_name, const char *const contact_jid, const char *const policy); #endif diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 304d984d..4e0ca9a8 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -290,6 +290,10 @@ connection_supports(const char *const feature) char* connection_jid_for_feature(const char *const feature) { + if (conn.features_by_jid == NULL) { + return NULL; + } + GList *jids = g_hash_table_get_keys(conn.features_by_jid); GList *curr = jids; diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h index ef997a29..b691e90d 100644 --- a/src/xmpp/connection.h +++ b/src/xmpp/connection.h @@ -54,7 +54,6 @@ void connection_set_disco_items(GSList *items); xmpp_conn_t* connection_get_conn(void); xmpp_ctx_t* connection_get_ctx(void); char *connection_get_domain(void); -char* connection_jid_for_feature(const char *const feature); GHashTable* connection_get_features(const char *const jid); void connection_clear_data(void); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 8dfe7c0e..7302b279 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -58,6 +58,7 @@ #define XMPP_FEATURE_BLOCKING "urn:xmpp:blocking" #define XMPP_FEATURE_RECEIPTS "urn:xmpp:receipts" #define XMPP_FEATURE_LASTACTIVITY "jabber:iq:last" +#define XMPP_FEATURE_MUC "http://jabber.org/protocol/muc" typedef enum { JABBER_CONNECTING, @@ -129,6 +130,7 @@ gboolean connection_is_secured(void); gboolean connection_send_stanza(const char *const stanza); GList* connection_get_available_resources(void); gboolean connection_supports(const char *const feature); +char* connection_jid_for_feature(const char *const feature); char* message_send_chat(const char *const barejid, const char *const msg, const char *const oob_url, gboolean request_receipt); diff --git a/tests/functionaltests/functionaltests.c b/tests/functionaltests/functionaltests.c index 617ab838..ef9f0e39 100644 --- a/tests/functionaltests/functionaltests.c +++ b/tests/functionaltests/functionaltests.c @@ -89,7 +89,6 @@ int main(int argc, char* argv[]) { PROF_FUNC_TEST(display_software_version_result_in_chat), PROF_FUNC_TEST(sends_room_join), - PROF_FUNC_TEST(sends_room_join_with_default_muc_service), PROF_FUNC_TEST(sends_room_join_with_nick), PROF_FUNC_TEST(sends_room_join_with_password), PROF_FUNC_TEST(sends_room_join_with_nick_and_password), diff --git a/tests/functionaltests/test_muc.c b/tests/functionaltests/test_muc.c index 5a117045..e7fc8dcb 100644 --- a/tests/functionaltests/test_muc.c +++ b/tests/functionaltests/test_muc.c @@ -26,21 +26,6 @@ sends_room_join(void **state) )); } -void -sends_room_join_with_default_muc_service(void **state) -{ - prof_connect(); - - prof_input("/join testroom"); - - assert_true(stbbr_last_received( - "" - "" - "" - "" - )); -} - void sends_room_join_with_nick(void **state) { diff --git a/tests/functionaltests/test_muc.h b/tests/functionaltests/test_muc.h index 30a6c2c8..4f3c4f5d 100644 --- a/tests/functionaltests/test_muc.h +++ b/tests/functionaltests/test_muc.h @@ -1,5 +1,4 @@ void sends_room_join(void **state); -void sends_room_join_with_default_muc_service(void **state); void sends_room_join_with_nick(void **state); void sends_room_join_with_password(void **state); void sends_room_join_with_nick_and_password(void **state); diff --git a/tests/functionaltests/test_rooms.c b/tests/functionaltests/test_rooms.c index 9bff2e19..c0103279 100644 --- a/tests/functionaltests/test_rooms.c +++ b/tests/functionaltests/test_rooms.c @@ -25,7 +25,7 @@ rooms_query(void **state) prof_connect(); - prof_input("/rooms"); + prof_input("/rooms conference.localhost"); assert_true(prof_output_exact("chatroom@conference.localhost, (A chat room)")); assert_true(prof_output_exact("hangout@conference.localhost, (Another chat room)")); diff --git a/tests/unittests/config/stub_accounts.c b/tests/unittests/config/stub_accounts.c index 4c0449d6..669ceb33 100644 --- a/tests/unittests/config/stub_accounts.c +++ b/tests/unittests/config/stub_accounts.c @@ -196,6 +196,7 @@ void accounts_clear_otr(const char * const account_name) {} void accounts_clear_pgp_keyid(const char * const account_name) {} void accounts_clear_script_start(const char * const account_name) {} void accounts_clear_theme(const char * const account_name) {} +void accounts_clear_muc(const char * const account_name) {} void accounts_add_otr_policy(const char * const account_name, const char * const contact_jid, const char * const policy) {} char* accounts_get_last_activity(const char *const account_name) {