Add support to register with a room

`/affiliation register` can now be used to register a nickname with a
MUC.

Tested with a server without forms. Couldn't find a server which
supports forms yet.

Implements https://github.com/profanity-im/profanity/issues/1210
This commit is contained in:
Michael Vetter
2021-03-18 20:32:12 +01:00
parent 064174efa3
commit fde0a0d1c6
8 changed files with 164 additions and 6 deletions

View File

@@ -2659,3 +2659,128 @@ _register_change_password_result_id_handler(xmpp_stanza_t* const stanza, void* c
}
return 0;
}
static int
_muc_register_nick_response_handler(xmpp_stanza_t* const stanza, void* const userdata)
{
const char* type = xmpp_stanza_get_type(stanza);
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
xmpp_stanza_t* error = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
const char* errtype = xmpp_stanza_get_type(error);
if (errtype) {
if (g_strcmp0(errtype, STANZA_TYPE_CANCEL) == 0) {
// find reason
xmpp_stanza_t* reason = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_CONFLICT, STANZA_NS_STANZAS);
if (reason) {
cons_show_error("Error while registering nickname: nick already registered with MUC");
log_debug("Error while registering nickname: nick already registered with MUC");
} else {
xmpp_stanza_t* reason = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_SERVICE_UNAVAILABLE, STANZA_NS_STANZAS);
if (reason) {
cons_show_error("Error while registering nickname: registration not supported by MUC");
log_debug("Error while registering nickname: registration not supported by MUC");
}
}
} else if (g_strcmp0(errtype, STANZA_TYPE_MODIFY) == 0) {
xmpp_stanza_t* reason = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_BAD_REQUEST, STANZA_NS_STANZAS);
if (reason) {
cons_show_error("Error while registering nickname: invalid form");
log_debug("Error while registering nickname: invalid form");
}
}
}
} else if (g_strcmp0(type, STANZA_TYPE_RESULT) == 0) {
cons_show("Registration request succesfully received");
log_debug("Registration request succesfully received");
}
return 0;
}
void
iq_submit_muc_register_nick_form(ProfConfWin* confwin)
{
char* id = connection_create_stanza_id();
xmpp_ctx_t* const ctx = connection_get_ctx();
xmpp_stanza_t* iq = stanza_create_muc_register_nick(ctx, id, confwin->roomjid, NULL, confwin->form);
iq_id_handler_add(id, _muc_register_nick_response_handler, NULL, NULL);
free(id);
iq_send_stanza(iq);
xmpp_stanza_release(iq);
}
static int
_muc_register_nick_handler(xmpp_stanza_t* const stanza, void* const userdata)
{
const char* type = xmpp_stanza_get_type(stanza);
// error case
if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
xmpp_stanza_t* error = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
const char* errtype = xmpp_stanza_get_type(error);
if (errtype) {
if (g_strcmp0(errtype, STANZA_TYPE_CANCEL) == 0) {
// find reason
xmpp_stanza_t* reason = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_ITEM_NOT_FOUND, STANZA_NS_STANZAS);
if (reason) {
cons_show_error("Error while registering nickname: room does not exist");
log_debug("Error while registering nickname: room does not exist");
} else {
xmpp_stanza_t* reason = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_NOT_ALLOWED, STANZA_NS_STANZAS);
if (reason) {
cons_show_error("Error while registering nickname: not allowed to register");
log_debug("Error while registering nickname: not allowed to register");
}
}
}
}
} else if (g_strcmp0(type, STANZA_TYPE_RESULT) == 0) {
xmpp_stanza_t* query = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_QUERY, STANZA_NS_REGISTER);
if (query) {
// user might already be registered
xmpp_stanza_t* username = xmpp_stanza_get_child_by_name(query, STANZA_NAME_USERNAME);
if (username) {
const char* value = xmpp_stanza_get_text(username);
cons_show("User already registered: %s", value);
} else {
xmpp_stanza_t* x_st = xmpp_stanza_get_child_by_name_and_ns(query, STANZA_NAME_X, STANZA_NS_DATA);
if (x_st) {
const char* from = xmpp_stanza_get_from(stanza);
DataForm* form = form_create(x_st);
ProfConfWin* confwin = (ProfConfWin*)wins_new_config(from, form, iq_submit_muc_register_nick_form, NULL, NULL);
confwin_handle_configuration(confwin, form);
}
}
}
}
return 0;
}
void
iq_muc_register_nick(const char* const roomjid)
{
xmpp_ctx_t* const ctx = connection_get_ctx();
char* id = connection_create_stanza_id();
xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id);
xmpp_stanza_set_to(iq, roomjid);
xmpp_stanza_t* query = xmpp_stanza_new(ctx);
xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
xmpp_stanza_set_ns(query, STANZA_NS_REGISTER);
xmpp_stanza_add_child(iq, query);
iq_id_handler_add(id, _muc_register_nick_handler, NULL, NULL);
free(id);
iq_send_stanza(iq);
xmpp_stanza_release(iq);
xmpp_stanza_release(query);
}

View File

@@ -2828,3 +2828,18 @@ stanza_create_approve_voice(xmpp_ctx_t* ctx, const char* const id, const char* c
return message;
}
xmpp_stanza_t*
stanza_create_muc_register_nick(xmpp_ctx_t* ctx, const char* const id, const char* const jid, const char* const node, DataForm* form)
{
xmpp_stanza_t* iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
xmpp_stanza_set_to(iq, jid);
xmpp_stanza_t* x = form_create_submission(form);
xmpp_stanza_add_child(iq, x);
xmpp_stanza_release(x);
return iq;
}

View File

@@ -159,6 +159,8 @@
#define STANZA_TYPE_ERROR "error"
#define STANZA_TYPE_RESULT "result"
#define STANZA_TYPE_SUBMIT "submit"
#define STANZA_TYPE_CANCEL "cancel"
#define STANZA_TYPE_MODIFY "modify"
#define STANZA_ATTR_TO "to"
#define STANZA_ATTR_FROM "from"
@@ -393,13 +395,10 @@ XMPPCaps* stanza_parse_caps(xmpp_stanza_t* const stanza);
void stanza_free_caps(XMPPCaps* caps);
xmpp_stanza_t* stanza_create_avatar_retrieve_data_request(xmpp_ctx_t* ctx, const char* stanza_id, const char* const item_id, const char* const jid);
xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const lastid);
xmpp_stanza_t* stanza_change_password(xmpp_ctx_t* ctx, const char* const user, const char* const password);
xmpp_stanza_t* stanza_request_voice(xmpp_ctx_t* ctx, const char* const room);
xmpp_stanza_t* stanza_create_approve_voice(xmpp_ctx_t* ctx, const char* const id, const char* const jid, const char* const node, DataForm* form);
xmpp_stanza_t* stanza_create_muc_register_nick(xmpp_ctx_t* ctx, const char* const id, const char* const jid, const char* const node, DataForm* form);
#endif

View File

@@ -259,6 +259,7 @@ void iq_command_list(const char* const target);
void iq_command_exec(const char* const target, const char* const command);
void iq_mam_request(ProfChatWin* win);
void iq_register_change_password(const char* const user, const char* const password);
void iq_muc_register_nick(const char* const roomjid);
EntityCapabilities* caps_lookup(const char* const jid);
void caps_close(void);