reorder some of the main files
parent
92c059912e
commit
0c8ab4f082
|
@ -11,6 +11,8 @@ set(CROW_FEATURES compression)
|
|||
cmake_policy(SET CMP0057 NEW)
|
||||
#find_package(Crow)
|
||||
|
||||
set(PRECOMPILED_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/include/crowsite/crow_pch.h")
|
||||
|
||||
set(CROW_BUILD_TESTS OFF)
|
||||
set(CROW_BUILD_EXAMPLES OFF)
|
||||
set(CROW_INSTALL OFF)
|
||||
|
@ -43,7 +45,7 @@ include_directories(${OPENSSL_INCLUDE_DIR})
|
|||
|
||||
file(GLOB_RECURSE source_files src/*.cpp)
|
||||
|
||||
add_executable(crowsite ${source_files})
|
||||
add_executable(crowsite ${source_files} ${PRECOMPILED_HEADER})
|
||||
|
||||
target_compile_definitions(crowsite PUBLIC CROW_ENABLE_COMPRESSION)
|
||||
|
||||
|
@ -70,3 +72,5 @@ if (${ENABLE_TSAN} MATCHES ON)
|
|||
target_compile_options(crowsite PRIVATE -fsanitize=thread)
|
||||
target_link_options(crowsite PRIVATE -fsanitize=thread)
|
||||
endif ()
|
||||
|
||||
target_precompile_headers(crowsite PRIVATE ${PRECOMPILED_HEADER})
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
#include <blt/std/hashmap.h>
|
||||
|
||||
//#define CROW_STATIC_DIRECTORY "/home/brett/projects/cpp/crowsite/crow_test/static/"
|
||||
#define CROW_STATIC_DIRECTORY "/home/brett/Documents/code/c++/crowsite/crow_test/static/"
|
||||
#define CROWSITE_STATIC_DIRECTORY "/home/brett/Documents/code/c++/crowsite/crow_test/static/"
|
||||
//#define SITE_FILES_PATH "/home/brett/projects/cpp/crowsite/crow_test"
|
||||
#define SITE_FILES_PATH "/home/brett/Documents/code/c++/crowsite/crow_test"
|
||||
#define CROW_STATIC_ENDPOINT "/static/<path>"
|
||||
#define CROWSITE_FILES_PATH "/home/brett/Documents/code/c++/crowsite/crow_test"
|
||||
#define CROWSITE_STATIC_ENDPOINT "/static/<path>"
|
||||
|
||||
#define MILES_SITE
|
||||
#undef MILES_SITE
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
#define CROWSITE_CROW_INCLUDES_H
|
||||
|
||||
#include <crowsite/config.h>
|
||||
#include "crow.h"
|
||||
#include <crowsite/crow_pch.h>
|
||||
|
||||
#endif //CROWSITE_CROW_INCLUDES_H
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
/*
|
||||
* Created by Brett on 29/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef CROWSITE_CROW_PCH_H
|
||||
#define CROWSITE_CROW_PCH_H
|
||||
|
||||
#include "crow/query_string.h"
|
||||
#include "crow/http_parser_merged.h"
|
||||
#include "crow/ci_map.h"
|
||||
#include "crow/TinySHA1.hpp"
|
||||
#include "crow/settings.h"
|
||||
#include "crow/socket_adaptors.h"
|
||||
#include "crow/json.h"
|
||||
#include "crow/mustache.h"
|
||||
#include "crow/logging.h"
|
||||
#include "crow/task_timer.h"
|
||||
#include "crow/utility.h"
|
||||
#include "crow/common.h"
|
||||
#include "crow/http_request.h"
|
||||
#include "crow/websocket.h"
|
||||
#include "crow/parser.h"
|
||||
#include "crow/http_response.h"
|
||||
#include "crow/multipart.h"
|
||||
#include "crow/routing.h"
|
||||
#include "crow/middleware.h"
|
||||
#include "crow/middleware_context.h"
|
||||
#include "crow/compression.h"
|
||||
#include "crow/http_connection.h"
|
||||
#include "crow/http_server.h"
|
||||
#include "crow/app.h"
|
||||
#include "crow/middlewares/session.h"
|
||||
#include "crow/middlewares/cookie_parser.h"
|
||||
|
||||
using Session = crow::SessionMiddleware<crow::FileStore>;
|
||||
using CrowApp = crow::App<crow::CookieParser, Session>;
|
||||
|
||||
|
||||
#endif //CROWSITE_CROW_PCH_H
|
|
@ -1,19 +0,0 @@
|
|||
//
|
||||
// Created by brett on 21/08/23.
|
||||
//
|
||||
|
||||
#ifndef CROWSITE_CROW_UTILITY_H
|
||||
#define CROWSITE_CROW_UTILITY_H
|
||||
|
||||
#include <crow/http_response.h>
|
||||
|
||||
namespace cs {
|
||||
inline crow::response redirect(const std::string& loc = "/", int code = 303)
|
||||
{
|
||||
crow::response res(code);
|
||||
res.set_header("Location", loc);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //CROWSITE_CROW_UTILITY_H
|
|
@ -6,14 +6,13 @@
|
|||
#define CROWSITE_CACHE_H
|
||||
|
||||
#include <crowsite/site/web.h>
|
||||
#include <crowsite/util/crow_typedef.h>
|
||||
#include <filesystem>
|
||||
#include <blt/std/hashmap.h>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
using RuntimeContext = HASHMAP<std::string, std::string>;
|
||||
|
||||
class LexerSyntaxError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
|
@ -54,7 +53,7 @@ namespace cs
|
|||
std::string renderedPage;
|
||||
};
|
||||
|
||||
StaticContext& m_Context;
|
||||
context& m_Context;
|
||||
CacheSettings m_Settings;
|
||||
HASHMAP<std::string, CacheValue> m_Pages;
|
||||
|
||||
|
@ -75,11 +74,11 @@ namespace cs
|
|||
void prune(uint64_t amount);
|
||||
|
||||
public:
|
||||
explicit CacheEngine(StaticContext& context, const CacheSettings& settings = {});
|
||||
explicit CacheEngine(context& context, const CacheSettings& settings = {});
|
||||
|
||||
const std::string& fetch(const std::string& path);
|
||||
|
||||
std::string fetch(const std::string& path, const RuntimeContext& context);
|
||||
std::string fetch(const std::string& path, const context& context);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
#pragma once
|
||||
/*
|
||||
* Created by Brett on 27/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef CROWSITE_HOME_H
|
||||
#define CROWSITE_HOME_H
|
||||
|
||||
#include <crowsite/site/cache.h>
|
||||
#include <crowsite/util/crow_session_util.h>
|
||||
#include <crowsite/util/crow_conversion.h>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
inline crow::response handle_root_page(const site_params& params)
|
||||
{
|
||||
//auto page = crow::mustache::load("index.html"); //
|
||||
//return "<html><head><title>Hello There</title></head><body><h1>Suck it " + name + "</h1></body></html>";
|
||||
// BLT_TRACE(req.body);
|
||||
// for (const auto& h : req.headers)
|
||||
// BLT_TRACE("Header: %s = %s", h.first.c_str(), h.second.c_str());
|
||||
// BLT_TRACE(req.raw_url);
|
||||
// BLT_TRACE(req.url);
|
||||
// BLT_TRACE(req.remote_ip_address);
|
||||
// for (const auto& v : req.url_params.keys())
|
||||
// BLT_TRACE("URL: %s = %s", v.c_str(), req.url_params.get(v));
|
||||
if (params.name.ends_with(".html"))
|
||||
{
|
||||
checkAndUpdateUserSession(params.app, params.req);
|
||||
auto& session = params.app.get_context<Session>(params.req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
auto user_perms = cs::getUserPermissions(cs::getUserFromID(s_clientID));
|
||||
|
||||
crow::mustache::context ctx;
|
||||
cs::context context;
|
||||
|
||||
generateRuntimeContext(params, context);
|
||||
|
||||
// pass perms in
|
||||
if (user_perms & cs::PERM_ADMIN)
|
||||
ctx["_admin"] = true;
|
||||
|
||||
if (cs::isUserLoggedIn(s_clientID, s_clientToken))
|
||||
{
|
||||
ctx["_logged_in"] = true;
|
||||
} else
|
||||
{
|
||||
ctx["_not_logged_in"] = true;
|
||||
}
|
||||
|
||||
// we don't want to pass all get parameters to the context to prevent leaking information
|
||||
auto referer = params.req.url_params.get("referer");
|
||||
if (referer)
|
||||
ctx["referer"] = referer;
|
||||
auto page = crow::mustache::compile(params.engine.fetch(params.name, context));
|
||||
return page.render(ctx);
|
||||
}
|
||||
|
||||
return params.engine.fetch("default.html");
|
||||
}
|
||||
|
||||
inline crow::response handle_auth_page(const site_params& params)
|
||||
{
|
||||
if (isUserAdmin(params.app, params.req))
|
||||
return redirect("/login.html");
|
||||
|
||||
|
||||
return handle_root_page(params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //CROWSITE_HOME_H
|
|
@ -9,21 +9,14 @@
|
|||
#define CROWSITE_POSTS_H
|
||||
|
||||
#include <crowsite/site/cache.h>
|
||||
#include <crow/http_request.h>
|
||||
#include <crow/http_response.h>
|
||||
#include <crowsite/util/crow_fix.h>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
struct request_info {
|
||||
CacheEngine& engine;
|
||||
const crow::request& req;
|
||||
std::string clientID;
|
||||
std::string tokenID;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
crow::response handleProjectPage(const request_info& req);
|
||||
void posts_init();
|
||||
void posts_cleanup();
|
||||
|
||||
response_info handleProjectPage(const request_info& req);
|
||||
}
|
||||
|
||||
#endif //CROWSITE_POSTS_H
|
||||
|
|
|
@ -8,28 +8,11 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
#include <crowsite/config.h>
|
||||
#include <crowsite/util/crow_typedef.h>
|
||||
#include <utility>
|
||||
|
||||
namespace cs {
|
||||
|
||||
class StaticContext {
|
||||
private:
|
||||
HASHMAP<std::string, std::string> replacements;
|
||||
public:
|
||||
inline auto begin() {
|
||||
return replacements.begin();
|
||||
}
|
||||
inline auto end() {
|
||||
return replacements.end();
|
||||
}
|
||||
inline std::string& operator[](const std::string& key){
|
||||
return replacements[key];
|
||||
}
|
||||
inline void add(const std::string& key, const std::string& value){
|
||||
replacements[key] = value;
|
||||
}
|
||||
};
|
||||
|
||||
class HTMLPage {
|
||||
private:
|
||||
std::string m_SiteData;
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
/*
|
||||
* Created by Brett on 29/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef CROWSITE_CROW_CONVERSION_H
|
||||
#define CROWSITE_CROW_CONVERSION_H
|
||||
|
||||
#include "crow/http_response.h"
|
||||
#include <crowsite/util/crow_fix.h>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
crow::response toResponse(cs::response_info res);
|
||||
|
||||
inline crow::response redirect(const std::string& loc, int code = 303)
|
||||
{
|
||||
crow::response res(code);
|
||||
res.set_header("Location", loc);
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //CROWSITE_CROW_CONVERSION_H
|
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
/*
|
||||
* Created by Brett on 27/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef CROWSITE_CROW_FIX_H
|
||||
#define CROWSITE_CROW_FIX_H
|
||||
|
||||
/**
|
||||
* Basically waste a bunch of time to both a. reduce the compile time of using crow
|
||||
* and b. reduce the runtime overhead of crow, by increasing runtime in some respects
|
||||
* TODO: explain why this is better later, maybe test as well.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <blt/std/hashmap.h>
|
||||
#include "crowsite/site/cache.h"
|
||||
#include "crowsite/util/crow_typedef.h"
|
||||
|
||||
namespace cs
|
||||
{
|
||||
query_string toQueryString(const std::vector<char*>& kv);
|
||||
|
||||
struct request_info
|
||||
{
|
||||
std::string raw_url; ///< The full URL containing the `?` and URL parameters.
|
||||
std::string clientID;
|
||||
std::string tokenID;
|
||||
std::string path;
|
||||
query_string url_params; ///< The parameters associated with the request. (everything after the `?` in the URL)
|
||||
CacheEngine& engine;
|
||||
std::optional<header_map> headers{};
|
||||
};
|
||||
|
||||
struct response_info
|
||||
{
|
||||
std::string body;
|
||||
std::optional<context> ctx{};
|
||||
};
|
||||
}
|
||||
|
||||
#endif //CROWSITE_CROW_FIX_H
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
/*
|
||||
* Created by Brett on 29/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef CROWSITE_CROW_LOG_H
|
||||
#define CROWSITE_CROW_LOG_H
|
||||
|
||||
#include <string>
|
||||
#include <crow/logging.h>
|
||||
|
||||
class BLT_CrowLogger : public crow::ILogHandler
|
||||
{
|
||||
public:
|
||||
void log(std::string message, crow::LogLevel crow_level) final;
|
||||
};
|
||||
|
||||
#endif //CROWSITE_CROW_LOG_H
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
/*
|
||||
* Created by Brett on 29/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef CROWSITE_CROW_SESSION_UTIL_H
|
||||
#define CROWSITE_CROW_SESSION_UTIL_H
|
||||
|
||||
#include "crowsite/site/auth.h"
|
||||
#include "crow_typedef.h"
|
||||
#include "crowsite/site/cache.h"
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
struct site_params
|
||||
{
|
||||
CrowApp& app;
|
||||
cs::CacheEngine& engine;
|
||||
const crow::request& req;
|
||||
const std::string& name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Note this function destroys the user's session and any login related cookies!
|
||||
*/
|
||||
void destroyUserSession(CrowApp& app, const crow::request& req);
|
||||
|
||||
bool checkAndUpdateUserSession(CrowApp& app, const crow::request& req);
|
||||
|
||||
bool isUserLoggedIn(CrowApp& app, const crow::request& req);
|
||||
|
||||
bool isUserAdmin(CrowApp& app, const crow::request& req);
|
||||
|
||||
void generateRuntimeContext(const site_params& params, cs::context& context);
|
||||
}
|
||||
|
||||
#endif //CROWSITE_CROW_SESSION_UTIL_H
|
|
@ -0,0 +1,20 @@
|
|||
#pragma once
|
||||
/*
|
||||
* Created by Brett on 28/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
|
||||
#ifndef CROWSITE_CROW_TYPEDEF_H
|
||||
#define CROWSITE_CROW_TYPEDEF_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
typedef HASHMAP<std::string, std::string> header_map;
|
||||
typedef HASHMAP<std::string, std::string> query_string;
|
||||
typedef HASHMAP<std::string, std::string> context;
|
||||
}
|
||||
|
||||
#endif //CROWSITE_CROW_TYPEDEF_H
|
|
@ -470,6 +470,11 @@ namespace crow
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline const std::vector<char*>& getValues() const
|
||||
{
|
||||
return key_value_pairs_;
|
||||
}
|
||||
|
||||
std::vector<std::string> keys() const
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <crowsite/site/auth.h>
|
||||
#include <crowsite/config.h>
|
||||
#include <crowsite/requests/jellyfin.h>
|
||||
#include <crowsite/utility.h>
|
||||
#include "blt/std/logging.h"
|
||||
#include "blt/std/uuid.h"
|
||||
#include <openssl/sha.h>
|
||||
|
@ -190,7 +191,7 @@ namespace cs
|
|||
void auth::init()
|
||||
{
|
||||
// TODO: proper multithreading
|
||||
auto path = (std::string(SITE_FILES_PATH) + "/data/db/");
|
||||
auto path = cs::fs::createDataFilePath("db/");
|
||||
auto dbname = "users.sqlite";
|
||||
auto full_path = path + dbname;
|
||||
BLT_TRACE("Using %s for users database", full_path.c_str());
|
||||
|
|
|
@ -224,14 +224,14 @@ namespace cs
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool isTrue(const RuntimeContext& context, const std::string& token)
|
||||
static inline bool isTrue(const context& context, const std::string& token)
|
||||
{
|
||||
//BLT_DEBUG("isTrue for token '%s' contains? %s", token.c_str(), context.contains(token) ? "True" : "False");
|
||||
return context.contains(token) && !context.at(token).empty();
|
||||
}
|
||||
|
||||
// http://www.cs.unb.ca/~wdu/cs4613/a2ans.htm
|
||||
bool factor(const RuntimeContext& context)
|
||||
bool factor(const context& context)
|
||||
{
|
||||
if (!hasNextToken())
|
||||
blt_throw(LexerSyntaxError("Processing boolean factor but no token was found!"));
|
||||
|
@ -256,7 +256,7 @@ namespace cs
|
|||
}
|
||||
}
|
||||
|
||||
bool expr(const RuntimeContext& context)
|
||||
bool expr(const context& context)
|
||||
{
|
||||
auto fac = factor(context);
|
||||
if (!hasNextToken())
|
||||
|
@ -281,7 +281,7 @@ namespace cs
|
|||
processString();
|
||||
}
|
||||
|
||||
bool eval(const RuntimeContext& context)
|
||||
bool eval(const context& context)
|
||||
{
|
||||
return expr(context);
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ namespace cs
|
|||
return tagLocations[0];
|
||||
}
|
||||
|
||||
static std::string searchAndReplace(const std::string& data, const RuntimeContext& context)
|
||||
static std::string searchAndReplace(const std::string& data, const context& context)
|
||||
{
|
||||
RuntimeLexer lexer(data);
|
||||
std::string results;
|
||||
|
@ -373,7 +373,7 @@ namespace cs
|
|||
if (lexer.hasTemplatePrefix('/'))
|
||||
lexer.consumeToken();
|
||||
else
|
||||
blt_throw(LexerSyntaxError("Ending token not found!"));
|
||||
blt_throw(LexerSyntaxError("Ending token not found!"));
|
||||
|
||||
} else
|
||||
results += lexer.consume();
|
||||
|
@ -389,8 +389,8 @@ namespace cs
|
|||
return (double) (v) / 1000000000.0;
|
||||
}
|
||||
|
||||
CacheEngine::CacheEngine(StaticContext& context, const CacheSettings& settings): m_Context(context),
|
||||
m_Settings((settings))
|
||||
CacheEngine::CacheEngine(context& ctx, const CacheSettings& settings): m_Context(ctx),
|
||||
m_Settings((settings))
|
||||
{}
|
||||
|
||||
uint64_t CacheEngine::calculateMemoryUsage(const std::string& path, const CacheEngine::CacheValue& value)
|
||||
|
@ -571,7 +571,7 @@ namespace cs
|
|||
page.getRawSite() = resolvedSite;
|
||||
}
|
||||
|
||||
std::string CacheEngine::fetch(const std::string& path, const RuntimeContext& context)
|
||||
std::string CacheEngine::fetch(const std::string& path, const context& context)
|
||||
{
|
||||
auto fetched = fetch(path);
|
||||
return RuntimeLexer::searchAndReplace(fetched, context);
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Created by Brett on 27/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
#include <crowsite/site/home.h>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
* See LICENSE file for license detail
|
||||
*/
|
||||
#include <crowsite/site/posts.h>
|
||||
#include <crowsite/site/auth.h>
|
||||
#include <crowsite/utility.h>
|
||||
#include <crowsite/util/md_to_html.h>
|
||||
#include <blt/std/logging.h>
|
||||
|
@ -11,7 +12,7 @@
|
|||
namespace cs
|
||||
{
|
||||
|
||||
crow::response handleProjectPage(const request_info& req)
|
||||
response_info handleProjectPage(const request_info& req)
|
||||
{
|
||||
std::string buffer;
|
||||
buffer += "<html><head></head><body>";
|
||||
|
@ -19,9 +20,18 @@ namespace cs
|
|||
buffer += htmlData;
|
||||
buffer += "</body>";
|
||||
|
||||
return buffer;
|
||||
return {buffer};
|
||||
}
|
||||
|
||||
void posts_init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void posts_cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Created by Brett on 27/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
#include <crowsite/util/crow_fix.h>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
query_string toQueryString(const std::vector<char*>& key_values)
|
||||
{
|
||||
query_string query_kv;
|
||||
for (const auto& kv : key_values)
|
||||
{
|
||||
std::string str(kv);
|
||||
auto equ_loc = str.find('=');
|
||||
query_kv[str.substr(0, equ_loc)] = str.substr(equ_loc+1, str.size());
|
||||
}
|
||||
return query_kv;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Created by Brett on 29/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
#include <crowsite/util/crow_log.h>
|
||||
#include <crowsite/util/crow_conversion.h>
|
||||
#include <blt/std/logging.h>
|
||||
|
||||
void BLT_CrowLogger::log(std::string message, crow::LogLevel crow_level)
|
||||
{
|
||||
blt::logging::log_level blt_level = blt::logging::log_level::NONE;
|
||||
switch (crow_level)
|
||||
{
|
||||
case crow::LogLevel::DEBUG:
|
||||
blt_level = blt::logging::log_level::DEBUG;
|
||||
break;
|
||||
case crow::LogLevel::INFO:
|
||||
blt_level = blt::logging::log_level::INFO;
|
||||
break;
|
||||
case crow::LogLevel::WARNING:
|
||||
blt_level = blt::logging::log_level::WARN;
|
||||
break;
|
||||
case crow::LogLevel::ERROR:
|
||||
blt_level = blt::logging::log_level::ERROR;
|
||||
break;
|
||||
case crow::LogLevel::CRITICAL:
|
||||
blt_level = blt::logging::log_level::FATAL;
|
||||
break;
|
||||
}
|
||||
BLT_LOG("Crow: %s", blt_level, message.c_str());
|
||||
}
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
crow::response toResponse(cs::response_info res)
|
||||
{
|
||||
if (res.ctx.has_value())
|
||||
{
|
||||
auto v = crow::mustache::compile(res.body);
|
||||
crow::mustache::context ctx;
|
||||
for (const auto& c : res.ctx.value())
|
||||
ctx[c.first] = c.second;
|
||||
return v.render(ctx);
|
||||
}
|
||||
return res.body;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Created by Brett on 29/08/23.
|
||||
* Licensed under GNU General Public License V3.0
|
||||
* See LICENSE file for license detail
|
||||
*/
|
||||
#include <crowsite/util/crow_session_util.h>
|
||||
#include <crowsite/crow_pch.h>
|
||||
|
||||
namespace cs
|
||||
{
|
||||
|
||||
void destroyUserSession(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto& cookie_context = app.get_context<crow::CookieParser>(req);
|
||||
|
||||
session.set("clientID", "");
|
||||
session.set("clientToken", "");
|
||||
cookie_context.set_cookie("clientID", "");
|
||||
cookie_context.set_cookie("clientToken", "");
|
||||
}
|
||||
|
||||
bool checkAndUpdateUserSession(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto& cookie_context = app.get_context<crow::CookieParser>(req);
|
||||
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
|
||||
auto c_clientID = cookie_context.get_cookie("clientID");
|
||||
auto c_clientToken = cookie_context.get_cookie("clientToken");
|
||||
|
||||
if ((!c_clientID.empty() && !c_clientToken.empty()) && (s_clientID != c_clientID || s_clientToken != c_clientToken))
|
||||
{
|
||||
session.set("clientID", c_clientID);
|
||||
session.set("clientToken", c_clientToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isUserLoggedIn(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
return cs::isUserLoggedIn(s_clientID, s_clientToken);
|
||||
}
|
||||
|
||||
bool isUserAdmin(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
return cs::isUserAdmin(cs::getUserFromID(s_clientID));
|
||||
}
|
||||
|
||||
void generateRuntimeContext(const site_params& params, cs::context& context)
|
||||
{
|
||||
auto& session = params.app.get_context<Session>(params.req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
if (cs::isUserLoggedIn(s_clientID, s_clientToken))
|
||||
{
|
||||
auto username = cs::getUserFromID(s_clientID);
|
||||
auto perms = cs::getUserPermissions(username);
|
||||
auto isAdmin = cs::isUserAdmin(username);
|
||||
context["_logged_in"] = "True";
|
||||
context["_username"] = username;
|
||||
if (isAdmin)
|
||||
context["_admin"] = "True";
|
||||
if (perms & cs::PERM_READ_FILES)
|
||||
context["_read_files"] = "True";
|
||||
if (perms & cs::PERM_WRITE_FILES)
|
||||
context["_write_files"] = "True";
|
||||
if (perms & cs::PERM_CREATE_POSTS)
|
||||
context["_create_posts"] = "True";
|
||||
if (perms & cs::PERM_CREATE_COMMENTS)
|
||||
context["_create_comments"] = "True";
|
||||
if (perms & cs::PERM_CREATE_SHARES)
|
||||
context["_create_shares"] = "True";
|
||||
if (perms & cs::PERM_EDIT_POSTS)
|
||||
context["_edit_posts"] = "True";
|
||||
if (perms & cs::PERM_EDIT_COMMENTS)
|
||||
context["_edit_comments"] = "True";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@ namespace cs {
|
|||
|
||||
std::string str()
|
||||
{
|
||||
std::string out (buffer, buffer + used_size);
|
||||
std::string out (buffer, used_size);
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace cs
|
|||
{
|
||||
std::string createStaticFilePath(const std::string& file)
|
||||
{
|
||||
auto path = std::string(CROW_STATIC_DIRECTORY);
|
||||
auto path = std::string(CROWSITE_STATIC_DIRECTORY);
|
||||
if (!path.ends_with('/'))
|
||||
path += '/';
|
||||
path += file;
|
||||
|
@ -67,7 +67,7 @@ namespace cs
|
|||
|
||||
std::string createWebFilePath(const std::string& file)
|
||||
{
|
||||
auto path = std::string(SITE_FILES_PATH);
|
||||
auto path = std::string(CROWSITE_FILES_PATH);
|
||||
if (!path.ends_with('/'))
|
||||
path += '/';
|
||||
path += "webcontent/";
|
||||
|
@ -79,7 +79,7 @@ namespace cs
|
|||
|
||||
std::string createDataFilePath(const std::string& file)
|
||||
{
|
||||
auto path = std::string(SITE_FILES_PATH);
|
||||
auto path = std::string(CROWSITE_FILES_PATH);
|
||||
if (!path.ends_with('/'))
|
||||
path += '/';
|
||||
path += "data/";
|
||||
|
|
242
src/main.cpp
242
src/main.cpp
|
@ -3,191 +3,19 @@
|
|||
#include <crowsite/utility.h>
|
||||
#include <crowsite/site/cache.h>
|
||||
#include <crowsite/beemovie.h>
|
||||
#include <crowsite/crow_utility.h>
|
||||
#include <crowsite/requests/jellyfin.h>
|
||||
#include <crowsite/requests/curl.h>
|
||||
#include <blt/parse/argparse.h>
|
||||
#include <crowsite/site/auth.h>
|
||||
#include <crow/middlewares/session.h>
|
||||
#include <crow/middlewares/cookie_parser.h>
|
||||
#include <crowsite/site/home.h>
|
||||
#include <crowsite/site/posts.h>
|
||||
#include <crowsite/util/memory_reader.h>
|
||||
#include <crowsite/util/crow_log.h>
|
||||
#include <crowsite/util/crow_conversion.h>
|
||||
|
||||
using Session = crow::SessionMiddleware<crow::FileStore>;
|
||||
using CrowApp = crow::App<crow::CookieParser, Session>;
|
||||
|
||||
class BLT_CrowLogger : public crow::ILogHandler
|
||||
{
|
||||
public:
|
||||
void log(std::string message, crow::LogLevel crow_level) final
|
||||
{
|
||||
blt::logging::log_level blt_level = blt::logging::log_level::NONE;
|
||||
switch (crow_level)
|
||||
{
|
||||
case crow::LogLevel::DEBUG:
|
||||
blt_level = blt::logging::log_level::DEBUG;
|
||||
break;
|
||||
case crow::LogLevel::INFO:
|
||||
blt_level = blt::logging::log_level::INFO;
|
||||
break;
|
||||
case crow::LogLevel::WARNING:
|
||||
blt_level = blt::logging::log_level::WARN;
|
||||
break;
|
||||
case crow::LogLevel::ERROR:
|
||||
blt_level = blt::logging::log_level::ERROR;
|
||||
break;
|
||||
case crow::LogLevel::CRITICAL:
|
||||
blt_level = blt::logging::log_level::FATAL;
|
||||
break;
|
||||
}
|
||||
BLT_LOG("Crow: %s", blt_level, message.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
struct site_params
|
||||
{
|
||||
CrowApp& app;
|
||||
cs::CacheEngine& engine;
|
||||
const crow::request& req;
|
||||
const std::string& name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Note this function destroys the user's session and any login related cookies!
|
||||
*/
|
||||
void destroyUserSession(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto& cookie_context = app.get_context<crow::CookieParser>(req);
|
||||
|
||||
session.set("clientID", "");
|
||||
session.set("clientToken", "");
|
||||
cookie_context.set_cookie("clientID", "");
|
||||
cookie_context.set_cookie("clientToken", "");
|
||||
}
|
||||
|
||||
bool checkAndUpdateUserSession(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto& cookie_context = app.get_context<crow::CookieParser>(req);
|
||||
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
|
||||
auto c_clientID = cookie_context.get_cookie("clientID");
|
||||
auto c_clientToken = cookie_context.get_cookie("clientToken");
|
||||
|
||||
if ((!c_clientID.empty() && !c_clientToken.empty()) && (s_clientID != c_clientID || s_clientToken != c_clientToken))
|
||||
{
|
||||
session.set("clientID", c_clientID);
|
||||
session.set("clientToken", c_clientToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isUserLoggedIn(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
return cs::isUserLoggedIn(s_clientID, s_clientToken);
|
||||
}
|
||||
|
||||
bool isUserAdmin(CrowApp& app, const crow::request& req)
|
||||
{
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
return cs::isUserAdmin(cs::getUserFromID(s_clientID));
|
||||
}
|
||||
|
||||
void generateRuntimeContext(const site_params& params, cs::RuntimeContext& context)
|
||||
{
|
||||
auto& session = params.app.get_context<Session>(params.req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
if (cs::isUserLoggedIn(s_clientID, s_clientToken))
|
||||
{
|
||||
auto username = cs::getUserFromID(s_clientID);
|
||||
auto perms = cs::getUserPermissions(username);
|
||||
auto isAdmin = cs::isUserAdmin(username);
|
||||
context["_logged_in"] = "True";
|
||||
context["_username"] = username;
|
||||
if (isAdmin)
|
||||
context["_admin"] = "True";
|
||||
if (perms & cs::PERM_READ_FILES)
|
||||
context["_read_files"] = "True";
|
||||
if (perms & cs::PERM_WRITE_FILES)
|
||||
context["_write_files"] = "True";
|
||||
if (perms & cs::PERM_CREATE_POSTS)
|
||||
context["_create_posts"] = "True";
|
||||
if (perms & cs::PERM_CREATE_COMMENTS)
|
||||
context["_create_comments"] = "True";
|
||||
if (perms & cs::PERM_CREATE_SHARES)
|
||||
context["_create_shares"] = "True";
|
||||
if (perms & cs::PERM_EDIT_POSTS)
|
||||
context["_edit_posts"] = "True";
|
||||
if (perms & cs::PERM_EDIT_COMMENTS)
|
||||
context["_edit_comments"] = "True";
|
||||
}
|
||||
}
|
||||
|
||||
crow::response handle_root_page(const site_params& params)
|
||||
{
|
||||
//auto page = crow::mustache::load("index.html"); //
|
||||
//return "<html><head><title>Hello There</title></head><body><h1>Suck it " + name + "</h1></body></html>";
|
||||
// BLT_TRACE(req.body);
|
||||
// for (const auto& h : req.headers)
|
||||
// BLT_TRACE("Header: %s = %s", h.first.c_str(), h.second.c_str());
|
||||
// BLT_TRACE(req.raw_url);
|
||||
// BLT_TRACE(req.url);
|
||||
// BLT_TRACE(req.remote_ip_address);
|
||||
// for (const auto& v : req.url_params.keys())
|
||||
// BLT_TRACE("URL: %s = %s", v.c_str(), req.url_params.get(v));
|
||||
if (params.name.ends_with(".html"))
|
||||
{
|
||||
checkAndUpdateUserSession(params.app, params.req);
|
||||
auto& session = params.app.get_context<Session>(params.req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
auto user_perms = cs::getUserPermissions(cs::getUserFromID(s_clientID));
|
||||
|
||||
crow::mustache::context ctx;
|
||||
cs::RuntimeContext context;
|
||||
|
||||
generateRuntimeContext(params, context);
|
||||
|
||||
// pass perms in
|
||||
if (user_perms & cs::PERM_ADMIN)
|
||||
ctx["_admin"] = true;
|
||||
|
||||
if (cs::isUserLoggedIn(s_clientID, s_clientToken))
|
||||
{
|
||||
ctx["_logged_in"] = true;
|
||||
} else
|
||||
{
|
||||
ctx["_not_logged_in"] = true;
|
||||
}
|
||||
|
||||
// we don't want to pass all get parameters to the context to prevent leaking information
|
||||
auto referer = params.req.url_params.get("referer");
|
||||
if (referer)
|
||||
ctx["referer"] = referer;
|
||||
auto page = crow::mustache::compile(params.engine.fetch(params.name, context));
|
||||
return page.render(ctx);
|
||||
}
|
||||
|
||||
return params.engine.fetch("default.html");
|
||||
}
|
||||
|
||||
crow::response handle_auth_page(const site_params& params)
|
||||
{
|
||||
if (isUserAdmin(params.app, params.req))
|
||||
return cs::redirect("/login.html");
|
||||
|
||||
|
||||
return handle_root_page(params);
|
||||
}
|
||||
#define CS_SESSION cs::checkAndUpdateUserSession(app, req); \
|
||||
auto& session = app.get_context<Session>(req); \
|
||||
auto s_clientID = session.get("clientID", ""); \
|
||||
auto s_clientToken = session.get("clientToken", ""); \
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
@ -207,7 +35,7 @@ int main(int argc, const char** argv)
|
|||
cs::auth::init();
|
||||
|
||||
BLT_INFO("Starting site %s.", SITE_NAME);
|
||||
crow::mustache::set_global_base(SITE_FILES_PATH);
|
||||
crow::mustache::set_global_base(CROWSITE_FILES_PATH);
|
||||
static BLT_CrowLogger bltCrowLogger{};
|
||||
crow::logger::setHandler(&bltCrowLogger);
|
||||
|
||||
|
@ -221,26 +49,28 @@ int main(int argc, const char** argv)
|
|||
// set session id length (small value only for demonstration purposes)
|
||||
16,
|
||||
// init the store
|
||||
crow::FileStore{std::string(SITE_FILES_PATH) + "/data/session", session_age}}};
|
||||
crow::FileStore{std::string(CROWSITE_FILES_PATH) + "/data/session", session_age}}};
|
||||
app.use_compression(crow::compression::GZIP);
|
||||
app.loglevel(crow::LogLevel::WARNING);
|
||||
|
||||
BLT_INFO("Creating static context");
|
||||
|
||||
cs::StaticContext context;
|
||||
context["SITE_TITLE"] = SITE_TITLE;
|
||||
context["SITE_NAME"] = SITE_NAME;
|
||||
context["SITE_VERSION"] = SITE_VERSION;
|
||||
context["BEE_MOVIE"] = beemovie_script;
|
||||
context["SITE_BACKGROUND"] = "/static/images/backgrounds/2023-05-26_23.18.23.png";
|
||||
context["MENU_BAR_COLOR"] = "#335";
|
||||
context["MENU_BAR_HOVER"] = "#223";
|
||||
context["MENU_BAR_ACTIVE"] = "#7821be";
|
||||
cs::context static_context;
|
||||
static_context["SITE_TITLE"] = SITE_TITLE;
|
||||
static_context["SITE_NAME"] = SITE_NAME;
|
||||
static_context["SITE_VERSION"] = SITE_VERSION;
|
||||
static_context["BEE_MOVIE"] = beemovie_script;
|
||||
static_context["SITE_BACKGROUND"] = "/static/images/backgrounds/2023-05-26_23.18.23.png";
|
||||
static_context["MENU_BAR_COLOR"] = "#335";
|
||||
static_context["MENU_BAR_HOVER"] = "#223";
|
||||
static_context["MENU_BAR_ACTIVE"] = "#7821be";
|
||||
|
||||
BLT_INFO("Starting cache engine");
|
||||
|
||||
cs::CacheSettings settings;
|
||||
cs::CacheEngine engine(context, settings);
|
||||
cs::CacheEngine engine(static_context, settings);
|
||||
|
||||
cs::posts_init();
|
||||
|
||||
BLT_INFO("Creating routes");
|
||||
|
||||
|
@ -255,22 +85,22 @@ int main(int argc, const char** argv)
|
|||
|
||||
CROW_ROUTE(app, "/login.html")(
|
||||
[&app, &engine](const crow::request& req) -> crow::response {
|
||||
if (isUserLoggedIn(app, req))
|
||||
if (cs::isUserLoggedIn(app, req))
|
||||
return cs::redirect("/");
|
||||
return handle_root_page({app, engine, req, "login.html"});
|
||||
return cs::handle_root_page({app, engine, req, "login.html"});
|
||||
}
|
||||
);
|
||||
|
||||
CROW_ROUTE(app, "/logout.html")(
|
||||
[&app](const crow::request& req) -> crow::response {
|
||||
destroyUserSession(app, req);
|
||||
cs::destroyUserSession(app, req);
|
||||
return cs::redirect("/");
|
||||
}
|
||||
);
|
||||
|
||||
CROW_ROUTE(app, "/<string>")(
|
||||
[&app, &engine](const crow::request& req, const std::string& name) -> crow::response {
|
||||
return handle_root_page({app, engine, req, name});
|
||||
return cs::handle_root_page({app, engine, req, name});
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -314,29 +144,27 @@ int main(int argc, const char** argv)
|
|||
|
||||
CROW_ROUTE(app, "/projects/<path>")(
|
||||
[&engine, &app](const crow::request& req, const std::string& path) {
|
||||
checkAndUpdateUserSession(app, req);
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
CS_SESSION;
|
||||
|
||||
return cs::handleProjectPage({engine, req, s_clientID, s_clientToken, path});
|
||||
return toResponse(
|
||||
cs::handleProjectPage({req.raw_url, s_clientID, s_clientToken, path, cs::toQueryString(req.url_params.getValues()), engine}));
|
||||
}
|
||||
);
|
||||
|
||||
CROW_ROUTE(app, "/projects/")(
|
||||
[&engine, &app](const crow::request& req) {
|
||||
checkAndUpdateUserSession(app, req);
|
||||
auto& session = app.get_context<Session>(req);
|
||||
auto s_clientID = session.get("clientID", "");
|
||||
auto s_clientToken = session.get("clientToken", "");
|
||||
CS_SESSION;
|
||||
|
||||
return cs::handleProjectPage({engine, req, s_clientID, s_clientToken, "index.html"});
|
||||
return toResponse(
|
||||
cs::handleProjectPage(
|
||||
{req.raw_url, s_clientID, s_clientToken, "index.html", cs::toQueryString(req.url_params.getValues()), engine}
|
||||
));
|
||||
}
|
||||
);
|
||||
|
||||
CROW_ROUTE(app, "/")(
|
||||
[&engine, &app](const crow::request& req) {
|
||||
return handle_root_page({app, engine, req, "index.html"});
|
||||
return cs::handle_root_page({app, engine, req, "index.html"});
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -363,6 +191,8 @@ int main(int argc, const char** argv)
|
|||
BLT_INFO("Starting Crow website on port %d", port);
|
||||
app.port(port).multithreaded().run();
|
||||
|
||||
cs::posts_cleanup();
|
||||
|
||||
cs::requests::cleanup();
|
||||
cs::auth::cleanup();
|
||||
|
||||
|
|
Loading…
Reference in New Issue