Add session id preset, remove boost filesystem, small fixes

This commit is contained in:
Vladislav Oleshko 2022-06-21 15:38:22 +03:00
parent b939dd4f1d
commit 29c657df8f
4 changed files with 83 additions and 45 deletions

View File

@ -1,7 +1,8 @@
#include "crow.h"
#include "crow/middlewares/session.h"
crow::response redirect() {
crow::response redirect()
{
crow::response rsp;
rsp.redirect("/");
return rsp;
@ -10,7 +11,7 @@ crow::response redirect() {
int main()
{
// Choose a storage kind for:
// - InMemoryStore stores all entries in memory
// - InMemoryStore stores all entries in memory
// - FileStore stores all entries in json files
using Session = crow::SessionMiddleware<crow::InMemoryStore>;
@ -18,16 +19,15 @@ int main()
// Check out the existing ones for guidelines
// Make sure the CookieParser is registered before the Session
crow::App<crow::CookieParser, Session> app {Session{
// choose a secret key for sigining cookies
"MY_SECRET_KEY",
// customize cookies
crow::CookieParser::Cookie("session").max_age(/*one day*/24 * 60 * 60).path("/"),
// set session_id length (small value only for demonstration purposes)
4,
// init the store
crow::InMemoryStore{}
}};
crow::App<crow::CookieParser, Session> app{Session{
// choose a secret key for sigining sessions ids
"MY_SECRET_KEY",
// customize cookies
crow::CookieParser::Cookie("session").max_age(/*one day*/ 24 * 60 * 60).path("/"),
// set session id length (small value only for demonstration purposes)
4,
// init the store
crow::InMemoryStore{}}};
// List all values
CROW_ROUTE(app, "/")
@ -37,13 +37,16 @@ int main()
// atomically increase number of views
// if "views" doesn't exist, it'll be default initialized
session.apply("views", [](int v){ return v + 1; });
session.apply("views", [](int v) {
return v + 1;
});
// get all currently present keys
auto keys = session.keys();
std::string out;
for (const auto& key: keys) out += "<p> " + key + " = " + session.string(key) + "</p>";
for (const auto& key : keys)
out += "<p> " + key + " = " + session.string(key) + "</p>";
return out;
});
@ -96,18 +99,34 @@ int main()
std::lock_guard<std::recursive_mutex> l(session.mutex());
if (session.get("views", 0) % 2 == 0) {
if (session.get("views", 0) % 2 == 0)
{
session.set("even", true);
} else {
}
else
{
session.evict("even");
}
return redirect();
});
// Manually hand out session ids
// This allows sharing sessions between devices or binding them to users, etc.
// Session ids are signed so they don't have to be random tokens
CROW_ROUTE(app, "/login")
([&](const crow::request& req) {
auto& session = app.get_context<Session>(req);
if (!session.exists())
{
session.preset_id("user_email@email.com");
}
});
app.port(18080)
//.multithreaded()
.run();
//.multithreaded()
.run();
return 0;
}

View File

@ -21,10 +21,8 @@
// fallback to boost otherwise
#ifdef CROW_CAN_USE_CPP17
#include <variant>
#include <filesystem>
#else
#include "boost/variant.hpp"
#include "boost/filesystem.hpp"
#endif
namespace crow
@ -34,7 +32,7 @@ namespace crow
{
using multi_value_types = black_magic::S<bool, int32_t, int64_t, uint64_t, double, std::string>;
/// A multi_value is a safe variant wrapper with json support
/// A multi_value is a safe variant wrapper with json conversion support
#ifdef CROW_CAN_USE_CPP17
struct multi_value
{
@ -156,6 +154,8 @@ namespace crow
{
if (rv.nt() == num_type::Floating_point)
return multi_value{rv.d()};
else if (rv.nt() == num_type::Unsigned_integer)
return multi_value{rv.u()};
else
return multi_value{rv.i()};
}
@ -170,6 +170,7 @@ namespace crow
struct CachedSession
{
std::string session_id;
std::string requested_session_id;
std::unordered_map<std::string, multi_value> entries;
// values that were changed after last load
@ -206,7 +207,7 @@ namespace crow
}
// Check wheter this session is already present
bool valid() { return bool(node); }
bool exists() { return bool(node); }
// Get a value by key or fallback if it doesn't exist or is of another type
template<typename T>
@ -220,6 +221,14 @@ namespace crow
return fallback;
}
// Request a special session id for the store
// WARNING: it does not check for collisions!
void preset_id(std::string id)
{
check_node();
node->requested_session_id = std::move(id);
}
// Set a value by key
template<typename T>
void set(const std::string& key, T value)
@ -348,7 +357,12 @@ namespace crow
// generate new id
if (ctx.node->session_id == "")
{
ctx.node->session_id = next_id();
// check for requested id
ctx.node->session_id = std::move(ctx.node->requested_session_id);
if (ctx.node->session_id == "")
{
ctx.node->session_id = utility::random_alphanum(id_length_);
}
auto& cookies = all_ctx.template get<CookieParser>();
store_id(cookies, ctx.node->session_id);
}
@ -452,12 +466,7 @@ namespace crow
// FileStore stores all data as json files in a folder
struct FileStore
{
#ifdef CROW_CAN_USE_CPP17
using path_t = std::filesystem::path;
#else
using path_t = std::string;
#endif
FileStore(const path_t& folder):
FileStore(const std::string& folder):
path(folder)
{}
@ -485,12 +494,7 @@ namespace crow
std::string get_filename(const std::string& key)
{
#ifdef CROW_CAN_USE_CPP17
return path / (key + ".json");
#else
using namespace boost::filesystem;
return (path / (key + ".json")).string();
#endif
return utility::join_path(path, key + ".json");
}
bool contains(const std::string& key)
@ -499,7 +503,7 @@ namespace crow
return file.good();
}
path_t path;
std::string path;
};
} // namespace crow

View File

@ -643,10 +643,7 @@ namespace crow
inline std::string default_loader(const std::string& filename)
{
std::string path = detail::get_template_base_directory_ref();
if (!(path.back() == '/' || path.back() == '\\'))
path += '/';
path += filename;
std::ifstream inf(path);
std::ifstream inf(utility::join_path(path, filename));
if (!inf)
{
CROW_LOG_WARNING << "Template \"" << filename << "\" not found.";

View File

@ -12,6 +12,10 @@
#include "crow/settings.h"
#ifdef CROW_CAN_USE_CPP17
#include <filesystem>
#endif
// TODO(EDev): Adding C++20's [[likely]] and [[unlikely]] attributes might be useful
#if defined(__GNUG__) || defined(__clang__)
#define CROW_LIKELY(X) __builtin_expect(!!(X), 1)
@ -780,17 +784,31 @@ namespace crow
}
}
}
inline std::string random_alphanum(std::size_t size) {
static const char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";
inline std::string random_alphanum(std::size_t size)
{
static const char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> dist(0, sizeof(alphabet)-2);
std::uniform_int_distribution<std::mt19937::result_type> dist(0, sizeof(alphabet) - 2);
std::string out;
out.reserve(size);
for (std::size_t i = 0; i < size; i++) out.push_back(alphabet[dist(rng)]);
for (std::size_t i = 0; i < size; i++)
out.push_back(alphabet[dist(rng)]);
return out;
}
inline std::string join_path(std::string path, const std::string& fname)
{
#ifdef CROW_CAN_USE_CPP17
return std::filesystem::path(path) / fname;
#else
if (!(path.back() == '/' || path.back() == '\\'))
path += '/';
path += fname;
return path;
#endif
}
} // namespace utility
} // namespace crow