Add login JSON API

Implement a "normal" way to login RsLoginHelper::attemptLogin
Implement a way to get locations list RsLoginHelper::getLocations
Enable JSON API into retroshare-android-service
This commit is contained in:
Gioacchino Mazzurco 2018-06-27 08:52:03 +02:00
parent d14a455cf1
commit 4637fbaff5
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
3 changed files with 181 additions and 90 deletions

View File

@ -47,80 +47,89 @@
#include <vector>
#include <retroshare/rstypes.h>
struct RsLoginHelper;
/**
* Pointer to global instance of RsLoginHelper
* @jsonapi{development}
*/
extern RsLoginHelper* rsLoginHelper;
/*!
* Initialisation Class (not publicly disclosed to RsIFace)
*/
class RsInit
{
public:
/* reorganised RsInit system */
public:
enum LoadCertificateStatus : uint8_t
{
OK, /// Everything go as expected, no error occurred
ERR_ALREADY_RUNNING, /// Another istance is running already
ERR_CANT_ACQUIRE_LOCK, /// Another istance is already running?
ERR_UNKOWN /// Unkown error, maybe password is wrong?
};
/*!
* PreLogin
* Call before init retroshare, initialises rsinitconfig's public attributes
*/
static void InitRsConfig() ;
/* reorganised RsInit system */
/*!
* Should be called to load up ssl cert and private key, and intialises gpg
* this must be called before accessing rsserver (e.g. ::startupretroshare)
* @param argc passed from executable
* @param argv commandline arguments passed to executable
* @param strictCheck set to true if you want rs to continue executing if invalid argument passed and vice versa
* @return RS_INIT_...
*/
static int InitRetroShare(int argc, char **argv, bool strictCheck=true);
/*!
* PreLogin
* Call before init retroshare, initialises rsinitconfig's public attributes
*/
static void InitRsConfig();
static bool isPortable();
static bool isWindowsXP();
static bool collectEntropy(uint32_t bytes) ;
/*!
* Should be called to load up ssl cert and private key, and intialises gpg
* this must be called before accessing rsserver (e.g. ::startupretroshare)
* @param argc passed from executable
* @param argv commandline arguments passed to executable
* @param strictCheck set to true if you want rs to continue executing if
* invalid argument passed and vice versa
* @return RS_INIT_...
*/
static int InitRetroShare(int argc, char **argv, bool strictCheck=true);
/*!
* Setup Hidden Location;
*/
static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob);
static bool isPortable();
static bool isWindowsXP();
static bool collectEntropy(uint32_t bytes) ;
static bool LoadPassword(const std::string& passwd) ;
/*
* Setup Hidden Location;
*/
static void SetHiddenLocation(const std::string& hiddenaddress, uint16_t port, bool useBob);
/*!
static bool LoadPassword(const std::string& passwd) ;
/*
* Final Certificate load. This can be called if:
* a) InitRetroshare() returns RS_INIT_HAVE_ACCOUNT -> autoLoad/password Set.
* b) or LoadPassword()
*
* This uses the preferredId from RsAccounts.
* This wrapper also locks the profile before finalising the login
*/
static LoadCertificateStatus LockAndLoadCertificates(
bool autoLoginNT, std::string& lockFilePath );
* Final Certificate load. This can be called if:
* a) InitRetroshare() returns RS_INIT_HAVE_ACCOUNT -> autoLoad/password Set.
* b) or LoadPassword()
*
* This uses the preferredId from RsAccounts.
* This wrapper also locks the profile before finalising the login
*/
static int LockAndLoadCertificates(bool autoLoginNT, std::string& lockFilePath);
// Post Login Options
static bool getStartMinimised();
/*!
* Post Login Options
*/
static int getSslPwdLen();
static bool getAutoLogin();
static void setAutoLogin(bool autoLogin);
static bool RsClearAutoLogin() ;
static bool getStartMinimised();
private:
/** @brief Lock profile directory
* param[in] accountDir account directory to lock
* param[out] lockFilePath path of the created lock-file
*/
static LoadCertificateStatus LockConfigDirectory(
const std::string& accountDir, std::string& lockFilePath);
static int getSslPwdLen();
static bool getAutoLogin();
static void setAutoLogin(bool autoLogin);
static bool RsClearAutoLogin() ;
private:
#if 0
/* Auto Login */
static bool RsStoreAutoLogin() ;
static bool RsTryAutoLogin() ;
#endif
// THESE CAN BE REMOVED FROM THE CLASS TOO.
/* Lock/unlock profile directory */
static int LockConfigDirectory(const std::string& accountDir, std::string& lockFilePath);
static void UnlockConfigDirectory();
/* The true LoadCertificates() method */
static int LoadCertificates(bool autoLoginNT) ;
/// @brief Unlock profile directory
static void UnlockConfigDirectory();
static int LoadCertificates(bool autoLoginNT);
};
@ -170,9 +179,43 @@ namespace RsAccounts
bool GenerateSSLCertificate(const RsPgpId& pgp_id, const std::string& org, const std::string& loc, const std::string& country, const bool ishiddenloc, const std::string& passwd, RsPeerId &sslId, std::string &errString);
}
/**
* This helper class have been implemented because there was not reasonable way
* to login in the API that could be exposed via JSON API
*/
struct RsLoginHelper
{
/**
* @brief Normal way to attempt login
* @jsonapi{development}
* @param[in] account Id of the account to which attempt login
* @param[in] password Password for the given account
* @return RsInit::OK if login attempt success, error code otherwhise
*/
RsInit::LoadCertificateStatus attemptLogin(
const RsPeerId& account, const std::string& password );
struct Location : RsSerializable
{
RsPeerId mLocationId;
RsPgpId mPgpId;
std::string mLocationName;
std::string mPpgName;
/// @see RsSerializable::serial_process
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx );
};
/**
* @brief Get locations and associated information
* @jsonapi{development}
* @param[out] locations storage for the retrived locations
*/
void getLocations(std::vector<RsLoginHelper::Location>& locations);
};
#endif

View File

@ -103,7 +103,9 @@ RsDht *rsDht = NULL ;
//std::map<std::string,std::vector<std::string> > RsInit::unsupported_keys ;
class RsInitConfig
RsLoginHelper* rsLoginHelper;
class RsInitConfig
{
public:
@ -433,7 +435,8 @@ int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
AuthSSL::AuthSSLInit();
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL, "");
rsAccounts = new RsAccountsDetail();
rsLoginHelper = new RsLoginHelper;
rsAccounts = new RsAccountsDetail;
// first check config directories, and set bootstrap values.
if(!rsAccounts->setupBaseDirectory(opt_base_dir))
@ -503,12 +506,21 @@ int RsInit::InitRetroShare(int argc, char **argv, bool /* strictCheck */)
* 1 : Another instance already has the lock
* 2 : Unexpected error
*/
int RsInit::LockConfigDirectory(const std::string& accountDir, std::string& lockFilePath)
RsInit::LoadCertificateStatus RsInit::LockConfigDirectory(
const std::string& accountDir, std::string& lockFilePath )
{
const std::string lockFile = accountDir + "/" + "lock";
lockFilePath = lockFile;
return RsDirUtil::createLockFile(lockFile,rsInitConfig->lockHandle) ;
int rt = RsDirUtil::createLockFile(lockFile,rsInitConfig->lockHandle);
switch (rt)
{
case 0: return RsInit::OK;
case 1: return RsInit::ERR_ALREADY_RUNNING;
case 2: return RsInit::ERR_CANT_ACQUIRE_LOCK;
default: return RsInit::ERR_UNKOWN;
}
}
/*
@ -540,54 +552,45 @@ bool RsInit::LoadPassword(const std::string& inPwd)
return true;
}
/**
* Locks the profile directory and tries to finalize the login procedure
*
* Return value:
* 0 : success
* 1 : another instance is already running
* 2 : unexpected error while locking
* 3 : unexpected error while loading certificates
*/
int RsInit::LockAndLoadCertificates(bool autoLoginNT, std::string& lockFilePath)
RsInit::LoadCertificateStatus RsInit::LockAndLoadCertificates(
bool autoLoginNT, std::string& lockFilePath )
{
if (!rsAccounts->lockPreferredAccount())
{
return 3; // invalid PreferredAccount.
return RsInit::ERR_UNKOWN; // invalid PreferredAccount.
}
int retVal = 0;
LoadCertificateStatus retVal = RsInit::OK;
// Logic that used to be external to RsInit...
RsPeerId accountId;
if (!rsAccounts->getPreferredAccountId(accountId))
{
retVal = 3; // invalid PreferredAccount;
retVal = RsInit::ERR_UNKOWN; // invalid PreferredAccount;
}
RsPgpId pgpId;
std::string pgpName, pgpEmail, location;
if (retVal == 0 && !rsAccounts->getAccountDetails(accountId, pgpId, pgpName, pgpEmail, location))
retVal = 3; // invalid PreferredAccount;
if (retVal == RsInit::OK &&
!rsAccounts->getAccountDetails(
accountId, pgpId, pgpName, pgpEmail, location ) )
retVal = RsInit::ERR_UNKOWN; // invalid PreferredAccount;
if (retVal == 0 && !rsAccounts->SelectPGPAccount(pgpId))
retVal = 3; // PGP Error.
if (retVal == RsInit::OK && !rsAccounts->SelectPGPAccount(pgpId))
retVal = RsInit::ERR_UNKOWN; // PGP Error.
if(retVal == 0)
retVal = LockConfigDirectory(rsAccounts->PathAccountDirectory(), lockFilePath);
if(retVal == RsInit::OK)
retVal = LockConfigDirectory(
rsAccounts->PathAccountDirectory(), lockFilePath );
if(retVal == 0 && LoadCertificates(autoLoginNT) != 1)
if(retVal == RsInit::OK && LoadCertificates(autoLoginNT) != 1)
{
UnlockConfigDirectory();
retVal = 3;
retVal = RsInit::ERR_UNKOWN;
}
if(retVal != 0)
{
rsAccounts->unlockPreferredAccount();
}
if(retVal != RsInit::OK) rsAccounts->unlockPreferredAccount();
return retVal;
}
@ -1900,3 +1903,43 @@ int RsServer::StartupRetroShare()
return 1;
}
RsInit::LoadCertificateStatus RsLoginHelper::attemptLogin(
const RsPeerId& account, const std::string& password)
{
if(!rsNotify->cachePgpPassphrase(password)) return RsInit::ERR_UNKOWN;
if(!rsNotify->setDisableAskPassword(true)) return RsInit::ERR_UNKOWN;
if(!RsAccounts::SelectAccount(account)) return RsInit::ERR_UNKOWN;
std::string ignore;
RsInit::LoadCertificateStatus ret =
RsInit::LockAndLoadCertificates(false, ignore);
rsNotify->setDisableAskPassword(false);
if(ret != RsInit::OK) return ret;
if(RsControl::instance()->StartupRetroShare() == 1) return RsInit::OK;
return RsInit::ERR_UNKOWN;
}
void RsLoginHelper::getLocations(std::vector<RsLoginHelper::Location>& store)
{
std::list<RsPeerId> locIds;
RsAccounts::GetAccountIds(locIds);
store.clear();
for(const RsPeerId& locId : locIds )
{
Location l; l.mLocationId = locId;
std::string discardPgpMail;
RsAccounts::GetAccountDetails( locId, l.mPgpId, l.mPpgName,
discardPgpMail, l.mLocationName );
store.push_back(l);
}
}
void RsLoginHelper::Location::serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{
RS_SERIAL_PROCESS(mLocationId);
RS_SERIAL_PROCESS(mPgpId);
RS_SERIAL_PROCESS(mLocationName);
RS_SERIAL_PROCESS(mPpgName);
}

View File

@ -30,6 +30,8 @@
#include "api/ApiServerLocal.h"
#include "api/RsControlModule.h"
#include "jsonapi/jsonapi.h"
using namespace resource_api;
int main(int argc, char *argv[])
@ -60,6 +62,9 @@ int main(int argc, char *argv[])
ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal;
JsonApiServer jas(9092);
jas.start("JsonApiServer");
// This ugly but RsControlModule has no other way to callback for stop
QTimer shouldExitTimer;
shouldExitTimer.setTimerType(Qt::VeryCoarseTimer);