mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 06:06:10 -04:00
Implement JSON API HTTP Basic authentication
jsonapi-generator is now capable of generating API for headers outside retroshare/ directory jsonapi-generator do a bit of methods parameter sanity check JsonApiServer is now integrated in the rsinit hell like other services Add *::exportGPGKeyPairToString to a bunch of classes in cascade RsControl is now capable of calling back a function when retroshare is almost completely stopped, this is useful when running retroshare toghether with externally managed runloop such as QCoreApplication Expose a bunch of methods through JSON API retroshare-nogui remove some dead code and fix stopping from the RetroShare API
This commit is contained in:
parent
ac9350d375
commit
eb77f921ec
32 changed files with 816 additions and 398 deletions
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "jsonapi.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <restbed>
|
||||
|
@ -27,10 +28,17 @@
|
|||
#include "retroshare/rsfiles.h"
|
||||
#include "util/radix64.h"
|
||||
#include "retroshare/rsversion.h"
|
||||
#include "retroshare/rsinit.h"
|
||||
#include "util/rsnet.h"
|
||||
#include "retroshare/rsiface.h"
|
||||
#include "retroshare/rsinit.h"
|
||||
#include "util/rsurl.h"
|
||||
|
||||
// Generated at compile time
|
||||
#include "jsonapi-includes.inl"
|
||||
|
||||
/*extern*/ JsonApiServer* jsonApiServer = nullptr;
|
||||
|
||||
#define INITIALIZE_API_CALL_JSON_CONTEXT \
|
||||
RsGenericSerializer::SerializeContext cReq( \
|
||||
nullptr, 0, \
|
||||
|
@ -71,10 +79,10 @@ static bool checkRsServicePtrReady(
|
|||
{
|
||||
if(serviceInstance) return true;
|
||||
|
||||
std::string jsonApiError;
|
||||
std::string jsonApiError = __PRETTY_FUNCTION__;
|
||||
jsonApiError += "Service: ";
|
||||
jsonApiError += serviceName;
|
||||
jsonApiError += " not initialized! Are you sure you logged in already?";
|
||||
jsonApiError += " not initialized!";
|
||||
|
||||
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
|
||||
RS_SERIAL_PROCESS(jsonApiError);
|
||||
|
@ -84,13 +92,53 @@ static bool checkRsServicePtrReady(
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
JsonApiServer::JsonApiServer(
|
||||
uint16_t port, const std::string& bindAddress,
|
||||
const std::function<void(int)> shutdownCallback ) :
|
||||
mPort(port), mBindAddress(bindAddress), mShutdownCallback(shutdownCallback)
|
||||
JsonApiServer::JsonApiServer(uint16_t port, const std::string& bindAddress,
|
||||
const std::function<bool(const std::string&)> newAccessRequestCallback ) :
|
||||
mPort(port), mBindAddress(bindAddress),
|
||||
mNewAccessRequestCallback(newAccessRequestCallback),
|
||||
configMutex("JsonApiServer config")
|
||||
{
|
||||
registerHandler("/jsonApiServer/shutdown",
|
||||
registerHandler("/rsLoginHelper/attemptLogin",
|
||||
[this](const std::shared_ptr<rb::Session> session)
|
||||
{
|
||||
size_t reqSize = session->get_request()->get_header("Content-Length", 0);
|
||||
session->fetch( reqSize, [this](
|
||||
const std::shared_ptr<rb::Session> session,
|
||||
const rb::Bytes& body )
|
||||
{
|
||||
INITIALIZE_API_CALL_JSON_CONTEXT;
|
||||
|
||||
RsPeerId account;
|
||||
std::string password;
|
||||
|
||||
// deserialize input parameters from JSON
|
||||
{
|
||||
RsGenericSerializer::SerializeContext& ctx(cReq);
|
||||
RsGenericSerializer::SerializeJob j(RsGenericSerializer::FROM_JSON);
|
||||
RS_SERIAL_PROCESS(account);
|
||||
RS_SERIAL_PROCESS(password);
|
||||
}
|
||||
|
||||
// call retroshare C++ API
|
||||
RsInit::LoadCertificateStatus retval =
|
||||
rsLoginHelper->attemptLogin(account, password);
|
||||
|
||||
if( retval == RsInit::OK )
|
||||
authorizeToken(account.toStdString()+":"+password);
|
||||
|
||||
// serialize out parameters and return value to JSON
|
||||
{
|
||||
RsGenericSerializer::SerializeContext& ctx(cAns);
|
||||
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
|
||||
RS_SERIAL_PROCESS(retval);
|
||||
}
|
||||
|
||||
// return them to the API caller
|
||||
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
|
||||
} );
|
||||
}, false);
|
||||
|
||||
registerHandler("/rsControl/rsGlobalShutDown",
|
||||
[this](const std::shared_ptr<rb::Session> session)
|
||||
{
|
||||
size_t reqSize = session->get_request()->get_header("Content-Length", 0);
|
||||
|
@ -100,37 +148,9 @@ JsonApiServer::JsonApiServer(
|
|||
{
|
||||
INITIALIZE_API_CALL_JSON_CONTEXT;
|
||||
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
|
||||
shutdown();
|
||||
rsControl->rsGlobalShutDown();
|
||||
} );
|
||||
});
|
||||
|
||||
registerHandler("/jsonApiServer/version",
|
||||
[](const std::shared_ptr<rb::Session> session)
|
||||
{
|
||||
size_t reqSize = session->get_request()->get_header("Content-Length", 0);
|
||||
session->fetch( reqSize, [](
|
||||
const std::shared_ptr<rb::Session> session,
|
||||
const rb::Bytes& body )
|
||||
{
|
||||
INITIALIZE_API_CALL_JSON_CONTEXT;
|
||||
|
||||
uint32_t major = RS_MAJOR_VERSION;
|
||||
uint32_t minor = RS_MINOR_VERSION;
|
||||
uint32_t mini = RS_MINI_VERSION;
|
||||
std::string extra = RS_EXTRA_VERSION;
|
||||
std::string human = RS_HUMAN_READABLE_VERSION;
|
||||
|
||||
RsGenericSerializer::SerializeContext& ctx(cAns);
|
||||
RsGenericSerializer::SerializeJob j(RsGenericSerializer::TO_JSON);
|
||||
RS_SERIAL_PROCESS(major);
|
||||
RS_SERIAL_PROCESS(minor);
|
||||
RS_SERIAL_PROCESS(mini);
|
||||
RS_SERIAL_PROCESS(extra);
|
||||
RS_SERIAL_PROCESS(human);
|
||||
|
||||
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
|
||||
} );
|
||||
});
|
||||
}, true);
|
||||
|
||||
registerHandler("/rsFiles/getFileData",
|
||||
[](const std::shared_ptr<rb::Session> session)
|
||||
|
@ -186,7 +206,7 @@ JsonApiServer::JsonApiServer(
|
|||
|
||||
DEFAULT_API_CALL_JSON_RETURN(rb::OK);
|
||||
} );
|
||||
});
|
||||
}, true);
|
||||
|
||||
// Generated at compile time
|
||||
#include "jsonapi-wrappers.inl"
|
||||
|
@ -198,22 +218,173 @@ void JsonApiServer::run()
|
|||
settings->set_port(mPort);
|
||||
settings->set_bind_address(mBindAddress);
|
||||
settings->set_default_header("Cache-Control", "no-cache");
|
||||
|
||||
{
|
||||
sockaddr_storage tmp;
|
||||
sockaddr_storage_inet_pton(tmp, mBindAddress);
|
||||
sockaddr_storage_setport(tmp, mPort);
|
||||
sockaddr_storage_ipv6_to_ipv4(tmp);
|
||||
RsUrl tmpUrl(sockaddr_storage_tostring(tmp));
|
||||
tmpUrl.setScheme("http");
|
||||
|
||||
std::cerr << "JSON API listening on " << tmpUrl.toString()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
mService.start(settings);
|
||||
}
|
||||
|
||||
void JsonApiServer::registerHandler(
|
||||
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,
|
||||
bool requiresAutentication )
|
||||
{
|
||||
std::shared_ptr<restbed::Resource> resource(new rb::Resource);
|
||||
resource->set_path(path);
|
||||
resource->set_method_handler("GET", handler);
|
||||
resource->set_method_handler("POST", handler);
|
||||
|
||||
if(requiresAutentication)
|
||||
resource->set_authentication_handler(
|
||||
[this](
|
||||
const std::shared_ptr<rb::Session> session,
|
||||
const std::function<void (const std::shared_ptr<rb::Session>)>& callback )
|
||||
{
|
||||
if(!rsLoginHelper->isLoggedIn())
|
||||
{
|
||||
session->close(rb::CONFLICT);
|
||||
return;
|
||||
}
|
||||
|
||||
std::istringstream authHeader;
|
||||
authHeader.str(session->get_request()->get_header("Authorization"));
|
||||
|
||||
std::string authToken;
|
||||
std::getline(authHeader, authToken, ' ');
|
||||
|
||||
if(authToken != "Basic")
|
||||
{
|
||||
session->close(rb::UNAUTHORIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
std::getline(authHeader, authToken, ' ');
|
||||
authToken = decodeToken(authToken);
|
||||
|
||||
if(isAuthTokenValid(authToken)) callback(session);
|
||||
else session->close(rb::UNAUTHORIZED);
|
||||
} );
|
||||
|
||||
mService.publish(resource);
|
||||
}
|
||||
|
||||
void JsonApiServer::shutdown(int exitCode)
|
||||
void JsonApiServer::setNewAccessRequestCallback(
|
||||
const std::function<bool (const std::string&)>& callback )
|
||||
{ mNewAccessRequestCallback = callback; }
|
||||
|
||||
void JsonApiServer::shutdown() { mService.stop(); }
|
||||
|
||||
bool JsonApiServer::requestNewTokenAutorization(const std::string& token)
|
||||
{
|
||||
mService.stop();
|
||||
mShutdownCallback(exitCode);
|
||||
if(rsLoginHelper->isLoggedIn() && mNewAccessRequestCallback(token))
|
||||
return authorizeToken(token);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsonApiServer::isAuthTokenValid(const std::string& token)
|
||||
{
|
||||
RS_STACK_MUTEX(configMutex);
|
||||
return mAuthTokenStorage.mAuthorizedTokens.count(token);
|
||||
}
|
||||
|
||||
std::set<std::string> JsonApiServer::getAuthorizedTokens()
|
||||
{
|
||||
RS_STACK_MUTEX(configMutex);
|
||||
return mAuthTokenStorage.mAuthorizedTokens;
|
||||
}
|
||||
|
||||
bool JsonApiServer::revokeAuthToken(const std::string& token)
|
||||
{
|
||||
RS_STACK_MUTEX(configMutex);
|
||||
if(mAuthTokenStorage.mAuthorizedTokens.erase(token))
|
||||
{
|
||||
IndicateConfigChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsonApiServer::authorizeToken(const std::string& token)
|
||||
{
|
||||
if(token.empty()) return false;
|
||||
|
||||
RS_STACK_MUTEX(configMutex);
|
||||
if(mAuthTokenStorage.mAuthorizedTokens.insert(token).second)
|
||||
{
|
||||
IndicateConfigChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*static*/ std::string JsonApiServer::decodeToken(const std::string& token)
|
||||
{
|
||||
std::vector<uint8_t> decodedVect(Radix64::decode(token));
|
||||
std::string decodedToken(
|
||||
reinterpret_cast<const char*>(&decodedVect[0]),
|
||||
decodedVect.size() );
|
||||
return decodedToken;
|
||||
}
|
||||
|
||||
/*static*/ std::string JsonApiServer::encondeToken(const std::string& token)
|
||||
{
|
||||
std::string encoded;
|
||||
Radix64::encode( reinterpret_cast<const uint8_t*>(token.c_str()),
|
||||
token.length(), encoded );
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/*static*/ void JsonApiServer::version(
|
||||
uint32_t& major, uint32_t& minor, uint32_t& mini, std::string& extra,
|
||||
std::string& human )
|
||||
{
|
||||
major = RS_MAJOR_VERSION;
|
||||
minor = RS_MINOR_VERSION;
|
||||
mini = RS_MINI_VERSION;
|
||||
extra = RS_EXTRA_VERSION;
|
||||
human = RS_HUMAN_READABLE_VERSION;
|
||||
}
|
||||
|
||||
RsSerialiser* JsonApiServer::setupSerialiser()
|
||||
{
|
||||
RsSerialiser* rss = new RsSerialiser;
|
||||
rss->addSerialType(new JsonApiConfigSerializer);
|
||||
return rss;
|
||||
}
|
||||
|
||||
bool JsonApiServer::saveList(bool& cleanup, std::list<RsItem*>& saveItems)
|
||||
{
|
||||
cleanup = false;
|
||||
configMutex.lock();
|
||||
saveItems.push_back(&mAuthTokenStorage);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonApiServer::loadList(std::list<RsItem*>& loadList)
|
||||
{
|
||||
for(RsItem* it : loadList)
|
||||
switch (static_cast<JsonApiItemsType>(it->PacketSubType()))
|
||||
{
|
||||
case JsonApiItemsType::AuthTokenItem:
|
||||
mAuthTokenStorage = *static_cast<JsonApiServerAuthTokenStorage*>(it);
|
||||
delete it;
|
||||
break;
|
||||
default:
|
||||
delete it;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void JsonApiServer::saveDone() { configMutex.unlock(); }
|
||||
|
||||
|
|
|
@ -15,36 +15,59 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <restbed>
|
||||
#include <cstdint>
|
||||
|
||||
#include "util/rsthreads.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "rsitems/rsitem.h"
|
||||
#include "jsonapi/jsonapiitems.h"
|
||||
#include "util/rsthreads.h"
|
||||
|
||||
namespace rb = restbed;
|
||||
|
||||
struct JsonApiServer;
|
||||
|
||||
/**
|
||||
* Pointer to global instance of JsonApiServer
|
||||
* @jsonapi{development}
|
||||
*/
|
||||
extern JsonApiServer* jsonApiServer;
|
||||
|
||||
/**
|
||||
* Simple usage
|
||||
* \code{.cpp}
|
||||
* JsonApiServer jas(9092);
|
||||
* jsonApiServer = &jas;
|
||||
* jas.start("JsonApiServer");
|
||||
* \endcode
|
||||
* Uses p3Config to securely store persistent JSON API authorization tokens
|
||||
*/
|
||||
struct JsonApiServer : RsSingleJobThread
|
||||
struct JsonApiServer : RsSingleJobThread, p3Config
|
||||
{
|
||||
/**
|
||||
* @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(
|
||||
uint16_t port = 9092,
|
||||
const std::string& bindAddress = "127.0.0.1",
|
||||
const std::function<void(int)> shutdownCallback = [](int){} );
|
||||
|
||||
/// @see RsSingleJobThread
|
||||
virtual void run();
|
||||
const std::function<bool(const std::string&)> newAccessRequestCallback = [](const std::string&){return false;} );
|
||||
|
||||
/**
|
||||
* @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)
|
||||
|
@ -52,24 +75,118 @@ struct JsonApiServer : RsSingleJobThread
|
|||
*/
|
||||
void registerHandler(
|
||||
const std::string& path,
|
||||
const std::function<void(const std::shared_ptr<rb::Session>)>& handler );
|
||||
const std::function<void(const std::shared_ptr<rb::Session>)>& handler,
|
||||
bool requiresAutentication = true );
|
||||
|
||||
/**
|
||||
* @brief Shutdown the JSON API server and call shutdownCallback
|
||||
* @jsonapi{development}
|
||||
* Beware that this method shout down only the JSON API server instance not
|
||||
* the whole RetroShare instance, this behaviour can be altered via
|
||||
* shutdownCallback paramether of @see JsonApiServer::JsonApiServer
|
||||
* This method is made available also via JSON API with path
|
||||
* /jsonApiServer/shutdown
|
||||
* @param exitCode just passed down to the shutdownCallback
|
||||
* @brief Set new access request callback
|
||||
* @param callback function to call when a new JSON API access is requested
|
||||
*/
|
||||
void shutdown(int exitCode = 0);
|
||||
void setNewAccessRequestCallback(
|
||||
const std::function<bool(const std::string&)>& callback );
|
||||
|
||||
/**
|
||||
* @brief Shutdown the JSON API server
|
||||
* Beware that this method shout down only the JSON API server instance not
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
/**
|
||||
* @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::set<std::string> getAuthorizedTokens();
|
||||
|
||||
/**
|
||||
* @brief Revoke given auth token
|
||||
* @jsonapi{development}
|
||||
* @param[in] token decoded
|
||||
* @return true if the token has been revoked, false otherwise
|
||||
*/
|
||||
bool revokeAuthToken(const std::string& token);
|
||||
|
||||
/**
|
||||
* @brief Add new auth token to the authorized set
|
||||
* @jsonapi{development}
|
||||
* @param[in] token toke to autorize decoded
|
||||
* @return true if the token has been added to authorized, false if error
|
||||
* occurred or if the token was already authorized
|
||||
*/
|
||||
bool authorizeToken(const std::string& token);
|
||||
|
||||
/**
|
||||
* @brief Get decoded version of the given encoded token
|
||||
* @jsonapi{development,unauthenticated}
|
||||
* @param[in] token encoded
|
||||
* @return token decoded
|
||||
*/
|
||||
static std::string decodeToken(const std::string& token);
|
||||
|
||||
/**
|
||||
* @brief Get encoded version of the given decoded token
|
||||
* @jsonapi{development,unauthenticated}
|
||||
* @param[in] token decoded
|
||||
* @return token encoded
|
||||
*/
|
||||
static std::string encondeToken(const std::string& token);
|
||||
|
||||
/**
|
||||
* @brief Write version information to given paramethers
|
||||
* @jsonapi{development,unauthenticated}
|
||||
* @param[out] major storage
|
||||
* @param[out] minor storage
|
||||
* @param[out] mini storage
|
||||
* @param[out] extra storage
|
||||
* @param[out] human storage
|
||||
*/
|
||||
static void version( uint32_t& major, uint32_t& minor, uint32_t& mini,
|
||||
std::string& extra, std::string&human );
|
||||
|
||||
/// @see RsSingleJobThread
|
||||
virtual void run();
|
||||
|
||||
private:
|
||||
/// @see p3Config::setupSerialiser
|
||||
virtual RsSerialiser* setupSerialiser();
|
||||
|
||||
/// @see p3Config::saveList
|
||||
virtual bool saveList(bool &cleanup, std::list<RsItem *>& saveItems);
|
||||
|
||||
/// @see p3Config::loadList
|
||||
virtual bool loadList(std::list<RsItem *>& loadList);
|
||||
|
||||
/// @see p3Config::saveDone
|
||||
virtual void saveDone();
|
||||
|
||||
const uint16_t mPort;
|
||||
const std::string mBindAddress;
|
||||
rb::Service mService;
|
||||
const std::function<void(int)> mShutdownCallback;
|
||||
|
||||
/// Called when new JSON API auth token is requested to be authorized
|
||||
std::function<bool(const std::string&)> mNewAccessRequestCallback;
|
||||
|
||||
/// Encrypted persistent storage for authorized JSON API tokens
|
||||
JsonApiServerAuthTokenStorage mAuthTokenStorage;
|
||||
RsMutex configMutex;
|
||||
};
|
||||
|
||||
|
|
69
libretroshare/src/jsonapi/jsonapiitems.h
Normal file
69
libretroshare/src/jsonapi/jsonapiitems.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* RetroShare JSON API
|
||||
* Copyright (C) 2018 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
|
||||
#include "rsitems/rsitem.h"
|
||||
#include "rsitems/rsserviceids.h"
|
||||
#include "serialiser/rsserializer.h"
|
||||
#include "serialiser/rsserializable.h"
|
||||
|
||||
enum class JsonApiItemsType : uint8_t { AuthTokenItem = 0 };
|
||||
|
||||
struct JsonApiServerAuthTokenStorage : RsItem
|
||||
{
|
||||
JsonApiServerAuthTokenStorage() :
|
||||
RsItem( RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_JSONAPI,
|
||||
static_cast<uint8_t>(JsonApiItemsType::AuthTokenItem) ) {}
|
||||
|
||||
/// @see RsSerializable
|
||||
virtual void serial_process(RsGenericSerializer::SerializeJob j,
|
||||
RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RS_SERIAL_PROCESS(mAuthorizedTokens);
|
||||
}
|
||||
|
||||
/// @see RsItem
|
||||
virtual void clear() { mAuthorizedTokens.clear(); }
|
||||
|
||||
std::set<std::string> mAuthorizedTokens;
|
||||
};
|
||||
|
||||
|
||||
struct JsonApiConfigSerializer : RsServiceSerializer
|
||||
{
|
||||
JsonApiConfigSerializer() : RsServiceSerializer(RS_SERVICE_TYPE_JSONAPI) {}
|
||||
virtual ~JsonApiConfigSerializer() {}
|
||||
|
||||
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
|
||||
{
|
||||
if(service_id != RS_SERVICE_TYPE_JSONAPI) return nullptr;
|
||||
|
||||
switch(static_cast<JsonApiItemsType>(item_sub_id))
|
||||
{
|
||||
case JsonApiItemsType::AuthTokenItem: return new JsonApiServerAuthTokenStorage();
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue