session storage

cookies are a todo along with tokens / token storage
main
Brett 2023-08-17 01:38:48 -04:00
parent 2d2ccc2567
commit 1011152fbe
7 changed files with 58 additions and 10 deletions

View File

@ -0,0 +1 @@
jlbpNSZuchBeVInZ 1692336738

View File

@ -0,0 +1 @@
{"clientID":"2e68464b-a37c-58a2-a970-97fedf56e8f9","clientToken":"00000000-0000-0000-0000-000000000000"}

View File

@ -17,7 +17,9 @@
<label for="username">Username</label><br> <label for="username">Username</label><br>
<input type="text" id="username" name="username"><br> <input type="text" id="username" name="username"><br>
<label for="password">Password</label><br> <label for="password">Password</label><br>
<input type="password" id="password" name="password"> <input type="password" id="password" name="password"><br>
<label for="remember_me">Remember Me?</label><br>
<input type="checkbox" id="remember_me" value="T" name="remember_me"><br>
<input type="submit" value="Login"> <input type="submit" value="Login">
</form> </form>
</div> </div>

View File

@ -6,10 +6,16 @@
#define CROWSITE_AUTH_H #define CROWSITE_AUTH_H
#include "crowsite/utility.h" #include "crowsite/utility.h"
#include <string>
namespace cs { namespace cs {
struct cookie_data {
std::string clientID;
std::string clientToken;
};
bool handleLoginPost(cs::parser::Post& postData); bool handleLoginPost(cs::parser::Post& postData, cookie_data& cookieOut);
} }

View File

@ -4,10 +4,13 @@
#include <crowsite/site/auth.h> #include <crowsite/site/auth.h>
#include <crowsite/requests/jellyfin.h> #include <crowsite/requests/jellyfin.h>
#include "blt/std/logging.h" #include "blt/std/logging.h"
#include "blt/std/uuid.h"
using namespace blt;
namespace cs { namespace cs {
bool handleLoginPost(parser::Post& postData) bool handleLoginPost(parser::Post& postData, cookie_data& cookieOut)
{ {
// javascript should make sure we don't send post requests without information // javascript should make sure we don't send post requests without information
// this way it can be interactive // this way it can be interactive
@ -15,6 +18,9 @@ namespace cs {
return false; return false;
auto auth = jellyfin::authenticateUser(postData["username"], postData["password"]); auto auth = jellyfin::authenticateUser(postData["username"], postData["password"]);
cookieOut.clientID = uuid::toString(uuid::genV5("ClientID?"));
cookieOut.clientToken = uuid::toString(uuid::genV4());
return auth == jellyfin::auth_response::AUTHORIZED; return auth == jellyfin::auth_response::AUTHORIZED;
} }
} }

View File

@ -17,6 +17,8 @@ namespace cs {
auto stripped_key = curl_easy_unescape(nullptr, key.c_str(), 0, nullptr); auto stripped_key = curl_easy_unescape(nullptr, key.c_str(), 0, nullptr);
auto stripped_value = curl_easy_unescape(nullptr, value.c_str(), 0, nullptr); auto stripped_value = curl_easy_unescape(nullptr, value.c_str(), 0, nullptr);
m_Values[stripped_key] = stripped_value; m_Values[stripped_key] = stripped_value;
curl_free(stripped_key);
curl_free(stripped_value);
} }
} }

View File

@ -11,6 +11,8 @@
#include <crowsite/requests/curl.h> #include <crowsite/requests/curl.h>
#include <blt/parse/argparse.h> #include <blt/parse/argparse.h>
#include <crowsite/site/auth.h> #include <crowsite/site/auth.h>
#include <crow/middlewares/session.h>
#include <crow/middlewares/cookie_parser.h>
class BLT_CrowLogger : public crow::ILogHandler class BLT_CrowLogger : public crow::ILogHandler
{ {
@ -40,6 +42,11 @@ class BLT_CrowLogger : public crow::ILogHandler
} }
}; };
inline crow::response redirect(const std::string& loc){
crow::response res;
res.redirect(loc);
return res;
}
int main(int argc, const char** argv) int main(int argc, const char** argv)
{ {
@ -57,16 +64,24 @@ int main(int argc, const char** argv)
cs::jellyfin::setToken(blt::arg_parse::get<std::string>(args["token"])); cs::jellyfin::setToken(blt::arg_parse::get<std::string>(args["token"]));
cs::jellyfin::processUserData(); cs::jellyfin::processUserData();
auto res = cs::jellyfin::authenticateUser(blt::arg_parse::get<std::string>(args["user"]), blt::arg_parse::get<std::string>(args["pass"]));
BLT_INFO("Has true: %b", res == cs::jellyfin::auth_response::AUTHORIZED);
BLT_INFO("Starting site %s.", SITE_NAME); BLT_INFO("Starting site %s.", SITE_NAME);
crow::mustache::set_global_base(SITE_FILES_PATH); crow::mustache::set_global_base(SITE_FILES_PATH);
static BLT_CrowLogger bltCrowLogger{}; static BLT_CrowLogger bltCrowLogger{};
crow::logger::setHandler(&bltCrowLogger); crow::logger::setHandler(&bltCrowLogger);
using Session = crow::SessionMiddleware<crow::FileStore>;
const auto session_age = 24 * 60 * 60;
const auto cookie_age = 180 * 24 * 60 * 60;
BLT_INFO("Init Crow with compression and logging enabled!"); BLT_INFO("Init Crow with compression and logging enabled!");
crow::SimpleApp app; crow::App<crow::CookieParser, Session> app {Session{
// customize cookies
crow::CookieParser::Cookie("session").max_age(session_age).path("/"),
// 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}}};
app.use_compression(crow::compression::GZIP); app.use_compression(crow::compression::GZIP);
app.loglevel(crow::LogLevel::WARNING); app.loglevel(crow::LogLevel::WARNING);
@ -126,15 +141,30 @@ int main(int argc, const char** argv)
); );
CROW_ROUTE(app, "/res/login").methods(crow::HTTPMethod::POST)( CROW_ROUTE(app, "/res/login").methods(crow::HTTPMethod::POST)(
[](const crow::request& req) { [&app](const crow::request& req) {
cs::parser::Post pp(req.body); cs::parser::Post pp(req.body);
auto& session = app.get_context<Session>(req);
crow::response res(303); crow::response res(303);
cs::cookie_data data;
// either redirect to clear the form if failed or pass user to index // either redirect to clear the form if failed or pass user to index
if (cs::handleLoginPost(pp)) if (cs::handleLoginPost(pp, data))
{
session.set("clientID", data.clientID);
session.set("clientToken", data.clientToken);
if (pp.hasKey("remember_me")){
auto value = pp["remember_me"];
auto& cookie_context = app.get_context<crow::CookieParser>(req);
if (value[0] == 'T')
{
cookie_context.set_cookie("clientID", data.clientID).path("/").max_age(cookie_age);
cookie_context.set_cookie("clientToken", data.clientToken).path("/").max_age(cookie_age);
}
}
res.set_header("Location", pp.hasKey("referer") ? pp["referer"] : "/"); res.set_header("Location", pp.hasKey("referer") ? pp["referer"] : "/");
else } else
res.set_header("Location", "/login.html"); res.set_header("Location", "/login.html");
return res; return res;