2015-03-18 18:48:43 +00:00
|
|
|
#include "IdentityHandler.h"
|
|
|
|
|
|
|
|
#include <retroshare/rsidentity.h>
|
2015-03-19 10:09:35 +00:00
|
|
|
#include <time.h>
|
2015-03-18 18:48:43 +00:00
|
|
|
|
|
|
|
#include "Operators.h"
|
|
|
|
#include "ApiTypes.h"
|
|
|
|
#include "GxsResponseTask.h"
|
|
|
|
#ifndef WINDOWS_SYS
|
|
|
|
#include "unistd.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace resource_api
|
|
|
|
{
|
|
|
|
|
|
|
|
class SendIdentitiesListTask: public GxsResponseTask
|
|
|
|
{
|
|
|
|
public:
|
2016-02-07 11:11:45 +01:00
|
|
|
SendIdentitiesListTask(RsIdentity* idservice, std::list<RsGxsId> ids, StateToken state):
|
|
|
|
GxsResponseTask(idservice, 0), mStateToken(state)
|
2015-03-18 18:48:43 +00:00
|
|
|
{
|
|
|
|
for(std::list<RsGxsId>::iterator vit = ids.begin(); vit != ids.end(); ++vit)
|
|
|
|
{
|
|
|
|
requestGxsId(*vit);
|
2016-02-07 11:11:45 +01:00
|
|
|
mIds.push_back(*vit);// convert from list to vector
|
2015-03-18 18:48:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
std::vector<RsGxsId> mIds;
|
2016-02-07 11:11:45 +01:00
|
|
|
StateToken mStateToken;
|
2015-03-18 18:48:43 +00:00
|
|
|
protected:
|
|
|
|
virtual void gxsDoWork(Request &req, Response &resp)
|
|
|
|
{
|
|
|
|
resp.mDataStream.getStreamToMember();
|
|
|
|
for(std::vector<RsGxsId>::iterator vit = mIds.begin(); vit != mIds.end(); ++vit)
|
|
|
|
{
|
|
|
|
streamGxsId(*vit, resp.mDataStream.getStreamToMember());
|
|
|
|
}
|
2016-02-07 11:11:45 +01:00
|
|
|
resp.mStateToken = mStateToken;
|
2015-03-18 18:48:43 +00:00
|
|
|
resp.setOk();
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2016-01-31 16:04:34 +01:00
|
|
|
class CreateIdentityTask: public GxsResponseTask
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
CreateIdentityTask(RsIdentity* idservice):
|
|
|
|
GxsResponseTask(idservice, idservice->getTokenService()), mState(BEGIN), mToken(0), mRsIdentity(idservice){}
|
|
|
|
private:
|
|
|
|
enum State {BEGIN, WAIT_ACKN, WAIT_ID};
|
|
|
|
State mState;
|
|
|
|
uint32_t mToken;
|
|
|
|
RsIdentity* mRsIdentity;
|
|
|
|
RsGxsId mId;
|
|
|
|
protected:
|
|
|
|
virtual void gxsDoWork(Request &req, Response &resp)
|
|
|
|
{
|
|
|
|
switch(mState)
|
|
|
|
{
|
|
|
|
case BEGIN:{
|
|
|
|
RsIdentityParameters params;
|
|
|
|
req.mStream << makeKeyValueReference("name", params.nickname) << makeKeyValueReference("pgp_linked", params.isPgpLinked);
|
|
|
|
|
|
|
|
if(params.nickname == "")
|
|
|
|
{
|
|
|
|
resp.setFail("name can't be empty");
|
|
|
|
done();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mRsIdentity->createIdentity(mToken, params);
|
|
|
|
addWaitingToken(mToken);
|
|
|
|
mState = WAIT_ACKN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WAIT_ACKN:{
|
|
|
|
RsGxsGroupId grpId;
|
|
|
|
if(!mRsIdentity->acknowledgeGrp(mToken, grpId))
|
|
|
|
{
|
|
|
|
resp.setFail("acknowledge of group id failed");
|
|
|
|
done();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mId = RsGxsId(grpId);
|
|
|
|
requestGxsId(mId);
|
|
|
|
mState = WAIT_ID;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WAIT_ID:
|
|
|
|
streamGxsId(mId, resp.mDataStream);
|
|
|
|
resp.setOk();
|
|
|
|
done();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-02-07 11:11:45 +01:00
|
|
|
IdentityHandler::IdentityHandler(StateTokenServer *sts, RsNotify *notify, RsIdentity *identity):
|
|
|
|
mStateTokenServer(sts), mNotify(notify), mRsIdentity(identity),
|
|
|
|
mMtx("IdentityHandler Mtx"), mStateToken(sts->getNewToken())
|
2015-03-18 18:48:43 +00:00
|
|
|
{
|
2016-02-07 11:11:45 +01:00
|
|
|
mNotify->registerNotifyClient(this);
|
|
|
|
|
2015-03-18 18:48:43 +00:00
|
|
|
addResourceHandler("*", this, &IdentityHandler::handleWildcard);
|
|
|
|
addResourceHandler("own", this, &IdentityHandler::handleOwn);
|
2016-01-31 16:04:34 +01:00
|
|
|
addResourceHandler("create_identity", this, &IdentityHandler::handleCreateIdentity);
|
2015-03-18 18:48:43 +00:00
|
|
|
}
|
|
|
|
|
2016-02-07 11:11:45 +01:00
|
|
|
IdentityHandler::~IdentityHandler()
|
|
|
|
{
|
|
|
|
mNotify->unregisterNotifyClient(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IdentityHandler::notifyGxsChange(const RsGxsChanges &changes)
|
|
|
|
{
|
|
|
|
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
|
|
|
|
// if changes come from identity service, invalidate own state token
|
|
|
|
if(changes.mService == mRsIdentity->getTokenService())
|
|
|
|
{
|
|
|
|
mStateTokenServer->replaceToken(mStateToken);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-18 18:48:43 +00:00
|
|
|
void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
|
|
|
{
|
|
|
|
bool ok = true;
|
|
|
|
|
|
|
|
if(req.isPut())
|
|
|
|
{
|
2016-02-07 11:11:45 +01:00
|
|
|
#ifdef REMOVE
|
2015-03-18 18:48:43 +00:00
|
|
|
RsIdentityParameters params;
|
|
|
|
req.mStream << makeKeyValueReference("name", params.nickname);
|
|
|
|
if(req.mStream.isOK())
|
|
|
|
{
|
|
|
|
uint32_t token;
|
|
|
|
mRsIdentity->createIdentity(token, params);
|
|
|
|
// not sure if should acknowledge the token
|
|
|
|
// for now go the easier way
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok = false;
|
|
|
|
}
|
2016-02-07 11:11:45 +01:00
|
|
|
#endif
|
2015-03-18 18:48:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-02-07 11:11:45 +01:00
|
|
|
{
|
|
|
|
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
|
|
|
|
resp.mStateToken = mStateToken;
|
|
|
|
}
|
2015-03-18 18:48:43 +00:00
|
|
|
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;
|
|
|
|
KeyValueReference<RsGxsGroupId> id("id", grp.mMeta.mGroupId);
|
|
|
|
KeyValueReference<RsPgpId> pgp_id("pgp_id",grp.mPgpId );
|
|
|
|
// not very happy about this, i think the flags should stay hidden in rsidentities
|
|
|
|
bool own = (grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
|
|
|
|
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
|
|
|
|
resp.mDataStream.getStreamToMember()
|
|
|
|
<< id
|
|
|
|
<< pgp_id
|
|
|
|
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
|
|
|
|
<< makeKeyValueReference("own", own)
|
|
|
|
<< makeKeyValueReference("pgp_linked", pgp_linked);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ok = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ok)
|
|
|
|
{
|
|
|
|
resp.setOk();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
resp.setFail();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-06 22:27:02 -04:00
|
|
|
ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp)
|
2015-03-18 18:48:43 +00:00
|
|
|
{
|
2016-02-07 11:11:45 +01:00
|
|
|
StateToken state;
|
|
|
|
{
|
|
|
|
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
|
|
|
|
state = mStateToken;
|
|
|
|
}
|
2015-03-18 18:48:43 +00:00
|
|
|
std::list<RsGxsId> ids;
|
2015-07-29 15:02:10 +02:00
|
|
|
if(mRsIdentity->getOwnIds(ids))
|
2016-02-07 11:11:45 +01:00
|
|
|
return new SendIdentitiesListTask(mRsIdentity, ids, state);
|
2015-07-29 15:02:10 +02:00
|
|
|
resp.mDataStream.getStreamToMember();
|
|
|
|
resp.setWarning("identities not loaded yet");
|
|
|
|
return 0;
|
2015-03-18 18:48:43 +00:00
|
|
|
}
|
|
|
|
|
2016-06-05 10:43:57 -04:00
|
|
|
ResponseTask* IdentityHandler::handleCreateIdentity(Request & /* req */, Response & /* resp */)
|
2016-01-31 16:04:34 +01:00
|
|
|
{
|
|
|
|
return new CreateIdentityTask(mRsIdentity);
|
|
|
|
}
|
|
|
|
|
2015-03-18 18:48:43 +00:00
|
|
|
} // namespace resource_api
|