Use a db roster to manage biboumi’s presence with the contacts

This commit is contained in:
louiz’
2017-07-16 00:16:43 +02:00
parent b233470710
commit 84034ed3dc
4 changed files with 126 additions and 4 deletions
+58 -3
View File
@@ -83,6 +83,15 @@ void BiboumiComponent::shutdown()
{
for (auto& pair: this->bridges)
pair.second->shutdown("Gateway shutdown");
#ifdef USE_DATABASE
const auto full_roster = Database::get_full_roster();
for (const Database::RosterItem& roster_item: full_roster)
{
this->send_presence_to_contact(roster_item.col<Database::LocalJid>(),
roster_item.col<Database::RemoteJid>(),
"unavailable");
}
#endif
}
void BiboumiComponent::clean()
@@ -160,10 +169,28 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
{
if (type == "subscribe")
{ // Auto-accept any subscription request for an IRC server
this->accept_subscription(to_str, from.bare());
this->ask_subscription(to_str, from.bare());
this->send_presence_to_contact(to_str, from.bare(), "subscribed", id);
if (iid.type == Iid::Type::None)
this->send_presence_to_contact(to_str, from.bare(), "");
this->send_presence_to_contact(to_str, from.bare(), "subscribe");
#ifdef USE_DATABASE
if (!Database::has_roster_item(to_str, from.bare()))
Database::add_roster_item(to_str, from.bare());
#endif
}
else if (type == "unsubscribe")
{
#ifdef USE_DATABASE
const bool res = Database::has_roster_item(to_str, from.bare());
if (res)
Database::delete_roster_item(to_str, from.bare());
#endif
}
else if (type.empty())
{ // We just receive a presence from someone (as the result of a probe,
// or a directed presence, or a normal presence change)
this->send_presence_to_contact(to_str, from.bare(), "");
}
}
else
{
@@ -979,3 +1006,31 @@ void BiboumiComponent::ask_subscription(const std::string& from, const std::stri
presence["type"] = "subscribe";
this->send_stanza(presence);
}
void BiboumiComponent::send_presence_to_contact(const std::string& from, const std::string& to,
const std::string& type, const std::string& id)
{
Stanza presence("presence");
presence["from"] = from;
presence["to"] = to;
if (!type.empty())
presence["type"] = type;
if (!id.empty())
presence["id"] = id;
this->send_stanza(presence);
}
void BiboumiComponent::after_handshake()
{
XmppComponent::after_handshake();
#ifdef USE_DATABASE
const auto contacts = Database::get_contact_list(this->get_served_hostname());
for (const Database::RosterItem& roster_item: contacts)
{
const auto remote_jid = roster_item.col<Database::RemoteJid>();
this->send_presence_to_contact(this->get_served_hostname(), remote_jid, "probe");
}
#endif
}
+3
View File
@@ -36,6 +36,8 @@ public:
BiboumiComponent& operator=(const BiboumiComponent&) = delete;
BiboumiComponent& operator=(BiboumiComponent&&) = delete;
void after_handshake() override final;
/**
* Returns the bridge for the given user. If it does not exist, return
* nullptr.
@@ -87,6 +89,7 @@ public:
void send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick);
void accept_subscription(const std::string& from, const std::string& to);
void ask_subscription(const std::string& from, const std::string& to);
void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id="");
/**
* Handle the various stanza types
*/