summaryrefslogtreecommitdiff
path: root/src/xmpp/biboumi_component.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp/biboumi_component.cpp')
-rw-r--r--src/xmpp/biboumi_component.cpp63
1 files changed, 50 insertions, 13 deletions
diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index be34873..6fe6972 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -102,8 +102,8 @@ void BiboumiComponent::shutdown()
void BiboumiComponent::clean()
{
- auto it = this->bridges.begin();
- while (it != this->bridges.end())
+ auto it = std::begin(this->bridges);
+ while (it != std::end(this->bridges))
{
it->second->clean();
if (it->second->active_clients() == 0)
@@ -185,8 +185,13 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
}
bridge->join_irc_channel(iid, to.resource, password ? password->get_inner(): "",
from.resource, history_limit, x != nullptr);
- if (!own_nick.empty() && own_nick != to.resource)
- bridge->send_irc_nick_change(iid, to.resource, from.resource);
+ const IrcClient* irc = bridge->find_irc_client(iid.get_server());
+ if (irc)
+ {
+ const auto chan = irc->find_channel(iid.get_local());
+ if (chan->joined)
+ bridge->send_irc_nick_change(iid, to.resource, from.resource);
+ }
}
else if (type == "unavailable")
{
@@ -273,9 +278,10 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
std::string error_type("cancel");
std::string error_name("internal-server-error");
- utils::ScopeGuard stanza_error([this, &from_str, &to_str, &id, &error_type, &error_name](){
+ std::string error_text{};
+ utils::ScopeGuard stanza_error([this, &from_str, &to_str, &id, &error_type, &error_name, &error_text](){
this->send_stanza_error("message", from_str, to_str, id,
- error_type, error_name, "");
+ error_type, error_name, error_text);
});
const XmlNode* body = stanza.get_child("body", COMPONENT_NS);
@@ -284,7 +290,15 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
{
if (body && !body->get_inner().empty())
{
- bridge->send_channel_message(iid, body->get_inner(), id);
+ if (bridge->is_resource_in_chan(iid.to_tuple(), from.resource))
+ bridge->send_channel_message(iid, body->get_inner(), id);
+ else
+ {
+ error_type = "modify";
+ error_name = "not-acceptable";
+ error_text = "You are not a participant in this room.";
+ return;
+ }
}
const XmlNode* subject = stanza.get_child("subject", COMPONENT_NS);
if (subject)
@@ -350,7 +364,6 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
this->send_invitation_from_fulljid(std::to_string(iid), invite_to, from_str);
}
}
-
}
} catch (const IRCNotConnected& ex)
{
@@ -514,7 +527,11 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
{
if (node.empty())
{
- this->send_irc_channel_disco_info(id, from, to_str);
+ const IrcClient* irc_client = bridge->find_irc_client(iid.get_server());
+ const IrcChannel* irc_channel{};
+ if (irc_client)
+ irc_channel = irc_client->find_channel(iid.get_local());
+ this->send_irc_channel_disco_info(id, from, to_str, irc_channel);
stanza_error.disable();
}
else if (node == MUC_TRAFFIC_NS)
@@ -592,7 +609,6 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
const XmlNode* max = set_node->get_child("max", RSM_NS);
if (max)
rs_info.max = std::atoi(max->get_inner().data());
-
}
if (rs_info.max == -1)
rs_info.max = 100;
@@ -751,7 +767,7 @@ bool BiboumiComponent::handle_mam_request(const Stanza& stanza)
if (limit < 0 || limit > 100)
limit = 100;
auto result = Database::get_muc_logs(from.bare(), iid.get_local(), iid.get_server(),
- limit,
+ static_cast<std::size_t>(limit),
start, end,
reference_record_id, paging_order);
bool complete = std::get<bool>(result);
@@ -964,7 +980,8 @@ void BiboumiComponent::send_irc_channel_muc_traffic_info(const std::string& id,
this->send_stanza(iq);
}
-void BiboumiComponent::send_irc_channel_disco_info(const std::string& id, const std::string& jid_to, const std::string& jid_from)
+void BiboumiComponent::send_irc_channel_disco_info(const std::string& id, const std::string& jid_to,
+ const std::string& jid_from, const IrcChannel* irc_channel)
{
Jid from(jid_from);
Iid iid(from.local, {});
@@ -980,11 +997,31 @@ void BiboumiComponent::send_irc_channel_disco_info(const std::string& id, const
identity["category"] = "conference";
identity["type"] = "irc";
identity["name"] = ""s + iid.get_local() + " on " + iid.get_server();
- for (const char *ns: {DISCO_INFO_NS, MUC_NS, ADHOC_NS, PING_NS, MAM_NS, VERSION_NS, STABLE_MUC_ID_NS})
+ for (const char *ns: {DISCO_INFO_NS, MUC_NS, ADHOC_NS, PING_NS, MAM_NS, VERSION_NS, STABLE_MUC_ID_NS, SELF_PING_FLAG, "muc_nonanonymous"})
{
XmlSubNode feature(query, "feature");
feature["var"] = ns;
}
+
+ XmlSubNode x(query, "x");
+ x["xmlns"] = DATAFORM_NS;
+ x["type"] = "result";
+ {
+ XmlSubNode field(x, "field");
+ field["var"] = "FORM_TYPE";
+ field["type"] = "hidden";
+ XmlSubNode value(field, "value");
+ value.set_inner("http://jabber.org/protocol/muc#roominfo");
+ }
+
+ if (irc_channel && irc_channel->joined)
+ {
+ XmlSubNode field(x, "field");
+ field["var"] = "muc#roominfo_occupants";
+ field["label"] = "Number of occupants";
+ XmlSubNode value(field, "value");
+ value.set_inner(std::to_string(irc_channel->get_users().size()));
+ }
}
this->send_stanza(iq);
}