mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Merge pull request #2011 from G10h4ck/createLocationV2
Improve API to create locations
This commit is contained in:
commit
b49dfaead0
@ -165,6 +165,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
|||||||
RsThread::setStopTimeout(10);
|
RsThread::setStopTimeout(10);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !RS_VERSION_AT_LEAST(0,6,6)
|
||||||
registerHandler("/rsLoginHelper/createLocation",
|
registerHandler("/rsLoginHelper/createLocation",
|
||||||
[this](const std::shared_ptr<rb::Session> session)
|
[this](const std::shared_ptr<rb::Session> session)
|
||||||
{
|
{
|
||||||
@ -215,8 +216,9 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
|||||||
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
|
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
|
||||||
} );
|
} );
|
||||||
}, false);
|
}, false);
|
||||||
|
#endif // !RS_VERSION_AT_LEAST(0,6,6)
|
||||||
|
|
||||||
registerHandler("/rsLoginHelper/attemptLogin",
|
registerHandler("/rsLoginHelper/createLocationV2",
|
||||||
[this](const std::shared_ptr<rb::Session> session)
|
[this](const std::shared_ptr<rb::Session> session)
|
||||||
{
|
{
|
||||||
auto reqSize = session->get_request()->get_header("Content-Length", 0);
|
auto reqSize = session->get_request()->get_header("Content-Length", 0);
|
||||||
@ -226,25 +228,51 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
|||||||
{
|
{
|
||||||
INITIALIZE_API_CALL_JSON_CONTEXT;
|
INITIALIZE_API_CALL_JSON_CONTEXT;
|
||||||
|
|
||||||
RsPeerId account;
|
RsPeerId locationId;
|
||||||
|
RsPgpId pgpId;
|
||||||
|
std::string locationName;
|
||||||
|
std::string pgpName;
|
||||||
std::string password;
|
std::string password;
|
||||||
|
|
||||||
|
// JSON API only
|
||||||
|
std::string apiUser;
|
||||||
|
std::string apiPass;
|
||||||
|
|
||||||
// deserialize input parameters from JSON
|
// deserialize input parameters from JSON
|
||||||
{
|
{
|
||||||
RsGenericSerializer::SerializeContext& ctx(cReq);
|
RsGenericSerializer::SerializeContext& ctx(cReq);
|
||||||
RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON);
|
RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON);
|
||||||
RS_SERIAL_PROCESS(account);
|
RS_SERIAL_PROCESS(locationId);
|
||||||
|
RS_SERIAL_PROCESS(pgpId);
|
||||||
|
RS_SERIAL_PROCESS(locationName);
|
||||||
|
RS_SERIAL_PROCESS(pgpName);
|
||||||
RS_SERIAL_PROCESS(password);
|
RS_SERIAL_PROCESS(password);
|
||||||
|
|
||||||
|
// JSON API only
|
||||||
|
RS_SERIAL_PROCESS(apiUser);
|
||||||
|
RS_SERIAL_PROCESS(apiPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// call retroshare C++ API
|
std::error_condition retval;
|
||||||
RsInit::LoadCertificateStatus retval =
|
|
||||||
rsLoginHelper->attemptLogin(account, password);
|
if(apiUser.empty())
|
||||||
|
retval = RsJsonApiErrorNum::TOKEN_FORMAT_INVALID;
|
||||||
|
|
||||||
|
if(!retval)
|
||||||
|
retval = badApiCredientalsFormat(apiUser, apiPass);
|
||||||
|
|
||||||
|
if(!retval) // call retroshare C++ API
|
||||||
|
retval = rsLoginHelper->createLocationV2(
|
||||||
|
locationId, pgpId, locationName, pgpName, password );
|
||||||
|
|
||||||
|
if(!retval) retval = authorizeUser(apiUser, apiPass);
|
||||||
|
|
||||||
// serialize out parameters and return value to JSON
|
// serialize out parameters and return value to JSON
|
||||||
{
|
{
|
||||||
RsGenericSerializer::SerializeContext& ctx(cAns);
|
RsGenericSerializer::SerializeContext& ctx(cAns);
|
||||||
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
|
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
|
||||||
|
RS_SERIAL_PROCESS(locationId);
|
||||||
|
RS_SERIAL_PROCESS(pgpId);
|
||||||
RS_SERIAL_PROCESS(retval);
|
RS_SERIAL_PROCESS(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/// RetroShare initialization and login API
|
/// @file RetroShare initialization and login API
|
||||||
|
|
||||||
|
|
||||||
// Initialize ok, result >= 0
|
// Initialize ok, result >= 0
|
||||||
#define RS_INIT_OK 0 // Initialize ok
|
#define RS_INIT_OK 0 // Initialize ok
|
||||||
@ -32,11 +31,15 @@
|
|||||||
#define RS_INIT_NO_KEYRING -3 // Keyring is empty. Need to import it.
|
#define RS_INIT_NO_KEYRING -3 // Keyring is empty. Need to import it.
|
||||||
#define RS_INIT_NO_EXECUTABLE -4 // executable path hasn't been set in config options
|
#define RS_INIT_NO_EXECUTABLE -4 // executable path hasn't been set in config options
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <retroshare/rstypes.h>
|
#include <cstdint>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
#include "retroshare/rstypes.h"
|
||||||
|
#include "retroshare/rsversion.h"
|
||||||
|
|
||||||
|
|
||||||
class RsLoginHelper;
|
class RsLoginHelper;
|
||||||
|
|
||||||
@ -46,6 +49,71 @@ class RsLoginHelper;
|
|||||||
*/
|
*/
|
||||||
extern RsLoginHelper* rsLoginHelper;
|
extern RsLoginHelper* rsLoginHelper;
|
||||||
|
|
||||||
|
|
||||||
|
enum class RsInitErrorNum : int32_t
|
||||||
|
{
|
||||||
|
ALREADY_LOGGED_IN = 6000,
|
||||||
|
CANT_ACQUIRE_LOCK = 6001,
|
||||||
|
INVALID_LOCATION_NAME = 6002,
|
||||||
|
PGP_NAME_OR_ID_NEEDED = 6003,
|
||||||
|
PGP_KEY_CREATION_FAILED = 6004,
|
||||||
|
SSL_KEY_CREATION_FAILED = 6005,
|
||||||
|
INVALID_SSL_ID = 6006,
|
||||||
|
LOGIN_FAILED = 6007
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RsInitErrorCategory: std::error_category
|
||||||
|
{
|
||||||
|
const char* name() const noexcept override
|
||||||
|
{ return "RetroShare init"; }
|
||||||
|
|
||||||
|
std::string message(int ev) const override
|
||||||
|
{
|
||||||
|
switch (static_cast<RsInitErrorNum>(ev))
|
||||||
|
{
|
||||||
|
case RsInitErrorNum::ALREADY_LOGGED_IN:
|
||||||
|
return "Already logged in";
|
||||||
|
case RsInitErrorNum::CANT_ACQUIRE_LOCK:
|
||||||
|
return "Cannot aquire lock on location data. Another instance is "
|
||||||
|
"already running with this profile?";
|
||||||
|
case RsInitErrorNum::INVALID_LOCATION_NAME:
|
||||||
|
return "Invalid location name";
|
||||||
|
case RsInitErrorNum::PGP_NAME_OR_ID_NEEDED:
|
||||||
|
return "Either PGP name or PGP id is needed";
|
||||||
|
case RsInitErrorNum::PGP_KEY_CREATION_FAILED:
|
||||||
|
return "Failure creating PGP key";
|
||||||
|
case RsInitErrorNum::SSL_KEY_CREATION_FAILED:
|
||||||
|
return "Failure creating SSL key";
|
||||||
|
case RsInitErrorNum::INVALID_SSL_ID:
|
||||||
|
return "Invalid SSL id";
|
||||||
|
case RsInitErrorNum::LOGIN_FAILED:
|
||||||
|
return "Generic login failure";
|
||||||
|
default:
|
||||||
|
return rsErrorNotInCategory(ev, name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const static RsInitErrorCategory instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
/** Register RsJsonApiErrorNum as an error condition enum, must be in std
|
||||||
|
* namespace */
|
||||||
|
template<> struct is_error_condition_enum<RsInitErrorNum> : true_type {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Provide RsInitErrorNum conversion to std::error_condition, must be in
|
||||||
|
* same namespace of RsInitErrorNum */
|
||||||
|
inline std::error_condition make_error_condition(RsInitErrorNum e) noexcept
|
||||||
|
{
|
||||||
|
return std::error_condition(
|
||||||
|
static_cast<int>(e), RsInitErrorCategory::instance );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The RsInitConfig struct
|
* @brief The RsInitConfig struct
|
||||||
* This class contains common configuration options, that executables using libretroshare may want to
|
* This class contains common configuration options, that executables using libretroshare may want to
|
||||||
@ -85,7 +153,7 @@ struct RsConfigOptions
|
|||||||
class RsInit
|
class RsInit
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum LoadCertificateStatus : uint8_t
|
enum RS_DEPRECATED_FOR(RsInitErrorNum) LoadCertificateStatus : uint8_t
|
||||||
{
|
{
|
||||||
OK, /// Everything go as expected, no error occurred
|
OK, /// Everything go as expected, no error occurred
|
||||||
ERR_ALREADY_RUNNING, /// Another istance is running already
|
ERR_ALREADY_RUNNING, /// Another istance is running already
|
||||||
@ -317,7 +385,7 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Normal way to attempt login
|
* @brief Normal way to attempt login
|
||||||
* @jsonapi{development,manualwrapper}
|
* @jsonapi{development,unauthenticated}
|
||||||
* @param[in] account Id of the account to which attempt login
|
* @param[in] account Id of the account to which attempt login
|
||||||
* @param[in] password Password for the given account
|
* @param[in] password Password for the given account
|
||||||
* @return RsInit::OK if login attempt success, error code otherwhise
|
* @return RsInit::OK if login attempt success, error code otherwhise
|
||||||
@ -353,6 +421,44 @@ public:
|
|||||||
void getLocations(std::vector<RsLoginHelper::Location>& locations);
|
void getLocations(std::vector<RsLoginHelper::Location>& locations);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief Creates a new RetroShare location, and log in once is created
|
||||||
|
* @jsonapi{development,manualwrapper}
|
||||||
|
* @param[out] locationId storage for generated location SSL id
|
||||||
|
* @param[inout] pgpId specify PGP id to use to sign the location, if a null
|
||||||
|
* id is passed the PGP key is created too and this param is used as
|
||||||
|
* storage for its id.
|
||||||
|
* @param[in] password to protect and unlock the associated PGP key
|
||||||
|
* param[in] apiUser (JSON API only) string containing username for JSON API
|
||||||
|
* so it can be later used to authenticate JSON API calls. It is passed
|
||||||
|
* down to @see RsJsonApi::authorizeUser under the hood.
|
||||||
|
* param[in] apiPass (JSON API only) string containing password for JSON API
|
||||||
|
* so it can be later used to authenticate JSON API calls. It is passed
|
||||||
|
* down to @see RsJsonApi::authorizeUser under the hood.
|
||||||
|
* To improve security we strongly advise to not use the same as the
|
||||||
|
* password used for the PGP key.
|
||||||
|
* @return Success or error information
|
||||||
|
*/
|
||||||
|
std::error_condition createLocationV2(
|
||||||
|
RsPeerId& locationId,
|
||||||
|
RsPgpId& pgpId,
|
||||||
|
const std::string& locationName,
|
||||||
|
const std::string& pgpName,
|
||||||
|
const std::string& password
|
||||||
|
/* JSON API only
|
||||||
|
* const std::string& apiUser
|
||||||
|
* const std::string& apiPass */ );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if RetroShare is already logged in, this usually return true
|
||||||
|
* after a successfull attemptLogin() and before closeSession()
|
||||||
|
* @jsonapi{development,unauthenticated}
|
||||||
|
* @return true if already logged in, false otherwise
|
||||||
|
*/
|
||||||
|
bool isLoggedIn();
|
||||||
|
|
||||||
|
#if !RS_VERSION_AT_LEAST(0,6,6)
|
||||||
|
/**
|
||||||
|
* @deprecated Use @see createLocationV2 instead
|
||||||
* @brief Creates a new RetroShare location, and log in once is created
|
* @brief Creates a new RetroShare location, and log in once is created
|
||||||
* @jsonapi{development,manualwrapper}
|
* @jsonapi{development,manualwrapper}
|
||||||
* @param[inout] location provide input information to generate the location
|
* @param[inout] location provide input information to generate the location
|
||||||
@ -365,15 +471,9 @@ public:
|
|||||||
* Tor hidden location. UNTESTED!
|
* Tor hidden location. UNTESTED!
|
||||||
* @return true if success, false otherwise
|
* @return true if success, false otherwise
|
||||||
*/
|
*/
|
||||||
|
RS_DEPRECATED_FOR(createLocationV2)
|
||||||
bool createLocation( RsLoginHelper::Location& location,
|
bool createLocation( RsLoginHelper::Location& location,
|
||||||
const std::string& password, std::string& errorMessage,
|
const std::string& password, std::string& errorMessage,
|
||||||
bool makeHidden = false, bool makeAutoTor = false );
|
bool makeHidden = false, bool makeAutoTor = false );
|
||||||
|
#endif // !RS_VERSION_AT_LEAST(0,6,6)
|
||||||
/**
|
|
||||||
* @brief Check if RetroShare is already logged in, this usually return true
|
|
||||||
* after a successfull attemptLogin() and before closeSession()
|
|
||||||
* @jsonapi{development,unauthenticated}
|
|
||||||
* @return true if already logged in, false otherwise
|
|
||||||
*/
|
|
||||||
bool isLoggedIn();
|
|
||||||
};
|
};
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
|
||||||
|
#include "util/rsdebug.h"
|
||||||
#include "util/rsmemory.h"
|
#include "util/rsmemory.h"
|
||||||
|
|
||||||
class RsJsonApi;
|
class RsJsonApi;
|
||||||
@ -74,8 +75,7 @@ struct RsJsonApiErrorCategory: std::error_category
|
|||||||
case RsJsonApiErrorNum::NOT_A_MACHINE_GUN:
|
case RsJsonApiErrorNum::NOT_A_MACHINE_GUN:
|
||||||
return "Method must not be called in burst";
|
return "Method must not be called in burst";
|
||||||
default:
|
default:
|
||||||
return "Error message for error: " + std::to_string(ev) +
|
return rsErrorNotInCategory(ev, name());
|
||||||
" not available in category: " + name();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,8 @@ RsLoginHelper* rsLoginHelper = nullptr;
|
|||||||
|
|
||||||
RsAccounts* rsAccounts = nullptr;
|
RsAccounts* rsAccounts = nullptr;
|
||||||
|
|
||||||
|
const RsInitErrorCategory RsInitErrorCategory::instance;
|
||||||
|
|
||||||
RsConfigOptions::RsConfigOptions()
|
RsConfigOptions::RsConfigOptions()
|
||||||
:
|
:
|
||||||
autoLogin(false),
|
autoLogin(false),
|
||||||
@ -1950,6 +1952,47 @@ void RsLoginHelper::getLocations(std::vector<RsLoginHelper::Location>& store)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::error_condition RsLoginHelper::createLocationV2(
|
||||||
|
RsPeerId& locationId, RsPgpId& pgpId,
|
||||||
|
const std::string& locationName, const std::string& pgpName,
|
||||||
|
const std::string& password )
|
||||||
|
{
|
||||||
|
if(isLoggedIn()) return RsInitErrorNum::ALREADY_LOGGED_IN;
|
||||||
|
if(locationName.empty()) return RsInitErrorNum::INVALID_LOCATION_NAME;
|
||||||
|
if(pgpId.isNull() && pgpName.empty())
|
||||||
|
return RsInitErrorNum::PGP_NAME_OR_ID_NEEDED;
|
||||||
|
|
||||||
|
std::string errorMessage;
|
||||||
|
if(pgpId.isNull() && !RsAccounts::GeneratePGPCertificate(
|
||||||
|
pgpName, "", password, pgpId, 4096, errorMessage ) )
|
||||||
|
{
|
||||||
|
RS_ERR("Failure creating PGP key: ", errorMessage);
|
||||||
|
return RsInitErrorNum::PGP_KEY_CREATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sslPassword =
|
||||||
|
RsRandom::random_alphaNumericString(RsInit::getSslPwdLen());
|
||||||
|
|
||||||
|
rsNotify->cachePgpPassphrase(password);
|
||||||
|
rsNotify->setDisableAskPassword(true);
|
||||||
|
|
||||||
|
bool ret = RsAccounts::createNewAccount(
|
||||||
|
pgpId, "", locationName, "", false, false, sslPassword,
|
||||||
|
locationId, errorMessage );
|
||||||
|
if(!ret)
|
||||||
|
{
|
||||||
|
RS_ERR("Failure creating SSL key: ", errorMessage);
|
||||||
|
return RsInitErrorNum::SSL_KEY_CREATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsInit::LoadPassword(sslPassword);
|
||||||
|
ret = (RsInit::OK == attemptLogin(locationId, password));
|
||||||
|
rsNotify->setDisableAskPassword(false);
|
||||||
|
|
||||||
|
return (ret ? std::error_condition() : RsInitErrorNum::LOGIN_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !RS_VERSION_AT_LEAST(0,6,6)
|
||||||
bool RsLoginHelper::createLocation(
|
bool RsLoginHelper::createLocation(
|
||||||
RsLoginHelper::Location& l, const std::string& password,
|
RsLoginHelper::Location& l, const std::string& password,
|
||||||
std::string& errorMessage, bool makeHidden, bool makeAutoTor )
|
std::string& errorMessage, bool makeHidden, bool makeAutoTor )
|
||||||
@ -1991,6 +2034,7 @@ bool RsLoginHelper::createLocation(
|
|||||||
rsNotify->setDisableAskPassword(false);
|
rsNotify->setDisableAskPassword(false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif // !RS_VERSION_AT_LEAST(0,6,6)
|
||||||
|
|
||||||
bool RsLoginHelper::isLoggedIn()
|
bool RsLoginHelper::isLoggedIn()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user