From fb5a059e2ef18844edcd54559c195c9645a61d83 Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 5 Aug 2021 19:35:15 +0200 Subject: [PATCH] Implemented a simple registration form, and also login. --- modules/users/user.cpp | 184 ++++++++++++++++++++++++++++++++++++++++- modules/users/user.h | 4 + 2 files changed, 185 insertions(+), 3 deletions(-) diff --git a/modules/users/user.cpp b/modules/users/user.cpp index 1f0bb45..6a8acf5 100644 --- a/modules/users/user.cpp +++ b/modules/users/user.cpp @@ -1,6 +1,8 @@ #include "user.h" +#include "core/hash/sha256.h" #include "core/html/html_builder.h" +#include "core/http/cookie.h" #include "core/http/http_session.h" #include "core/http/request.h" #include "core/http/session_manager.h" @@ -29,6 +31,30 @@ void User::changed() { void User::update() { } +bool User::check_password(const std::string &p_password) { + return hash_password(p_password) == password_hash; +} + +void User::create_password(const std::string &p_password) { + //todo improve a bit + pre_salt = hash_password(name + email); + post_salt = hash_password(email + name); + + password_hash = hash_password(p_password); +} + +std::string User::hash_password(const std::string &p_password) { + SHA256 *s = SHA256::get(); + + std::string p = pre_salt + p_password + post_salt; + + std::string c = s->compute(p); + + delete s; + + return c; +} + void User::register_sessions() { if (sessions.size() == 0) { return; @@ -110,14 +136,34 @@ void User::handle_login_request_default(Request *request) { User *user = UserManager::get_singleton()->get_user(uname_val); if (user) { - //todo + if (!user->check_password(pass_val)) { + error_str += "Invalid username or password!"; + } else { + HTTPSession *session = request->get_or_create_session(); + + session->add_object("user", user); + user->sessions.push_back(session->session_id); + + request->add_cookie(::Cookie("session_id", session->session_id)); + + //todo implement redirect! + + request->body += "Login Success!
"; + + request->compile_and_send_body(); + + return; + } } else { - error_str = "Invalid username or password!"; + error_str += "Invalid username or password!"; } } HTMLBuilder b; + b.w("Login"); + b.br(); + if (error_str.size() != 0) { b.div()->cls("error"); @@ -152,7 +198,131 @@ void User::handle_login_request_default(Request *request) { } void User::handle_register_request_default(Request *request) { - request->body += "handle_register_request_default"; + std::string error_str = ""; + + std::string uname_val = ""; + std::string email_val = ""; + std::string pass_val = ""; + std::string pass_check_val = ""; + + if (request->get_method() == HTTP_METHOD_POST) { + uname_val = request->get_parameter("username"); + email_val = request->get_parameter("email"); + pass_val = request->get_parameter("password"); + pass_check_val = request->get_parameter("password_check"); + + //todo username length etc check + //todo pw length etc check + + User *user = UserManager::get_singleton()->get_user(uname_val); + + if (user) { + error_str += "Username already taken!
"; + } + + UserManager *um = UserManager::get_singleton(); + + bool email_found = false; + + for (int i = 0; i < um->_users_vec.size(); ++i) { + User *u = um->_users_vec[i]; + + if (!u) { + continue; + } + + if (u->email == email_val) { + email_found = true; + break; + } + } + + if (email_found) { + error_str += "Email already in use!
"; + } + + if (pass_val != pass_check_val) { + error_str += "The passwords did not match!
"; + } + + if (error_str.size() == 0) { + user = UserManager::get_singleton()->create_user(); + + user->name = uname_val; + user->email = email_val; + //todo + user->rank = 1; + user->create_password(pass_val); + user->save(); + + UserManager::get_singleton()->add_user(user); + + HTMLBuilder b; + + b.div()->cls("success"); + b.w("Registration successful! You can now log in!"); + b.br(); + b.a()->href("/user/login"); + b.w(">> Login <<"); + b.ca(); + b.cdiv(); + + request->body += b.result; + + request->compile_and_send_body(); + return; + } + } + + HTMLBuilder b; + + b.w("Registration"); + b.br(); + + if (error_str.size() != 0) { + b.div()->cls("error"); + + b.w(error_str); + + b.cdiv(); + } + + b.div()->cls("register"); + + //todo href path helper + b.form()->method("POST")->href("/user/register"); + + b.w("Username"); + b.br(); + b.input()->type("text")->name("username")->value(uname_val); + b.cinput(); + b.br(); + + b.w("Email"); + b.br(); + b.input()->type("email")->name("email")->value(email_val); + b.cinput(); + b.br(); + + b.w("Password"); + b.br(); + b.input()->type("password")->name("password"); + b.cinput(); + b.br(); + + b.w("Password again"); + b.br(); + b.input()->type("password")->name("password_check"); + b.cinput(); + b.br(); + + b.input()->type("submit")->value("Register"); + b.cinput(); + b.cform(); + + b.cdiv(); + + request->body += b.result; request->compile_and_send_body(); } @@ -170,6 +340,14 @@ void User::handle_request(Request *request) { handle_logout_request(request); } else if (segment == "delete") { handle_delete_request(request); + } else if (segment == "login") { + request->body += "You are already logged in."; + + request->compile_and_send_body(); + } else if (segment == "register") { + request->body += "You are already logged in."; + + request->compile_and_send_body(); } else { request->send_error(404); } diff --git a/modules/users/user.h b/modules/users/user.h index fc8dcf8..353caeb 100644 --- a/modules/users/user.h +++ b/modules/users/user.h @@ -30,6 +30,10 @@ public: virtual void changed(); virtual void update(); + virtual bool check_password(const std::string &p_password); + virtual void create_password(const std::string &p_password); + virtual std::string hash_password(const std::string &p_password); + static void handle_request_default(Request *request); static void handle_login_request_default(Request *request);