adding json interface running on another port

This commit is contained in:
Dario 2019-10-22 14:53:40 +02:00
parent 79b69d6e11
commit 8ba13bbebe
13 changed files with 285 additions and 10 deletions

View File

@ -19,13 +19,14 @@ include_directories(
FILE(GLOB TINF "dependencies/tinf/src/*.c" "dependencies/tinf/src/*.h")
FILE(GLOB HTTPInterface "src/cpp/HTTPInterface/*.h" "src/cpp/HTTPInterface/*.cpp")
FILE(GLOB JSONInterface "src/cpp/JSONInterface/*.h" "src/cpp/JSONInterface/*.cpp")
FILE(GLOB TASKS "src/cpp/tasks/*.cpp" "src/cpp/tasks/*.h")
FILE(GLOB SINGLETON_MANAGER "src/cpp/SingletonManager/*.h" "src/cpp/SingletonManager/*.cpp")
FILE(GLOB MODEL "src/cpp/model/*.h" "src/cpp/model/*.cpp")
FILE(GLOB CRYPTO "src/cpp/Crypto/*.h" "src/cpp/Crypto/*.cpp")
FILE(GLOB MAIN "src/cpp/*.cpp" "src/cpp/*.c" "src/cpp/*.h")
FILE(GLOB MYSQL "src/cpp/MySQL/*.cpp" "src/cpp/MySQL/*.h" "src/cpp/MySQL/Poco/*.h")
SET(LOCAL_SRCS ${TINF} ${MAIN} ${HTTPInterface} ${CRYPTO} ${MODEL} ${SINGLETON_MANAGER} ${MYSQL} ${TASKS})
SET(LOCAL_SRCS ${TINF} ${MAIN} ${HTTPInterface} ${JSONInterface} ${CRYPTO} ${MODEL} ${SINGLETON_MANAGER} ${MYSQL} ${TASKS})
aux_source_directory("src/cpp" LOCAL_SRCS)
if(MSVC)
@ -37,6 +38,7 @@ source_group("model" FILES ${MODEL})
source_group("mysql" FILES ${MYSQL})
source_group("SingletonManager" FILES ${SINGLETON_MANAGER})
source_group("HTTP-Interface" FILES ${HTTPInterface})
source_group("Json-Interface" FILES ${JSONInterface})
endif(MSVC)

View File

@ -1,6 +1,7 @@
#include "Gradido_LoginServer.h"
#include "ServerConfig.h"
#include "HTTPInterface/PageRequestHandlerFactory.h"
#include "JSONInterface/JsonRequestHandlerFactory.h"
#include "model/Profiler.h"
@ -81,6 +82,7 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
else
{
unsigned short port = (unsigned short)config().getInt("HTTPServer.port", 9980);
unsigned short json_port = (unsigned short)config().getInt("JSONServer.port", 1201);
// load word lists
if (!ServerConfig::loadMnemonicWordLists()) {
@ -155,27 +157,33 @@ int Gradido_LoginServer::main(const std::vector<std::string>& args)
requestLog.setChannel(requestLogAsyncChannel);
requestLog.setLevel("information");
// HTTP Interface Server
// set-up a server socket
Poco::Net::ServerSocket svs(port);
// set-up a HTTPServer instance
Poco::ThreadPool& pool = Poco::ThreadPool::defaultPool();
Poco::Net::HTTPServer srv(new PageRequestHandlerFactory, svs, new Poco::Net::HTTPServerParams);
ServerConfig::g_ServerKeySeed->put(7, 918276611);
Poco::Int64 key[6];
const unsigned char* seed = *ServerConfig::g_ServerKeySeed;
// skip first two values
seed += 16;
memcpy(key, seed, 6 * 8);
printf("key: 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n",
key[0], key[1], key[2], key[3], key[4], key[5]);
// start the HTTPServer
srv.start();
// JSON Interface Server
Poco::Net::ServerSocket json_svs(json_port);
Poco::Net::HTTPServer json_srv(new JsonRequestHandlerFactory, json_svs, new Poco::Net::HTTPServerParams);
// start the json server
json_srv.start();
printf("[Gradido_LoginServer::main] started in %s\n", usedTime.string().data());
// wait for CTRL-C or kill
waitForTerminationRequest();
// Stop the HTTPServer
srv.stop();
// Stop the json server
json_srv.stop();
ServerConfig::unload();
Poco::Net::uninitializeSSL();
}

View File

@ -0,0 +1,81 @@
#include "JsonGetLogin.h"
#include "Poco/URI.h"
#include "../SingletonManager/SessionManager.h"
Poco::JSON::Object JsonGetLogin::handle(Poco::Dynamic::Var params)
{
int session_id = 0;
Poco::JSON::Object result;
if (params.isStruct()) {
session_id = params["session_id"];
//std::string miau = params["miau"];
}
else if (params.isVector()) {
try {
const Poco::URI::QueryParameters queryParams = params.extract<Poco::URI::QueryParameters>();
for (auto it = queryParams.begin(); it != queryParams.end(); it++) {
if (it->first == "session_id") {
session_id = stoi(it->second);
break;
}
}
//auto var = params[0];
}
catch (const std::invalid_argument& ia) {
result.set("state", "error");
result.set("msg", "error parsing query params, invalid argument: ");
result.set("details", ia.what());
return result;
}
catch (const std::out_of_range& oor) {
result.set("state", "error");
result.set("msg", "error parsing query params, Out of Range error: ");
result.set("details", oor.what());
return result;
}
catch (const std::logic_error & ler) {
result.set("state", "error");
result.set("msg", "error parsing query params, Logical error: ");
result.set("details", ler.what());
return result;
}
catch (Poco::Exception& ex) {
//printf("[JsonGetLogin::handle] exception: %s\n", ex.displayText().data());
result.set("state", "error");
result.set("msg", "error parsing query params, Poco Error");
result.set("details", ex.displayText());
return result;
}
}
if (session_id) {
auto sm = SessionManager::getInstance();
auto session = sm->getSession(session_id);
if (session) {
auto user = session->getUser();
if (!user) {
result.set("state", "not found");
result.set("msg", "Session didn't contain user");
return result;
}
result.set("state", "success");
result.set("clientIP", session->getClientIp());
result.set("user", user->getJson());
return result;
}
else {
result.set("state", "not found");
result.set("msg", "Session not found");
return result;
}
}
else {
result.set("state", "error");
result.set("msg", "empty session id");
}
return result;
}

View File

@ -0,0 +1,16 @@
#ifndef __JSON_INTERFACE_JSON_GET_LOGIN_
#define __JSON_INTERFACE_JSON_GET_LOGIN_
#include "JsonRequestHandler.h"
class JsonGetLogin : public JsonRequestHandler
{
public:
Poco::JSON::Object handle(Poco::Dynamic::Var params);
protected:
};
#endif // __JSON_INTERFACE_JSON_GET_LOGIN_

View File

@ -0,0 +1,48 @@
#include "JsonRequestHandler.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/URI.h"
#include "Poco/DeflatingStream.h"
#include "Poco/JSON/Parser.h"
void JsonRequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)
{
response.setChunkedTransferEncoding(true);
response.setContentType("application/json");
bool _compressResponse(request.hasToken("Accept-Encoding", "gzip"));
if (_compressResponse) response.set("Content-Encoding", "gzip");
std::ostream& _responseStream = response.send();
Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1);
std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream;
auto method = request.getMethod();
std::istream& request_stream = request.stream();
Poco::JSON::Object json_result;
if (method == "POST") {
// extract parameter from request
Poco::JSON::Parser jsonParser;
try {
auto params = jsonParser.parse(request_stream);
// call logic
json_result = handle(params);
}
catch (Poco::Exception& ex) {
printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data());
}
}
else if(method == "GET") {
Poco::URI uri(request.getURI());
auto queryParameters = uri.getQueryParameters();
json_result = handle(queryParameters);
}
json_result.stringify(responseStream);
if (_compressResponse) _gzipStream.close();
}

View File

@ -0,0 +1,19 @@
#ifndef __JSON_INTERFACE_JSON_REQUEST_HANDLER_
#define __JSON_INTERFACE_JSON_REQUEST_HANDLER_
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/JSON/Object.h"
class JsonRequestHandler : public Poco::Net::HTTPRequestHandler
{
public:
void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);
virtual Poco::JSON::Object handle(Poco::Dynamic::Var params) = 0;
protected:
};
#endif // __JSON_INTERFACE_JSON_REQUEST_HANDLER_

View File

@ -0,0 +1,26 @@
#include "JsonRequestHandlerFactory.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "../SingletonManager/SessionManager.h"
#include "JsonGetLogin.h"
#include "JsonUnknown.h"
JsonRequestHandlerFactory::JsonRequestHandlerFactory()
: mRemoveGETParameters("^/([a-zA-Z0-9_-]*)")
{
}
Poco::Net::HTTPRequestHandler* JsonRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)
{
std::string uri = request.getURI();
std::string url_first_part;
mRemoveGETParameters.extract(uri, url_first_part);
if (url_first_part == "/login") {
return new JsonGetLogin;
}
return new JsonUnknown;
}

View File

@ -0,0 +1,19 @@
#ifndef __DR_JSON_REQUEST_HANDLER_FACTORY_H
#define __DR_JSON_REQUEST_HANDLER_FACTORY_H
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/RegularExpression.h"
#define HTTP_PAGES_COUNT 1
class JsonRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory
{
public:
JsonRequestHandlerFactory();
Poco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);
protected:
Poco::RegularExpression mRemoveGETParameters;
};
#endif // __DR_JSON_REQUEST_HANDLER_FACTORY_H

View File

@ -0,0 +1,11 @@
#include "JsonUnknown.h"
Poco::JSON::Object JsonUnknown::handle(Poco::Dynamic::Var params)
{
Poco::JSON::Object result;
result.set("state", "error");
result.set("msg", "unknown call");
return result;
}

View File

@ -0,0 +1,16 @@
#ifndef __JSON_INTERFACE_JSON_UNKNOWN_
#define __JSON_INTERFACE_JSON_UNKNOWN_
#include "JsonRequestHandler.h"
class JsonUnknown : public JsonRequestHandler
{
public:
Poco::JSON::Object handle(Poco::Dynamic::Var params);
protected:
};
#endif // __JSON_INTERFACE_JSON_UNKNOWN_

View File

@ -78,7 +78,7 @@ public:
bool generateKeys(bool savePrivkey, bool savePassphrase);
inline void setClientIp(Poco::Net::IPAddress ip) { mClientLoginIP = ip; }
inline Poco::Net::IPAddress getClientIp() { return mClientLoginIP; }
inline bool isIPValid(Poco::Net::IPAddress ip) { return mClientLoginIP == ip; }
bool isPwdValid(const std::string& pwd);

View File

@ -361,6 +361,19 @@ UserStates User::getUserState()
return state;
}
Poco::JSON::Object User::getJson()
{
lock();
Poco::JSON::Object userObj;
userObj.set("first_name", mFirstName);
userObj.set("last_name", mLastName);
userObj.set("email", mEmail);
userObj.set("public_hex", mPublicHex);
userObj.set("state", userStateToString(mState));
unlock();
return userObj;
}
// TODO: if a password and privkey already exist, load current private key and re encrypt with new crypto key
bool User::setNewPassword(const std::string& newPassword)
{
@ -692,4 +705,18 @@ bool User::loadEntryDBId(Poco::Data::Session session)
}
return true;
}
const char* User::userStateToString(UserStates state)
{
switch (state) {
case USER_EMPTY: return "empty";
case USER_LOADED_FROM_DB: return "loaded from db";
case USER_PASSWORD_INCORRECT: return "password incorrect";
case USER_EMAIL_NOT_ACTIVATED: return "email not activated";
case USER_NO_KEYS: return "no keys";
case USER_NO_PRIVATE_KEY: return "no private key";
case USER_COMPLETE: return "complete";
}
return "- unknown -";
}

View File

@ -8,6 +8,7 @@
#include "Poco/Thread.h"
#include "Poco/Types.h"
#include "Poco/Data/Session.h"
#include "Poco/JSON/Object.h"
#include "../tasks/CPUTask.h"
class NewUser;
@ -57,6 +58,7 @@ public:
static std::string generateNewPassphrase(Mnemonic* word_source);
static bool validatePassphrase(const std::string& passphrase);
static const char* userStateToString(UserStates state);
//static User* login(const std::string& email, const std::string& password, ErrorList* errorContainer = nullptr);
bool generateKeys(bool savePrivkey, const std::string& passphrase, Session* session);
@ -83,7 +85,7 @@ public:
Poco::Data::BLOB* encrypt(const ObfusArray* data);
Poco::JSON::Object getJson();
// for poco auto ptr
void duplicate();