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);
|
||||
#endif
|
||||
|
||||
#if !RS_VERSION_AT_LEAST(0,6,6)
|
||||
registerHandler("/rsLoginHelper/createLocation",
|
||||
[this](const std::shared_ptr<rb::Session> session)
|
||||
{
|
||||
@ -215,8 +216,9 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
|
||||
} );
|
||||
}, false);
|
||||
#endif // !RS_VERSION_AT_LEAST(0,6,6)
|
||||
|
||||
registerHandler("/rsLoginHelper/attemptLogin",
|
||||
registerHandler("/rsLoginHelper/createLocationV2",
|
||||
[this](const std::shared_ptr<rb::Session> session)
|
||||
{
|
||||
auto reqSize = session->get_request()->get_header("Content-Length", 0);
|
||||
@ -226,25 +228,51 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"),
|
||||
{
|
||||
INITIALIZE_API_CALL_JSON_CONTEXT;
|
||||
|
||||
RsPeerId account;
|
||||
RsPeerId locationId;
|
||||
RsPgpId pgpId;
|
||||
std::string locationName;
|
||||
std::string pgpName;
|
||||
std::string password;
|
||||
|
||||
// JSON API only
|
||||
std::string apiUser;
|
||||
std::string apiPass;
|
||||
|
||||
// deserialize input parameters from JSON
|
||||
{
|
||||
RsGenericSerializer::SerializeContext& ctx(cReq);
|
||||
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);
|
||||
|
||||
// JSON API only
|
||||
RS_SERIAL_PROCESS(apiUser);
|
||||
RS_SERIAL_PROCESS(apiPass);
|
||||
}
|
||||
|
||||
// call retroshare C++ API
|
||||
RsInit::LoadCertificateStatus retval =
|
||||
rsLoginHelper->attemptLogin(account, password);
|
||||
std::error_condition retval;
|
||||
|
||||
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
|
||||
{
|
||||
RsGenericSerializer::SerializeContext& ctx(cAns);
|
||||
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
|
||||
RS_SERIAL_PROCESS(locationId);
|
||||
RS_SERIAL_PROCESS(pgpId);
|
||||
RS_SERIAL_PROCESS(retval);
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,7 @@
|
||||
*******************************************************************************/
|
||||
#pragma once
|
||||
|
||||
/// RetroShare initialization and login API
|
||||
|
||||
/// @file RetroShare initialization and login API
|
||||
|
||||
// Initialize ok, result >= 0
|
||||
#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_EXECUTABLE -4 // executable path hasn't been set in config options
|
||||
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <retroshare/rstypes.h>
|
||||
#include <cstdint>
|
||||
#include <system_error>
|
||||
|
||||
#include "retroshare/rstypes.h"
|
||||
#include "retroshare/rsversion.h"
|
||||
|
||||
|
||||
class RsLoginHelper;
|
||||
|
||||
@ -46,6 +49,71 @@ class 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
|
||||
* This class contains common configuration options, that executables using libretroshare may want to
|
||||
@ -85,7 +153,7 @@ struct RsConfigOptions
|
||||
class RsInit
|
||||
{
|
||||
public:
|
||||
enum LoadCertificateStatus : uint8_t
|
||||
enum RS_DEPRECATED_FOR(RsInitErrorNum) LoadCertificateStatus : uint8_t
|
||||
{
|
||||
OK, /// Everything go as expected, no error occurred
|
||||
ERR_ALREADY_RUNNING, /// Another istance is running already
|
||||
@ -317,7 +385,7 @@ public:
|
||||
|
||||
/**
|
||||
* @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] password Password for the given account
|
||||
* @return RsInit::OK if login attempt success, error code otherwhise
|
||||
@ -353,6 +421,44 @@ public:
|
||||
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
|
||||
* @jsonapi{development,manualwrapper}
|
||||
* @param[inout] location provide input information to generate the location
|
||||
@ -365,15 +471,9 @@ public:
|
||||
* Tor hidden location. UNTESTED!
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
RS_DEPRECATED_FOR(createLocationV2)
|
||||
bool createLocation( RsLoginHelper::Location& location,
|
||||
const std::string& password, std::string& errorMessage,
|
||||
bool makeHidden = false, bool makeAutoTor = false );
|
||||
|
||||
/**
|
||||
* @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();
|
||||
#endif // !RS_VERSION_AT_LEAST(0,6,6)
|
||||
};
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <cstdint>
|
||||
#include <system_error>
|
||||
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsmemory.h"
|
||||
|
||||
class RsJsonApi;
|
||||
@ -74,8 +75,7 @@ struct RsJsonApiErrorCategory: std::error_category
|
||||
case RsJsonApiErrorNum::NOT_A_MACHINE_GUN:
|
||||
return "Method must not be called in burst";
|
||||
default:
|
||||
return "Error message for error: " + std::to_string(ev) +
|
||||
" not available in category: " + name();
|
||||
return rsErrorNotInCategory(ev, name());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,8 @@ RsLoginHelper* rsLoginHelper = nullptr;
|
||||
|
||||
RsAccounts* rsAccounts = nullptr;
|
||||
|
||||
const RsInitErrorCategory RsInitErrorCategory::instance;
|
||||
|
||||
RsConfigOptions::RsConfigOptions()
|
||||
:
|
||||
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(
|
||||
RsLoginHelper::Location& l, const std::string& password,
|
||||
std::string& errorMessage, bool makeHidden, bool makeAutoTor )
|
||||
@ -1991,6 +2034,7 @@ bool RsLoginHelper::createLocation(
|
||||
rsNotify->setDisableAskPassword(false);
|
||||
return ret;
|
||||
}
|
||||
#endif // !RS_VERSION_AT_LEAST(0,6,6)
|
||||
|
||||
bool RsLoginHelper::isLoggedIn()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user