Added support for ip whitelist and added rest method to update/get the config file
This commit is contained in:
parent
66882b3b67
commit
5f7e4e2cf2
@ -82,6 +82,7 @@ void HttpServer::EventHandler(mg_connection* pNc, int ev, void* p)
|
||||
http_message* hpm = (http_message*)p;
|
||||
std::string requestedUri = FixUnterminatedString(hpm->uri.p, hpm->uri.len);
|
||||
|
||||
// Get clients ip address
|
||||
std::string peer_addr;
|
||||
{
|
||||
char buf[32];
|
||||
@ -89,13 +90,7 @@ void HttpServer::EventHandler(mg_connection* pNc, int ev, void* p)
|
||||
peer_addr = buf;
|
||||
}
|
||||
|
||||
if ((XGConfig::general.onlyAllowLocalhost) && (peer_addr != "127.0.0.1"))
|
||||
{
|
||||
Json j;
|
||||
j.CloneFrom(RestResponseTemplates::GetByCode(UNAUTHORIZED, "Only localhost allowed!"));
|
||||
ServeStringToConnection(pNc, j.Render(), UNAUTHORIZED);
|
||||
}
|
||||
else
|
||||
if (IsConnectionAllowed(peer_addr))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -128,6 +123,12 @@ void HttpServer::EventHandler(mg_connection* pNc, int ev, void* p)
|
||||
|
||||
break;
|
||||
}
|
||||
else // Client is not allowed, serve error json
|
||||
{
|
||||
Json j;
|
||||
j.CloneFrom(RestResponseTemplates::GetByCode(UNAUTHORIZED, "Only localhost allowed!"));
|
||||
ServeStringToConnection(pNc, j.Render(), UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -199,6 +200,36 @@ void HttpServer::ServeDownloadeableResource(mg_connection* pNc, int ev, void* p,
|
||||
return;
|
||||
}
|
||||
|
||||
bool HttpServer::IsConnectionAllowed(std::string peer_address)
|
||||
{
|
||||
// Localhost is always allowed!
|
||||
if (peer_address == "127.0.0.1") return true;
|
||||
|
||||
// Peer is not localhost, but only localhost is allowed!
|
||||
else if (XGConfig::access.only_allow_localhost) return false;
|
||||
|
||||
// Let's check if the whitelist is active
|
||||
else if (XGConfig::access.enable_whitelist)
|
||||
{
|
||||
// It is. Let's check if our peer is whitelisted
|
||||
for (std::size_t i = 0; i < XGConfig::access.whitelist.size(); i++)
|
||||
{
|
||||
// Whitelist is enabled, and peer is whitelisted
|
||||
if (XGConfig::access.whitelist[i] == peer_address) return true;
|
||||
}
|
||||
|
||||
// Whitelist is enabled, but peer is NOT whitelisted
|
||||
return false;
|
||||
}
|
||||
else // Whitelist is NOT enabled and only_allow_localhost is FALSE!
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Should never come to this point
|
||||
return false;
|
||||
}
|
||||
|
||||
void HttpServer::OnExit()
|
||||
{
|
||||
log->cout << "Shutting down http-server...";
|
||||
|
@ -29,6 +29,8 @@ namespace Rest
|
||||
static void ServeStringToConnection(struct mg_connection* c, std::string str, int httpStatusCode = 200);
|
||||
static std::string FixUnterminatedString(const char* cstr, const std::size_t len);
|
||||
|
||||
static bool IsConnectionAllowed(std::string peer_address);
|
||||
|
||||
|
||||
struct mg_mgr* pMgr;
|
||||
struct mg_connection* pNc;
|
||||
|
@ -42,6 +42,7 @@ bool RestQueryHandler::ProcessQuery(const std::string clientAdress, const Json&
|
||||
else if (requestName == "fetch_alltime_logs") return FetchAlltimeLogs(requestBody, responseBody, responseCode);
|
||||
else if (requestName == "update_dep_youtubedl") return UpdateYoutubeDL(requestBody, responseBody, responseCode);
|
||||
else if (requestName == "remove_download_entry") return RemoveDownloadEntry(requestBody, responseBody, responseCode);
|
||||
else if (requestName == "update_config") return UpdateConfig(requestBody, responseBody, responseCode);
|
||||
|
||||
|
||||
|
||||
@ -437,6 +438,44 @@ bool RestQueryHandler::RemoveDownloadEntry(const JsonBlock& request, JsonBlock&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RestQueryHandler::UpdateConfig(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
||||
{
|
||||
if (ValidateField("config", JDType::JSON, request, responseBody))
|
||||
{
|
||||
bool prevStateConsole = XGConfig::general.show_console;
|
||||
XGConfig::LoadFromJson(request.Get("config").AsJson);
|
||||
|
||||
// Update console, if necessary
|
||||
if (XGConfig::general.show_console != prevStateConsole)
|
||||
{
|
||||
if (XGConfig::general.show_console) ConsoleManager::ShowConsole();
|
||||
else ConsoleManager::HideConsole();
|
||||
}
|
||||
|
||||
log->cout << "Updated config values...";
|
||||
log->Flush();
|
||||
XGConfig::Save();
|
||||
|
||||
responseBody.Set("message") = "Updated no settings";
|
||||
}
|
||||
else
|
||||
{
|
||||
responseBody.Set("message") = "Updated no settings";
|
||||
}
|
||||
|
||||
responseCode = OK;
|
||||
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
||||
responseBody.Set("settings") = XGConfig::GetSavefileBuffer();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool RestQueryHandler::ValidateField(const std::string name, const JasonPP::JDType type, const JasonPP::Json& checkThat, JasonPP::JsonBlock& putErrorResponseHere)
|
||||
|
@ -34,6 +34,7 @@ namespace Rest
|
||||
static bool GetDiskUsage(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
|
||||
static bool UpdateYoutubeDL(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
|
||||
static bool RemoveDownloadEntry(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
|
||||
static bool UpdateConfig(const JasonPP::JsonBlock& request, JasonPP::JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode);
|
||||
|
||||
static bool ValidateField(const std::string name, const JasonPP::JDType type, const JasonPP::Json& checkThat, JasonPP::JsonBlock& putErrorResponseHere);
|
||||
|
||||
|
@ -45,13 +45,20 @@ void XGConfig::InitializeDefaultValues()
|
||||
downloader.num_threads = 1;
|
||||
|
||||
general.show_console = true;
|
||||
general.onlyAllowLocalhost = true;
|
||||
|
||||
access.only_allow_localhost = true;
|
||||
access.enable_whitelist = true;
|
||||
access.whitelist = std::vector<std::string>();
|
||||
access.whitelist.push_back("127.0.0.1"); // Add localhost to whitelist
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void XGConfig::LoadFromJson(const JasonPP::JsonBlock& json)
|
||||
{
|
||||
savefileBuffer.Clear();
|
||||
savefileBuffer.CloneFrom(json);
|
||||
|
||||
if (IsJsonFieldValid(json, "logging.logfile_json", JDType::STRING))
|
||||
{
|
||||
logging.logfile_json = json.ShorthandGet("logging.logfile_json").AsString;
|
||||
@ -103,9 +110,28 @@ void XGConfig::LoadFromJson(const JasonPP::JsonBlock& json)
|
||||
{
|
||||
general.show_console = json.ShorthandGet("general.show_console").AsBool;
|
||||
}
|
||||
if (IsJsonFieldValid(json, "general.onlyAllowLocalhost", JDType::BOOL))
|
||||
|
||||
|
||||
|
||||
if (IsJsonFieldValid(json, "access.only_allow_localhost", JDType::BOOL))
|
||||
{
|
||||
general.onlyAllowLocalhost = json.ShorthandGet("general.onlyAllowLocalhost").AsBool;
|
||||
access.only_allow_localhost = json.ShorthandGet("access.only_allow_localhost").AsBool;
|
||||
}
|
||||
if (IsJsonFieldValid(json, "access.enable_whitelist", JDType::BOOL))
|
||||
{
|
||||
access.enable_whitelist = json.ShorthandGet("access.enable_whitelist").AsBool;
|
||||
}
|
||||
if (IsJsonFieldValid(json, "access.whitelist", JDType::ARRAY))
|
||||
{
|
||||
const JsonArray& cachedArr = json.ShorthandGet("access.whitelist").AsArray;
|
||||
access.whitelist.clear();
|
||||
for (std::size_t i = 0; i < cachedArr.Size(); i++)
|
||||
{
|
||||
if (cachedArr[i].GetDataType() == JDType::STRING)
|
||||
{
|
||||
access.whitelist.push_back(cachedArr[i].AsString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
@ -113,10 +139,13 @@ void XGConfig::LoadFromJson(const JasonPP::JsonBlock& json)
|
||||
|
||||
JsonBlock XGConfig::CreateJson()
|
||||
{
|
||||
JsonArray jsnArrWhitelist;
|
||||
jsnArrWhitelist.Add(access.whitelist);
|
||||
|
||||
return JsonBlock({
|
||||
Ele("httpServer", JsonBlock({
|
||||
Ele("port", httpServer.port),
|
||||
Ele("pollingRate", httpServer.polling_rate),
|
||||
Ele("polling_rate", httpServer.polling_rate),
|
||||
Ele("rootdir", httpServer.rootdir)
|
||||
})),
|
||||
Ele("logging", JsonBlock({
|
||||
@ -131,7 +160,11 @@ JsonBlock XGConfig::CreateJson()
|
||||
})),
|
||||
Ele("general", JsonBlock({
|
||||
Ele("show_console", general.show_console),
|
||||
Ele("onlyAllowLocalhost", general.onlyAllowLocalhost)
|
||||
})),
|
||||
Ele("access", JsonBlock({
|
||||
Ele("only_allow_localhost", access.only_allow_localhost),
|
||||
Ele("enable_whitelist", access.enable_whitelist),
|
||||
Ele("whitelist", jsnArrWhitelist),
|
||||
}))
|
||||
});
|
||||
}
|
||||
@ -210,6 +243,8 @@ void XGConfig::Save()
|
||||
bool XGConfig::SaveToFile(std::string filename)
|
||||
{
|
||||
Json cfgStruct(CreateJson());
|
||||
savefileBuffer.Clear();
|
||||
savefileBuffer.CloneFrom(cfgStruct.AsJson);
|
||||
return FileSystem::WriteFile(filename, cfgStruct.Render());
|
||||
}
|
||||
|
||||
@ -245,5 +280,7 @@ XGConfig::HttpServer XGConfig::httpServer;
|
||||
XGConfig::Logging XGConfig::logging;
|
||||
XGConfig::Downloader XGConfig::downloader;
|
||||
XGConfig::General XGConfig::general;
|
||||
XGConfig::Access XGConfig::access;
|
||||
|
||||
JasonPP::JsonBlock XGConfig::savefileBuffer;
|
||||
::Logging::Logger* XGConfig::log;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "Filesystem.h"
|
||||
#include "external_dependencies/leonetienne/JasonPP/JasonPP.hpp"
|
||||
#include "Logger.h"
|
||||
@ -30,27 +31,37 @@ public:
|
||||
struct General
|
||||
{
|
||||
bool show_console;
|
||||
bool onlyAllowLocalhost;
|
||||
};
|
||||
struct Access
|
||||
{
|
||||
bool only_allow_localhost;
|
||||
bool enable_whitelist;
|
||||
std::vector<std::string> whitelist;
|
||||
};
|
||||
|
||||
static void PreInit();
|
||||
static void Save();
|
||||
static void PostExit();
|
||||
|
||||
static void LoadFromJson(const JasonPP::JsonBlock& json);
|
||||
|
||||
static XGConfig::HttpServer httpServer;
|
||||
static XGConfig::Logging logging;
|
||||
static XGConfig::Downloader downloader;
|
||||
static XGConfig::General general;
|
||||
static XGConfig::Access access;
|
||||
|
||||
static const JasonPP::JsonBlock& GetSavefileBuffer() { return savefileBuffer; }
|
||||
|
||||
static ::Logging::Logger* log;
|
||||
|
||||
private:
|
||||
static bool SaveToFile(std::string filename);
|
||||
static JasonPP::JsonBlock savefileBuffer;
|
||||
|
||||
static bool IsJsonFieldValid(const JasonPP::JsonBlock& json, const std::string key, const JasonPP::JDType type);
|
||||
static void InitializeDefaultValues();
|
||||
static JasonPP::JsonBlock CreateJson();
|
||||
static void LoadFromJson(const JasonPP::JsonBlock& json);
|
||||
static void Load();
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"request\": \"queue_download\",\r\n \"video_url\": \"https://youtu.be/OF-thWTJcu0\",\r\n \"mode\": \"video\"\r\n}",
|
||||
"raw": "{\r\n \"request\": \"queue_download\",\r\n \"video_url\": \"https://www.youtube.com/watch?v=BHiWygziyso\",\r\n \"mode\": \"video\"\r\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
@ -66,7 +66,7 @@
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"request\": \"queue_download\",\r\n \"video_url\": \"https://youtu.be/wgfNsek8xkc\",\r\n \"mode\": \"audio\"\r\n}",
|
||||
"raw": "{\r\n \"request\": \"queue_download\",\r\n \"video_url\": \"https://youtu.be/m9HT74QccbQ\",\r\n \"mode\": \"audio\"\r\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
@ -93,7 +93,7 @@
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"request\": \"fetch_session_cache\",\r\n \"max-num\": -1\r\n}\r\n",
|
||||
"raw": "{\r\n \"request\": \"fetch_session_cache\",\r\n \"max_age\": -1\r\n}\r\n",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
@ -426,7 +426,61 @@
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"request\": \"remove_download_entry\",\r\n \"id\": \"1KnnPV\"\r\n}",
|
||||
"raw": "{\r\n \"request\": \"remove_download_entry\",\r\n \"id\": \"1KnnMe\"\r\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:6969/api",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "6969",
|
||||
"path": [
|
||||
"api"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "UpdateConfig",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"request\": \"update_config\",\r\n \"config\": {\r\n \"access\": {\r\n \"enable_whitelist\": false,\r\n \"only_allow_localhost\": false,\r\n \"whitelist\": [\r\n \"127.0.0.1\"\r\n ]\r\n },\r\n \"general\": {\r\n \"show_console\": true\r\n }\r\n }\r\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:6969/api",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "6969",
|
||||
"path": [
|
||||
"api"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "GetConfig",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\r\n \"request\": \"update_config\"\r\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
|
@ -14,11 +14,6 @@
|
||||
<Toggle :isOn="false"/>
|
||||
</div>
|
||||
|
||||
<div class="option toggle flex justify-between items-center">
|
||||
<p>Limit speed</p>
|
||||
<Toggle :isOn="false"/>
|
||||
</div>
|
||||
|
||||
<div class="option text narrow flex justify-between w-full items-center">
|
||||
<p class="mr-3">Max speed</p>
|
||||
<input type="text" id="max_speed" name="max_speed" placeholder="100M">
|
||||
@ -29,6 +24,11 @@
|
||||
<input type="text" id="max_threads" name="max_threads" placeholder="10">
|
||||
</div>
|
||||
|
||||
<div class="option toggle flex justify-between items-center">
|
||||
<p>Enable whitelist</p>
|
||||
<Toggle :isOn="false"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="w-full lg:w-1/2 border-left lg:pl-3 mt-6 lg:mt-0">
|
||||
|
0
tubio-frontend-nuxt-app/store/settings.js
Normal file
0
tubio-frontend-nuxt-app/store/settings.js
Normal file
Loading…
x
Reference in New Issue
Block a user