mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-14 00:49:41 -05:00
improved the login in the interaction between terminal api client and main
This commit is contained in:
parent
7ee527ecbd
commit
decbd3514d
@ -150,24 +150,29 @@ void RsControlModule::run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// skip account selection if autologin is available
|
// skip account selection if autologin is available
|
||||||
if(initResult != RS_INIT_HAVE_ACCOUNT)
|
bool wait_for_account_select = (initResult != RS_INIT_HAVE_ACCOUNT);
|
||||||
setRunState(WAITING_ACCOUNT_SELECT);
|
|
||||||
|
|
||||||
// wait for login request
|
// wait for login request
|
||||||
bool auto_login = false;
|
bool auto_login = false;
|
||||||
bool wait_for_account_select = (initResult != RS_INIT_HAVE_ACCOUNT);
|
|
||||||
|
if(wait_for_account_select)
|
||||||
|
setRunState(WAITING_ACCOUNT_SELECT);
|
||||||
|
|
||||||
while(wait_for_account_select && !processShouldExit())
|
while(wait_for_account_select && !processShouldExit())
|
||||||
{
|
{
|
||||||
usleep(5*1000);
|
usleep(500*1000);
|
||||||
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
RsStackMutex stack(mDataMtx); // ********** LOCKED **********
|
||||||
wait_for_account_select = mLoadPeerId.isNull();
|
|
||||||
|
if(!mLoadPeerId.isNull())
|
||||||
|
wait_for_account_select = wait_for_account_select && !RsAccounts::SelectAccount(mLoadPeerId);
|
||||||
|
|
||||||
auto_login = mAutoLoginNextTime;
|
auto_login = mAutoLoginNextTime;
|
||||||
if(!wait_for_account_select)
|
|
||||||
{
|
//if(!wait_for_account_select)
|
||||||
wait_for_account_select = !RsAccounts::SelectAccount(mLoadPeerId);
|
//{
|
||||||
if(wait_for_account_select)
|
// if(wait_for_account_select)
|
||||||
setRunState(WAITING_ACCOUNT_SELECT);
|
// setRunState(WAITING_ACCOUNT_SELECT);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(processShouldExit())
|
if(processShouldExit())
|
||||||
|
@ -23,6 +23,8 @@ class ApiServer;
|
|||||||
class RsControlModule: public ResourceRouter, NotifyClient, private RsSingleJobThread
|
class RsControlModule: public ResourceRouter, NotifyClient, private RsSingleJobThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum RunState { WAITING_INIT, FATAL_ERROR, WAITING_ACCOUNT_SELECT, WAITING_STARTUP, RUNNING_OK, RUNNING_OK_NO_FULL_CONTROL};
|
||||||
|
|
||||||
// ApiServer will be called once RS is started, to load additional api modules
|
// ApiServer will be called once RS is started, to load additional api modules
|
||||||
// full_control: set to true if this module should handle rsinit and login
|
// full_control: set to true if this module should handle rsinit and login
|
||||||
// set to false if rsinit is handled by the Qt gui
|
// set to false if rsinit is handled by the Qt gui
|
||||||
@ -32,6 +34,9 @@ public:
|
|||||||
// returns true if the process should terminate
|
// returns true if the process should terminate
|
||||||
bool processShouldExit();
|
bool processShouldExit();
|
||||||
|
|
||||||
|
// returns the current state of the software booting process
|
||||||
|
RunState runState() const { return mRunState ; }
|
||||||
|
|
||||||
// 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) override;
|
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;
|
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result, std::string reason = "") override;
|
||||||
@ -42,7 +47,6 @@ protected:
|
|||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum RunState { WAITING_INIT, FATAL_ERROR, WAITING_ACCOUNT_SELECT, WAITING_STARTUP, RUNNING_OK, RUNNING_OK_NO_FULL_CONTROL};
|
|
||||||
void handleRunState(Request& req, Response& resp);
|
void handleRunState(Request& req, Response& resp);
|
||||||
void handleIdentities(Request& req, Response& resp);
|
void handleIdentities(Request& req, Response& resp);
|
||||||
void handleLocations(Request& req, Response& resp);
|
void handleLocations(Request& req, Response& resp);
|
||||||
|
@ -87,10 +87,8 @@ private:
|
|||||||
|
|
||||||
namespace resource_api {
|
namespace resource_api {
|
||||||
|
|
||||||
TerminalApiClient::TerminalApiClient(ApiServer *api):
|
TerminalApiClient::TerminalApiClient(ApiServer *api): mApiServer(api)
|
||||||
mApiServer(api)
|
|
||||||
{
|
{
|
||||||
start("resapi terminal");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalApiClient::~TerminalApiClient()
|
TerminalApiClient::~TerminalApiClient()
|
||||||
@ -98,13 +96,6 @@ TerminalApiClient::~TerminalApiClient()
|
|||||||
fullstop();
|
fullstop();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AccountInfo
|
|
||||||
{
|
|
||||||
std::string name ;
|
|
||||||
std::string location ;
|
|
||||||
RsPeerId ssl_id ;
|
|
||||||
};
|
|
||||||
|
|
||||||
void TerminalApiClient::data_tick()
|
void TerminalApiClient::data_tick()
|
||||||
{
|
{
|
||||||
// values in milliseconds
|
// values in milliseconds
|
||||||
@ -228,44 +219,7 @@ void TerminalApiClient::data_tick()
|
|||||||
|
|
||||||
if(!ask_for_password && edge && runstate == "waiting_account_select")
|
if(!ask_for_password && edge && runstate == "waiting_account_select")
|
||||||
{
|
{
|
||||||
JsonStream reqs;
|
readAvailableAccounts(accounts) ;
|
||||||
JsonStream resps;
|
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("locations");
|
|
||||||
req.mPath.push("control");
|
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
|
||||||
waitForResponse(id);
|
|
||||||
|
|
||||||
resps.switchToDeserialisation();
|
|
||||||
if(!resps.hasMore())
|
|
||||||
std::cout << "Error: No Accounts. Use the Qt-GUI or the webinterface to create an account." << std::endl;
|
|
||||||
int i = 0;
|
|
||||||
accounts.clear();
|
|
||||||
while(resps.hasMore())
|
|
||||||
{
|
|
||||||
std::string id;
|
|
||||||
std::string name;
|
|
||||||
std::string location;
|
|
||||||
|
|
||||||
resps.getStreamToMember()
|
|
||||||
<< makeKeyValueReference("id", id)
|
|
||||||
<< makeKeyValueReference("name", name)
|
|
||||||
<< makeKeyValueReference("location", location);
|
|
||||||
|
|
||||||
AccountInfo info ;
|
|
||||||
info.location = location ;
|
|
||||||
info.name = name ;
|
|
||||||
info.ssl_id = RsPeerId(id) ;
|
|
||||||
|
|
||||||
accounts.push_back(info);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
account_number_size = (int)ceil(log(accounts.size())/log(10.0f)) ;
|
account_number_size = (int)ceil(log(accounts.size())/log(10.0f)) ;
|
||||||
|
|
||||||
for(uint32_t i=0;i<accounts.size();++i)
|
for(uint32_t i=0;i<accounts.size();++i)
|
||||||
@ -292,19 +246,7 @@ void TerminalApiClient::data_tick()
|
|||||||
std::cout << std::endl << "Selected account: " << accounts[selected_account_number].name << " (" << accounts[selected_account_number].location << ") SSL id: " << accounts[selected_account_number].ssl_id << std::endl;
|
std::cout << std::endl << "Selected account: " << accounts[selected_account_number].name << " (" << accounts[selected_account_number].location << ") SSL id: " << accounts[selected_account_number].ssl_id << std::endl;
|
||||||
|
|
||||||
std::string acc_ssl_id = accounts[selected_account_number].ssl_id.toStdString();
|
std::string acc_ssl_id = accounts[selected_account_number].ssl_id.toStdString();
|
||||||
JsonStream reqs;
|
sendSelectedAccount(acc_ssl_id) ;
|
||||||
JsonStream resps;
|
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("login");
|
|
||||||
req.mPath.push("control");
|
|
||||||
reqs << makeKeyValueReference("id", acc_ssl_id);
|
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
|
||||||
waitForResponse(id);
|
|
||||||
|
|
||||||
inbuf.clear();
|
inbuf.clear();
|
||||||
}
|
}
|
||||||
@ -330,33 +272,107 @@ void TerminalApiClient::data_tick()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(ask_for_password && enter_was_pressed && !inbuf.empty())
|
if(ask_for_password && enter_was_pressed && !inbuf.empty())
|
||||||
{
|
{
|
||||||
std::cout << "TerminalApiClient: got a password" << std::endl;
|
std::cout << "TerminalApiClient: got a password" << std::endl;
|
||||||
JsonStream reqs;
|
|
||||||
JsonStream resps;
|
|
||||||
Request req(reqs);
|
|
||||||
std::stringstream ss;
|
|
||||||
Response resp(resps, ss);
|
|
||||||
|
|
||||||
req.mPath.push("password");
|
// Send passwd to api server
|
||||||
req.mPath.push("control");
|
sendPassword(inbuf) ;
|
||||||
reqs << makeKeyValueReference("password", inbuf);
|
|
||||||
reqs.switchToDeserialisation();
|
|
||||||
|
|
||||||
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
// clears buffer
|
||||||
waitForResponse(id);
|
inbuf.clear();
|
||||||
|
|
||||||
inbuf.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalApiClient::waitForResponse(ApiServer::RequestId id)
|
void TerminalApiClient::waitForResponse(ApiServer::RequestId id) const
|
||||||
{
|
{
|
||||||
while(!mApiServer->isRequestDone(id))
|
while(!mApiServer->isRequestDone(id))
|
||||||
usleep(20*1000);
|
usleep(20*1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalApiClient::sendPassword(const std::string& passwd) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
req.mPath.push("password");
|
||||||
|
req.mPath.push("control");
|
||||||
|
|
||||||
|
std::string pass(passwd) ;
|
||||||
|
|
||||||
|
reqs << makeKeyValueReference("password", pass);
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalApiClient::sendSelectedAccount(const std::string& ssl_id) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
std::string acc_ssl_id(ssl_id) ;
|
||||||
|
req.mPath.push("login");
|
||||||
|
req.mPath.push("control");
|
||||||
|
reqs << makeKeyValueReference("id", acc_ssl_id);
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalApiClient::readAvailableAccounts(std::vector<AccountInfo>& accounts) const
|
||||||
|
{
|
||||||
|
JsonStream reqs;
|
||||||
|
JsonStream resps;
|
||||||
|
Request req(reqs);
|
||||||
|
std::stringstream ss;
|
||||||
|
Response resp(resps, ss);
|
||||||
|
|
||||||
|
req.mPath.push("locations");
|
||||||
|
req.mPath.push("control");
|
||||||
|
reqs.switchToDeserialisation();
|
||||||
|
|
||||||
|
ApiServer::RequestId id = mApiServer->handleRequest(req, resp);
|
||||||
|
waitForResponse(id);
|
||||||
|
|
||||||
|
resps.switchToDeserialisation();
|
||||||
|
|
||||||
|
if(!resps.hasMore())
|
||||||
|
std::cout << "Error: No Accounts. Use the Qt-GUI or the webinterface to create an account." << std::endl;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
accounts.clear();
|
||||||
|
|
||||||
|
while(resps.hasMore())
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
std::string name;
|
||||||
|
std::string location;
|
||||||
|
|
||||||
|
resps.getStreamToMember()
|
||||||
|
<< makeKeyValueReference("id", id)
|
||||||
|
<< makeKeyValueReference("name", name)
|
||||||
|
<< makeKeyValueReference("location", location);
|
||||||
|
|
||||||
|
AccountInfo info ;
|
||||||
|
info.location = location ;
|
||||||
|
info.name = name ;
|
||||||
|
info.ssl_id = RsPeerId(id) ;
|
||||||
|
|
||||||
|
accounts.push_back(info);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool TerminalApiClient::isTokenValid(StateToken runstate_state_token)
|
bool TerminalApiClient::isTokenValid(StateToken runstate_state_token)
|
||||||
{
|
{
|
||||||
JsonStream reqs;
|
JsonStream reqs;
|
||||||
|
@ -8,7 +8,7 @@ namespace resource_api {
|
|||||||
// - account selection
|
// - account selection
|
||||||
// - login
|
// - login
|
||||||
// - shutdown
|
// - shutdown
|
||||||
class TerminalApiClient: private RsTickingThread{
|
class TerminalApiClient: public RsTickingThread{
|
||||||
public:
|
public:
|
||||||
// zero setup: create an instance of this class and destroy it when not needed anymore
|
// zero setup: create an instance of this class and destroy it when not needed anymore
|
||||||
// no need to call start or stop or something
|
// no need to call start or stop or something
|
||||||
@ -19,9 +19,24 @@ protected:
|
|||||||
// from RsThread
|
// from RsThread
|
||||||
virtual void data_tick(); /* called once the thread is started. Should be overloaded by subclasses. */
|
virtual void data_tick(); /* called once the thread is started. Should be overloaded by subclasses. */
|
||||||
private:
|
private:
|
||||||
void waitForResponse(ApiServer::RequestId id);
|
struct AccountInfo
|
||||||
|
{
|
||||||
|
std::string name ;
|
||||||
|
std::string location ;
|
||||||
|
RsPeerId ssl_id ;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void waitForResponse(ApiServer::RequestId id) const;
|
||||||
bool isTokenValid(StateToken st);
|
bool isTokenValid(StateToken st);
|
||||||
ApiServer* mApiServer;
|
ApiServer* mApiServer;
|
||||||
|
|
||||||
|
// Methods to talk to the ApiServer
|
||||||
|
|
||||||
|
void sendPassword(const std::string& passwd) const;
|
||||||
|
void sendSelectedAccount(const std::string& ssl_id) const;
|
||||||
|
void readAvailableAccounts(std::vector<AccountInfo>& accounts) const;
|
||||||
|
void getRunningState() const ;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace resource_api
|
} // namespace resource_api
|
||||||
|
@ -100,9 +100,25 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
resource_api::TerminalApiClient tac(&api);
|
resource_api::TerminalApiClient tac(&api);
|
||||||
|
tac.start();
|
||||||
|
|
||||||
while(ctrl_mod.processShouldExit() == false)
|
while(ctrl_mod.processShouldExit() == false)
|
||||||
{
|
{
|
||||||
usleep(20*1000);
|
usleep(200*1000);
|
||||||
|
|
||||||
|
if(!tac.isRunning())
|
||||||
|
{
|
||||||
|
if(!RsInit::isLocationRunning())
|
||||||
|
{
|
||||||
|
std::cerr << "Terminal API client stopped but location not set ! Relaunching." ;
|
||||||
|
tac.start();
|
||||||
|
}
|
||||||
|
else if(RsInit::isLocationRunning())
|
||||||
|
{
|
||||||
|
std::cerr << "Terminal API client running but location already set ! Stopping it." ;
|
||||||
|
tac.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(httpd)
|
if(httpd)
|
||||||
|
Loading…
Reference in New Issue
Block a user