Merge pull request #781 from Sonetio/libresapi_requests

Added few requests handling in libresapi
This commit is contained in:
electron128 2017-04-24 18:43:17 +02:00 committed by GitHub
commit be9f126898
7 changed files with 502 additions and 1 deletions

View File

@ -145,6 +145,7 @@ ChatHandler::ChatHandler(StateTokenServer *sts, RsNotify *notify, RsMsgs *msgs,
addResourceHandler("*", this, &ChatHandler::handleWildcard);
addResourceHandler("lobbies", this, &ChatHandler::handleLobbies);
addResourceHandler("create_lobby", this, &ChatHandler::handleCreateLobby);
addResourceHandler("subscribe_lobby", this, &ChatHandler::handleSubscribeLobby);
addResourceHandler("unsubscribe_lobby", this, &ChatHandler::handleUnsubscribeLobby);
addResourceHandler("autosubscribe_lobby", this, &ChatHandler::handleAutoSubsribeLobby);
@ -1210,4 +1211,37 @@ void ChatHandler::handleCloseDistantChatConnexion(Request& req, Response& resp)
else resp.setFail("Failed to close distant chat");
}
void ChatHandler::handleCreateLobby(Request& req, Response& resp)
{
std::set<RsPeerId> invited_identites;
std::string lobby_name;
std::string lobby_topic;
std::string gxs_id;
req.mStream << makeKeyValueReference("lobby_name", lobby_name);
req.mStream << makeKeyValueReference("lobby_topic", lobby_topic);
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
RsGxsId gxsId(gxs_id);
bool lobby_public;
bool pgp_signed;
req.mStream << makeKeyValueReference("lobby_public", lobby_public);
req.mStream << makeKeyValueReference("pgp_signed", pgp_signed);
ChatLobbyFlags lobby_flags;
if(lobby_public)
lobby_flags |= RS_CHAT_LOBBY_FLAGS_PUBLIC;
if(pgp_signed)
lobby_flags |= RS_CHAT_LOBBY_FLAGS_PGP_SIGNED;
mRsMsgs->createChatLobby(lobby_name, gxsId, lobby_topic, invited_identites, lobby_flags);
tick();
resp.setOk();
}
} // namespace resource_api

View File

@ -118,6 +118,7 @@ public:
private:
void handleWildcard(Request& req, Response& resp);
void handleLobbies(Request& req, Response& resp);
void handleCreateLobby(Request& req, Response& resp);
void handleSubscribeLobby(Request& req, Response& resp);
void handleUnsubscribeLobby(Request& req, Response& resp);
void handleAutoSubsribeLobby(Request& req, Response& resp);

View File

@ -1,6 +1,7 @@
#include "IdentityHandler.h"
#include <retroshare/rsidentity.h>
#include <retroshare/rspeers.h>
#include <time.h>
#include "Operators.h"
@ -95,6 +96,37 @@ protected:
}
};
class DeleteIdentityTask : public GxsResponseTask
{
public:
DeleteIdentityTask(RsIdentity* idservice) :
GxsResponseTask(idservice, idservice->getTokenService()),
mToken(0),
mRsIdentity(idservice)
{}
protected:
virtual void gxsDoWork(Request &req, Response &resp)
{
RsGxsIdGroup group;
std::string gxs_id;
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
group.mMeta.mGroupId = RsGxsGroupId(gxs_id);
mRsIdentity->deleteIdentity(mToken, group);
addWaitingToken(mToken);
done();
return;
}
private:
uint32_t mToken;
RsIdentity* mRsIdentity;
RsGxsId mId;
};
IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIdentity *identity):
mStateTokenServer(sts), mNotify(notify), mRsIdentity(identity),
mMtx("IdentityHandler Mtx"), mStateToken(sts->getNewToken())
@ -107,7 +139,16 @@ IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIden
addResourceHandler("own_ids", this, &IdentityHandler::handleOwnIdsRequest);
addResourceHandler("notown_ids", this, &IdentityHandler::handleNotOwnIdsRequest);
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
addResourceHandler("add_contact", this, &IdentityHandler::handleAddContact);
addResourceHandler("remove_contact", this, &IdentityHandler::handleRemoveContact);
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
addResourceHandler("delete_identity", this, &IdentityHandler::handleDeleteIdentity);
addResourceHandler("get_identity_details", this, &IdentityHandler::handleGetIdentityDetails);
addResourceHandler("set_ban_node", this, &IdentityHandler::handleSetBanNode);
addResourceHandler("set_opinion", this, &IdentityHandler::handleSetOpinion);
}
IdentityHandler::~IdentityHandler()
@ -166,6 +207,7 @@ void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp)
<< makeKeyValueReference("gxs_id", grp.mMeta.mGroupId)
<< makeKeyValueReference("pgp_id",grp.mPgpId )
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
<< makeKeyValueReference("contact", grp.mIsAContact)
<< makeKeyValueReference("own", own)
<< makeKeyValueReference("pgp_linked", pgp_linked);
}
@ -282,6 +324,207 @@ void IdentityHandler::handleOwnIdsRequest(Request & /*req*/, Response &resp)
else resp.setFail();
}
void IdentityHandler::handleAddContact(Request& req, Response& resp)
{
std::string gxs_id;
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), true);
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mStateTokenServer->replaceToken(mStateToken);
}
resp.setOk();
}
void IdentityHandler::handleRemoveContact(Request& req, Response& resp)
{
std::string gxs_id;
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
mRsIdentity->setAsRegularContact(RsGxsId(gxs_id), false);
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mStateTokenServer->replaceToken(mStateToken);
}
resp.setOk();
}
void IdentityHandler::handleGetIdentityDetails(Request& req, Response& resp)
{
std::string gxs_id;
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
std::list<RsGxsGroupId> groupIds;
groupIds.push_back(RsGxsGroupId(gxs_id));
mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds);
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
}
RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector;
if (!mRsIdentity->getGroupData(token, datavector))
{
resp.setFail();
return;
}
if(datavector.empty())
{
resp.setFail();
return;
}
data = datavector[0];
resp.mDataStream << makeKeyValue("gxs_name", data.mMeta.mGroupName);
resp.mDataStream << makeKeyValue("gxs_id", data.mMeta.mGroupId.toStdString());
resp.mDataStream << makeKeyValue("pgp_id_known", data.mPgpKnown);
resp.mDataStream << makeKeyValue("pgp_id", data.mPgpId.toStdString());
std::string pgp_name;
if (data.mPgpKnown)
{
RsPeerDetails details;
rsPeers->getGPGDetails(data.mPgpId, details);
pgp_name = details.name;
}
else
{
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
pgp_name = "[Unknown node]";
else
pgp_name = "Anonymous Id";
}
resp.mDataStream << makeKeyValue("pgp_name", pgp_name);
resp.mDataStream << makeKeyValue("last_usage", (uint32_t)data.mLastUsageTS);
bool isAnonymous = false;
if(!data.mPgpKnown)
{
if (!(data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility))
isAnonymous = true;
}
resp.mDataStream << makeKeyValue("anonymous", isAnonymous);
bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
resp.mDataStream << makeKeyValue("own", isOwnId);
std::string type;
if(isOwnId)
{
if (data.mPgpKnown && !data.mPgpId.isNull())
type = "Identity owned by you, linked to your Retroshare node";
else
type = "Anonymous identity, owned by you";
}
else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{
if (data.mPgpKnown)
{
if (rsPeers->isGPGAccepted(data.mPgpId))
type = "Linked to a friend Retroshare node";
else
type = "Linked to a known Retroshare node";
}
else
type = "Linked to unknown Retroshare node";
}
else
type = "Anonymous identity";
resp.mDataStream << makeKeyValue("type", type);
resp.mDataStream << makeKeyValue("bannned_node", rsReputations->isNodeBanned(data.mPgpId));
RsReputations::ReputationInfo info;
rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId), data.mPgpId, info);
resp.mDataStream << makeKeyValue("friends_positive_votes", info.mFriendsPositiveVotes);
resp.mDataStream << makeKeyValue("friends_negative_votes", info.mFriendsNegativeVotes);
resp.mDataStream << makeKeyValue("overall_reputation_level", (int)info.mOverallReputationLevel);
resp.mDataStream << makeKeyValue("own_opinion", (int)info.mOwnOpinion);
RsIdentityDetails details;
mRsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId), details);
StreamBase& usagesStream = resp.mDataStream.getStreamToMember("usages");
usagesStream.getStreamToMember();
for(std::map<RsIdentityUsage,time_t>::const_iterator it(details.mUseCases.begin()); it != details.mUseCases.end(); ++it)
{
usagesStream.getStreamToMember()
<< makeKeyValue("usage_time", (uint32_t)data.mLastUsageTS)
<< makeKeyValue("usage_service", (int)(it->first.mServiceId))
<< makeKeyValue("usage_case", (int)(it->first.mUsageCode));
}
resp.setOk();
}
void IdentityHandler::handleSetBanNode(Request& req, Response& resp)
{
std::string pgp_id;
req.mStream << makeKeyValueReference("pgp_id", pgp_id);
RsPgpId pgpId(pgp_id);
bool banned_node;
req.mStream << makeKeyValueReference("banned_node", banned_node);
rsReputations->banNode(pgpId, banned_node);
resp.setOk();
}
void IdentityHandler::handleSetOpinion(Request& req, Response& resp)
{
std::string gxs_id;
req.mStream << makeKeyValueReference("gxs_id", gxs_id);
RsGxsId gxsId(gxs_id);
int own_opinion;
req.mStream << makeKeyValueReference("own_opinion", own_opinion);
RsReputations::Opinion opinion;
switch(own_opinion)
{
case 0:
opinion = RsReputations::OPINION_NEGATIVE;
break;
case 1: opinion =
RsReputations::OPINION_NEUTRAL;
break;
case 2:
opinion = RsReputations::OPINION_POSITIVE;
break;
default:
resp.setFail();
return;
}
rsReputations->setOwnOpinion(gxsId, opinion);
resp.setOk();
}
ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp)
{
StateToken state;
@ -302,4 +545,9 @@ ResponseTask* IdentityHandler::handleCreateIdentity(Request & /* req */, Respons
return new CreateIdentityTask(mRsIdentity);
}
ResponseTask* IdentityHandler::handleDeleteIdentity(Request& req, Response& resp)
{
return new DeleteIdentityTask(mRsIdentity);
}
} // namespace resource_api

View File

@ -26,8 +26,17 @@ private:
void handleNotOwnIdsRequest(Request& req, Response& resp);
void handleOwnIdsRequest(Request& req, Response& resp);
void handleAddContact(Request& req, Response& resp);
void handleRemoveContact(Request& req, Response& resp);
void handleGetIdentityDetails(Request& req, Response& resp);
void handleSetBanNode(Request& req, Response& resp);
void handleSetOpinion(Request& req, Response& resp);
ResponseTask *handleOwn(Request& req, Response& resp);
ResponseTask *handleCreateIdentity(Request& req, Response& resp);
ResponseTask *handleDeleteIdentity(Request& req, Response& resp);
StateTokenServer* mStateTokenServer;
RsNotify* mNotify;

View File

@ -4,6 +4,7 @@
#include <retroshare/rsmsgs.h>
#include <util/radix64.h>
#include <retroshare/rsstatus.h>
#include <retroshare/rsiface.h>
#include <algorithm>
@ -106,6 +107,84 @@ bool peerInfoToStream(StreamBase& stream, RsPeerDetails& details, RsPeers* peers
return ok;
}
std::string peerStateString(int peerState)
{
if (peerState & RS_PEER_STATE_CONNECTED) {
return "Connected";
} else if (peerState & RS_PEER_STATE_UNREACHABLE) {
return "Unreachable";
} else if (peerState & RS_PEER_STATE_ONLINE) {
return "Available";
} else if (peerState & RS_PEER_STATE_FRIEND) {
return "Offline";
}
return "Neighbor";
}
std::string connectStateString(RsPeerDetails &details)
{
std::string stateString;
bool isConnected = false;
switch (details.connectState) {
case 0:
stateString = peerStateString(details.state);
break;
case RS_PEER_CONNECTSTATE_TRYING_TCP:
stateString = "Trying TCP";
break;
case RS_PEER_CONNECTSTATE_TRYING_UDP:
stateString = "Trying UDP";
break;
case RS_PEER_CONNECTSTATE_CONNECTED_TCP:
stateString = "Connected: TCP";
isConnected = true;
break;
case RS_PEER_CONNECTSTATE_CONNECTED_UDP:
stateString = "Connected: UDP";
isConnected = true;
break;
case RS_PEER_CONNECTSTATE_CONNECTED_TOR:
stateString = "Connected: Tor";
isConnected = true;
break;
case RS_PEER_CONNECTSTATE_CONNECTED_I2P:
stateString = "Connected: I2P";
isConnected = true;
break;
case RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN:
stateString = "Connected: Unknown";
isConnected = true;
break;
}
if(isConnected) {
stateString += " ";
if(details.actAsServer)
stateString += "inbound connection";
else
stateString += "outbound connection";
}
if (details.connectStateString.empty() == false) {
if (stateString.empty() == false) {
stateString += ": ";
}
stateString += details.connectStateString;
}
/* HACK to display DHT Status info too */
if (details.foundDHT) {
if (stateString.empty() == false) {
stateString += ", ";
}
stateString += "DHT: Contact";
}
return stateString;
}
PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *peers, RsMsgs* msgs):
mStateTokenServer(sts),
mNotify(notify),
@ -121,6 +200,8 @@ PeersHandler::PeersHandler(StateTokenServer* sts, RsNotify* notify, RsPeers *pee
addResourceHandler("set_custom_state_string", this, &PeersHandler::handleSetCustomStateString);
addResourceHandler("get_pgp_options", this, &PeersHandler::handleGetPGPOptions);
addResourceHandler("set_pgp_options", this, &PeersHandler::handleSetPGPOptions);
addResourceHandler("get_node_options", this, &PeersHandler::handleGetNodeOptions);
addResourceHandler("set_node_options", this, &PeersHandler::handleSetNodeOptions);
addResourceHandler("examine_cert", this, &PeersHandler::handleExamineCert);
}
@ -140,6 +221,12 @@ void PeersHandler::notifyListChange(int list, int /* type */)
}
}
void PeersHandler::notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
mStateTokenServer->replaceToken(mStateToken);
}
void PeersHandler::notifyPeerHasNewAvatar(std::string /*peer_id*/)
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/
@ -645,6 +732,123 @@ void PeersHandler::handleSetPGPOptions(Request& req, Response& resp)
resp.setOk();
}
void PeersHandler::handleGetNodeOptions(Request& req, Response& resp)
{
std::string peer_id;
req.mStream << makeKeyValueReference("peer_id", peer_id);
RsPeerId peerId(peer_id);
RsPeerDetails detail;
if(!mRsPeers->getPeerDetails(peerId, detail))
{
resp.setFail();
return;
}
resp.mDataStream << makeKeyValue("peer_id", detail.id.toStdString());
resp.mDataStream << makeKeyValue("name", detail.name);
resp.mDataStream << makeKeyValue("location", detail.location);
resp.mDataStream << makeKeyValue("pgp_id", detail.gpg_id.toStdString());
resp.mDataStream << makeKeyValue("last_contact", detail.lastConnect);
std::string status_message = mRsMsgs->getCustomStateString(detail.id);
resp.mDataStream << makeKeyValueReference("status_message", status_message);
std::string encryption;
RsPeerCryptoParams cdet;
if(RsControl::instance()->getPeerCryptoDetails(detail.id, cdet) && cdet.connexion_state != 0)
{
encryption = cdet.cipher_version;
encryption += ": ";
encryption += cdet.cipher_name;
if(cdet.cipher_version != "TLSv1.2")
encryption += cdet.cipher_bits_1;
}
else
encryption = "Not connected";
resp.mDataStream << makeKeyValueReference("encryption", encryption);
resp.mDataStream << makeKeyValue("is_hidden_node", detail.isHiddenNode);
if (detail.isHiddenNode)
{
resp.mDataStream << makeKeyValue("local_address", detail.hiddenNodeAddress);
resp.mDataStream << makeKeyValue("local_port", (int)detail.hiddenNodePort);
resp.mDataStream << makeKeyValue("ext_address", std::string("none"));
resp.mDataStream << makeKeyValue("ext_port", 0);
resp.mDataStream << makeKeyValue("dyn_dns", std::string("none"));
}
else
{
resp.mDataStream << makeKeyValue("local_address", detail.localAddr);
resp.mDataStream << makeKeyValue("local_port", (int)detail.localPort);
resp.mDataStream << makeKeyValue("ext_address", detail.extAddr);
resp.mDataStream << makeKeyValue("ext_port", (int)detail.extPort);
resp.mDataStream << makeKeyValue("dyn_dns", detail.dyndns);
}
resp.mDataStream << makeKeyValue("connection_status", connectStateString(detail));
StreamBase& addressesStream = resp.mDataStream.getStreamToMember("ip_addresses");
// mark as list (in case list is empty)
addressesStream.getStreamToMember();
for(std::list<std::string>::const_iterator it(detail.ipAddressList.begin()); it != detail.ipAddressList.end(); ++it)
{
addressesStream.getStreamToMember() << makeKeyValue("ip_address", (*it));
}
std::string certificate = mRsPeers->GetRetroshareInvite(detail.id, false);
resp.mDataStream << makeKeyValueReference("certificate", certificate);
resp.setOk();
}
void PeersHandler::handleSetNodeOptions(Request& req, Response& resp)
{
std::string peer_id;
req.mStream << makeKeyValueReference("peer_id", peer_id);
RsPeerId peerId(peer_id);
RsPeerDetails detail;
if(!mRsPeers->getPeerDetails(peerId, detail))
{
resp.setFail();
return;
}
std::string local_address;
std::string ext_address;
std::string dyn_dns;
int local_port;
int ext_port;
req.mStream << makeKeyValueReference("local_address", local_address);
req.mStream << makeKeyValueReference("local_port", local_port);
req.mStream << makeKeyValueReference("ext_address", ext_address);
req.mStream << makeKeyValueReference("ext_port", ext_port);
req.mStream << makeKeyValueReference("dyn_dns", dyn_dns);
if(!detail.isHiddenNode)
{
if(detail.localAddr != local_address || (int)detail.localPort != local_port)
mRsPeers->setLocalAddress(peerId, local_address, local_port);
if(detail.extAddr != ext_address || (int)detail.extPort != ext_port)
mRsPeers->setExtAddress(peerId, ext_address, ext_port);
if(detail.dyndns != dyn_dns)
mRsPeers->setDynDNS(peerId, dyn_dns);
}
else
{
if(detail.hiddenNodeAddress != local_address || detail.hiddenNodePort != local_port)
rsPeers->setHiddenNode(peerId, local_address, local_port);
}
resp.setOk();
}
StateToken PeersHandler::getCurrentStateToken()
{
RsStackMutex stack(mMtx); /********** STACK LOCKED MTX ******/

View File

@ -21,6 +21,7 @@ public:
// from NotifyClient
// note: this may get called from foreign threads
virtual void notifyListChange(int list, int type); // friends list change
virtual void notifyPeerStatusChanged(const std::string& /*peer_id*/, uint32_t /*state*/);
virtual void notifyPeerHasNewAvatar(std::string /*peer_id*/);
// from Tickable
@ -44,6 +45,9 @@ private:
void handleGetPGPOptions(Request& req, Response& resp);
void handleSetPGPOptions(Request& req, Response& resp);
void handleGetNodeOptions(Request& req, Response& resp);
void handleSetNodeOptions(Request& req, Response& resp);
// a helper which ensures proper mutex locking
StateToken getCurrentStateToken();

View File

@ -456,6 +456,7 @@ void RsControlModule::handleCreateLocation(Request &req, Response &resp)
// give the password to the password callback
{
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
mPassword = pgp_password;
mFixedPassword = pgp_password;
}
bool ssl_ok = RsAccounts::GenerateSSLCertificate(pgp_id, "", ssl_name, "", hidden_port!=0, ssl_password, ssl_id, err_string);