From 5a5bb7f63222189ea0dcfbd387d5e34458ccefe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 14 Dec 2016 18:28:44 +0100 Subject: Introduce a XmlSubNode class that automatically adds itself into its parent --- louloulibs/xmpp/adhoc_command.cpp | 32 +- louloulibs/xmpp/adhoc_commands_handler.cpp | 30 +- louloulibs/xmpp/xmpp_component.cpp | 539 ++++++++++++++--------------- louloulibs/xmpp/xmpp_stanza.hpp | 14 + 4 files changed, 302 insertions(+), 313 deletions(-) (limited to 'louloulibs') diff --git a/louloulibs/xmpp/adhoc_command.cpp b/louloulibs/xmpp/adhoc_command.cpp index 99701d7..08d2d17 100644 --- a/louloulibs/xmpp/adhoc_command.cpp +++ b/louloulibs/xmpp/adhoc_command.cpp @@ -18,30 +18,24 @@ bool AdhocCommand::is_admin_only() const void PingStep1(XmppComponent&, AdhocSession&, XmlNode& command_node) { - XmlNode note("note"); + XmlSubNode note(command_node, "note"); note["type"] = "info"; note.set_inner("Pong"); - command_node.add_child(std::move(note)); } void HelloStep1(XmppComponent&, AdhocSession&, XmlNode& command_node) { - XmlNode x("jabber:x:data:x"); + XmlSubNode x(command_node, "jabber:x:data:x"); x["type"] = "form"; - XmlNode title("title"); + XmlSubNode title(x, "title"); title.set_inner("Configure your name."); - x.add_child(std::move(title)); - XmlNode instructions("instructions"); + XmlSubNode instructions(x, "instructions"); instructions.set_inner("Please provide your name."); - x.add_child(std::move(instructions)); - XmlNode name_field("field"); + XmlSubNode name_field(x, "field"); name_field["var"] = "name"; name_field["type"] = "text-single"; name_field["label"] = "Your name"; - XmlNode required("required"); - name_field.add_child(std::move(required)); - x.add_child(std::move(name_field)); - command_node.add_child(std::move(x)); + XmlSubNode required(name_field, "required"); } void HelloStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node) @@ -60,21 +54,18 @@ void HelloStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node) { if (const XmlNode* value = name_field->get_child("value", "jabber:x:data")) { - XmlNode note("note"); + command_node.delete_all_children(); + XmlSubNode note(command_node, "note"); note["type"] = "info"; note.set_inner("Hello "s + value->get_inner() + "!"s); - command_node.delete_all_children(); - command_node.add_child(std::move(note)); return; } } } command_node.delete_all_children(); - XmlNode error(ADHOC_NS":error"); + XmlSubNode error(command_node, ADHOC_NS":error"); error["type"] = "modify"; - XmlNode condition(STANZA_NS":bad-request"); - error.add_child(std::move(condition)); - command_node.add_child(std::move(error)); + XmlSubNode condition(error, STANZA_NS":bad-request"); session.terminate(); } @@ -82,8 +73,7 @@ void Reload(XmppComponent&, AdhocSession&, XmlNode& command_node) { ::reload_process(); command_node.delete_all_children(); - XmlNode note("note"); + XmlSubNode note(command_node, "note"); note["type"] = "info"; note.set_inner("Configuration reloaded."); - command_node.add_child(std::move(note)); } diff --git a/louloulibs/xmpp/adhoc_commands_handler.cpp b/louloulibs/xmpp/adhoc_commands_handler.cpp index 540cac0..d3ede2d 100644 --- a/louloulibs/xmpp/adhoc_commands_handler.cpp +++ b/louloulibs/xmpp/adhoc_commands_handler.cpp @@ -36,20 +36,16 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co auto command_it = this->commands.find(node); if (command_it == this->commands.end()) { - XmlNode error(ADHOC_NS":error"); + XmlSubNode error(command_node, ADHOC_NS":error"); error["type"] = "cancel"; - XmlNode condition(STANZA_NS":item-not-found"); - error.add_child(std::move(condition)); - command_node.add_child(std::move(error)); + XmlSubNode condition(error, STANZA_NS":item-not-found"); } else if (command_it->second.is_admin_only() && Config::get("admin", "") != jid.local + "@" + jid.domain) { - XmlNode error(ADHOC_NS":error"); + XmlSubNode error(command_node, ADHOC_NS":error"); error["type"] = "cancel"; - XmlNode condition(STANZA_NS":forbidden"); - error.add_child(std::move(condition)); - command_node.add_child(std::move(error)); + XmlSubNode condition(error, STANZA_NS":forbidden"); } else { @@ -68,11 +64,9 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co auto session_it = this->sessions.find(std::make_pair(sessionid, executor_jid)); if (session_it == this->sessions.end()) { - XmlNode error(ADHOC_NS":error"); + XmlSubNode error(command_node, ADHOC_NS":error"); error["type"] = "modify"; - XmlNode condition(STANZA_NS":bad-request"); - error.add_child(std::move(condition)); - command_node.add_child(std::move(error)); + XmlSubNode condition(error, STANZA_NS":bad-request"); } else if (action == "execute" || action == "next" || action == "complete") { @@ -90,10 +84,8 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co else { command_node["status"] = "executing"; - XmlNode actions("actions"); - XmlNode next("next"); - actions.add_child(std::move(next)); - command_node.add_child(std::move(actions)); + XmlSubNode actions(command_node, "actions"); + XmlSubNode next(actions, "next"); } } else if (action == "cancel") @@ -104,11 +96,9 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co } else // unsupported action { - XmlNode error(ADHOC_NS":error"); + XmlSubNode error(command_node, ADHOC_NS":error"); error["type"] = "modify"; - XmlNode condition(STANZA_NS":bad-request"); - error.add_child(std::move(condition)); - command_node.add_child(std::move(error)); + XmlSubNode condition(error, STANZA_NS":bad-request"); } } return command_node; diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index f0b0de7..e1b6131 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -172,12 +172,13 @@ void XmppComponent::on_stanza(const Stanza& stanza) void XmppComponent::send_stream_error(const std::string& name, const std::string& explanation) { - XmlNode node("stream:error"); - XmlNode error(name); - error["xmlns"] = STREAM_NS; - if (!explanation.empty()) - error.set_inner(explanation); - node.add_child(std::move(error)); + Stanza node("stream:error"); + { + XmlSubNode error(node, name); + error["xmlns"] = STREAM_NS; + if (!explanation.empty()) + error.set_inner(explanation); + } this->send_stanza(node); } @@ -187,31 +188,34 @@ void XmppComponent::send_stanza_error(const std::string& kind, const std::string const bool fulljid) { Stanza node(kind); - if (!to.empty()) - node["to"] = to; - if (!from.empty()) + { + if (!to.empty()) + node["to"] = to; + if (!from.empty()) + { + if (fulljid) + node["from"] = from; + else + node["from"] = from + "@" + this->served_hostname; + } + if (!id.empty()) + node["id"] = id; + node["type"] = "error"; { - if (fulljid) - node["from"] = from; - else - node["from"] = from + "@" + this->served_hostname; + XmlSubNode error(node, "error"); + error["type"] = error_type; + { + XmlSubNode inner_error(error, defined_condition); + inner_error["xmlns"] = STANZA_NS; + } + if (!text.empty()) + { + XmlSubNode text_node(error, "text"); + text_node["xmlns"] = STANZA_NS; + text_node.set_inner(text); + } } - if (!id.empty()) - node["id"] = id; - node["type"] = "error"; - XmlNode error("error"); - error["type"] = error_type; - XmlNode inner_error(defined_condition); - inner_error["xmlns"] = STANZA_NS; - error.add_child(std::move(inner_error)); - if (!text.empty()) - { - XmlNode text_node("text"); - text_node["xmlns"] = STANZA_NS; - text_node.set_inner(text); - error.add_child(std::move(text_node)); - } - node.add_child(std::move(error)); + } this->send_stanza(node); } @@ -264,38 +268,33 @@ void* XmppComponent::get_receive_buffer(const size_t size) const void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, const std::string& to, const std::string& type, const bool fulljid, const bool nocopy) { - XmlNode node("message"); - node["to"] = to; - if (fulljid) - node["from"] = from; - else - node["from"] = from + "@" + this->served_hostname; - if (!type.empty()) - node["type"] = type; - XmlNode body_node("body"); - body_node.set_inner(std::get<0>(body)); - node.add_child(std::move(body_node)); - if (std::get<1>(body)) - { - XmlNode html("html"); - html["xmlns"] = XHTMLIM_NS; - // Pass the ownership of the pointer to this xmlnode - html.add_child(std::move(std::get<1>(body))); - node.add_child(std::move(html)); - } - - if (nocopy) - { - XmlNode private_node("private"); - private_node["xmlns"] = "urn:xmpp:carbons:2"; - node.add_child(std::move(private_node)); - - XmlNode nocopy("no-copy"); - nocopy["xmlns"] = "urn:xmpp:hints"; - node.add_child(std::move(nocopy)); - } - - this->send_stanza(node); + Stanza message("message"); + { + message["to"] = to; + if (fulljid) + message["from"] = from; + else + message["from"] = from + "@" + this->served_hostname; + if (!type.empty()) + message["type"] = type; + XmlSubNode body_node(message, "body"); + body_node.set_inner(std::get<0>(body)); + if (std::get<1>(body)) + { + XmlSubNode html(message, "html"); + html["xmlns"] = XHTMLIM_NS; + // Pass the ownership of the pointer to this xmlnode + html.add_child(std::move(std::get<1>(body))); + } + if (nocopy) + { + XmlSubNode private_node(message, "private"); + private_node["xmlns"] = "urn:xmpp:carbons:2"; + XmlSubNode nocopy(message, "no-copy"); + nocopy["xmlns"] = "urn:xmpp:hints"; + } + } + this->send_stanza(message); } void XmppComponent::send_user_join(const std::string& from, @@ -306,34 +305,33 @@ void XmppComponent::send_user_join(const std::string& from, const std::string& to, const bool self) { - XmlNode node("presence"); - node["to"] = to; - node["from"] = from + "@" + this->served_hostname + "/" + nick; - - XmlNode x("x"); - x["xmlns"] = MUC_USER_NS; - - XmlNode item("item"); - if (!affiliation.empty()) - item["affiliation"] = affiliation; - if (!role.empty()) - item["role"] = role; - if (!realjid.empty()) - { - const std::string preped_jid = jidprep(realjid); - if (!preped_jid.empty()) - item["jid"] = preped_jid; - } - x.add_child(std::move(item)); - - if (self) - { - XmlNode status("status"); - status["code"] = "110"; - x.add_child(std::move(status)); - } - node.add_child(std::move(x)); - this->send_stanza(node); + Stanza presence("presence"); + { + presence["to"] = to; + presence["from"] = from + "@" + this->served_hostname + "/" + nick; + + XmlSubNode x(presence, "x"); + x["xmlns"] = MUC_USER_NS; + + XmlSubNode item(x, "item"); + if (!affiliation.empty()) + item["affiliation"] = affiliation; + if (!role.empty()) + item["role"] = role; + if (!realjid.empty()) + { + const std::string preped_jid = jidprep(realjid); + if (!preped_jid.empty()) + item["jid"] = preped_jid; + } + + if (self) + { + XmlSubNode status(x, "status"); + status["code"] = "110"; + } + } + this->send_stanza(presence); } void XmppComponent::send_invalid_room_error(const std::string& muc_name, @@ -341,44 +339,43 @@ void XmppComponent::send_invalid_room_error(const std::string& muc_name, const std::string& to) { Stanza presence("presence"); - if (!muc_name.empty()) - presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; - else - presence["from"] = this->served_hostname; - presence["to"] = to; - presence["type"] = "error"; - XmlNode x("x"); - x["xmlns"] = MUC_NS; - presence.add_child(std::move(x)); - XmlNode error("error"); - error["by"] = muc_name + "@" + this->served_hostname; - error["type"] = "cancel"; - XmlNode item_not_found("item-not-found"); - item_not_found["xmlns"] = STANZA_NS; - error.add_child(std::move(item_not_found)); - XmlNode text("text"); - text["xmlns"] = STANZA_NS; - text["xml:lang"] = "en"; - text.set_inner(muc_name + - " is not a valid IRC channel name. A correct room jid is of the form: #%@" + - this->served_hostname); - error.add_child(std::move(text)); - presence.add_child(std::move(error)); + { + if (!muc_name.empty ()) + presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; + else + presence["from"] = this->served_hostname; + presence["to"] = to; + presence["type"] = "error"; + XmlSubNode x(presence, "x"); + x["xmlns"] = MUC_NS; + XmlSubNode error(presence, "error"); + error["by"] = muc_name + "@" + this->served_hostname; + error["type"] = "cancel"; + XmlSubNode item_not_found(error, "item-not-found"); + item_not_found["xmlns"] = STANZA_NS; + XmlSubNode text(error, "text"); + text["xmlns"] = STANZA_NS; + text["xml:lang"] = "en"; + text.set_inner(muc_name + + " is not a valid IRC channel name. A correct room jid is of the form: #%@" + + this->served_hostname); + } this->send_stanza(presence); } void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to, const std::string& who) { - XmlNode message("message"); - message["to"] = to; - if (who.empty()) - message["from"] = from + "@" + this->served_hostname; - else - message["from"] = from + "@" + this->served_hostname + "/" + who; - message["type"] = "groupchat"; - XmlNode subject("subject"); - subject.set_inner(std::get<0>(topic)); - message.add_child(std::move(subject)); + Stanza message("message"); + { + message["to"] = to; + if (who.empty()) + message["from"] = from + "@" + this->served_hostname; + else + message["from"] = from + "@" + this->served_hostname + "/" + who; + message["type"] = "groupchat"; + XmlSubNode subject(message, "subject"); + subject.set_inner(std::get<0>(topic)); + } this->send_stanza(message); } @@ -391,16 +388,18 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str else // Message from the room itself message["from"] = muc_name + "@" + this->served_hostname; message["type"] = "groupchat"; - XmlNode body("body"); - body.set_inner(std::get<0>(xmpp_body)); - message.add_child(std::move(body)); + + { + XmlSubNode body(message, "body"); + body.set_inner(std::get<0>(xmpp_body)); + } + if (std::get<1>(xmpp_body)) { - XmlNode html("html"); + XmlSubNode html(message, "html"); html["xmlns"] = XHTMLIM_NS; // Pass the ownership of the pointer to this xmlnode html.add_child(std::move(std::get<1>(xmpp_body))); - message.add_child(std::move(html)); } this->send_stanza(message); } @@ -415,41 +414,41 @@ void XmppComponent::send_history_message(const std::string& muc_name, const std: message["from"] = muc_name + "@" + this->served_hostname; message["type"] = "groupchat"; - XmlNode body("body"); - body.set_inner(body_txt); - message.add_child(std::move(body)); - - XmlNode delay("delay"); - delay["xmlns"] = DELAY_NS; - delay["from"] = muc_name + "@" + this->served_hostname; - delay["stamp"] = utils::to_string(timestamp); + { + XmlSubNode body(message, "body"); + body.set_inner(body_txt); + } + { + XmlSubNode delay(message, "delay"); + delay["xmlns"] = DELAY_NS; + delay["from"] = muc_name + "@" + this->served_hostname; + delay["stamp"] = utils::to_string(timestamp); + } - message.add_child(std::move(delay)); this->send_stanza(message); } void XmppComponent::send_muc_leave(const std::string& muc_name, std::string&& nick, Xmpp::body&& message, const std::string& jid_to, const bool self) { Stanza presence("presence"); - presence["to"] = jid_to; - presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; - presence["type"] = "unavailable"; - const std::string message_str = std::get<0>(message); - XmlNode x("x"); - x["xmlns"] = MUC_USER_NS; - if (self) - { - XmlNode status("status"); - status["code"] = "110"; - x.add_child(std::move(status)); - } - presence.add_child(std::move(x)); - if (!message_str.empty()) - { - XmlNode status("status"); - status.set_inner(message_str); - presence.add_child(std::move(status)); - } + { + presence["to"] = jid_to; + presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; + presence["type"] = "unavailable"; + const std::string message_str = std::get<0>(message); + XmlSubNode x(presence, "x"); + x["xmlns"] = MUC_USER_NS; + if (self) + { + XmlSubNode status(x, "status"); + status["code"] = "110"; + } + if (!message_str.empty()) + { + XmlSubNode status(presence, "status"); + status.set_inner(message_str); + } + } this->send_stanza(presence); } @@ -462,24 +461,22 @@ void XmppComponent::send_nick_change(const std::string& muc_name, const bool self) { Stanza presence("presence"); - presence["to"] = jid_to; - presence["from"] = muc_name + "@" + this->served_hostname + "/" + old_nick; - presence["type"] = "unavailable"; - XmlNode x("x"); - x["xmlns"] = MUC_USER_NS; - XmlNode item("item"); - item["nick"] = new_nick; - x.add_child(std::move(item)); - XmlNode status("status"); - status["code"] = "303"; - x.add_child(std::move(status)); - if (self) - { - XmlNode status2("status"); - status2["code"] = "110"; - x.add_child(std::move(status2)); - } - presence.add_child(std::move(x)); + { + presence["to"] = jid_to; + presence["from"] = muc_name + "@" + this->served_hostname + "/" + old_nick; + presence["type"] = "unavailable"; + XmlSubNode x(presence, "x"); + x["xmlns"] = MUC_USER_NS; + XmlSubNode item(x, "item"); + item["nick"] = new_nick; + XmlSubNode status(x, "status"); + status["code"] = "303"; + if (self) + { + XmlSubNode status(x, "status"); + status["code"] = "110"; + } + } this->send_stanza(presence); this->send_user_join(muc_name, new_nick, "", affiliation, role, jid_to, self); @@ -489,32 +486,28 @@ void XmppComponent::kick_user(const std::string& muc_name, const std::string& ta const std::string& author, const std::string& jid_to, const bool self) { Stanza presence("presence"); - presence["from"] = muc_name + "@" + this->served_hostname + "/" + target; - presence["to"] = jid_to; - presence["type"] = "unavailable"; - XmlNode x("x"); - x["xmlns"] = MUC_USER_NS; - XmlNode item("item"); - item["affiliation"] = "none"; - item["role"] = "none"; - XmlNode actor("actor"); - actor["nick"] = author; - actor["jid"] = author; // backward compatibility with old clients - item.add_child(std::move(actor)); - XmlNode reason("reason"); - reason.set_inner(txt); - item.add_child(std::move(reason)); - x.add_child(std::move(item)); - XmlNode status("status"); - status["code"] = "307"; - x.add_child(std::move(status)); - if (self) - { - XmlNode status("status"); - status["code"] = "110"; - x.add_child(std::move(status)); - } - presence.add_child(std::move(x)); + { + presence["from"] = muc_name + "@" + this->served_hostname + "/" + target; + presence["to"] = jid_to; + presence["type"] = "unavailable"; + XmlSubNode x(presence, "x"); + x["xmlns"] = MUC_USER_NS; + XmlSubNode item(x, "item"); + item["affiliation"] = "none"; + item["role"] = "none"; + XmlSubNode actor(item, "actor"); + actor["nick"] = author; + actor["jid"] = author; // backward compatibility with old clients + XmlSubNode reason(item, "reason"); + reason.set_inner(txt); + XmlSubNode status(x, "status"); + status["code"] = "307"; + if (self) + { + XmlSubNode status(x, "status"); + status["code"] = "110"; + } + } this->send_stanza(presence); } @@ -527,28 +520,26 @@ void XmppComponent::send_presence_error(const std::string& muc_name, const std::string& text) { Stanza presence("presence"); - presence["from"] = muc_name + "@" + this->served_hostname + "/" + nickname; - presence["to"] = jid_to; - presence["type"] = "error"; - XmlNode x("x"); - x["xmlns"] = MUC_NS; - presence.add_child(std::move(x)); - XmlNode error("error"); - error["by"] = muc_name + "@" + this->served_hostname; - error["type"] = type; - if (!text.empty()) - { - XmlNode text_node("text"); - text_node["xmlns"] = STANZA_NS; - text_node.set_inner(text); - error.add_child(std::move(text_node)); - } - if (!error_code.empty()) - error["code"] = error_code; - XmlNode subnode(condition); - subnode["xmlns"] = STANZA_NS; - error.add_child(std::move(subnode)); - presence.add_child(std::move(error)); + { + presence["from"] = muc_name + "@" + this->served_hostname + "/" + nickname; + presence["to"] = jid_to; + presence["type"] = "error"; + XmlSubNode x(presence, "x"); + x["xmlns"] = MUC_NS; + XmlSubNode error(presence, "error"); + error["by"] = muc_name + "@" + this->served_hostname; + error["type"] = type; + if (!text.empty()) + { + XmlSubNode text_node(error, "text"); + text_node["xmlns"] = STANZA_NS; + text_node.set_inner(text); + } + if (!error_code.empty()) + error["code"] = error_code; + XmlSubNode subnode(error, condition); + subnode["xmlns"] = STANZA_NS; + } this->send_stanza(presence); } @@ -559,15 +550,15 @@ void XmppComponent::send_affiliation_role_change(const std::string& muc_name, const std::string& jid_to) { Stanza presence("presence"); - presence["from"] = muc_name + "@" + this->served_hostname + "/" + target; - presence["to"] = jid_to; - XmlNode x("x"); - x["xmlns"] = MUC_USER_NS; - XmlNode item("item"); - item["affiliation"] = affiliation; - item["role"] = role; - x.add_child(std::move(item)); - presence.add_child(std::move(x)); + { + presence["from"] = muc_name + "@" + this->served_hostname + "/" + target; + presence["to"] = jid_to; + XmlSubNode x(presence, "x"); + x["xmlns"] = MUC_USER_NS; + XmlSubNode item(x, "item"); + item["affiliation"] = affiliation; + item["role"] = role; + } this->send_stanza(presence); } @@ -579,27 +570,30 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t iq["id"] = id; iq["to"] = jid_to; iq["from"] = jid_from; - XmlNode query("query"); - query["xmlns"] = VERSION_NS; - if (version.empty()) - { - XmlNode name("name"); - name.set_inner("biboumi"); - query.add_child(std::move(name)); - XmlNode version("version"); - version.set_inner(SOFTWARE_VERSION); - query.add_child(std::move(version)); - XmlNode os("os"); - os.set_inner(SYSTEM_NAME); - query.add_child(std::move(os)); + { + XmlSubNode query(iq, "query"); + query["xmlns"] = VERSION_NS; + if (version.empty()) + { + { + XmlSubNode name(query, "name"); + name.set_inner("biboumi"); + } + { + XmlSubNode version(query, "version"); + version.set_inner(SOFTWARE_VERSION); + } + { + XmlSubNode os(query, "os"); + os.set_inner(SYSTEM_NAME); + } } - else + else { - XmlNode name("name"); + XmlSubNode name(query, "name"); name.set_inner(version); - query.add_child(std::move(name)); } - iq.add_child(std::move(query)); + } this->send_stanza(iq); } @@ -608,24 +602,24 @@ void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::s const bool with_admin_only, const AdhocCommandsHandler& adhoc_handler) { Stanza iq("iq"); - iq["type"] = "result"; - iq["id"] = id; - iq["to"] = requester_jid; - iq["from"] = from_jid; - XmlNode query("query"); - query["xmlns"] = DISCO_ITEMS_NS; - query["node"] = ADHOC_NS; - for (const auto& kv: adhoc_handler.get_commands()) - { - if (kv.second.is_admin_only() && !with_admin_only) - continue; - XmlNode item("item"); - item["jid"] = from_jid; - item["node"] = kv.first; - item["name"] = kv.second.name; - query.add_child(std::move(item)); - } - iq.add_child(std::move(query)); + { + iq["type"] = "result"; + iq["id"] = id; + iq["to"] = requester_jid; + iq["from"] = from_jid; + XmlSubNode query(iq, "query"); + query["xmlns"] = DISCO_ITEMS_NS; + query["node"] = ADHOC_NS; + for (const auto &kv: adhoc_handler.get_commands()) + { + if (kv.second.is_admin_only() && !with_admin_only) + continue; + XmlSubNode item(query, "item"); + item["jid"] = from_jid; + item["node"] = kv.first; + item["name"] = kv.second.name; + } + } this->send_stanza(iq); } @@ -633,13 +627,14 @@ void XmppComponent::send_iq_version_request(const std::string& from, const std::string& jid_to) { Stanza iq("iq"); - iq["type"] = "get"; - iq["id"] = "version_"s + XmppComponent::next_id(); - iq["from"] = from + "@" + this->served_hostname; - iq["to"] = jid_to; - XmlNode query("query"); - query["xmlns"] = VERSION_NS; - iq.add_child(std::move(query)); + { + iq["type"] = "get"; + iq["id"] = "version_"s + XmppComponent::next_id(); + iq["from"] = from + "@" + this->served_hostname; + iq["to"] = jid_to; + XmlSubNode query(iq, "query"); + query["xmlns"] = VERSION_NS; + } this->send_stanza(iq); } diff --git a/louloulibs/xmpp/xmpp_stanza.hpp b/louloulibs/xmpp/xmpp_stanza.hpp index 4ca758e..f4b3948 100644 --- a/louloulibs/xmpp/xmpp_stanza.hpp +++ b/louloulibs/xmpp/xmpp_stanza.hpp @@ -143,4 +143,18 @@ std::ostream& operator<<(std::ostream& os, const XmlNode& node); */ using Stanza = XmlNode; +class XmlSubNode: public XmlNode +{ +public: + XmlSubNode(XmlNode& parent_ref, const std::string& name): + XmlNode(name), + parent_to_add(parent_ref) + {} + ~XmlSubNode() + { + this->parent_to_add.add_child(std::move(*this)); + } +private: + XmlNode& parent_to_add; +}; \ No newline at end of file -- cgit v1.2.3