Don’t treat presence updates as MUC joins
If the user sends a directed presence to an unjoined MUC without a <x/> element, send a presence error back instead of attempting to join it again, as this is almost never what the user wants. Fixes #3415.
This commit is contained in:
committed by
louiz’
parent
440e04c6ba
commit
14fe971183
@@ -170,8 +170,7 @@ IrcClient* Bridge::find_irc_client(const std::string& hostname) const
|
|||||||
bool Bridge::join_irc_channel(const Iid& iid, std::string nickname,
|
bool Bridge::join_irc_channel(const Iid& iid, std::string nickname,
|
||||||
const std::string& password,
|
const std::string& password,
|
||||||
const std::string& resource,
|
const std::string& resource,
|
||||||
HistoryLimit history_limit,
|
HistoryLimit history_limit)
|
||||||
const bool force_join)
|
|
||||||
{
|
{
|
||||||
const auto& hostname = iid.get_server();
|
const auto& hostname = iid.get_server();
|
||||||
#ifdef USE_DATABASE
|
#ifdef USE_DATABASE
|
||||||
@@ -189,8 +188,8 @@ bool Bridge::join_irc_channel(const Iid& iid, std::string nickname,
|
|||||||
{
|
{
|
||||||
irc->send_join_command(iid.get_local(), password);
|
irc->send_join_command(iid.get_local(), password);
|
||||||
return true;
|
return true;
|
||||||
} else if (!res_in_chan || force_join) {
|
} else {
|
||||||
// See https://github.com/xsf/xeps/pull/499 for the force_join argument
|
// See https://github.com/xsf/xeps/pull/499
|
||||||
this->generate_channel_join_for_resource(iid, resource);
|
this->generate_channel_join_for_resource(iid, resource);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -72,14 +72,12 @@ public:
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to join an irc_channel, does nothing and return true if the channel
|
* Try to join an irc_channel.
|
||||||
* was already joined.
|
|
||||||
*/
|
*/
|
||||||
bool join_irc_channel(const Iid& iid, std::string nickname,
|
bool join_irc_channel(const Iid& iid, std::string nickname,
|
||||||
const std::string& password,
|
const std::string& password,
|
||||||
const std::string& resource,
|
const std::string& resource,
|
||||||
HistoryLimit history_limit,
|
HistoryLimit history_limit);
|
||||||
const bool force_join);
|
|
||||||
|
|
||||||
void send_channel_message(const Iid& iid, const std::string& body, std::string id);
|
void send_channel_message(const Iid& iid, const std::string& body, std::string id);
|
||||||
void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG");
|
void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG");
|
||||||
|
|||||||
@@ -158,8 +158,24 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
|
|||||||
{
|
{
|
||||||
const std::string own_nick = bridge->get_own_nick(iid);
|
const std::string own_nick = bridge->get_own_nick(iid);
|
||||||
const XmlNode* x = stanza.get_child("x", MUC_NS);
|
const XmlNode* x = stanza.get_child("x", MUC_NS);
|
||||||
const XmlNode* password = x ? x->get_child("password", MUC_NS): nullptr;
|
const IrcClient* irc = bridge->find_irc_client(iid.get_server());
|
||||||
const XmlNode* history = x ? x->get_child("history", MUC_NS): nullptr;
|
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 (!x)
|
||||||
|
{ // send an error if we are not joined yet, instead of treating it as a join
|
||||||
|
this->send_stanza_error("presence", from_str, to_str, id,
|
||||||
|
"modify", "not-acceptable",
|
||||||
|
"You are not joined to this MUC.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if there is no <x/>, this is a presence status update, we don’t care about those
|
||||||
|
if (x)
|
||||||
|
{
|
||||||
|
const XmlNode* password = x->get_child("password", MUC_NS);
|
||||||
|
const XmlNode* history = x->get_child("history", MUC_NS);
|
||||||
HistoryLimit history_limit;
|
HistoryLimit history_limit;
|
||||||
if (history)
|
if (history)
|
||||||
{
|
{
|
||||||
@@ -184,13 +200,7 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
|
|||||||
history_limit.stanzas = 0;
|
history_limit.stanzas = 0;
|
||||||
}
|
}
|
||||||
bridge->join_irc_channel(iid, to.resource, password ? password->get_inner(): "",
|
bridge->join_irc_channel(iid, to.resource, password ? password->get_inner(): "",
|
||||||
from.resource, history_limit, x != nullptr);
|
from.resource, history_limit);
|
||||||
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")
|
else if (type == "unavailable")
|
||||||
|
|||||||
Reference in New Issue
Block a user