Basic User and UserManager classes
This commit is contained in:
parent
5c45d68996
commit
2ae880ff94
12 changed files with 213 additions and 116 deletions
|
@ -26,9 +26,10 @@ int main(void)
|
|||
std::cout << "Can't connect to database.\n";
|
||||
}
|
||||
|
||||
UserManager userManager(&transport);
|
||||
UserManager userManager(&transport, &sql);
|
||||
UserRegistration userRegistration(&transport, &userManager, &sql);
|
||||
logger.setUserRegistration(&userRegistration);
|
||||
logger.setUserManager(&userManager);
|
||||
|
||||
transport.connect();
|
||||
eventLoop.run();
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
namespace Transport {
|
||||
|
||||
/// Represents variable:value pairs.
|
||||
typedef boost::program_options::variables_map Variables;
|
||||
|
||||
/// Represents config file.
|
||||
|
|
|
@ -52,6 +52,10 @@ class Logger
|
|||
/// \param userRegistration userRegistration class
|
||||
void setUserRegistration(UserRegistration *userRegistration);
|
||||
|
||||
/// Starts logging data related to UserManager class.
|
||||
/// \param userManager userManager class
|
||||
void setUserManager(UserManager *userManager);
|
||||
|
||||
private:
|
||||
// Component
|
||||
void handleConnected();
|
||||
|
@ -66,6 +70,10 @@ class Logger
|
|||
void handleUserRegistered(const UserInfo &user);
|
||||
void handleUserUnregistered(const UserInfo &user);
|
||||
void handleUserUpdated(const UserInfo &user);
|
||||
|
||||
// UserManager
|
||||
void handleUserCreated(User *user);
|
||||
void handleUserDestroyed(User *user);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -65,6 +65,16 @@ namespace Transport {
|
|||
/// Component destructor.
|
||||
~Component();
|
||||
|
||||
/// Returns Swift::Component associated with this Transport::Component.
|
||||
/// You can use it to send presences and other stanzas.
|
||||
/// \return Swift::Component associated with this Transport::Component
|
||||
Swift::Component *getComponent();
|
||||
|
||||
/// Returns Swift::PresenceOracle associated with this Transport::Component.
|
||||
/// You can use it to check current resource connected for particular user.
|
||||
/// \return Swift::PresenceOracle associated with this Transport::Component
|
||||
Swift::PresenceOracle *getPresenceOracle();
|
||||
|
||||
/// Connects the Jabber server.
|
||||
/// \see Component()
|
||||
void connect();
|
||||
|
|
|
@ -24,26 +24,48 @@
|
|||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/Presence/PresenceOracle.h"
|
||||
#include "Swiften/Disco/EntityCapsManager.h"
|
||||
#include "storagebackend.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
struct UserInfo;
|
||||
|
||||
// Representation of XMPP User
|
||||
/// Represents online XMPP user.
|
||||
class User {
|
||||
public:
|
||||
User(const Swift::JID &jid, const std::string &username, const std::string &password, Component * component);
|
||||
/// Creates new User class.
|
||||
/// \param jid XMPP JID associated with this user
|
||||
/// \param userInfo UserInfo struct with informations needed to connect
|
||||
/// this user to legacy network
|
||||
/// \param component Component associated with this user
|
||||
User(const Swift::JID &jid, UserInfo &userInfo, Component * component);
|
||||
|
||||
/// Destroyes User.
|
||||
virtual ~User();
|
||||
|
||||
/// Returns JID of XMPP user who is currently connected using this User class.
|
||||
/// \return full JID
|
||||
const Swift::JID &getJID();
|
||||
|
||||
/// Returns UserInfo struct with informations needed to connect the legacy network.
|
||||
/// \return UserInfo struct
|
||||
UserInfo &getUserInfo() { return m_userInfo; }
|
||||
|
||||
/// Handles presence from XMPP JID associated with this user.
|
||||
/// \param presence Swift::Presence.
|
||||
void handlePresence(Swift::Presence::ref presence);
|
||||
|
||||
/// Returns language.
|
||||
/// \return language
|
||||
const char *getLang() { return "en"; }
|
||||
|
||||
private:
|
||||
Swift::JID m_jid;
|
||||
Swift::Component *m_component;
|
||||
Component *m_component;
|
||||
Swift::EntityCapsManager *m_entityCapsManager;
|
||||
Swift::PresenceOracle *m_presenceOracle;
|
||||
UserInfo m_userInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,28 +28,53 @@ namespace Transport {
|
|||
|
||||
class User;
|
||||
class Component;
|
||||
class StorageBackend;
|
||||
|
||||
// Class for managing online XMPP users.
|
||||
class UserManager
|
||||
{
|
||||
/// Manages online XMPP Users.
|
||||
|
||||
/// This class handles presences and creates User classes when new user connects.
|
||||
/// It also removes the User class once the last user's resource disconnected.
|
||||
class UserManager {
|
||||
public:
|
||||
UserManager(Component *component);
|
||||
/// Creates new UserManager.
|
||||
/// \param component Component which's presence will be handled
|
||||
/// \param storageBackend Storage backend used to fetch UserInfos
|
||||
UserManager(Component *component, StorageBackend *storageBackend);
|
||||
|
||||
/// Destroys UserManager.
|
||||
~UserManager();
|
||||
|
||||
// User *
|
||||
User *getUserByJID(const std::string &barejid);
|
||||
/// Returns user according to his bare JID.
|
||||
/// \param barejid bare JID of user
|
||||
/// \return User class associated with this user
|
||||
User *getUser(const std::string &barejid);
|
||||
|
||||
// Returns count of online users;
|
||||
int userCount();
|
||||
/// Returns number of online users.
|
||||
/// \return number of online users
|
||||
int getUserCount();
|
||||
|
||||
void removeUser(User *user) {}
|
||||
/// Removes user. This function disconnects user and safely removes
|
||||
/// User class. This does *not* remove user from database.
|
||||
/// \param user User class to remove
|
||||
void removeUser(User *user);
|
||||
|
||||
/// Called when new User class is created.
|
||||
/// \param user newly created User class
|
||||
boost::signal<void (User *user)> onUserCreated;
|
||||
|
||||
/// Called when User class is going to be removed
|
||||
/// \param user removed User class
|
||||
boost::signal<void (User *user)> onUserDestroyed;
|
||||
|
||||
private:
|
||||
void handlePresence(Swift::Presence::ref presence);
|
||||
void addUser(User *user);
|
||||
|
||||
long m_onlineBuddies;
|
||||
User *m_cachedUser;
|
||||
std::map<std::string, User *> m_users;
|
||||
Component *m_component;
|
||||
StorageBackend *m_storageBackend;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -33,20 +33,40 @@ class StorageBackend;
|
|||
class UserManager;
|
||||
class Config;
|
||||
|
||||
/// Allows users to register the transport using service discovery.
|
||||
class UserRegistration : Swift::GetResponder<Swift::InBandRegistrationPayload>, Swift::SetResponder<Swift::InBandRegistrationPayload> {
|
||||
public:
|
||||
/// Creates new UserRegistration handler.
|
||||
/// \param component Component associated with this class
|
||||
/// \param userManager UserManager associated with this class
|
||||
/// \param storageBackend StorageBackend where the registered users will be stored
|
||||
UserRegistration(Component *component, UserManager *userManager, StorageBackend *storageBackend);
|
||||
|
||||
/// Destroys UserRegistration.
|
||||
~UserRegistration();
|
||||
|
||||
// Registers new user, returns false if user was already registered.
|
||||
bool registerUser(const UserInfo &user);
|
||||
/// Registers new user. This function stores user into database and subscribe user to transport.
|
||||
/// \param userInfo UserInfo struct with informations about registered user
|
||||
/// \return false if user is already registered
|
||||
bool registerUser(const UserInfo &userInfo);
|
||||
|
||||
// Unregisters user, returns true if user was successfully unregistered.
|
||||
/// Unregisters user. This function removes all data about user from databa, unsubscribe all buddies
|
||||
/// managed by this transport and disconnects user if he's connected.
|
||||
/// \param barejid bare JID of user to unregister
|
||||
/// \return false if there is no such user registered
|
||||
bool unregisterUser(const std::string &barejid);
|
||||
|
||||
boost::signal<void (const UserInfo &user)> onUserRegistered;
|
||||
boost::signal<void (const UserInfo &user)> onUserUnregistered;
|
||||
boost::signal<void (const UserInfo &user)> onUserUpdated;
|
||||
/// Called when new user has been registered.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserRegistered;
|
||||
|
||||
/// Called when user has been unregistered.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserUnregistered;
|
||||
|
||||
/// Called when user's registration has been updated.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserUpdated;
|
||||
|
||||
private:
|
||||
bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
|
||||
|
|
|
@ -50,6 +50,10 @@ void Logger::setUserRegistration(UserRegistration *userRegistration) {
|
|||
userRegistration->onUserUpdated.connect(bind(&Logger::handleUserUpdated, this, _1));
|
||||
}
|
||||
|
||||
void Logger::setUserManager(UserManager *userManager) {
|
||||
userManager->onUserCreated.connect(bind(&Logger::handleUserCreated, this, _1));
|
||||
userManager->onUserDestroyed.connect(bind(&Logger::handleUserDestroyed, this, _1));
|
||||
}
|
||||
|
||||
void Logger::handleConnected() {
|
||||
std::cout << "[COMPONENT] Connected to Jabber Server!\n";
|
||||
|
@ -92,4 +96,12 @@ void Logger::handleUserUpdated(const UserInfo &user) {
|
|||
std::cout << "[REGISTRATION] User \"" << user.jid << "\" updated \"" << user.uin << "\"\n";
|
||||
}
|
||||
|
||||
void Logger::handleUserCreated(User *user) {
|
||||
std::cout << "[USERMANAGER] User \"" << user->getJID().toString() << "\" (UIN: \"" << user->getUserInfo().uin << "\") connected and User class has been created\n";
|
||||
}
|
||||
|
||||
void Logger::handleUserDestroyed(User *user) {
|
||||
std::cout << "[USERMANAGER] User \"" << user->getJID().toBare().toString() << "\" (UIN: \"" << user->getUserInfo().uin << "\") disconnected and User class is going to be destroyed\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,6 +78,14 @@ Component::~Component() {
|
|||
delete m_factories;
|
||||
}
|
||||
|
||||
Swift::Component *Component::getComponent() {
|
||||
return m_component;
|
||||
}
|
||||
|
||||
Swift::PresenceOracle *Component::getPresenceOracle() {
|
||||
return m_presenceOracle;
|
||||
}
|
||||
|
||||
void Component::setTransportFeatures(std::list<std::string> &features) {
|
||||
m_discoInfoResponder->setTransportFeatures(features);
|
||||
}
|
||||
|
|
25
src/user.cpp
25
src/user.cpp
|
@ -20,19 +20,20 @@
|
|||
|
||||
#include "transport/user.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/storagebackend.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
User::User(const Swift::JID &jid, const std::string &username, const std::string &password, Component *component) {
|
||||
User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component) {
|
||||
m_jid = jid;
|
||||
|
||||
m_component = component->m_component;
|
||||
m_component = component;
|
||||
m_presenceOracle = component->m_presenceOracle;
|
||||
m_entityCapsManager = component->m_entityCapsManager;
|
||||
// m_activeResource = m_jid.getResource();
|
||||
|
||||
m_userInfo = userInfo;
|
||||
}
|
||||
|
||||
User::~User(){
|
||||
|
||||
}
|
||||
|
@ -41,4 +42,20 @@ const Swift::JID &User::getJID() {
|
|||
return m_jid;
|
||||
}
|
||||
|
||||
void User::handlePresence(Swift::Presence::ref presence) {
|
||||
Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(m_jid.toBare());
|
||||
if (highest) {
|
||||
highest->setTo(presence->getFrom());
|
||||
highest->setFrom(m_component->getJID());
|
||||
m_component->getComponent()->sendPresence(highest);
|
||||
}
|
||||
else {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo(m_jid.toBare());
|
||||
response->setFrom(m_component->getJID());
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
m_component->getComponent()->sendPresence(response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,12 +21,15 @@
|
|||
#include "transport/usermanager.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/storagebackend.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
UserManager::UserManager(Component *component) {
|
||||
UserManager::UserManager(Component *component, StorageBackend *storageBackend) {
|
||||
m_cachedUser = NULL;
|
||||
m_onlineBuddies = 0;
|
||||
m_component = component;
|
||||
m_storageBackend = storageBackend;
|
||||
|
||||
component->onUserPresenceReceived.connect(bind(&UserManager::handlePresence, this, _1));
|
||||
}
|
||||
|
@ -34,7 +37,12 @@ UserManager::UserManager(Component *component) {
|
|||
UserManager::~UserManager(){
|
||||
}
|
||||
|
||||
User *UserManager::getUserByJID(const std::string &barejid){
|
||||
void UserManager::addUser(User *user) {
|
||||
m_users[user->getJID().toBare().toString()] = user;
|
||||
onUserCreated(user);
|
||||
}
|
||||
|
||||
User *UserManager::getUser(const std::string &barejid){
|
||||
if (m_cachedUser && barejid == m_cachedUser->getJID().toBare().toString()) {
|
||||
return m_cachedUser;
|
||||
}
|
||||
|
@ -47,55 +55,49 @@ User *UserManager::getUserByJID(const std::string &barejid){
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int UserManager::userCount() {
|
||||
void UserManager::removeUser(User *user) {
|
||||
m_users.erase(user->getJID().toBare().toString());
|
||||
if (m_cachedUser == user)
|
||||
m_cachedUser = NULL;
|
||||
onUserDestroyed(user);
|
||||
delete user;
|
||||
}
|
||||
|
||||
int UserManager::getUserCount() {
|
||||
return m_users.size();
|
||||
}
|
||||
|
||||
void UserManager::handlePresence(Swift::Presence::ref presence) {
|
||||
// std::string barejid = presence->getTo().toBare().toString().getUTF8String();
|
||||
// std::string userkey = presence->getFrom().toBare().toString().getUTF8String();
|
||||
// // if (Transport::instance()->protocol()->tempAccountsAllowed()) {
|
||||
// // std::string server = barejid.substr(barejid.find("%") + 1, barejid.length() - barejid.find("%"));
|
||||
// // userkey += server;
|
||||
// // }
|
||||
//
|
||||
// User *user = getUserByJID(userkey);
|
||||
// if (user ) {
|
||||
// user->handlePresence(presence);
|
||||
// }
|
||||
// else {
|
||||
// // // No user, unavailable presence... nothing to do
|
||||
// // if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
// // Swift::Presence::ref response = Swift::Presence::create();
|
||||
// // response->setTo(presence->getFrom());
|
||||
// // response->setFrom(Swift::JID(Transport::instance()->jid()));
|
||||
// // response->setType(Swift::Presence::Unavailable);
|
||||
// // m_component->sendPresence(response);
|
||||
// //
|
||||
// // // UserRow res = Transport::instance()->sql()->getUserByJid(userkey);
|
||||
// // // if (res.id != -1) {
|
||||
// // // Transport::instance()->sql()->setUserOnline(res.id, false);
|
||||
// // // }
|
||||
// // return;
|
||||
// // }
|
||||
// // UserRow res = Transport::instance()->sql()->getUserByJid(userkey);
|
||||
// // if (res.id == -1 && !Transport::instance()->protocol()->tempAccountsAllowed()) {
|
||||
// // // presence from unregistered user
|
||||
// // Log(presence->getFrom().toString().getUTF8String(), "This user is not registered");
|
||||
// // return;
|
||||
// // }
|
||||
// // else {
|
||||
// // if (res.id == -1 && Transport::instance()->protocol()->tempAccountsAllowed()) {
|
||||
// // res.jid = userkey;
|
||||
// // res.uin = presence->getFrom().toBare().toString().getUTF8String();
|
||||
// // res.password = "";
|
||||
// // res.language = "en";
|
||||
// // res.encoding = CONFIG().encoding;
|
||||
// // res.vip = 0;
|
||||
// // Transport::instance()->sql()->addUser(res);
|
||||
// // res = Transport::instance()->sql()->getUserByJid(userkey);
|
||||
// // }
|
||||
// //
|
||||
std::string barejid = presence->getTo().toBare().toString();
|
||||
std::string userkey = presence->getFrom().toBare().toString();
|
||||
|
||||
User *user = getUser(userkey);
|
||||
if (!user ) {
|
||||
// No user and unavailable presence -> answer with unavailable
|
||||
if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo(presence->getFrom());
|
||||
response->setFrom(presence->getTo());
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
m_component->getComponent()->sendPresence(response);
|
||||
|
||||
UserInfo res;
|
||||
bool registered = m_storageBackend->getUser(userkey, res);
|
||||
if (registered) {
|
||||
m_storageBackend->setUserOnline(res.id, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
UserInfo res;
|
||||
bool registered = m_storageBackend->getUser(userkey, res);
|
||||
|
||||
if (!registered) {
|
||||
// TODO: logging
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: isVIP
|
||||
// // bool isVip = res.vip;
|
||||
// // std::list<std::string> const &x = CONFIG().allowedServers;
|
||||
// // if (CONFIG().onlyForVIP && !isVip && std::find(x.begin(), x.end(), presence->getFrom().getDomain().getUTF8String()) == x.end()) {
|
||||
|
@ -103,60 +105,31 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
|
|||
// // return;
|
||||
// // }
|
||||
// //
|
||||
// // Log(presence->getFrom().toString().getUTF8String(), "Creating new User instance");
|
||||
// //
|
||||
// // if (Transport::instance()->protocol()->tempAccountsAllowed()) {
|
||||
// // std::string server = barejid.substr(barejid.find("%") + 1, barejid.length() - barejid.find("%"));
|
||||
// // res.uin = presence->getTo().getResource().getUTF8String() + "@" + server;
|
||||
// // }
|
||||
// // else {
|
||||
// // if (purple_accounts_find(res.uin.c_str(), Transport::instance()->protocol()->protocol().c_str()) != NULL) {
|
||||
// // PurpleAccount *act = purple_accounts_find(res.uin.c_str(), Transport::instance()->protocol()->protocol().c_str());
|
||||
// // user = Transport::instance()->userManager()->getUserByAccount(act);
|
||||
// // if (user) {
|
||||
// // Log(presence->getFrom().toString().getUTF8String(), "This account is already connected by another jid " << user->jid());
|
||||
// // return;
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// // user = (AbstractUser *) new User(res, userkey, m_component, m_presenceOracle, m_entityCapsManager);
|
||||
user = new User(presence->getFrom(), res, m_component);
|
||||
// TODO: handle features somehow
|
||||
// // user->setFeatures(isVip ? CONFIG().VIPFeatures : CONFIG().transportFeatures);
|
||||
// // // if (c != NULL)
|
||||
// // // if (Transport::instance()->hasClientCapabilities(c->findAttribute("ver")))
|
||||
// // // user->setResource(stanza.from().resource(), stanza.priority(), Transport::instance()->getCapabilities(c->findAttribute("ver")));
|
||||
// // //
|
||||
// // Transport::instance()->userManager()->addUser(user);
|
||||
// // user->receivedPresence(presence);
|
||||
// // // if (protocol()->tempAccountsAllowed()) {
|
||||
// // // std::string server = stanza.to().username().substr(stanza.to().username().find("%") + 1, stanza.to().username().length() - stanza.to().username().find("%"));
|
||||
// // // server = stanza.from().bare() + server;
|
||||
// // // purple_timeout_add_seconds(15, &connectUser, g_strdup(server.c_str()));
|
||||
// // // }
|
||||
// // // else
|
||||
// // // purple_timeout_add_seconds(15, &connectUser, g_strdup(stanza.from().bare().c_str()));
|
||||
// // // }
|
||||
// // }
|
||||
// // // if (stanza.presence() == Presence::Unavailable && stanza.to().username() == ""){
|
||||
// // // Log(stanza.from().full(), "User is already logged out => sending unavailable presence");
|
||||
// // // Tag *tag = new Tag("presence");
|
||||
// // // tag->addAttribute( "to", stanza.from().bare() );
|
||||
// // // tag->addAttribute( "type", "unavailable" );
|
||||
// // // tag->addAttribute( "from", jid() );
|
||||
// // // j->send( tag );
|
||||
// // // }
|
||||
// }
|
||||
//
|
||||
// if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
// if (user) {
|
||||
// Swift::Presence::ref highest = m_presenceOracle->getHighestPriorityPresence(presence->getFrom().toBare());
|
||||
// if (presence->getType() == Swift::Presence::Unavailable && (!highest || (highest && highest->getType() == Swift::Presence::Unavailable))) {
|
||||
// Transport::instance()->userManager()->removeUser(user);
|
||||
// }
|
||||
// }
|
||||
addUser(user);
|
||||
}
|
||||
user->handlePresence(presence);
|
||||
|
||||
if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
if (user) {
|
||||
Swift::Presence::ref highest = m_component->getPresenceOracle()->getHighestPriorityPresence(presence->getFrom().toBare());
|
||||
// There's no presence for this user, so disconnect
|
||||
if (!highest || (highest && highest->getType() == Swift::Presence::Unavailable)) {
|
||||
removeUser(user);
|
||||
}
|
||||
}
|
||||
// TODO: HANDLE MUC SOMEHOW
|
||||
// else if (user && Transport::instance()->protocol()->tempAccountsAllowed() && !((User *) user)->hasOpenedMUC()) {
|
||||
// Transport::instance()->userManager()->removeUser(user);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ bool UserRegistration::unregisterUser(const std::string &barejid) {
|
|||
|
||||
Swift::Presence::ref response;
|
||||
|
||||
User *user = m_userManager->getUserByJID(barejid);
|
||||
User *user = m_userManager->getUser(barejid);
|
||||
|
||||
// roster contains already escaped jids
|
||||
std::list <std::string> roster;
|
||||
|
|
Loading…
Add table
Reference in a new issue