mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-03 11:00:14 -05:00
converted JsonAPI with public api and using RestbedService system
This commit is contained in:
parent
3ca22f0052
commit
a304ec20ef
@ -42,10 +42,9 @@
|
|||||||
// Generated at compile time
|
// Generated at compile time
|
||||||
#include "jsonapi-includes.inl"
|
#include "jsonapi-includes.inl"
|
||||||
|
|
||||||
/*extern*/ JsonApiServer* jsonApiServer = nullptr;
|
/*extern*/ RsJsonAPI* rsJsonAPI = nullptr;
|
||||||
|
|
||||||
const std::string JsonApiServer::DEFAULT_LISTENING_ADDRESS = "127.0.0.1";
|
const std::string RsJsonAPI::DEFAULT_BINDING_ADDRESS = "127.0.0.1";
|
||||||
p3ConfigMgr *JsonApiServer::_config_mgr = nullptr;
|
|
||||||
|
|
||||||
/*static*/ const std::multimap<std::string, std::string>
|
/*static*/ const std::multimap<std::string, std::string>
|
||||||
JsonApiServer::corsHeaders =
|
JsonApiServer::corsHeaders =
|
||||||
@ -118,33 +117,6 @@ JsonApiServer::corsOptionsHeaders =
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonApiServer& JsonApiServer::instance()
|
|
||||||
{
|
|
||||||
static JsonApiServer *_instance = nullptr;
|
|
||||||
|
|
||||||
if(_instance == NULL)
|
|
||||||
{
|
|
||||||
_instance = new JsonApiServer();
|
|
||||||
|
|
||||||
if(_config_mgr == nullptr)
|
|
||||||
RsErr() << "JsonApiServer::instance() called before JsonApiServer::setConfigManager(). This is a bug!" << std::endl;
|
|
||||||
|
|
||||||
_config_mgr->addConfiguration("jsonapi.cfg",_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsonApiServer::start(uint16_t port, const std::string& bindAddress, const std::function<bool(const std::string&)> callback)
|
|
||||||
{
|
|
||||||
mPort = port;
|
|
||||||
mBindAddress = bindAddress;
|
|
||||||
mNewAccessRequestCallback = callback;
|
|
||||||
|
|
||||||
std::cerr << "(II) Starting Json API on port " << port << ", address " << bindAddress << std::endl;
|
|
||||||
RsThread::start("JsonApiServer");
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config")
|
JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config")
|
||||||
{
|
{
|
||||||
registerHandler("/rsLoginHelper/createLocation",
|
registerHandler("/rsLoginHelper/createLocation",
|
||||||
@ -179,7 +151,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config")
|
|||||||
makeAutoTor );
|
makeAutoTor );
|
||||||
|
|
||||||
if(retval)
|
if(retval)
|
||||||
authorizeToken(location.mLocationId.toStdString()+":"+password);
|
authorizeUser(location.mLocationId.toStdString(),password);
|
||||||
|
|
||||||
// serialize out parameters and return value to JSON
|
// serialize out parameters and return value to JSON
|
||||||
{
|
{
|
||||||
@ -221,7 +193,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config")
|
|||||||
rsLoginHelper->attemptLogin(account, password);
|
rsLoginHelper->attemptLogin(account, password);
|
||||||
|
|
||||||
if( retval == RsInit::OK )
|
if( retval == RsInit::OK )
|
||||||
authorizeToken(account.toStdString()+":"+password);
|
authorizeUser(account.toStdString(),password);
|
||||||
|
|
||||||
// serialize out parameters and return value to JSON
|
// serialize out parameters and return value to JSON
|
||||||
{
|
{
|
||||||
@ -367,11 +339,6 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config")
|
|||||||
session->yield(message.str());
|
session->yield(message.str());
|
||||||
} );
|
} );
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
RsFileHash dummyHash;
|
|
||||||
setFilename("jsonapi.cfg"); // hack
|
|
||||||
loadConfiguration(dummyHash);
|
|
||||||
|
|
||||||
// Generated at compile time
|
// Generated at compile time
|
||||||
#include "jsonapi-wrappers.inl"
|
#include "jsonapi-wrappers.inl"
|
||||||
}
|
}
|
||||||
@ -398,6 +365,11 @@ void JsonApiServer::run()
|
|||||||
mService.start(settings);
|
mService.start(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<restbed::Resource> > JsonApiServer::getResources() const
|
||||||
|
{
|
||||||
|
return _resources;
|
||||||
|
}
|
||||||
|
|
||||||
void JsonApiServer::registerHandler(
|
void JsonApiServer::registerHandler(
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
const std::function<void (const std::shared_ptr<restbed::Session>)>& handler,
|
const std::function<void (const std::shared_ptr<restbed::Session>)>& handler,
|
||||||
@ -446,34 +418,21 @@ void JsonApiServer::registerHandler(
|
|||||||
else session->close(rb::UNAUTHORIZED);
|
else session->close(rb::UNAUTHORIZED);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
mService.publish(resource);
|
_resources.push_back(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonApiServer::setNewAccessRequestCallback(
|
void JsonApiServer::setNewAccessRequestCallback( const std::function<bool (const std::string&,std::string&)>& callback )
|
||||||
const std::function<bool (const std::string&)>& callback )
|
|
||||||
{ mNewAccessRequestCallback = callback; }
|
|
||||||
|
|
||||||
void JsonApiServer::shutdown()
|
|
||||||
{
|
{
|
||||||
mService.stop();
|
mNewAccessRequestCallback = callback;
|
||||||
|
|
||||||
RsThread::ask_for_stop();
|
|
||||||
|
|
||||||
std::cerr << "Stopping JsonApiServer" ;
|
|
||||||
|
|
||||||
while(isRunning())
|
|
||||||
{
|
|
||||||
sleep(1);
|
|
||||||
std::cerr << "." ;
|
|
||||||
std::cerr.flush();
|
|
||||||
}
|
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonApiServer::requestNewTokenAutorization(const std::string& token)
|
bool JsonApiServer::requestNewTokenAutorization(const std::string& user)
|
||||||
{
|
{
|
||||||
if(rsLoginHelper->isLoggedIn() && mNewAccessRequestCallback(token))
|
std::string passwd;
|
||||||
return authorizeToken(token);
|
|
||||||
|
if(rsLoginHelper->isLoggedIn() && mNewAccessRequestCallback(user,passwd))
|
||||||
|
return authorizeUser(user,passwd);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,24 +535,24 @@ bool JsonApiServer::authorizeUser(const std::string& user,const std::string& pas
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool JsonApiServer::authorizeToken(const std::string& token)
|
// bool JsonApiServer::authorizeToken(const std::string& token)
|
||||||
{
|
// {
|
||||||
std::string user,password;
|
// std::string user,password;
|
||||||
|
//
|
||||||
if(!parseToken(token,user,password))
|
// if(!parseToken(token,user,password))
|
||||||
return false;
|
// return false;
|
||||||
|
//
|
||||||
RS_STACK_MUTEX(configMutex);
|
// RS_STACK_MUTEX(configMutex);
|
||||||
|
//
|
||||||
std::string& p(mAuthTokenStorage.mAuthorizedTokens[user]);
|
// std::string& p(mAuthTokenStorage.mAuthorizedTokens[user]);
|
||||||
|
//
|
||||||
if(p != password)
|
// if(p != password)
|
||||||
{
|
// {
|
||||||
p = password;
|
// p = password;
|
||||||
IndicateConfigChanged();
|
// IndicateConfigChanged();
|
||||||
}
|
// }
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/*static*/ std::string JsonApiServer::decodeToken(const std::string& radix64_token)
|
/*static*/ std::string JsonApiServer::decodeToken(const std::string& radix64_token)
|
||||||
{
|
{
|
||||||
@ -660,3 +619,10 @@ void JsonApiServer::handleCorsOptions(
|
|||||||
const std::shared_ptr<restbed::Session> session )
|
const std::shared_ptr<restbed::Session> session )
|
||||||
{ session->close(rb::NO_CONTENT, corsOptionsHeaders); }
|
{ session->close(rb::NO_CONTENT, corsOptionsHeaders); }
|
||||||
|
|
||||||
|
int JsonApiServer::status() const
|
||||||
|
{
|
||||||
|
if(isRunning())
|
||||||
|
return JSONAPI_STATUS_RUNNING;
|
||||||
|
else
|
||||||
|
return JSONAPI_STATUS_NOT_RUNNING;
|
||||||
|
}
|
||||||
|
@ -29,18 +29,12 @@
|
|||||||
#include "pqi/p3cfgmgr.h"
|
#include "pqi/p3cfgmgr.h"
|
||||||
#include "rsitems/rsitem.h"
|
#include "rsitems/rsitem.h"
|
||||||
#include "jsonapi/jsonapiitems.h"
|
#include "jsonapi/jsonapiitems.h"
|
||||||
|
#include "jsonapi/restbedservice.h"
|
||||||
|
#include "retroshare/rsjsonapi.h"
|
||||||
#include "util/rsthreads.h"
|
#include "util/rsthreads.h"
|
||||||
|
|
||||||
namespace rb = restbed;
|
namespace rb = restbed;
|
||||||
|
|
||||||
struct JsonApiServer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pointer to global instance of JsonApiServer
|
|
||||||
* @jsonapi{development}
|
|
||||||
*/
|
|
||||||
extern JsonApiServer* jsonApiServer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple usage
|
* Simple usage
|
||||||
* \code{.cpp}
|
* \code{.cpp}
|
||||||
@ -50,102 +44,27 @@ extern JsonApiServer* jsonApiServer;
|
|||||||
* \endcode
|
* \endcode
|
||||||
* Uses p3Config to securely store persistent JSON API authorization tokens
|
* Uses p3Config to securely store persistent JSON API authorization tokens
|
||||||
*/
|
*/
|
||||||
struct JsonApiServer : RsSingleJobThread, p3Config
|
class JsonApiServer : public p3Config, public RestbedService, public RsJsonAPI
|
||||||
{
|
{
|
||||||
static const uint16_t DEFAULT_PORT = 9092 ;
|
public:
|
||||||
static const std::string DEFAULT_LISTENING_ADDRESS ;
|
JsonApiServer() ;
|
||||||
|
virtual ~JsonApiServer() = default;
|
||||||
|
|
||||||
static JsonApiServer& instance() ;
|
// public API
|
||||||
|
|
||||||
/**
|
virtual bool restart() override { return RestbedService::restart();}
|
||||||
* @param[in] path Path itno which publish the API call
|
virtual bool stop() override { return RestbedService::stop();}
|
||||||
* @param[in] handler function which will be called to handle the requested
|
virtual void setListeningPort(uint16_t port) override { RestbedService::setListeningPort(port) ;}
|
||||||
* @param[in] requiresAutentication specify if the API call must be
|
virtual void setBindingAddress(const std::string& address) override { RestbedService::setBindAddress(address); }
|
||||||
* autenticated or not
|
virtual int status() const override;
|
||||||
* path, the function must be declared like:
|
|
||||||
* \code{.cpp}
|
|
||||||
* void functionName(const shared_ptr<restbed::Session> session)
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
void registerHandler(
|
|
||||||
const std::string& path,
|
|
||||||
const std::function<void(const std::shared_ptr<rb::Session>)>& handler,
|
|
||||||
bool requiresAutentication = true );
|
|
||||||
|
|
||||||
/**
|
virtual bool authorizeUser(const std::string& alphanumeric_user,const std::string& alphanumeric_passwd) override;
|
||||||
* @brief Set new access request callback
|
virtual std::map<std::string,std::string> getAuthorizedTokens() override;
|
||||||
* @param callback function to call when a new JSON API access is requested
|
bool revokeAuthToken(const std::string& user) override;
|
||||||
*/
|
bool isAuthTokenValid(const std::string& token) override;
|
||||||
void setNewAccessRequestCallback(
|
bool requestNewTokenAutorization(const std::string& user) override;
|
||||||
const std::function<bool(const std::string&)>& callback );
|
|
||||||
|
|
||||||
/**
|
// private API
|
||||||
* @brief Shutdown the JSON API server
|
|
||||||
* Beware that this method shout down only the JSON API server instance not
|
|
||||||
*/
|
|
||||||
void shutdown();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief start
|
|
||||||
* Starts the json Api server.
|
|
||||||
*
|
|
||||||
* @param port port to listen to
|
|
||||||
* @param listen_address bind address to listen to
|
|
||||||
*/
|
|
||||||
void start( uint16_t port = DEFAULT_PORT,
|
|
||||||
const std::string& bindAddress = "127.0.0.1",
|
|
||||||
const std::function<bool(const std::string&)> newAccessRequestCallback = [](const std::string&){return false;});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function should be used by JSON API clients that aren't
|
|
||||||
* authenticated yet, to ask their token to be authorized, the success or
|
|
||||||
* failure will depend on mNewAccessRequestCallback return value, and it
|
|
||||||
* will likely need human user interaction in the process.
|
|
||||||
* @jsonapi{development,unauthenticated}
|
|
||||||
* @param[in] token token to autorize
|
|
||||||
* @return true if authorization succeded, false otherwise.
|
|
||||||
*/
|
|
||||||
bool requestNewTokenAutorization(const std::string& token);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if given JSON API auth token is authorized
|
|
||||||
* @jsonapi{development}
|
|
||||||
* @param[in] token decoded
|
|
||||||
* @return tru if authorized, false otherwise
|
|
||||||
*/
|
|
||||||
bool isAuthTokenValid(const std::string& token);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get uthorized tokens
|
|
||||||
* @jsonapi{development}
|
|
||||||
* @return the set of authorized encoded tokens
|
|
||||||
*/
|
|
||||||
std::map<std::string,std::string> getAuthorizedTokens();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Revoke given auth token
|
|
||||||
* @jsonapi{development}
|
|
||||||
* @param[in] user par of the decoded token
|
|
||||||
* @return true if the token has been revoked, false otherwise
|
|
||||||
*/
|
|
||||||
bool revokeAuthToken(const std::string& user);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Add new auth token to the authorized set
|
|
||||||
* @jsonapi{development}
|
|
||||||
* @param[in] token token to autorize decoded, in format user:passwd where user and passwd are alphanumeric strings
|
|
||||||
* @return true if the token has been added to authorized, false if error occurred (e.g. token format is invalid)
|
|
||||||
*/
|
|
||||||
bool authorizeToken(const std::string& token);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Add new auth (user,passwd) token to the authorized set, creating the token user:passwd internally.
|
|
||||||
* @jsonapi{development}
|
|
||||||
* @param[in] alphanumeric_user username to autorize decoded
|
|
||||||
* @param[in] alphanumeric_passwd passwd to autorize decoded
|
|
||||||
* @return true if the token has been added to authorized, false if error occurred
|
|
||||||
*/
|
|
||||||
bool authorizeUser(const std::string& alphanumeric_user,const std::string& alphanumeric_passwd);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get decoded version of the given encoded token
|
* @brief Get decoded version of the given encoded token
|
||||||
@ -176,23 +95,35 @@ struct JsonApiServer : RsSingleJobThread, p3Config
|
|||||||
std::string& extra, std::string&human );
|
std::string& extra, std::string&human );
|
||||||
|
|
||||||
|
|
||||||
static void setConfigMgr(p3ConfigMgr *cfg) { _config_mgr = cfg; }
|
// /!\ These methods shouldn't be accessible through http!
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param[in] path Path itno which publish the API call
|
||||||
|
* @param[in] handler function which will be called to handle the requested
|
||||||
|
* @param[in] requiresAutentication specify if the API call must be
|
||||||
|
* autenticated or not
|
||||||
|
* path, the function must be declared like:
|
||||||
|
* \code{.cpp}
|
||||||
|
* void functionName(const shared_ptr<restbed::Session> session)
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
void registerHandler(
|
||||||
|
const std::string& path,
|
||||||
|
const std::function<void(const std::shared_ptr<rb::Session>)>& handler,
|
||||||
|
bool requiresAutentication = true );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set new access request callback
|
||||||
|
* @param callback function to call when a new JSON API access is requested
|
||||||
|
*/
|
||||||
|
void setNewAccessRequestCallback(const std::function<bool(const std::string&,std::string&)>& callback );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @see RsSingleJobThread
|
/// @see RsSingleJobThread
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
virtual std::vector<std::shared_ptr<rb::Resource> > getResources() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* @brief construct a JsonApiServer instance with given parameters
|
|
||||||
* @param[in] port listening port fpt the JSON API socket
|
|
||||||
* @param[in] bindAddress binding address for the JSON API socket
|
|
||||||
* @param newAccessRequestCallback called when a new auth token is asked to
|
|
||||||
* be authorized via JSON API, the auth token is passed as parameter, and
|
|
||||||
* the callback should return true if the new token get access granted and
|
|
||||||
* false otherwise, this usually requires user interacion to confirm access
|
|
||||||
*/
|
|
||||||
JsonApiServer( );
|
|
||||||
|
|
||||||
|
|
||||||
/// @see p3Config::setupSerialiser
|
/// @see p3Config::setupSerialiser
|
||||||
virtual RsSerialiser* setupSerialiser();
|
virtual RsSerialiser* setupSerialiser();
|
||||||
@ -211,7 +142,9 @@ private:
|
|||||||
rb::Service mService;
|
rb::Service mService;
|
||||||
|
|
||||||
/// Called when new JSON API auth token is requested to be authorized
|
/// Called when new JSON API auth token is requested to be authorized
|
||||||
std::function<bool(const std::string&)> mNewAccessRequestCallback;
|
/// The callback supplies the password to be used to make the token
|
||||||
|
///
|
||||||
|
std::function<bool(const std::string&,std::string& passwd)> mNewAccessRequestCallback;
|
||||||
|
|
||||||
/// Encrypted persistent storage for authorized JSON API tokens
|
/// Encrypted persistent storage for authorized JSON API tokens
|
||||||
JsonApiServerAuthTokenStorage mAuthTokenStorage;
|
JsonApiServerAuthTokenStorage mAuthTokenStorage;
|
||||||
@ -224,19 +157,18 @@ private:
|
|||||||
static bool checkRsServicePtrReady(
|
static bool checkRsServicePtrReady(
|
||||||
const void* serviceInstance, const std::string& serviceName,
|
const void* serviceInstance, const std::string& serviceName,
|
||||||
RsGenericSerializer::SerializeContext& ctx,
|
RsGenericSerializer::SerializeContext& ctx,
|
||||||
const std::shared_ptr<restbed::Session> session );
|
const std::shared_ptr<rb::Session> session );
|
||||||
|
|
||||||
static inline bool checkRsServicePtrReady(
|
static inline bool checkRsServicePtrReady(
|
||||||
const std::shared_ptr<const void> serviceInstance,
|
const std::shared_ptr<const void> serviceInstance,
|
||||||
const std::string& serviceName,
|
const std::string& serviceName,
|
||||||
RsGenericSerializer::SerializeContext& ctx,
|
RsGenericSerializer::SerializeContext& ctx,
|
||||||
const std::shared_ptr<restbed::Session> session )
|
const std::shared_ptr<rb::Session> session )
|
||||||
{
|
{
|
||||||
return checkRsServicePtrReady(
|
return checkRsServicePtrReady(
|
||||||
serviceInstance.get(), serviceName, ctx, session );
|
serviceInstance.get(), serviceName, ctx, session );
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonApiServer *_instance;
|
std::vector<std::shared_ptr<rb::Resource> > _resources;
|
||||||
static p3ConfigMgr *_config_mgr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
}
|
}
|
||||||
auto settings = std::make_shared< restbed::Settings >( );
|
auto settings = std::make_shared< restbed::Settings >( );
|
||||||
settings->set_port( _listening_port );
|
settings->set_port( _listening_port );
|
||||||
|
settings->set_bind_address( _binding_address );
|
||||||
settings->set_default_header( "Connection", "close" );
|
settings->set_default_header( "Connection", "close" );
|
||||||
|
|
||||||
if(_service->is_up())
|
if(_service->is_up())
|
||||||
@ -82,13 +83,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setListeningPort(uint16_t p) { _listening_port = p ; }
|
void setListeningPort(uint16_t p) { _listening_port = p ; }
|
||||||
|
void setBindAddress(const std::string& bindAddress) { _binding_address = bindAddress ; }
|
||||||
void setResources(const std::vector<std::shared_ptr<restbed::Resource> >& r) { _resources = r ; }
|
void setResources(const std::vector<std::shared_ptr<restbed::Resource> >& r) { _resources = r ; }
|
||||||
uint16_t listeningPort() const { return _listening_port;}
|
uint16_t listeningPort() const { return _listening_port;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<restbed::Service> _service;
|
std::shared_ptr<restbed::Service> _service;
|
||||||
uint16_t _listening_port;
|
|
||||||
std::vector<std::shared_ptr<restbed::Resource> > _resources;
|
std::vector<std::shared_ptr<restbed::Resource> > _resources;
|
||||||
|
|
||||||
|
uint16_t _listening_port;
|
||||||
|
std::string _binding_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
RestbedService::RestbedService()
|
RestbedService::RestbedService()
|
||||||
@ -135,3 +139,11 @@ void RestbedService::setListeningPort(uint16_t port)
|
|||||||
restart();
|
restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RestbedService::setBindAddress(const std::string& bind_address)
|
||||||
|
{
|
||||||
|
_restbed_thread->setBindAddress(bind_address);
|
||||||
|
|
||||||
|
if(_restbed_thread->isRunning())
|
||||||
|
restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ public:
|
|||||||
virtual bool stop();
|
virtual bool stop();
|
||||||
|
|
||||||
virtual void setListeningPort(uint16_t port) ;
|
virtual void setListeningPort(uint16_t port) ;
|
||||||
|
virtual void setBindAddress(const std::string& bind_address);
|
||||||
|
|
||||||
virtual std::vector<std::shared_ptr<restbed::Resource> > getResources()const =0;
|
virtual std::vector<std::shared_ptr<restbed::Resource> > getResources()const =0;
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* libretroshare/src/retroshare: rsjsonapi.h *
|
* libretroshare/src/retroshare: rsjsonapi.h *
|
||||||
* *
|
* *
|
||||||
|
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio.eigenlab.org> *
|
||||||
* Copyright (C) 2019-2019 Cyril Soler <csoler@users.sourceforge.net> *
|
* Copyright (C) 2019-2019 Cyril Soler <csoler@users.sourceforge.net> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
@ -22,16 +23,77 @@
|
|||||||
class RsJsonAPI
|
class RsJsonAPI
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum {
|
||||||
|
JSONAPI_STATUS_UNKNOWN = 0x00,
|
||||||
|
JSONAPI_STATUS_RUNNING = 0x01,
|
||||||
|
JSONAPI_STATUS_NOT_RUNNING = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
static const uint16_t DEFAULT_PORT = 9092 ;
|
static const uint16_t DEFAULT_PORT = 9092 ;
|
||||||
static const std::string DEFAULT_BINDING_ADDRESS ; // 127.0.0.1
|
static const std::string DEFAULT_BINDING_ADDRESS ; // 127.0.0.1
|
||||||
|
|
||||||
virtual bool restart() =0;
|
virtual bool restart() =0;
|
||||||
virtual bool stop() =0;
|
virtual bool stop() =0;
|
||||||
|
|
||||||
virtual void setHtmlFilesDirectory(const std::string& html_dir) =0;
|
virtual void setBindingAddress(const std::string& address) =0;
|
||||||
virtual void setListeningPort(uint16_t port) =0;
|
virtual void setListeningPort(uint16_t port) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get status of the json api server
|
||||||
|
* @jsonapi{development}
|
||||||
|
* @return the status picked in the enum JSONAPI_STATUS_UNKNOWN/RUNNING/NOT_RUNNING
|
||||||
|
*/
|
||||||
virtual int status() const=0;
|
virtual int status() const=0;
|
||||||
|
|
||||||
|
//=============================================================================================//
|
||||||
|
// API methods that are also accessible through http //
|
||||||
|
//=============================================================================================//
|
||||||
|
/**
|
||||||
|
* @brief This function should be used by JSON API clients that aren't
|
||||||
|
* authenticated yet, to ask their token to be authorized, the success or
|
||||||
|
* failure will depend on mNewAccessRequestCallback return value, and it
|
||||||
|
* will likely need human user interaction in the process.
|
||||||
|
* @jsonapi{development,unauthenticated}
|
||||||
|
* @param[in] token token to autorize
|
||||||
|
* @return true if authorization succeded, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool requestNewTokenAutorization(const std::string& token)=0;
|
||||||
|
|
||||||
|
//=============================================================================================//
|
||||||
|
// API methods that SHOULD NOT be accessible through http //
|
||||||
|
//=============================================================================================//
|
||||||
|
|
||||||
|
//////////////// @Gio: The methods below should not be accessible from the API server !
|
||||||
|
///
|
||||||
|
/**
|
||||||
|
* @brief Add new auth (user,passwd) token to the authorized set, creating the token user:passwd internally.
|
||||||
|
* @param[in] alphanumeric_user username to autorize decoded
|
||||||
|
* @param[in] alphanumeric_passwd passwd to autorize decoded
|
||||||
|
* @return true if the token has been added to authorized, false if error occurred
|
||||||
|
*/
|
||||||
|
virtual bool authorizeUser(const std::string& alphanumeric_user,const std::string& alphanumeric_passwd)=0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Revoke given auth token
|
||||||
|
* @param[in] user par of the decoded token
|
||||||
|
* @return true if the token has been revoked, false otherwise
|
||||||
|
*/
|
||||||
|
virtual bool revokeAuthToken(const std::string& user)=0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get authorized tokens
|
||||||
|
* @return the set of authorized encoded tokens
|
||||||
|
*/
|
||||||
|
virtual std::map<std::string,std::string> getAuthorizedTokens() =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if given JSON API auth token is authorized
|
||||||
|
* @param[in] token decoded
|
||||||
|
* @return tru if authorized, false otherwise
|
||||||
|
*/
|
||||||
|
virtual bool isAuthTokenValid(const std::string& token);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RsJsonAPI *rsJsonAPI;
|
extern RsJsonAPI *rsJsonAPI;
|
||||||
|
@ -91,7 +91,7 @@ void RsServer::rsGlobalShutDown()
|
|||||||
mNetMgr->shutdown(); /* Handles UPnP */
|
mNetMgr->shutdown(); /* Handles UPnP */
|
||||||
|
|
||||||
#ifdef RS_JSONAPI
|
#ifdef RS_JSONAPI
|
||||||
JsonApiServer::instance().shutdown();
|
rsJsonAPI->stop();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rsAutoProxyMonitor::instance()->stopAllRSShutdown();
|
rsAutoProxyMonitor::instance()->stopAllRSShutdown();
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "retroshare/rsiface.h"
|
#include "retroshare/rsiface.h"
|
||||||
#include "retroshare/rstypes.h"
|
#include "retroshare/rstypes.h"
|
||||||
#include "util/rsthreads.h"
|
#include "util/rsthreads.h"
|
||||||
|
#include "jsonapi/jsonapi.h"
|
||||||
|
|
||||||
#include "chat/p3chatservice.h"
|
#include "chat/p3chatservice.h"
|
||||||
#include "gxstunnel/p3gxstunnel.h"
|
#include "gxstunnel/p3gxstunnel.h"
|
||||||
@ -157,6 +158,7 @@ public:
|
|||||||
RsPluginManager *mPluginsManager;
|
RsPluginManager *mPluginsManager;
|
||||||
|
|
||||||
//sslroot *sslr;
|
//sslroot *sslr;
|
||||||
|
JsonApiServer *mJsonAPIServer;
|
||||||
|
|
||||||
/* services */
|
/* services */
|
||||||
p3heartbeat *mHeart;
|
p3heartbeat *mHeart;
|
||||||
|
@ -37,6 +37,7 @@ public:
|
|||||||
virtual bool restart() override { return RestbedService::restart();}
|
virtual bool restart() override { return RestbedService::restart();}
|
||||||
virtual bool stop() override { return RestbedService::stop();}
|
virtual bool stop() override { return RestbedService::stop();}
|
||||||
virtual void setListeningPort(uint16_t port) override { RestbedService::setListeningPort(port) ;}
|
virtual void setListeningPort(uint16_t port) override { RestbedService::setListeningPort(port) ;}
|
||||||
|
virtual void setBindingAddress(const std::string& address) override { RestbedService::setBindAddress(address) ;}
|
||||||
|
|
||||||
virtual int status() const override;
|
virtual int status() const override;
|
||||||
virtual std::vector<std::shared_ptr<restbed::Resource> > getResources() const override;
|
virtual std::vector<std::shared_ptr<restbed::Resource> > getResources() const override;
|
||||||
|
@ -410,7 +410,11 @@ int RsInit::InitRetroShare(const RsConfigOptions& conf)
|
|||||||
|
|
||||||
#ifdef RS_JSONAPI
|
#ifdef RS_JSONAPI
|
||||||
if(rsInitConfig->jsonApiPort)
|
if(rsInitConfig->jsonApiPort)
|
||||||
JsonApiServer::instance().start(rsInitConfig->jsonApiPort, rsInitConfig->jsonApiBindAddress);
|
{
|
||||||
|
rsJsonAPI->setListeningPort(rsInitConfig->jsonApiPort);
|
||||||
|
rsJsonAPI->setBindingAddress(rsInitConfig->jsonApiBindAddress);
|
||||||
|
rsJsonAPI->restart();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ifdef RS_JSONAPI
|
#endif // ifdef RS_JSONAPI
|
||||||
|
|
||||||
@ -1212,7 +1216,15 @@ int RsServer::StartupRetroShare()
|
|||||||
//
|
//
|
||||||
mPluginsManager->loadPlugins(programatically_inserted_plugins) ;
|
mPluginsManager->loadPlugins(programatically_inserted_plugins) ;
|
||||||
|
|
||||||
JsonApiServer::setConfigMgr(mConfigMgr);
|
#ifdef RS_JSONAPI
|
||||||
|
mJsonAPIServer = new JsonApiServer;
|
||||||
|
rsJsonAPI = mJsonAPIServer;
|
||||||
|
|
||||||
|
mConfigMgr->addConfiguration("jsonapi.cfg",mJsonAPIServer);
|
||||||
|
|
||||||
|
RsFileHash dummyHash;
|
||||||
|
mJsonAPIServer->loadConfiguration(dummyHash);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**** Reputation system ****/
|
/**** Reputation system ****/
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ void JsonApiPage::load()
|
|||||||
|
|
||||||
QStringList newTk;
|
QStringList newTk;
|
||||||
|
|
||||||
for(const auto& it : JsonApiServer::instance().getAuthorizedTokens())
|
for(const auto& it : rsJsonAPI->getAuthorizedTokens())
|
||||||
newTk.push_back(QString::fromStdString(it.first)+":"+QString::fromStdString(it.second)) ;
|
newTk.push_back(QString::fromStdString(it.first)+":"+QString::fromStdString(it.second)) ;
|
||||||
|
|
||||||
whileBlocking(ui.tokensListView)->setModel(new QStringListModel(newTk));
|
whileBlocking(ui.tokensListView)->setModel(new QStringListModel(newTk));
|
||||||
@ -105,17 +105,17 @@ QString JsonApiPage::helpText() const { return ""; }
|
|||||||
/*static*/ bool JsonApiPage::checkStartJsonApi()
|
/*static*/ bool JsonApiPage::checkStartJsonApi()
|
||||||
{
|
{
|
||||||
if(Settings->getJsonApiEnabled())
|
if(Settings->getJsonApiEnabled())
|
||||||
JsonApiServer::instance().start( Settings->getJsonApiPort(), Settings->getJsonApiListenAddress().toStdString() );
|
rsJsonAPI->restart();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void JsonApiPage::checkShutdownJsonApi()
|
/*static*/ void JsonApiPage::checkShutdownJsonApi()
|
||||||
{
|
{
|
||||||
if(!JsonApiServer::instance().isRunning())
|
rsJsonAPI->isRunning())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
JsonApiServer::instance().shutdown(); // this is a blocking call until the thread is terminated.
|
rsJsonAPI->stop(); // this is a blocking call until the thread is terminated.
|
||||||
|
|
||||||
#ifdef SUSPENDED_CODE
|
#ifdef SUSPENDED_CODE
|
||||||
/* It is important to make a copy of +jsonApiServer+ pointer so the old
|
/* It is important to make a copy of +jsonApiServer+ pointer so the old
|
||||||
@ -148,17 +148,21 @@ void JsonApiPage::onApplyClicked(bool)
|
|||||||
// restart
|
// restart
|
||||||
|
|
||||||
checkShutdownJsonApi();
|
checkShutdownJsonApi();
|
||||||
|
|
||||||
|
rsJsonAPI->setListeningPort(ui.portSpinBox->value());
|
||||||
|
rsJsonAPI->setBindingAddress(ui.listenAddressLineEdit->text().toStdString());
|
||||||
|
|
||||||
checkStartJsonApi();
|
checkStartJsonApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonApiPage::addTokenClicked(bool)
|
void JsonApiPage::addTokenClicked(bool)
|
||||||
{
|
{
|
||||||
QString token(ui.tokenLineEdit->text());
|
QString token(ui.tokenLineEdit->text());
|
||||||
JsonApiServer::instance().authorizeToken(token.toStdString());
|
rsJsonAPI->authorizeUser(token.toStdString());
|
||||||
|
|
||||||
QStringList newTk;
|
QStringList newTk;
|
||||||
|
|
||||||
for(const auto& it : JsonApiServer::instance().getAuthorizedTokens())
|
for(const auto& it : rsJsonAPI->getAuthorizedTokens())
|
||||||
newTk.push_back(QString::fromStdString(it.first)+":"+QString::fromStdString(it.second)) ;
|
newTk.push_back(QString::fromStdString(it.first)+":"+QString::fromStdString(it.second)) ;
|
||||||
|
|
||||||
whileBlocking(ui.tokensListView)->setModel(new QStringListModel(newTk));
|
whileBlocking(ui.tokensListView)->setModel(new QStringListModel(newTk));
|
||||||
@ -167,11 +171,11 @@ void JsonApiPage::addTokenClicked(bool)
|
|||||||
void JsonApiPage::removeTokenClicked(bool)
|
void JsonApiPage::removeTokenClicked(bool)
|
||||||
{
|
{
|
||||||
QString token(ui.tokenLineEdit->text());
|
QString token(ui.tokenLineEdit->text());
|
||||||
JsonApiServer::instance().revokeAuthToken(token.toStdString());
|
rsJsonAPI->revokeAuthToken(token.toStdString());
|
||||||
|
|
||||||
QStringList newTk;
|
QStringList newTk;
|
||||||
|
|
||||||
for(const auto& it : JsonApiServer::instance().getAuthorizedTokens())
|
for(const auto& it : rsJsonAPI->getAuthorizedTokens())
|
||||||
newTk.push_back(QString::fromStdString(it.first)+":"+QString::fromStdString(it.second)) ;
|
newTk.push_back(QString::fromStdString(it.first)+":"+QString::fromStdString(it.second)) ;
|
||||||
|
|
||||||
whileBlocking(ui.tokensListView)->setModel(new QStringListModel(Settings->getJsonApiAuthTokens()) );
|
whileBlocking(ui.tokensListView)->setModel(new QStringListModel(Settings->getJsonApiAuthTokens()) );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user