Add an ad-hoc configure command on IRC channels
Include encodingIn and encodingOut options, unused at the moment
This commit is contained in:
@@ -312,6 +312,96 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
|
|||||||
command_node.add_child(std::move(error));
|
command_node.add_child(std::move(error));
|
||||||
session.terminate();
|
session.terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureIrcChannelStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node)
|
||||||
|
{
|
||||||
|
const Jid owner(session.get_owner_jid());
|
||||||
|
const Jid target(session.get_target_jid());
|
||||||
|
const Iid iid(target.local);
|
||||||
|
auto options = Database::get_irc_channel_options_with_server_default(owner.local + "@" + owner.domain,
|
||||||
|
iid.get_server(), iid.get_local());
|
||||||
|
|
||||||
|
XmlNode x("jabber:x:data:x");
|
||||||
|
x["type"] = "form";
|
||||||
|
XmlNode title("title");
|
||||||
|
title.set_inner("Configure the IRC channel "s + iid.get_local() + " on server "s + iid.get_server());
|
||||||
|
x.add_child(std::move(title));
|
||||||
|
XmlNode instructions("instructions");
|
||||||
|
instructions.set_inner("Edit the form, to configure the settings of the IRC channel "s + iid.get_local());
|
||||||
|
x.add_child(std::move(instructions));
|
||||||
|
|
||||||
|
XmlNode required("required");
|
||||||
|
|
||||||
|
XmlNode encoding_out("field");
|
||||||
|
encoding_out["var"] = "encoding_out";
|
||||||
|
encoding_out["type"] = "text-single";
|
||||||
|
encoding_out["desc"] = "The encoding used when sending messages to the IRC server. Defaults to the server's “out encoding” if unset for the channel";
|
||||||
|
encoding_out["label"] = "Out encoding";
|
||||||
|
if (!options.encodingOut.value().empty())
|
||||||
|
{
|
||||||
|
XmlNode encoding_out_value("value");
|
||||||
|
encoding_out_value.set_inner(options.encodingOut.value());
|
||||||
|
encoding_out.add_child(std::move(encoding_out_value));
|
||||||
|
}
|
||||||
|
encoding_out.add_child(required);
|
||||||
|
x.add_child(std::move(encoding_out));
|
||||||
|
|
||||||
|
XmlNode encoding_in("field");
|
||||||
|
encoding_in["var"] = "encoding_in";
|
||||||
|
encoding_in["type"] = "text-single";
|
||||||
|
encoding_in["desc"] = "The encoding used to decode message received from the IRC server. Defaults to the server's “in encoding” if unset for the channel";
|
||||||
|
encoding_in["label"] = "In encoding";
|
||||||
|
if (!options.encodingIn.value().empty())
|
||||||
|
{
|
||||||
|
XmlNode encoding_in_value("value");
|
||||||
|
encoding_in_value.set_inner(options.encodingIn.value());
|
||||||
|
encoding_in.add_child(std::move(encoding_in_value));
|
||||||
|
}
|
||||||
|
encoding_in.add_child(required);
|
||||||
|
x.add_child(std::move(encoding_in));
|
||||||
|
|
||||||
|
command_node.add_child(std::move(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node)
|
||||||
|
{
|
||||||
|
const XmlNode* x = command_node.get_child("x", "jabber:x:data");
|
||||||
|
if (x)
|
||||||
|
{
|
||||||
|
const Jid owner(session.get_owner_jid());
|
||||||
|
const Jid target(session.get_target_jid());
|
||||||
|
const Iid iid(target.local);
|
||||||
|
auto options = Database::get_irc_channel_options(owner.local + "@" + owner.domain,
|
||||||
|
iid.get_server(), iid.get_local());
|
||||||
|
for (const XmlNode* field: x->get_children("field", "jabber:x:data"))
|
||||||
|
{
|
||||||
|
const XmlNode* value = field->get_child("value", "jabber:x:data");
|
||||||
|
|
||||||
|
if (field->get_tag("var") == "encoding_out" &&
|
||||||
|
value && !value->get_inner().empty())
|
||||||
|
options.encodingOut = value->get_inner();
|
||||||
|
|
||||||
|
else if (field->get_tag("var") == "encoding_in" &&
|
||||||
|
value && !value->get_inner().empty())
|
||||||
|
options.encodingIn = value->get_inner();
|
||||||
|
}
|
||||||
|
|
||||||
|
options.update();
|
||||||
|
|
||||||
|
command_node.delete_all_children();
|
||||||
|
XmlNode note("note");
|
||||||
|
note["type"] = "info";
|
||||||
|
note.set_inner("Configuration successfully applied.");
|
||||||
|
command_node.add_child(std::move(note));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
XmlNode error(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));
|
||||||
|
session.terminate();
|
||||||
|
}
|
||||||
#endif // USE_DATABASE
|
#endif // USE_DATABASE
|
||||||
|
|
||||||
void DisconnectUserFromServerStep1(XmppComponent& xmpp_component, AdhocSession& session, XmlNode& command_node)
|
void DisconnectUserFromServerStep1(XmppComponent& xmpp_component, AdhocSession& session, XmlNode& command_node)
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ void DisconnectUserStep2(XmppComponent&, AdhocSession& session, XmlNode& command
|
|||||||
void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
|
|
||||||
|
void ConfigureIrcChannelStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
|
void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
|
|
||||||
void DisconnectUserFromServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void DisconnectUserFromServerStep1(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
void DisconnectUserFromServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void DisconnectUserFromServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
void DisconnectUserFromServerStep3(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
void DisconnectUserFromServerStep3(XmppComponent&, AdhocSession& session, XmlNode& command_node);
|
||||||
|
|||||||
@@ -43,7 +43,8 @@ static std::set<std::string> kickable_errors{
|
|||||||
|
|
||||||
BiboumiComponent::BiboumiComponent(std::shared_ptr<Poller> poller, const std::string& hostname, const std::string& secret):
|
BiboumiComponent::BiboumiComponent(std::shared_ptr<Poller> poller, const std::string& hostname, const std::string& secret):
|
||||||
XmppComponent(poller, hostname, secret),
|
XmppComponent(poller, hostname, secret),
|
||||||
irc_server_adhoc_commands_handler(*this)
|
irc_server_adhoc_commands_handler(*this),
|
||||||
|
irc_channel_adhoc_commands_handler(*this)
|
||||||
{
|
{
|
||||||
this->stanza_handlers.emplace("presence",
|
this->stanza_handlers.emplace("presence",
|
||||||
std::bind(&BiboumiComponent::handle_presence, this,std::placeholders::_1));
|
std::bind(&BiboumiComponent::handle_presence, this,std::placeholders::_1));
|
||||||
@@ -65,6 +66,9 @@ BiboumiComponent::BiboumiComponent(std::shared_ptr<Poller> poller, const std::st
|
|||||||
{"configure", AdhocCommand({&ConfigureIrcServerStep1, &ConfigureIrcServerStep2}, "Configure a few settings for that IRC server", false)},
|
{"configure", AdhocCommand({&ConfigureIrcServerStep1, &ConfigureIrcServerStep2}, "Configure a few settings for that IRC server", false)},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
this->irc_channel_adhoc_commands_handler.get_commands() = {
|
||||||
|
{"configure", AdhocCommand({&ConfigureIrcChannelStep1, &ConfigureIrcChannelStep2}, "Configure a few settings for that IRC channel", false)},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void BiboumiComponent::shutdown()
|
void BiboumiComponent::shutdown()
|
||||||
@@ -331,6 +335,8 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
|
|||||||
AdhocCommandsHandler* adhoc_handler;
|
AdhocCommandsHandler* adhoc_handler;
|
||||||
if (!to.local.empty() && !iid.is_user && !iid.is_channel)
|
if (!to.local.empty() && !iid.is_user && !iid.is_channel)
|
||||||
adhoc_handler = &this->irc_server_adhoc_commands_handler;
|
adhoc_handler = &this->irc_server_adhoc_commands_handler;
|
||||||
|
else if (!to.local.empty() && iid.is_channel)
|
||||||
|
adhoc_handler = &this->irc_channel_adhoc_commands_handler;
|
||||||
else
|
else
|
||||||
adhoc_handler = &this->adhoc_commands_handler;
|
adhoc_handler = &this->adhoc_commands_handler;
|
||||||
|
|
||||||
@@ -407,6 +413,14 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
|
|||||||
this->irc_server_adhoc_commands_handler);
|
this->irc_server_adhoc_commands_handler);
|
||||||
stanza_error.disable();
|
stanza_error.disable();
|
||||||
}
|
}
|
||||||
|
else if (!iid.is_user && iid.is_channel)
|
||||||
|
{ // Get the channel's adhoc commands
|
||||||
|
this->send_adhoc_commands_list(id, from, to_str,
|
||||||
|
(Config::get("admin", "") ==
|
||||||
|
from_jid.bare()),
|
||||||
|
this->irc_channel_adhoc_commands_handler);
|
||||||
|
stanza_error.disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (node.empty() && !iid.is_user && !iid.is_channel)
|
else if (node.empty() && !iid.is_user && !iid.is_channel)
|
||||||
{ // Disco on an IRC server: get the list of channels
|
{ // Disco on an IRC server: get the list of channels
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ private:
|
|||||||
std::unordered_map<std::string, std::unique_ptr<Bridge>> bridges;
|
std::unordered_map<std::string, std::unique_ptr<Bridge>> bridges;
|
||||||
|
|
||||||
AdhocCommandsHandler irc_server_adhoc_commands_handler;
|
AdhocCommandsHandler irc_server_adhoc_commands_handler;
|
||||||
|
AdhocCommandsHandler irc_channel_adhoc_commands_handler;
|
||||||
|
|
||||||
BiboumiComponent(const BiboumiComponent&) = delete;
|
BiboumiComponent(const BiboumiComponent&) = delete;
|
||||||
BiboumiComponent(BiboumiComponent&&) = delete;
|
BiboumiComponent(BiboumiComponent&&) = delete;
|
||||||
|
|||||||
Reference in New Issue
Block a user