Merge pull request #760 from Sonetio/windows_service

Added Windows support to retroshare-android-service
This commit is contained in:
electron128 2017-04-05 18:49:32 +02:00 committed by GitHub
commit 4067c95761
17 changed files with 763 additions and 29 deletions

View File

@ -17,6 +17,10 @@
#include "ChannelsHandler.h" #include "ChannelsHandler.h"
#include "StatsHandler.h" #include "StatsHandler.h"
#ifdef LIBRESAPI_QT
#include "SettingsHandler.h"
#endif
/* /*
data types in json http://json.org/ data types in json http://json.org/
string (utf-8 unicode) string (utf-8 unicode)
@ -237,6 +241,9 @@ public:
mApiPluginHandler(sts, ifaces), mApiPluginHandler(sts, ifaces),
mChannelsHandler(ifaces.mGxsChannels), mChannelsHandler(ifaces.mGxsChannels),
mStatsHandler() mStatsHandler()
#ifdef LIBRESAPI_QT
,mSettingsHandler(sts)
#endif
{ {
// the dynamic cast is to not confuse the addResourceHandler template like this: // the dynamic cast is to not confuse the addResourceHandler template like this:
// addResourceHandler(derived class, parent class) // addResourceHandler(derived class, parent class)
@ -262,7 +269,11 @@ public:
&ChannelsHandler::handleRequest); &ChannelsHandler::handleRequest);
router.addResourceHandler("stats", dynamic_cast<ResourceRouter*>(&mStatsHandler), router.addResourceHandler("stats", dynamic_cast<ResourceRouter*>(&mStatsHandler),
&StatsHandler::handleRequest); &StatsHandler::handleRequest);
} #ifdef LIBRESAPI_QT
router.addResourceHandler("settings", dynamic_cast<ResourceRouter*>(&mSettingsHandler),
&SettingsHandler::handleRequest);
#endif
}
PeersHandler mPeersHandler; PeersHandler mPeersHandler;
IdentityHandler mIdentityHandler; IdentityHandler mIdentityHandler;
@ -274,6 +285,10 @@ public:
ApiPluginHandler mApiPluginHandler; ApiPluginHandler mApiPluginHandler;
ChannelsHandler mChannelsHandler; ChannelsHandler mChannelsHandler;
StatsHandler mStatsHandler; StatsHandler mStatsHandler;
#ifdef LIBRESAPI_QT
SettingsHandler mSettingsHandler;
#endif
}; };
ApiServer::ApiServer(): ApiServer::ApiServer():
@ -362,6 +377,9 @@ std::string ApiServer::handleRequest(Request &request)
if(data.isRawData()) if(data.isRawData())
return data.getRawData(); return data.getRawData();
if(!resp.mCallbackName.empty())
outstream << resource_api::makeKeyValueReference("callback_name", resp.mCallbackName);
outstream << resource_api::makeKeyValue("debug_msg", debugString.str()); outstream << resource_api::makeKeyValue("debug_msg", debugString.str());
outstream << resource_api::makeKeyValueReference("returncode", returncode); outstream << resource_api::makeKeyValueReference("returncode", returncode);
if(!resp.mStateToken.isNull()) if(!resp.mStateToken.isNull())

View File

@ -252,6 +252,9 @@ public:
StateToken mStateToken; StateToken mStateToken;
//Just for GUI benefit
std::string mCallbackName;
// the result // the result
StreamBase& mDataStream; StreamBase& mDataStream;

View File

@ -5,6 +5,7 @@
#include <retroshare/rspeers.h> #include <retroshare/rspeers.h>
#include <retroshare/rsidentity.h> #include <retroshare/rsidentity.h>
#include <retroshare/rshistory.h>
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
@ -146,6 +147,7 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs,
addResourceHandler("lobbies", this, &ChatHandler::handleLobbies); addResourceHandler("lobbies", this, &ChatHandler::handleLobbies);
addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby); addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby);
addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby); addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby);
addResourceHandler("autosubscribe_lobby", this, &ChatHandler::handleAutoSubsribeLobby);
addResourceHandler("clear_lobby", this, &ChatHandler::handleClearLobby); addResourceHandler("clear_lobby", this, &ChatHandler::handleClearLobby);
addResourceHandler("lobby_participants", this, &ChatHandler::handleLobbyParticipants); addResourceHandler("lobby_participants", this, &ChatHandler::handleLobbyParticipants);
addResourceHandler("messages", this, &ChatHandler::handleMessages); addResourceHandler("messages", this, &ChatHandler::handleMessages);
@ -889,6 +891,15 @@ void ChatHandler::handleUnsubscribeLobby(Request &req, Response &resp)
resp.setOk(); resp.setOk();
} }
void ChatHandler::handleAutoSubsribeLobby(Request& req, Response& resp)
{
ChatLobbyId chatId = 0;
bool autosubsribe;
req.mStream << makeKeyValueReference("chatid", chatId) << makeKeyValueReference("autosubsribe", autosubsribe);
mRsMsgs->setLobbyAutoSubscribe(chatId, autosubsribe);
resp.setOk();
}
void ChatHandler::handleClearLobby(Request &req, Response &resp) void ChatHandler::handleClearLobby(Request &req, Response &resp)
{ {
ChatLobbyId id = 0; ChatLobbyId id = 0;
@ -930,13 +941,14 @@ void ChatHandler::handleMessages(Request &req, Response &resp)
{ {
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
ChatId id(req.mPath.top()); ChatId id(req.mPath.top());
// make response a list // make response a list
resp.mDataStream.getStreamToMember(); resp.mDataStream.getStreamToMember();
if(id.isNotSet()) if(id.isNotSet())
{ {
resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id");
return; return;
} }
std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.find(id); std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.find(id);
if(mit == mMsgs.end()) if(mit == mMsgs.end())
@ -973,10 +985,11 @@ void ChatHandler::handleSendMessage(Request &req, Response &resp)
void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp) void ChatHandler::handleMarkChatAsRead(Request &req, Response &resp)
{ {
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
ChatId id(req.mPath.top()); ChatId id(req.mPath.top());
if(id.isNotSet()) if(id.isNotSet())
{ {
resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id"); resp.setFail("\""+req.mPath.top()+"\" is not a valid chat id");
return; return;
} }
std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.find(id); std::map<ChatId, std::list<Msg> >::iterator mit = mMsgs.find(id);

View File

@ -120,6 +120,7 @@ private:
void handleLobbies(Request& req, Response& resp); void handleLobbies(Request& req, Response& resp);
void handleSubscribeLobby(Request& req, Response& resp); void handleSubscribeLobby(Request& req, Response& resp);
void handleUnsubscribeLobby(Request& req, Response& resp); void handleUnsubscribeLobby(Request& req, Response& resp);
void handleAutoSubsribeLobby(Request& req, Response& resp);
void handleClearLobby(Request& req, Response& resp); void handleClearLobby(Request& req, Response& resp);
ResponseTask* handleLobbyParticipants(Request& req, Response& resp); ResponseTask* handleLobbyParticipants(Request& req, Response& resp);
void handleMessages(Request& req, Response& resp); void handleMessages(Request& req, Response& resp);

View File

@ -101,9 +101,13 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden
{ {
mNotify->registerNotifyClient(this); mNotify->registerNotifyClient(this);
addResourceHandler("*", this, &IdentityHandler::handleWildcard); addResourceHandler("*", this, &IdentityHandler::handleWildcard);
addResourceHandler("own", this, &IdentityHandler::handleOwn); addResourceHandler("own", this, &IdentityHandler::handleOwn);
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
addResourceHandler("own_ids", this, &IdentityHandler::handleOwnIdsRequest);
addResourceHandler("notown_ids", this, &IdentityHandler::handleNotOwnIdsRequest);
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
} }
IdentityHandler::~IdentityHandler() IdentityHandler::~IdentityHandler()
@ -172,6 +176,112 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp)
else resp.setFail(); else resp.setFail();
} }
void IdentityHandler::handleNotOwnIdsRequest(Request & /*req*/, Response &resp)
{
bool ok = true;
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts);
time_t start = time(NULL);
while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
&&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
&&((time(NULL) < (start+10)))
)
{
#ifdef WINDOWS_SYS
Sleep(500);
#else
usleep(500*1000);
#endif
}
if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
{
std::vector<RsGxsIdGroup> grps;
ok &= mRsIdentity->getGroupData(token, grps);
for(std::vector<RsGxsIdGroup>::iterator vit = grps.begin(); vit != grps.end(); vit++)
{
RsGxsIdGroup& grp = *vit;
//electron: not very happy about this, i think the flags should stay hidden in rsidentities
if(!(grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) && grp.mIsAContact)
{
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ;
resp.mDataStream.getStreamToMember()
<< makeKeyValueReference("id", grp.mMeta.mGroupId) /// @deprecated using "id" as key can cause problems in some JS based languages like Qml @see gxs_id instead
<< makeKeyValueReference("gxs_id", grp.mMeta.mGroupId)
<< makeKeyValueReference("pgp_id",grp.mPgpId )
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
<< makeKeyValueReference("pgp_linked", pgp_linked);
}
}
}
else ok = false;
if(ok) resp.setOk();
else resp.setFail();
}
void IdentityHandler::handleOwnIdsRequest(Request & /*req*/, Response &resp)
{
bool ok = true;
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts);
time_t start = time(NULL);
while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
&&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
&&((time(NULL) < (start+10)))
)
{
#ifdef WINDOWS_SYS
Sleep(500);
#else
usleep(500*1000);
#endif
}
if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
{
std::vector<RsGxsIdGroup> grps;
ok &= mRsIdentity->getGroupData(token, grps);
for(std::vector<RsGxsIdGroup>::iterator vit = grps.begin(); vit != grps.end(); vit++)
{
RsGxsIdGroup& grp = *vit;
//electron: not very happy about this, i think the flags should stay hidden in rsidentities
if(vit->mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
{
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility ) ;
resp.mDataStream.getStreamToMember()
<< makeKeyValueReference("own_gxs_id", grp.mMeta.mGroupId)
<< makeKeyValueReference("pgp_id",grp.mPgpId )
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
<< makeKeyValueReference("pgp_linked", pgp_linked);
}
}
}
else
ok = false;
if(ok) resp.setOk();
else resp.setFail();
}
ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp)
{ {
StateToken state; StateToken state;

View File

@ -23,6 +23,9 @@ public:
private: private:
void handleWildcard(Request& req, Response& resp); void handleWildcard(Request& req, Response& resp);
void handleNotOwnIdsRequest(Request& req, Response& resp);
void handleOwnIdsRequest(Request& req, Response& resp);
ResponseTask *handleOwn(Request& req, Response& resp); ResponseTask *handleOwn(Request& req, Response& resp);
ResponseTask *handleCreateIdentity(Request& req, Response& resp); ResponseTask *handleCreateIdentity(Request& req, Response& resp);

View File

@ -3,6 +3,7 @@
#include <retroshare/rspeers.h> #include <retroshare/rspeers.h>
#include <retroshare/rsmsgs.h> #include <retroshare/rsmsgs.h>
#include <util/radix64.h> #include <util/radix64.h>
#include <retroshare/rsstatus.h>
#include <algorithm> #include <algorithm>
@ -12,6 +13,12 @@
namespace resource_api namespace resource_api
{ {
#define PEER_STATE_ONLINE 1
#define PEER_STATE_BUSY 2
#define PEER_STATE_AWAY 3
#define PEER_STATE_AVAILABLE 4
#define PEER_STATE_INACTIVE 5
#define PEER_STATE_OFFLINE 6
// todo: groups, add friend, remove friend, permissions // todo: groups, add friend, remove friend, permissions
void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details) void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details)
@ -21,7 +28,50 @@ void peerDetailsToStream(StreamBase& stream, RsPeerDetails& details)
<< makeKeyValueReference("name", details.name) << makeKeyValueReference("name", details.name)
<< makeKeyValueReference("location", details.location) << makeKeyValueReference("location", details.location)
<< makeKeyValueReference("pgp_id", details.gpg_id) << makeKeyValueReference("pgp_id", details.gpg_id)
; << makeKeyValueReference("pgp_id", details.gpg_id);
if(details.state & RS_PEER_STATE_CONNECTED)
{
std::list<StatusInfo> statusInfo;
rsStatus->getStatusList(statusInfo);
std::string state_string;
std::list<StatusInfo>::iterator it;
for (it = statusInfo.begin(); it != statusInfo.end(); ++it)
{
if (it->id == details.id)
{
switch (it->status)
{
case RS_STATUS_INACTIVE:
state_string = "inactive";
break;
case RS_STATUS_ONLINE:
state_string = "online";
break;
case RS_STATUS_AWAY:
state_string = "away";
break;
case RS_STATUS_BUSY:
state_string = "busy";
break;
default:
state_string = "undefined";
break;
}
break;
}
}
stream << makeKeyValueReference("state_string", state_string);
}
else
{
std::string state_string = "undefined";
stream << makeKeyValueReference("state_string", state_string);
}
} }
bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers, std::list<RsGroupInfo>& grpInfo, bool have_avatar) bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers, std::list<RsGroupInfo>& grpInfo, bool have_avatar)
@ -29,7 +79,9 @@ bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers
bool ok = true; bool ok = true;
peerDetailsToStream(stream, details); peerDetailsToStream(stream, details);
stream << makeKeyValue("is_online", peers->isOnline(details.id)) stream << makeKeyValue("is_online", peers->isOnline(details.id))
<< makeKeyValue("chat_id", ChatId(details.id).toStdString()); << makeKeyValue("chat_id", ChatId(details.id).toStdString())
<< makeKeyValue("custom_state_string", rsMsgs->getCustomStateString(details.id));
std::string avatar_address = "/"+details.id.toStdString()+"/avatar_image"; std::string avatar_address = "/"+details.id.toStdString()+"/avatar_image";
@ -63,7 +115,11 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee
mNotify->registerNotifyClient(this); mNotify->registerNotifyClient(this);
mStateTokenServer->registerTickClient(this); mStateTokenServer->registerTickClient(this);
addResourceHandler("*", this, &PeersHandler::handleWildcard); addResourceHandler("*", this, &PeersHandler::handleWildcard);
addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert); addResourceHandler("get_state_string", this, &PeersHandler::handleGetStateString);
addResourceHandler("set_state_string", this, &PeersHandler::handleSetStateString);
addResourceHandler("get_custom_state_string", this, &PeersHandler::handleGetCustomStateString);
addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString);
addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert);
} }
PeersHandler::~PeersHandler() PeersHandler::~PeersHandler()
@ -100,6 +156,27 @@ void PeersHandler::tick()
mStateTokenServer->discardToken(mStateToken); mStateTokenServer->discardToken(mStateToken);
mStateToken = mStateTokenServer->getNewToken(); mStateToken = mStateTokenServer->getNewToken();
} }
StatusInfo statusInfo;
rsStatus->getOwnStatus(statusInfo);
if(statusInfo.status != status)
{
status = statusInfo.status;
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mStateTokenServer->discardToken(mStringStateToken);
mStringStateToken = mStateTokenServer->getNewToken();
}
std::string custom_state = rsMsgs->getCustomStateString();
if(custom_state != custom_state_string)
{
custom_state_string = custom_state;
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mStateTokenServer->discardToken(mCustomStateToken);
mCustomStateToken = mStateTokenServer->getNewToken();
}
} }
void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count) void PeersHandler::notifyUnreadMsgCountChanged(const RsPeerId &peer, uint32_t count)
@ -121,6 +198,73 @@ static bool have_avatar(RsMsgs* msgs, const RsPeerId& id)
return size != 0; return size != 0;
} }
void PeersHandler::handleGetStateString(Request& req, Response& resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStringStateToken;
}
std::string state_string;
StatusInfo statusInfo;
if (rsStatus->getOwnStatus(statusInfo))
{
if(statusInfo.status == RS_STATUS_ONLINE)
state_string = "online";
else if(statusInfo.status == RS_STATUS_BUSY)
state_string = "busy";
else if(statusInfo.status == RS_STATUS_AWAY)
state_string = "away";
else if(statusInfo.status == RS_STATUS_INACTIVE)
state_string = "inactive";
else
state_string = "undefined";
}
else
state_string = "undefined";
resp.mDataStream << makeKeyValueReference("state_string", state_string);
resp.setOk();
}
void PeersHandler::handleSetStateString(Request& req, Response& resp)
{
std::string state_string;
req.mStream << makeKeyValueReference("state_string", state_string);
uint32_t status;
if(state_string == "online")
status = RS_STATUS_ONLINE;
else if(state_string == "busy")
status = RS_STATUS_BUSY;
else if(state_string == "away")
status = RS_STATUS_AWAY;
rsStatus->sendStatus(RsPeerId(), status);
resp.setOk();
}
void PeersHandler::handleGetCustomStateString(Request& req, Response& resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mCustomStateToken;
}
std::string custom_state_string = rsMsgs->getCustomStateString();
resp.mDataStream << makeKeyValueReference("custom_state_string", custom_state_string);
resp.setOk();
}
void PeersHandler::handleSetCustomStateString(Request& req, Response& resp)
{
std::string custom_state_string;
req.mStream << makeKeyValueReference("custom_state_string", custom_state_string);
rsMsgs->setCustomStateString(custom_state_string);
resp.setOk();
}
void PeersHandler::handleWildcard(Request &req, Response &resp) void PeersHandler::handleWildcard(Request &req, Response &resp)
{ {
bool ok = false; bool ok = false;
@ -176,6 +320,9 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
unread_msgs = mUnreadMsgsCounts; unread_msgs = mUnreadMsgsCounts;
} }
std::list<StatusInfo> statusInfo;
rsStatus->getStatusList(statusInfo);
// list all peers // list all peers
ok = true; ok = true;
std::list<RsPgpId> identities; std::list<RsPgpId> identities;
@ -216,6 +363,11 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
StreamBase& locationStream = itemStream.getStreamToMember("locations"); StreamBase& locationStream = itemStream.getStreamToMember("locations");
// mark as list (in case list is empty) // mark as list (in case list is empty)
locationStream.getStreamToMember(); locationStream.getStreamToMember();
int bestPeerState = 0;
unsigned int bestRSState = 0;
std::string bestCustomStateString;
for(std::vector<RsPeerDetails>::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit) for(std::vector<RsPeerDetails>::iterator vit = detailsVec.begin(); vit != detailsVec.end(); ++vit)
{ {
if(vit->gpg_id == *lit) if(vit->gpg_id == *lit)
@ -226,8 +378,85 @@ void PeersHandler::handleWildcard(Request &req, Response &resp)
unread = unread_msgs.find(vit->id)->second; unread = unread_msgs.find(vit->id)->second;
stream << makeKeyValueReference("unread_msgs", unread); stream << makeKeyValueReference("unread_msgs", unread);
peerInfoToStream(stream,*vit, mRsPeers, grpInfo, have_avatar(mRsMsgs, vit->id)); peerInfoToStream(stream,*vit, mRsPeers, grpInfo, have_avatar(mRsMsgs, vit->id));
}
/* Custom state string */
std::string customStateString;
if (vit->state & RS_PEER_STATE_CONNECTED)
{
customStateString = rsMsgs->getCustomStateString(vit->id);
}
int peerState = 0;
if (vit->state & RS_PEER_STATE_CONNECTED)
{
// get the status info for this ssl id
int rsState = 0;
std::list<StatusInfo>::iterator it;
for (it = statusInfo.begin(); it != statusInfo.end(); ++it)
{
if (it->id == vit->id)
{
rsState = it->status;
switch (rsState)
{
case RS_STATUS_INACTIVE:
peerState = PEER_STATE_INACTIVE;
break;
case RS_STATUS_ONLINE:
peerState = PEER_STATE_ONLINE;
break;
case RS_STATUS_AWAY:
peerState = PEER_STATE_AWAY;
break;
case RS_STATUS_BUSY:
peerState = PEER_STATE_BUSY;
break;
}
/* find the best ssl contact for the gpg item */
if (bestPeerState == 0 || peerState < bestPeerState)
{
bestPeerState = peerState;
bestRSState = rsState;
bestCustomStateString = customStateString;
}
else if (peerState == bestPeerState)
{
/* equal state */
if (bestCustomStateString.empty() && !customStateString.empty())
{
bestPeerState = peerState;
bestRSState = rsState;
bestCustomStateString = customStateString;
}
}
break;
}
}
}
}
} }
itemStream << makeKeyValue("custom_state_string", bestCustomStateString);
std::string state_string;
if(bestRSState == RS_STATUS_ONLINE)
state_string = "online";
else if(bestRSState == RS_STATUS_BUSY)
state_string = "busy";
else if(bestRSState == RS_STATUS_AWAY)
state_string = "away";
else if(bestRSState == RS_STATUS_INACTIVE)
state_string = "inactive";
else
state_string = "undefined";
itemStream << makeKeyValue("state_string", state_string);
} }
resp.mStateToken = getCurrentStateToken(); resp.mStateToken = getCurrentStateToken();
} }

View File

@ -35,6 +35,12 @@ private:
void handleWildcard(Request& req, Response& resp); void handleWildcard(Request& req, Response& resp);
void handleExamineCert(Request& req, Response& resp); void handleExamineCert(Request& req, Response& resp);
void handleGetStateString(Request& req, Response& resp);
void handleSetStateString(Request& req, Response& resp);
void handleGetCustomStateString(Request& req, Response& resp);
void handleSetCustomStateString(Request& req, Response& resp);
// a helper which ensures proper mutex locking // a helper which ensures proper mutex locking
StateToken getCurrentStateToken(); StateToken getCurrentStateToken();
@ -44,9 +50,14 @@ private:
RsMsgs* mRsMsgs; // required for avatar data RsMsgs* mRsMsgs; // required for avatar data
std::list<RsPeerId> mOnlinePeers; std::list<RsPeerId> mOnlinePeers;
uint32_t status;
std::string custom_state_string;
RsMutex mMtx; RsMutex mMtx;
StateToken mStateToken; // mutex protected StateToken mStateToken; // mutex protected
StateToken mStringStateToken; // mutex protected
StateToken mCustomStateToken; // mutex protected
std::map<RsPeerId, uint32_t> mUnreadMsgsCounts; std::map<RsPeerId, uint32_t> mUnreadMsgsCounts;
}; };
} // namespace resource_api } // namespace resource_api

View File

@ -37,6 +37,13 @@ ResponseTask* ResourceRouter::handleRequest(Request& req, Response& resp)
if(vit->first == req.mPath.top()) if(vit->first == req.mPath.top())
{ {
req.mPath.pop(); req.mPath.pop();
//Just for GUI benefit
std::string callbackName;
req.mStream << makeKeyValueReference("callback_name", callbackName);
resp.mCallbackName = callbackName;
//
return vit->second->handleRequest(req, resp); return vit->second->handleRequest(req, resp);
} }
} }

View File

@ -6,6 +6,7 @@
#include <retroshare/rsinit.h> #include <retroshare/rsinit.h>
#include <retroshare/rsiface.h> #include <retroshare/rsiface.h>
#include <util/rsdir.h>
#include "api/ApiServer.h" #include "api/ApiServer.h"
#include "api/Operators.h" #include "api/Operators.h"
@ -301,6 +302,7 @@ void RsControlModule::handlePassword(Request &req, Response &resp)
mPassword = passwd; mPassword = passwd;
mWantPassword = false; mWantPassword = false;
mStateTokenServer->replaceToken(mStateToken); mStateTokenServer->replaceToken(mStateToken);
mFixedPassword = passwd;
} }
resp.mDataStream resp.mDataStream
@ -425,17 +427,17 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
RsPeerId ssl_id; RsPeerId ssl_id;
std::string err_string; std::string err_string;
// give the password to the password callback // give the password to the password callback
{ {
RsStackMutex stack(mDataMtx); // ********** LOCKED ********** RsStackMutex stack(mDataMtx); // ********** LOCKED **********
mFixedPassword = pgp_password; mFixedPassword = pgp_password;
} }
bool ssl_ok = RsAccounts::GenerateSSLCertificate(pgp_id, "", ssl_name, "", hidden_port!=0, ssl_password, ssl_id, err_string); bool ssl_ok = RsAccounts::GenerateSSLCertificate(pgp_id, "", ssl_name, "", hidden_port!=0, ssl_password, ssl_id, err_string);
// clear fixed password to restore normal password operation // clear fixed password to restore normal password operation
{ // {
RsStackMutex stack(mDataMtx); // ********** LOCKED ********** // RsStackMutex stack(mDataMtx); // ********** LOCKED **********
mFixedPassword = ""; // mFixedPassword = "";
} // }
if (ssl_ok) if (ssl_ok)
{ {
@ -456,6 +458,20 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
resp.setFail("could not create a new location. Error: "+err_string); resp.setFail("could not create a new location. Error: "+err_string);
} }
bool RsControlModule::askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason /*=""*/)
{
if(rsPeers->gpgSignData(data,len,sign,signlen,reason))
{
signature_result = SELF_SIGNATURE_RESULT_SUCCESS;
return true;
}
else
{
signature_result = SELF_SIGNATURE_RESULT_FAILED;
return false;
}
}
void RsControlModule::setRunState(RunState s, std::string errstr) void RsControlModule::setRunState(RunState s, std::string errstr)
{ {
RsStackMutex stack(mDataMtx); // ********** LOCKED ********** RsStackMutex stack(mDataMtx); // ********** LOCKED **********

View File

@ -31,8 +31,9 @@ public:
// returns true if the process should terminate // returns true if the process should terminate
bool processShouldExit(); bool processShouldExit();
// from NotifyClient // from NotifyClient
virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled); virtual bool askForPassword(const std::string &title, const std::string& key_details, bool prev_is_bad , std::string& password,bool& canceled) override;
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason = "") override;
protected: protected:
// from RsThread // from RsThread

View File

@ -0,0 +1,182 @@
#include "SettingsHandler.h"
#include <iostream>
#include <retroshare/rsinit.h>
namespace resource_api
{
#define SETTINGS_FILE (QString::fromUtf8(RsAccounts::AccountDirectory().c_str()) + "/Sonet.conf")
SettingsHandler::SettingsHandler(StateTokenServer *sts, const QString settingsGroup) :
QSettings(SETTINGS_FILE, QSettings::IniFormat),
mStateTokenServer(sts),
mMtx("SettingsHandler Mutex"),
mStateToken(sts->getNewToken())
{
RsPeerId sPreferedId;
m_bValid = RsAccounts::GetPreferredAccountId(sPreferedId);
if (!settingsGroup.isEmpty())
beginGroup(settingsGroup);
addResourceHandler("*", this, &SettingsHandler::handleSettingsRequest);
addResourceHandler("get_advanced_mode", this, &SettingsHandler::handleGetAdvancedMode);
addResourceHandler("set_advanced_mode", this, &SettingsHandler::handleSetAdvancedMode);
addResourceHandler("get_flickable_grid_mode", this, &SettingsHandler::handleGetFlickableGridMode);
addResourceHandler("set_flickable_grid_mode", this, &SettingsHandler::handleSetFlickableGridMode);
addResourceHandler("get_auto_login", this, &SettingsHandler::handleGetAutoLogin);
addResourceHandler("set_auto_login", this, &SettingsHandler::handleSetAutoLogin);
}
SettingsHandler::~SettingsHandler()
{
sync();
}
void SettingsHandler::handleSettingsRequest(Request &/*req*/, Response &resp)
{
}
void SettingsHandler::handleGetAdvancedMode(Request &/*req*/, Response &resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
bool advanced_mode = valueFromGroup("General", "Advanced", false).toBool();
resp.mDataStream << makeKeyValueReference("advanced_mode", advanced_mode);
resp.setOk();
sync();
}
void SettingsHandler::handleSetAdvancedMode(Request &req, Response &resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
bool advanced_mode;
req.mStream << makeKeyValueReference("advanced_mode", advanced_mode);
setValueToGroup("General", "Advanced", advanced_mode);
resp.setOk();
sync();
}
void SettingsHandler::handleGetFlickableGridMode(Request &/*req*/, Response &resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
bool flickable_grid_mode = valueFromGroup("General", "FlickableGrid", false).toBool();
resp.mDataStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode);
resp.setOk();
sync();
}
void SettingsHandler::handleSetFlickableGridMode(Request &req, Response &resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
bool flickable_grid_mode;
req.mStream << makeKeyValueReference("flickable_grid_mode", flickable_grid_mode);
setValueToGroup("General", "FlickableGrid", flickable_grid_mode);
resp.setOk();
sync();
}
void SettingsHandler::handleGetAutoLogin(Request &/*req*/, Response &resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
bool autoLogin = RsInit::getAutoLogin();;
resp.mDataStream << makeKeyValueReference("auto_login", autoLogin);
resp.setOk();
sync();
}
void SettingsHandler::handleSetAutoLogin(Request &req, Response &resp)
{
{
RS_STACK_MUTEX(mMtx);
resp.mStateToken = mStateToken;
}
bool autoLogin;
req.mStream << makeKeyValueReference("auto_login", autoLogin);
RsInit::setAutoLogin(autoLogin);
resp.setOk();
sync();
}
QVariant SettingsHandler::value(const QString &key, const QVariant &defaultVal) const
{
if (m_bValid == false)
{
return defaultVal.isNull() ? defaultValue(key) : defaultVal;
}
return QSettings::value(key, defaultVal.isNull() ? defaultValue(key) : defaultVal);
}
void SettingsHandler::setValue(const QString &key, const QVariant &val)
{
if (m_bValid == false)
{
std::cerr << "RSettings::setValue() Calling on invalid object, key = " << key.toStdString() << std::endl;
return;
}
if (val == defaultValue(key))
QSettings::remove(key);
else if (val != value(key))
QSettings::setValue(key, val);
}
QVariant SettingsHandler::valueFromGroup(const QString &group, const QString &key, const QVariant &defaultVal)
{
beginGroup(group);
QVariant val = value(key, defaultVal);
endGroup();
return val;
}
void SettingsHandler::setValueToGroup(const QString &group, const QString &key, const QVariant &val)
{
beginGroup(group);
setValue(key, val);
endGroup();
}
void SettingsHandler::setDefault(const QString &key, const QVariant &val)
{
_defaults.insert(key, val);
}
QVariant SettingsHandler::defaultValue(const QString &key) const
{
if (_defaults.contains(key))
return _defaults.value(key);
return QVariant();
}
void SettingsHandler::reset()
{
/* Static method, so we have to create a QSettings object. */
QSettings settings(SETTINGS_FILE, QSettings::IniFormat);
settings.clear();
}
} // namespace resource_api

View File

@ -0,0 +1,59 @@
#ifndef SETTINGSHANDLER_H
#define SETTINGSHANDLER_H
#include <QSettings>
#include <util/rsthreads.h>
#include "ResourceRouter.h"
#include "StateTokenServer.h"
/* Reimplemented class RSettings*/
namespace resource_api
{
class SettingsHandler : public ResourceRouter, public QSettings
{
public:
SettingsHandler(StateTokenServer* sts, const QString group = QString());
~SettingsHandler();
static void reset();
QVariant value(const QString &key,
const QVariant &defaultVal = QVariant()) const;
void setValue(const QString &key, const QVariant &val);
QVariant valueFromGroup(const QString &group, const QString &key,
const QVariant &defaultVal = QVariant());
void setValueToGroup(const QString &group, const QString &key,
const QVariant &val);
protected:
void setDefault(const QString &key, const QVariant &val);
QVariant defaultValue(const QString &key) const;
bool m_bValid;
private:
void handleSettingsRequest(Request& req, Response& resp);
void handleGetAdvancedMode(Request& req, Response& resp);
void handleSetAdvancedMode(Request& req, Response& resp);
void handleGetFlickableGridMode(Request& req, Response& resp);
void handleSetFlickableGridMode(Request& req, Response& resp);
void handleGetAutoLogin(Request& req, Response& resp);
void handleSetAutoLogin(Request& req, Response& resp);
QHash<QString, QVariant> _defaults;
StateTokenServer* mStateTokenServer;
RsMutex mMtx;
StateToken mStateToken; // mutex protected
};
} // namespace resource_api
#endif // SETTINGSHANDLER_H

View File

@ -10,6 +10,40 @@ DESTDIR = lib
INCLUDEPATH += ../../libretroshare/src INCLUDEPATH += ../../libretroshare/src
retroshare_android_service {
win32 {
OBJECTS_DIR = temp/obj
LIBS_DIR = $$PWD/../../libs/lib
LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a
LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a
for(lib, LIB_DIR):LIBS += -L"$$lib"
for(bin, BIN_DIR):LIBS += -L"$$bin"
LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32
LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32
LIBS += -lwinmm
DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
DEPENDPATH += . $$INC_DIR
INCLUDEPATH += . $$INC_DIR
greaterThan(QT_MAJOR_VERSION, 4) {
# Qt 5
RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src
} else {
# Qt 4
QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src
}
}
DEPENDPATH += . ../../libretroshare/src/
INCLUDEPATH += ../../libretroshare/src/
}
libresapihttpserver { libresapihttpserver {
CONFIG += libmicrohttpd CONFIG += libmicrohttpd
@ -183,3 +217,11 @@ libresapilocalserver {
SOURCES *= api/ApiServerLocal.cpp SOURCES *= api/ApiServerLocal.cpp
HEADERS *= api/ApiServerLocal.h HEADERS *= api/ApiServerLocal.h
} }
qt_dependencies {
CONFIG *= qt
QT *= core
SOURCES += api/SettingsHandler.cpp
HEADERS += api/SettingsHandler.h
}

View File

@ -6,13 +6,11 @@ QT += core network
QT -= gui QT -= gui
CONFIG += c++11 CONFIG += c++11
CONFIG += dll android-g++:CONFIG += dll
android-g++:TEMPLATE = lib android-g++:TEMPLATE = lib
!android-g++:TEMPLATE = app !android-g++:TEMPLATE = app
SOURCES += service.cpp
DEPENDPATH *= ../../libresapi/src DEPENDPATH *= ../../libresapi/src
INCLUDEPATH *= ../../libresapi/src INCLUDEPATH *= ../../libresapi/src
PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a
@ -22,3 +20,34 @@ DEPENDPATH *= ../../libretroshare/src
INCLUDEPATH *= ../../libretroshare/src INCLUDEPATH *= ../../libretroshare/src
PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a
LIBS *= ../../libretroshare/src/lib/libretroshare.a LIBS *= ../../libretroshare/src/lib/libretroshare.a
win32 {
OBJECTS_DIR = temp/obj
LIBS_DIR = $$PWD/../../libs/lib
LIBS += $$OUT_PWD/../../libretroshare/src/lib/libretroshare.a
LIBS += $$OUT_PWD/../../openpgpsdk/src/lib/libops.a
for(lib, LIB_DIR):LIBS += -L"$$lib"
for(bin, BIN_DIR):LIBS += -L"$$bin"
LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz -lws2_32
LIBS += -luuid -lole32 -liphlpapi -lcrypt32 -lgdi32
LIBS += -lwinmm
DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T
DEPENDPATH += . $$INC_DIR
INCLUDEPATH += . $$INC_DIR
greaterThan(QT_MAJOR_VERSION, 4) {
# Qt 5
RC_INCLUDEPATH += $$_PRO_FILE_PWD_/../../libretroshare/src
} else {
# Qt 4
QMAKE_RC += --include-dir=$$_PRO_FILE_PWD_/../../libretroshare/src
}
}
SOURCES += service.cpp

View File

@ -24,12 +24,10 @@
# include "util/androiddebug.h" # include "util/androiddebug.h"
#endif #endif
#include "retroshare/rsinit.h"
#include "api/ApiServer.h" #include "api/ApiServer.h"
#include "api/ApiServerLocal.h" #include "api/ApiServerLocal.h"
#include "api/RsControlModule.h" #include "api/RsControlModule.h"
using namespace resource_api; using namespace resource_api;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -39,11 +37,17 @@ int main(int argc, char *argv[])
#endif #endif
QCoreApplication a(argc, argv); QCoreApplication a(argc, argv);
ApiServer api; ApiServer api;
RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true); RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true);
api.addResourceHandler("control", dynamic_cast<resource_api::ResourceRouter*>(&ctrl_mod), &resource_api::RsControlModule::handleRequest); api.addResourceHandler("control", dynamic_cast<resource_api::ResourceRouter*>(&ctrl_mod), &resource_api::RsControlModule::handleRequest);
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory()); #ifdef QT_DEBUG
QString sockPath = "RS/";
#else
QString sockPath = QCoreApplication::applicationDirPath();
#endif
sockPath.append("/libresapi.sock"); sockPath.append("/libresapi.sock");
qDebug() << "Listening on:" << sockPath; qDebug() << "Listening on:" << sockPath;
ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal; ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal;

View File

@ -29,6 +29,11 @@ retroshare_qml_app:CONFIG -= no_retroshare_qml_app
CONFIG *= no_libresapilocalserver CONFIG *= no_libresapilocalserver
libresapilocalserver:CONFIG -= no_libresapilocalserver libresapilocalserver:CONFIG -= no_libresapilocalserver
# To enable Qt dependencies in libresapi append the following
# assignation to qmake command line "CONFIG+=qt_dependencies"
CONFIG *= no_qt_dependencies
qt_dependencies:CONFIG -= no_qt_dependencies
# To disable libresapi via HTTP (based on libmicrohttpd) append the following # To disable libresapi via HTTP (based on libmicrohttpd) append the following
# assignation to qmake command line "CONFIG+=no_libresapihttpserver" # assignation to qmake command line "CONFIG+=no_libresapihttpserver"
CONFIG *= libresapihttpserver CONFIG *= libresapihttpserver
@ -155,6 +160,7 @@ unfinished {
wikipoos:DEFINES *= RS_USE_WIKI wikipoos:DEFINES *= RS_USE_WIKI
rs_gxs:DEFINES *= RS_ENABLE_GXS rs_gxs:DEFINES *= RS_ENABLE_GXS
libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER
qt_dependencies:DEFINES *= LIBRESAPI_QT
libresapihttpserver:DEFINES *= ENABLE_WEBUI libresapihttpserver:DEFINES *= ENABLE_WEBUI
sqlcipher:DEFINES -= NO_SQLCIPHER sqlcipher:DEFINES -= NO_SQLCIPHER
no_sqlcipher:DEFINES *= NO_SQLCIPHER no_sqlcipher:DEFINES *= NO_SQLCIPHER