Hopefully working authorizations. Tested it only once :)

This commit is contained in:
HanzZ 2011-06-17 13:43:31 +02:00
parent cbd571766e
commit b0bcade44c
11 changed files with 238 additions and 10 deletions

View file

@ -45,6 +45,15 @@ static GOptionEntry options_entries[] = {
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, "", NULL }
};
struct authRequest {
PurpleAccountRequestAuthorizationCb authorize_cb;
PurpleAccountRequestAuthorizationCb deny_cb;
void *user_data;
std::string who;
PurpleAccount *account;
std::string mainJID; // JID of user connected with this request
};
static void * requestInput(const char *title, const char *primary,const char *secondary, const char *default_value, gboolean multiline, gboolean masked, gchar *hint,const char *ok_text, GCallback ok_cb,const char *cancel_text, GCallback cancel_cb, PurpleAccount *account, const char *who,PurpleConversation *conv, void *user_data) {
std::cout << "REQUEST INPUT\n";
if (primary) {
@ -294,6 +303,10 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::string &groups) {
PurpleAccount *account = m_sessions[user];
if (account) {
if (m_authRequests.find(user + buddyName) != m_authRequests.end()) {
m_authRequests[user + buddyName]->deny_cb(m_authRequests[user + buddyName]->user_data);
m_authRequests.erase(user + buddyName);
}
PurpleBuddy *buddy = purple_find_buddy(account, buddyName.c_str());
if (buddy) {
purple_account_remove_buddy(account, buddy, purple_buddy_get_group(buddy));
@ -305,6 +318,12 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::string &groups) {
PurpleAccount *account = m_sessions[user];
if (account) {
if (m_authRequests.find(user + buddyName) != m_authRequests.end()) {
m_authRequests[user + buddyName]->authorize_cb(m_authRequests[user + buddyName]->user_data);
m_authRequests.erase(user + buddyName);
}
PurpleBuddy *buddy = purple_find_buddy(account, buddyName.c_str());
if (buddy) {
purple_blist_alias_buddy(buddy, alias.c_str());
@ -347,6 +366,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
std::map<std::string, PurpleAccount *> m_sessions;
std::map<PurpleAccount *, std::string> m_accounts;
std::map<std::string, unsigned int> m_vcards;
std::map<std::string, authRequest *> m_authRequests;
private:
Config *config;
};
@ -693,10 +713,44 @@ static PurpleRequestUiOps requestUiOps =
NULL
};
static void * accountRequestAuth(PurpleAccount *account, const char *remote_user, const char *id, const char *alias, const char *message, gboolean on_list, PurpleAccountRequestAuthorizationCb authorize_cb, PurpleAccountRequestAuthorizationCb deny_cb, void *user_data) {
authRequest *req = new authRequest;
req->authorize_cb = authorize_cb;
req->deny_cb = deny_cb;
req->user_data = user_data;
req->account = account;
req->who = remote_user;
req->mainJID = np->m_accounts[account];
np->m_authRequests[req->mainJID + req->who] = req;
np->handleAuthorization(req->mainJID, req->who);
return req;
}
static void accountRequestClose(void *data){
authRequest *req = (authRequest *) data;
np->m_authRequests.erase(req->mainJID + req->who);
}
static PurpleAccountUiOps accountUiOps =
{
NULL,
NULL,
NULL,
accountRequestAuth,
accountRequestClose,
NULL,
NULL,
NULL,
NULL
};
static void transport_core_ui_init(void)
{
purple_blist_set_ui_ops(&blistUiOps);
// purple_accounts_set_ui_ops(&accountUiOps);
purple_accounts_set_ui_ops(&accountUiOps);
purple_notify_set_ui_ops(&notifyUiOps);
purple_request_set_ui_ops(&requestUiOps);
// purple_xfers_set_ui_ops(getXferUiOps());

View file

@ -64,6 +64,8 @@ class NetworkPlugin {
void handleBuddyStoppedTyping(const std::string &user, const std::string &buddyName);
void handleAuthorization(const std::string &user, const std::string &buddyName);
virtual void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) = 0;
virtual void handleLogoutRequest(const std::string &user, const std::string &legacyName) = 0;
virtual void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message) = 0;

View file

@ -68,6 +68,7 @@ class NetworkPluginServer {
void handleRoomChangedPayload(const std::string &payload);
void handleVCardPayload(const std::string &payload);
void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type);
void handleAuthorizationPayload(const std::string &payload);
void handleUserCreated(User *user);
void handleRoomJoined(User *user, const std::string &room, const std::string &nickname, const std::string &password);

View file

@ -76,6 +76,10 @@ class RosterManager {
/// \param buddy removed Buddy
boost::signal<void (Buddy *buddy)> onBuddyUnset;
boost::signal<void (Buddy *buddy)> onBuddyAdded;
boost::signal<void (Buddy *buddy)> onBuddyRemoved;
void handleSubscription(Swift::Presence::ref presence);
private:

View file

@ -3,8 +3,8 @@ FILE(GLOB SRC *.cpp)
ADD_EXECUTABLE(spectrum2 ${SRC})
ADD_DEPENDENCIES(spectrum2 libpurple_backend)
ADD_DEPENDENCIES(spectrum2 libircclient-qt_backend)
ADD_DEPENDENCIES(spectrum2 spectrum_libpurple_backend)
ADD_DEPENDENCIES(spectrum2 spectrum_libircclient-qt_backend)
target_link_libraries(spectrum2 transport)

View file

@ -9,8 +9,8 @@ backend_port=10001
#cert= #patch to PKCS#12 certificate
#cert_password= #password to that certificate if any
users_per_backend=2
backend=../../backends/libpurple/libpurple_backend
#backend=../../backends/libircclient-qt/libircclient-qt_backend
backend=../../backends/libpurple/spectrum_libpurple_backend
#backend=../../backends/libircclient-qt/spectrum_libircclient-qt_backend
protocol=prpl-jabber
#protocol=prpl-msn
#protocol=prpl-icq

View file

@ -169,6 +169,10 @@ std::string Buddy::JIDToLegacyName(const Swift::JID &jid) {
}
else {
name = jid.getUnescapedNode();
// Psi sucks...
if (name.find_last_of("\\40") != std::string::npos) {
name.replace(name.find_last_of("\\40"), 1, "@");
}
}
return name;
}

View file

@ -162,6 +162,19 @@ void NetworkPlugin::handleBuddyStoppedTyping(const std::string &user, const std:
send(message);
}
void NetworkPlugin::handleAuthorization(const std::string &user, const std::string &buddyName) {
pbnetwork::Buddy buddy;
buddy.set_username(user);
buddy.set_buddyname(buddyName);
std::string message;
buddy.SerializeToString(&message);
WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_AUTH_REQUEST);
send(message);
}
void NetworkPlugin::handleConnected(const std::string &user) {
std::cout << "LOGIN SENT\n";
pbnetwork::Connected d;

View file

@ -224,6 +224,32 @@ void NetworkPluginServer::handleVCardPayload(const std::string &data) {
m_vcardResponder->sendVCard(payload.id(), vcard);
}
void NetworkPluginServer::handleAuthorizationPayload(const std::string &data) {
pbnetwork::Buddy payload;
if (payload.ParseFromString(data) == false) {
// TODO: ERROR
return;
}
User *user = m_userManager->getUser(payload.username());
if (!user)
return;
Swift::Presence::ref response = Swift::Presence::create();
response->setTo(user->getJID());
std::string name = payload.buddyname();
// name = Swift::JID::getEscapedNode(name)
if (name.find_last_of("@") != std::string::npos) {
name.replace(name.find_last_of("@"), 1, "%");
}
response->setFrom(Swift::JID(name, m_component->getJID().toString()));
response->setType(Swift::Presence::Subscribe);
m_component->getStanzaChannel()->sendPresence(response);
}
void NetworkPluginServer::handleChatStatePayload(const std::string &data, Swift::ChatState::ChatStateType type) {
pbnetwork::Buddy payload;
if (payload.ParseFromString(data) == false) {
@ -245,7 +271,6 @@ void NetworkPluginServer::handleChatStatePayload(const std::string &data, Swift:
msg->addPayload(boost::make_shared<Swift::ChatState>(type));
conv->handleMessage(msg);
}
void NetworkPluginServer::handleBuddyChangedPayload(const std::string &data) {
@ -409,6 +434,9 @@ void NetworkPluginServer::handleDataRead(Client *c, const Swift::SafeByteArray &
case pbnetwork::WrapperMessage_Type_TYPE_BUDDY_STOPPED_TYPING:
handleChatStatePayload(wrapper.payload(), Swift::ChatState::Active);
break;
case pbnetwork::WrapperMessage_Type_TYPE_AUTH_REQUEST:
handleAuthorizationPayload(wrapper.payload());
break;
default:
return;
}

View file

@ -92,6 +92,7 @@ message WrapperMessage {
TYPE_BUDDY_TYPING = 18;
TYPE_BUDDY_STOPPED_TYPING = 19;
TYPE_BUDDY_TYPED = 20;
TYPE_AUTH_REQUEST = 21;
}
required Type type = 1;
optional bytes payload = 2;

View file

@ -39,9 +39,6 @@ RosterManager::RosterManager(User *user, Component *component){
m_setBuddyTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(1000);
m_RIETimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(5000);
m_RIETimer->onTick.connect(boost::bind(&RosterManager::sendRIE, this));
}
RosterManager::~RosterManager() {
@ -157,7 +154,131 @@ void RosterManager::sendRIE() {
void RosterManager::handleSubscription(Swift::Presence::ref presence) {
std::string legacyName = Buddy::JIDToLegacyName(presence->getTo());
// For server mode the subscription changes are handler in rosterresponder.cpp
// using roster pushes.
if (m_component->inServerMode()) {
Swift::Presence::ref response = Swift::Presence::create();
response->setTo(presence->getFrom());
response->setFrom(presence->getTo());
Buddy *buddy = getBuddy(Buddy::JIDToLegacyName(presence->getTo()));
if (buddy) {
switch (presence->getType()) {
case Swift::Presence::Subscribe:
response->setType(Swift::Presence::Subscribed);
break;
case Swift::Presence::Unsubscribe:
response->setType(Swift::Presence::Unsubscribed);
break;
default:
return;
}
m_component->getStanzaChannel()->sendPresence(response);
}
else {
BuddyInfo buddyInfo;
switch (presence->getType()) {
// buddy is not in roster, so add him
case Swift::Presence::Subscribe:
buddyInfo.id = -1;
buddyInfo.alias = "";
buddyInfo.legacyName = Buddy::JIDToLegacyName(presence->getTo());
buddyInfo.subscription = "both";
buddyInfo.flags = 0;
buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
setBuddy(buddy);
onBuddyAdded(buddy);
response->setType(Swift::Presence::Subscribed);
break;
// buddy is already there, so nothing to do, just answer
case Swift::Presence::Unsubscribe:
response->setType(Swift::Presence::Unsubscribed);
break;
default:
return;
}
m_component->getStanzaChannel()->sendPresence(response);
}
}
else {
Swift::Presence::ref response = Swift::Presence::create();
response->setTo(presence->getFrom());
response->setFrom(presence->getTo());
Buddy *buddy = getBuddy(Buddy::JIDToLegacyName(presence->getTo()));
if (buddy) {
switch (presence->getType()) {
// buddy is already there, so nothing to do, just answer
case Swift::Presence::Subscribe:
response->setType(Swift::Presence::Subscribed);
break;
// remove buddy
case Swift::Presence::Unsubscribe:
response->setType(Swift::Presence::Unsubscribed);
onBuddyRemoved(buddy);
break;
// just send response
case Swift::Presence::Unsubscribed:
response->setType(Swift::Presence::Unsubscribe);
break;
// just send response
case Swift::Presence::Subscribed:
response->setType(Swift::Presence::Subscribe);
break;
default:
return;
}
}
else {
BuddyInfo buddyInfo;
switch (presence->getType()) {
// buddy is not in roster, so add him
case Swift::Presence::Subscribe:
buddyInfo.id = -1;
buddyInfo.alias = "";
buddyInfo.legacyName = Buddy::JIDToLegacyName(presence->getTo());
buddyInfo.subscription = "both";
buddyInfo.flags = 0;
buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
setBuddy(buddy);
onBuddyAdded(buddy);
response->setType(Swift::Presence::Subscribed);
break;
// buddy is already there, so nothing to do, just answer
case Swift::Presence::Unsubscribe:
response->setType(Swift::Presence::Unsubscribed);
break;
// just send response
case Swift::Presence::Unsubscribed:
response->setType(Swift::Presence::Unsubscribe);
break;
// just send response
case Swift::Presence::Subscribed:
response->setType(Swift::Presence::Subscribe);
break;
default:
return;
}
}
m_component->getStanzaChannel()->sendPresence(response);
// We have to act as buddy and send its subscribe/unsubscribe just to be sure...
switch (response->getType()) {
case Swift::Presence::Unsubscribed:
response->setType(Swift::Presence::Unsubscribe);
m_component->getStanzaChannel()->sendPresence(response);
break;
case Swift::Presence::Subscribed:
response->setType(Swift::Presence::Subscribe);
m_component->getStanzaChannel()->sendPresence(response);
break;
default:
break;
}
}
}
void RosterManager::setStorageBackend(StorageBackend *storageBackend) {