Merged UserControllers and UserModels.

This commit is contained in:
Relintai 2022-01-07 17:50:39 +01:00
parent 0e95b8f945
commit 37d5c0fec8
13 changed files with 381 additions and 575 deletions

View File

@ -3,8 +3,6 @@
#include "core/http/http_session.h"
#include "core/http/request.h"
#include "rbac_user_model.h"
#include "modules/rbac/rbac_controller.h"
#include "modules/rbac/rbac_default_permissions.h"
#include "rbac_user.h"
@ -15,12 +13,12 @@ void RBACUserController::rbac_user_session_setup_middleware(Object *instance, Re
if (user_id != 0) {
Ref<RBACUser> u = UserModel::get_singleton()->get_user(user_id);
Ref<RBACUser> u = UserController::get_singleton()->db_get_user(user_id);
if (u.is_valid()) {
request->reference_data["user"] = u;
} else {
//log
// log
request->session->remove_int("user_id");
}
}
@ -30,7 +28,7 @@ void RBACUserController::rbac_user_session_setup_middleware(Object *instance, Re
}
void RBACUserController::rbac_default_user_session_middleware(Object *instance, Request *request) {
//note: add a new file handler middleware func, so basic file handling is easy to set up before this
// note: add a new file handler middleware func, so basic file handling is easy to set up before this
Ref<RBACRank> rank;
@ -39,14 +37,14 @@ void RBACUserController::rbac_default_user_session_middleware(Object *instance,
if (user_id != 0) {
Ref<RBACUser> u = UserModel::get_singleton()->get_user(user_id);
Ref<RBACUser> u = UserController::get_singleton()->db_get_user(user_id);
if (u.is_valid()) {
rank = u->rbac_rank;
request->reference_data["user"] = u;
} else {
//log
// log
request->session->remove_int("user_id");
}
}
@ -57,10 +55,10 @@ void RBACUserController::rbac_default_user_session_middleware(Object *instance,
if (!rank.is_valid()) {
if (RBACController::get_singleton()->continue_on_missing_default_rank()) {
RLOG_ERR("RBACController::get_singleton()->get_default_rank() has not been set up properly!!! Continuing!");
RLOG_ERR("get_default_rank() has not been set up properly!!! Continuing!");
request->next_stage();
} else {
RLOG_ERR("RBACController::get_singleton()->get_default_rank() has not been set up properly!!! Sending 404!");
RLOG_ERR("get_default_rank() has not been set up properly!!! Sending 404!");
request->send_error(404);
}
@ -70,9 +68,9 @@ void RBACUserController::rbac_default_user_session_middleware(Object *instance,
if (!rank->has_permission(request, User::PERMISSION_READ)) {
if (rank->has_rank_permission(RBAC_RANK_PERMISSION_USE_REDIRECT)) {
//Note this can make the webapp prone to enumerations, if not done correctly
//e.g. redirect from /admin, but sending 404 on a non existing uri, which does not have
//a special rbac entry
// Note this can make the webapp prone to enumerations, if not done correctly
// e.g. redirect from /admin, but sending 404 on a non existing uri, which does not have
// a special rbac entry
request->send_redirect(RBACController::get_singleton()->get_redirect_url());
return;
}
@ -84,6 +82,49 @@ void RBACUserController::rbac_default_user_session_middleware(Object *instance,
request->next_stage();
}
Ref<User> RBACUserController::db_get_user(const int id) {
Ref<RBACUser> u = UserController::db_get_user(id);
if (u.is_valid()) {
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
}
return u;
}
Ref<User> RBACUserController::db_get_user(const String &user_name_input) {
Ref<RBACUser> u = UserController::db_get_user(user_name_input);
if (u.is_valid()) {
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
}
return u;
}
Vector<Ref<User> > RBACUserController::db_get_all() {
Vector<Ref<User> > users = UserController::db_get_all();
for (int i = 0; i < users.size(); ++i) {
Ref<RBACUser> u = users[i];
if (u.is_valid()) {
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
}
}
return users;
}
Ref<User> RBACUserController::create_user() {
Ref<RBACUser> u;
u.instance();
u->rank = RBACController::get_singleton()->get_default_user_rank_id();
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
return u;
}
RBACUserController::RBACUserController() :
UserController() {
}

View File

@ -7,13 +7,22 @@ class Request;
class RBACUserController : public UserController {
RCPP_OBJECT(RBACUserController, UserController);
public:
//just session setup
// just session setup
static void rbac_user_session_setup_middleware(Object *instance, Request *request);
//this one also handles missing read permission / redirect
// this one also handles missing read permission / redirect
static void rbac_default_user_session_middleware(Object *instance, Request *request);
// db
Ref<User> db_get_user(const int id);
Ref<User> db_get_user(const String &user_name_input);
Vector<Ref<User> > db_get_all();
Ref<User> create_user();
RBACUserController();
~RBACUserController();

View File

@ -1,37 +0,0 @@
#include "rbac_user_initializer.h"
void UserInitializer::allocate_controller() {
ERR_FAIL_COND(_controller);
_controller = new RBACUserController();
}
void UserInitializer::free_controller() {
if (_controller) {
delete _controller;
_controller = nullptr;
}
}
void UserInitializer::allocate_model() {
ERR_FAIL_COND(_model);
_model = new RBACUserModel();
}
void UserInitializer::free_model() {
if (_model) {
delete _model;
_model = nullptr;
}
}
void UserInitializer::allocate_all() {
allocate_model();
allocate_controller();
}
void UserInitializer::free_all() {
free_controller();
free_model();
}
RBACUserController *UserInitializer::_controller = nullptr;
RBACUserModel *UserInitializer::_model = nullptr;

View File

@ -1,23 +0,0 @@
#ifndef USER_INITIALIZER_H
#define USER_INITIALIZER_H
#include "rbac_user_model.h"
#include "rbac_user_controller.h"
class UserInitializer {
public:
static void allocate_controller();
static void free_controller();
static void allocate_model();
static void free_model();
static void allocate_all();
static void free_all();
protected:
static RBACUserController *_controller;
static RBACUserModel *_model;
};
#endif

View File

@ -1,55 +0,0 @@
#include "rbac_user_model.h"
#include "modules/rbac_users/rbac_user.h"
#include "modules/rbac/rbac_controller.h"
Ref<User> RBACUserModel::get_user(const int id) {
Ref<RBACUser> u = UserModel::get_user(id);
if (u.is_valid()) {
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
}
return u;
}
Ref<User> RBACUserModel::get_user(const String &user_name_input) {
Ref<RBACUser> u = UserModel::get_user(user_name_input);
if (u.is_valid()) {
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
}
return u;
}
Vector<Ref<User> > RBACUserModel::get_all() {
Vector<Ref<User> > users = UserModel::get_all();
for (int i = 0; i < users.size(); ++i) {
Ref<RBACUser> u = users[i];
if (u.is_valid()) {
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
}
}
return users;
}
Ref<User> RBACUserModel::create_user() {
Ref<RBACUser> u;
u.instance();
u->rank = RBACController::get_singleton()->get_default_user_rank_id();
u->rbac_rank = RBACController::get_singleton()->get_rank(u->rank);
return u;
}
RBACUserModel::RBACUserModel() :
UserModel() {
}
RBACUserModel::~RBACUserModel() {
}

View File

@ -1,23 +0,0 @@
#ifndef RBAC_USER_MODEL_H
#define RBAC_USER_MODEL_H
#include "modules/users/user_model.h"
class RBACUserModel : public UserModel {
RCPP_OBJECT(RBACUserModel, UserModel);
public:
Ref<User> get_user(const int id);
Ref<User> get_user(const String &user_name_input);
Vector<Ref<User> > get_all();
Ref<User> create_user();
RBACUserModel();
~RBACUserModel();
protected:
};
#endif

View File

@ -20,7 +20,6 @@
#include "core/http/request.h"
#include "core/http/session_manager.h"
#include "core/utils.h"
#include "user_model.h"
String User::to_json(rapidjson::Document *into) {
rapidjson::Document *document;

View File

@ -6,7 +6,14 @@
#include "core/http/http_session.h"
#include "core/http/request.h"
#include "core/http/session_manager.h"
#include "user_model.h"
#include "core/database/database.h"
#include "core/database/database_manager.h"
#include "core/database/query_builder.h"
#include "core/database/query_result.h"
#include "core/database/table_builder.h"
#include "core/hash/sha256.h"
void UserController::handle_request_default(Request *request) {
if (request->session) {
@ -55,10 +62,10 @@ void UserController::handle_login_request_default(Request *request) {
data.uname_val = request->get_parameter("username");
data.pass_val = request->get_parameter("password");
Ref<User> user = UserModel::get_singleton()->get_user(data.uname_val);
Ref<User> user = db_get_user(data.uname_val);
if (user.is_valid()) {
if (!UserModel::get_singleton()->check_password(user, data.pass_val)) {
if (!check_password(user, data.pass_val)) {
data.error_str += "Invalid username or password!";
} else {
HTTPSession *session = request->get_or_create_session();
@ -150,11 +157,11 @@ void UserController::handle_register_request_default(Request *request) {
//todo username length etc check
//todo pw length etc check
if (UserModel::get_singleton()->is_username_taken(data.uname_val)) {
if (is_username_taken(data.uname_val)) {
data.error_str += "Username already taken!<br>";
}
if (UserModel::get_singleton()->is_email_taken(data.email_val)) {
if (is_email_taken(data.email_val)) {
data.error_str += "Email already in use!<br>";
}
@ -164,13 +171,13 @@ void UserController::handle_register_request_default(Request *request) {
if (data.error_str.size() == 0) {
Ref<User> user;
user = UserModel::get_singleton()->create_user();
user = create_user();
user->name_user_input = data.uname_val;
user->email_user_input = data.email_val;
UserModel::get_singleton()->create_password(user, data.pass_val);
UserModel::get_singleton()->save_user(user);
create_password(user, data.pass_val);
db_save_user(user);
render_register_success(request);
return;
@ -327,7 +334,7 @@ void UserController::handle_settings_request(Ref<User> &user, Request *request)
}
if (data.uname_val != "") {
if (UserModel::get_singleton()->is_username_taken(data.uname_val)) {
if (is_username_taken(data.uname_val)) {
data.error_str += "Username already taken!<br>";
} else {
//todo sanitize for html special chars!
@ -338,7 +345,7 @@ void UserController::handle_settings_request(Ref<User> &user, Request *request)
}
if (data.email_val != "") {
if (UserModel::get_singleton()->is_email_taken(data.email_val)) {
if (is_email_taken(data.email_val)) {
data.error_str += "Email already in use!<br>";
} else {
//todo sanitize for html special chars!
@ -353,14 +360,14 @@ void UserController::handle_settings_request(Ref<User> &user, Request *request)
if (data.pass_val != data.pass_check_val) {
data.error_str += "The passwords did not match!<br>";
} else {
UserModel::get_singleton()->create_password(user, data.pass_val);
create_password(user, data.pass_val);
changed = true;
}
}
if (changed) {
UserModel::get_singleton()->save_user(user);
db_save_user(user);
}
}
}
@ -434,7 +441,7 @@ void UserController::handle_password_reset_request(Ref<User> &user, Request *req
void UserController::handle_logout_request(Ref<User> &user, Request *request) {
request->remove_cookie("session_id");
UserModel::get_singleton()->save_user(user);
db_save_user(user);
SessionManager::get_singleton()->delete_session(request->session->session_id);
request->session = nullptr;
@ -502,7 +509,7 @@ void UserController::user_session_setup_middleware(Object *instance, Request *re
if (user_id != 0) {
Ref<User> u = UserModel::get_singleton()->get_user(user_id);
Ref<User> u = UserController::get_singleton()->db_get_user(user_id);
if (u.is_valid()) {
request->reference_data["user"] = u;
@ -516,12 +523,271 @@ void UserController::user_session_setup_middleware(Object *instance, Request *re
request->next_stage();
}
Ref<User> UserController::db_get_user(const int id) {
if (id == 0) {
return Ref<User>();
}
Ref<QueryBuilder> b = get_query_builder();
b->select("username, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->from(_table_name);
b->where()->wp("id", id);
b->end_command();
Ref<QueryResult> r = b->run();
if (!r->next_row()) {
return Ref<User>();
}
Ref<User> user;
user = create_user();
user->id = id;
user->name_user_input = r->get_cell(0);
user->email_user_input = r->get_cell(1);
user->rank = r->get_cell_int(2);
user->pre_salt = r->get_cell(3);
user->post_salt = r->get_cell(4);
user->password_hash = r->get_cell(5);
user->banned = r->get_cell_bool(6);
user->password_reset_token = r->get_cell(7);
user->locked = r->get_cell_bool(8);
return user;
}
Ref<User> UserController::db_get_user(const String &user_name_input) {
if (user_name_input == "") {
return Ref<User>();
}
Ref<QueryBuilder> b = get_query_builder();
b->select("id, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->from(_table_name);
b->where()->wp("username", user_name_input);
b->end_command();
Ref<QueryResult> r = b->run();
if (!r->next_row()) {
return Ref<User>();
}
Ref<User> user;
user = create_user();
user->id = r->get_cell_int(0);
user->name_user_input = user_name_input;
user->email_user_input = r->get_cell(1);
user->rank = r->get_cell_int(2);
user->pre_salt = r->get_cell(3);
user->post_salt = r->get_cell(4);
user->password_hash = r->get_cell(5);
user->banned = r->get_cell_bool(6);
user->password_reset_token = r->get_cell(7);
user->locked = r->get_cell_bool(8);
return user;
}
void UserController::db_save_user(Ref<User> &user) {
Ref<QueryBuilder> b = get_query_builder();
if (user->id == 0) {
b->insert(_table_name, "username, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->values();
b->val(user->name_user_input);
b->val(user->email_user_input);
b->val(user->rank);
b->val(user->pre_salt);
b->val(user->post_salt);
b->val(user->password_hash);
b->val(user->banned);
b->val(user->password_reset_token);
b->val(user->locked);
b->cvalues();
b->end_command();
b->select_last_insert_id();
Ref<QueryResult> r = b->run();
user->id = r->get_last_insert_rowid();
} else {
b->update(_table_name);
b->set();
b->setp("username", user->name_user_input);
b->setp("email", user->email_user_input);
b->setp("rank", user->rank);
b->setp("pre_salt", user->pre_salt);
b->setp("post_salt", user->post_salt);
b->setp("password_hash", user->password_hash);
b->setp("banned", user->banned);
b->setp("password_reset_token", user->password_reset_token);
b->setp("locked", user->locked);
b->cset();
b->where()->wp("id", user->id);
//b->print();
b->run_query();
}
}
Vector<Ref<User> > UserController::db_get_all() {
Ref<QueryBuilder> b = get_query_builder();
b->select("id, username, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->from(_table_name);
b->end_command();
//b->print();
Vector<Ref<User> > users;
Ref<QueryResult> r = b->run();
while (r->next_row()) {
Ref<User> user = create_user();
user->id = r->get_cell_int(0);
user->name_user_input = r->get_cell(1);
user->email_user_input = r->get_cell(2);
user->rank = r->get_cell_int(3);
user->pre_salt = r->get_cell(4);
user->post_salt = r->get_cell(5);
user->password_hash = r->get_cell(6);
user->banned = r->get_cell_bool(7);
user->password_reset_token = r->get_cell(8);
user->locked = r->get_cell_bool(9);
users.push_back(user);
}
return users;
}
Ref<User> UserController::create_user() {
Ref<User> u;
u.instance();
return u;
}
bool UserController::is_username_taken(const String &user_name_input) {
Ref<QueryBuilder> b = get_query_builder();
b->select("id")->from(_table_name)->where("username")->like(user_name_input)->end_command();
Ref<QueryResult> r = b->run();
return r->next_row();
}
bool UserController::is_email_taken(const String &email_input) {
Ref<QueryBuilder> b = get_query_builder();
b->select("id")->from(_table_name)->where("username")->like(email_input)->end_command();
Ref<QueryResult> r = b->run();
return r->next_row();
}
bool UserController::check_password(const Ref<User> &user, const String &p_password) {
return hash_password(user, p_password) == user->password_hash;
}
void UserController::create_password(Ref<User> &user, const String &p_password) {
if (!user.is_valid()) {
printf("Error UserController::create_password !user.is_valid()!\n");
return;
}
//todo improve a bit
user->pre_salt = hash_password(user, user->name_user_input + user->email_user_input);
user->post_salt = hash_password(user, user->email_user_input + user->name_user_input);
user->password_hash = hash_password(user, p_password);
}
String UserController::hash_password(const Ref<User> &user, const String &p_password) {
if (!user.is_valid()) {
printf("Error UserController::hash_password !user.is_valid()!\n");
return "";
}
Ref<SHA256> s = SHA256::get();
String p = user->pre_salt + p_password + user->post_salt;
String c = s->compute(p);
return c;
}
void UserController::create_table() {
Ref<TableBuilder> tb = get_table_builder();
tb->create_table(_table_name);
tb->integer("id")->auto_increment()->next_row();
tb->varchar("username", 60)->not_null()->next_row();
tb->varchar("email", 100)->not_null()->next_row();
tb->integer("rank")->not_null()->next_row();
tb->varchar("pre_salt", 100)->next_row();
tb->varchar("post_salt", 100)->next_row();
tb->varchar("password_hash", 100)->next_row();
tb->integer("banned")->next_row();
tb->varchar("password_reset_token", 100)->next_row();
tb->integer("locked")->next_row();
tb->primary_key("id");
tb->ccreate_table();
tb->run_query();
//tb->print();
}
void UserController::drop_table() {
Ref<TableBuilder> tb = get_table_builder();
tb->drop_table_if_exists(_table_name)->run_query();
}
void UserController::migrate() {
drop_table();
create_table();
}
void UserController::create_test_users() {
Ref<User> user;
user = create_user();
user->rank = 3;
user->name_user_input = "admin";
user->email_user_input = "admin@admin.com";
create_password(user, "Password");
db_save_user(user);
user = create_user();
user->rank = 1;
user->name_user_input = "user";
user->email_user_input = "user@user.com";
create_password(user, "Password");
db_save_user(user);
}
UserController *UserController::get_singleton() {
return _self;
}
UserController::UserController() :
Object() {
WebNode() {
if (_self) {
printf("UserController::UserController(): Error! self is not null!/n");
@ -543,3 +809,6 @@ UserController *UserController::_self = nullptr;
FormValidator *UserController::_login_validator = nullptr;
FormValidator *UserController::_registration_validator = nullptr;
FormValidator *UserController::_profile_validator = nullptr;
String UserController::_path = "./";
String UserController::_table_name = "users";

View File

@ -1,19 +1,19 @@
#ifndef USER_CONTROLLER_H
#define USER_CONTROLLER_H
#include "core/string.h"
#include "core/containers/vector.h"
#include "core/string.h"
#include "core/object.h"
#include "core/http/web_node.h"
#include "user.h"
class Request;
class FormValidator;
class UserController : public Object {
RCPP_OBJECT(UserController, Object);
class UserController : public WebNode {
RCPP_OBJECT(UserController, WebNode);
public:
virtual void handle_request_default(Request *request);
@ -64,6 +64,28 @@ public:
static void user_session_setup_middleware(Object *instance, Request *request);
// db
virtual Ref<User> db_get_user(const int id);
virtual Ref<User> db_get_user(const String &user_name_input);
virtual void db_save_user(Ref<User> &user);
virtual Vector<Ref<User> > db_get_all();
virtual Ref<User> create_user();
bool is_username_taken(const String &user_name_input);
bool is_email_taken(const String &email_input);
virtual bool check_password(const Ref<User> &user, const String &p_password);
virtual void create_password(Ref<User> &user, const String &p_password);
virtual String hash_password(const Ref<User> &user, const String &p_password);
virtual void create_table();
virtual void drop_table();
virtual void migrate();
virtual void create_test_users();
static UserController *get_singleton();
UserController();
@ -75,6 +97,11 @@ protected:
static FormValidator *_login_validator;
static FormValidator *_registration_validator;
static FormValidator *_profile_validator;
String _file_path;
static String _path;
static String _table_name;
};
#endif

View File

@ -1,37 +0,0 @@
#include "user_initializer.h"
void UserInitializer::allocate_controller() {
ERR_FAIL_COND(_controller);
_controller = new UserController();
}
void UserInitializer::free_controller() {
if (_controller) {
delete _controller;
_controller = nullptr;
}
}
void UserInitializer::allocate_model() {
ERR_FAIL_COND(_model);
_model = new UserModel();
}
void UserInitializer::free_model() {
if (_model) {
delete _model;
_model = nullptr;
}
}
void UserInitializer::allocate_all() {
allocate_model();
allocate_controller();
}
void UserInitializer::free_all() {
free_controller();
free_model();
}
UserController *UserInitializer::_controller = nullptr;
UserModel *UserInitializer::_model = nullptr;

View File

@ -1,23 +0,0 @@
#ifndef USER_INITIALIZER_H
#define USER_INITIALIZER_H
#include "user_model.h"
#include "user_controller.h"
class UserInitializer {
public:
static void allocate_controller();
static void free_controller();
static void allocate_model();
static void free_model();
static void allocate_all();
static void free_all();
protected:
static UserController *_controller;
static UserModel *_model;
};
#endif

View File

@ -1,292 +0,0 @@
#include "user_model.h"
#include "core/database/database.h"
#include "core/database/database_manager.h"
#include "core/database/query_builder.h"
#include "core/database/query_result.h"
#include "core/database/table_builder.h"
#include "core/hash/sha256.h"
Ref<User> UserModel::get_user(const int id) {
if (id == 0) {
return Ref<User>();
}
Ref<QueryBuilder> b = DatabaseManager::get_singleton()->ddb->get_query_builder();
b->select("username, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->from(_table_name);
b->where()->wp("id", id);
b->end_command();
Ref<QueryResult> r = b->run();
if (!r->next_row()) {
return Ref<User>();
}
Ref<User> user;
user = create_user();
user->id = id;
user->name_user_input = r->get_cell(0);
user->email_user_input = r->get_cell(1);
user->rank = r->get_cell_int(2);
user->pre_salt = r->get_cell(3);
user->post_salt = r->get_cell(4);
user->password_hash = r->get_cell(5);
user->banned = r->get_cell_bool(6);
user->password_reset_token = r->get_cell(7);
user->locked = r->get_cell_bool(8);
return user;
}
Ref<User> UserModel::get_user(const String &user_name_input) {
if (user_name_input == "") {
return Ref<User>();
}
Ref<QueryBuilder> b = DatabaseManager::get_singleton()->ddb->get_query_builder();
b->select("id, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->from(_table_name);
b->where()->wp("username", user_name_input);
b->end_command();
Ref<QueryResult> r = b->run();
if (!r->next_row()) {
return Ref<User>();
}
Ref<User> user;
user = create_user();
user->id = r->get_cell_int(0);
user->name_user_input = user_name_input;
user->email_user_input = r->get_cell(1);
user->rank = r->get_cell_int(2);
user->pre_salt = r->get_cell(3);
user->post_salt = r->get_cell(4);
user->password_hash = r->get_cell(5);
user->banned = r->get_cell_bool(6);
user->password_reset_token = r->get_cell(7);
user->locked = r->get_cell_bool(8);
return user;
}
void UserModel::save_user(Ref<User> &user) {
Ref<QueryBuilder> b = DatabaseManager::get_singleton()->ddb->get_query_builder();
if (user->id == 0) {
b->insert(_table_name, "username, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->values();
b->val(user->name_user_input);
b->val(user->email_user_input);
b->val(user->rank);
b->val(user->pre_salt);
b->val(user->post_salt);
b->val(user->password_hash);
b->val(user->banned);
b->val(user->password_reset_token);
b->val(user->locked);
b->cvalues();
b->end_command();
b->select_last_insert_id();
Ref<QueryResult> r = b->run();
user->id = r->get_last_insert_rowid();
} else {
b->update(_table_name);
b->set();
b->setp("username", user->name_user_input);
b->setp("email", user->email_user_input);
b->setp("rank", user->rank);
b->setp("pre_salt", user->pre_salt);
b->setp("post_salt", user->post_salt);
b->setp("password_hash", user->password_hash);
b->setp("banned", user->banned);
b->setp("password_reset_token", user->password_reset_token);
b->setp("locked", user->locked);
b->cset();
b->where()->wp("id", user->id);
//b->print();
b->run_query();
}
}
Vector<Ref<User> > UserModel::get_all() {
Ref<QueryBuilder> b = DatabaseManager::get_singleton()->ddb->get_query_builder();
b->select("id, username, email, rank, pre_salt, post_salt, password_hash, banned, password_reset_token, locked");
b->from(_table_name);
b->end_command();
//b->print();
Vector<Ref<User> > users;
Ref<QueryResult> r = b->run();
while (r->next_row()) {
Ref<User> user = create_user();
user->id = r->get_cell_int(0);
user->name_user_input = r->get_cell(1);
user->email_user_input = r->get_cell(2);
user->rank = r->get_cell_int(3);
user->pre_salt = r->get_cell(4);
user->post_salt = r->get_cell(5);
user->password_hash = r->get_cell(6);
user->banned = r->get_cell_bool(7);
user->password_reset_token = r->get_cell(8);
user->locked = r->get_cell_bool(9);
users.push_back(user);
}
return users;
}
Ref<User> UserModel::create_user() {
Ref<User> u;
u.instance();
return u;
}
bool UserModel::is_username_taken(const String &user_name_input) {
Ref<QueryBuilder> b = DatabaseManager::get_singleton()->ddb->get_query_builder();
b->select("id")->from(_table_name)->where("username")->like(user_name_input)->end_command();
Ref<QueryResult> r = b->run();
return r->next_row();
}
bool UserModel::is_email_taken(const String &email_input) {
Ref<QueryBuilder> b = DatabaseManager::get_singleton()->ddb->get_query_builder();
b->select("id")->from(_table_name)->where("username")->like(email_input)->end_command();
Ref<QueryResult> r = b->run();
return r->next_row();
}
bool UserModel::check_password(const Ref<User> &user, const String &p_password) {
return hash_password(user, p_password) == user->password_hash;
}
void UserModel::create_password(Ref<User> &user, const String &p_password) {
if (!user.is_valid()) {
printf("Error UserModel::create_password !user.is_valid()!\n");
return;
}
//todo improve a bit
user->pre_salt = hash_password(user, user->name_user_input + user->email_user_input);
user->post_salt = hash_password(user, user->email_user_input + user->name_user_input);
user->password_hash = hash_password(user, p_password);
}
String UserModel::hash_password(const Ref<User> &user, const String &p_password) {
if (!user.is_valid()) {
printf("Error UserModel::hash_password !user.is_valid()!\n");
return "";
}
Ref<SHA256> s = SHA256::get();
String p = user->pre_salt + p_password + user->post_salt;
String c = s->compute(p);
return c;
}
void UserModel::create_table() {
Ref<TableBuilder> tb = DatabaseManager::get_singleton()->ddb->get_table_builder();
tb->create_table(_table_name);
tb->integer("id")->auto_increment()->next_row();
tb->varchar("username", 60)->not_null()->next_row();
tb->varchar("email", 100)->not_null()->next_row();
tb->integer("rank")->not_null()->next_row();
tb->varchar("pre_salt", 100)->next_row();
tb->varchar("post_salt", 100)->next_row();
tb->varchar("password_hash", 100)->next_row();
tb->integer("banned")->next_row();
tb->varchar("password_reset_token", 100)->next_row();
tb->integer("locked")->next_row();
tb->primary_key("id");
tb->ccreate_table();
tb->run_query();
//tb->print();
}
void UserModel::drop_table() {
Ref<TableBuilder> tb = DatabaseManager::get_singleton()->ddb->get_table_builder();
tb->drop_table_if_exists(_table_name)->run_query();
}
void UserModel::migrate() {
drop_table();
create_table();
}
void UserModel::create_test_users() {
Ref<User> user;
user = UserModel::get_singleton()->create_user();
user->rank = 3;
user->name_user_input = "admin";
user->email_user_input = "admin@admin.com";
create_password(user, "Password");
save_user(user);
user = UserModel::get_singleton()->create_user();
user->rank = 1;
user->name_user_input = "user";
user->email_user_input = "user@user.com";
create_password(user, "Password");
save_user(user);
}
UserModel *UserModel::get_singleton() {
return _self;
}
UserModel::UserModel() :
Object() {
if (_self) {
printf("UserModel::UserModel(): Error! self is not null!/n");
}
_self = this;
}
UserModel::~UserModel() {
if (_self == this) {
_self = nullptr;
}
}
UserModel *UserModel::_self = nullptr;
String UserModel::_path = "./";
String UserModel::_table_name = "users";

View File

@ -1,49 +0,0 @@
#ifndef USER_MODEL_H
#define USER_MODEL_H
#include "core/string.h"
#include "core/containers/vector.h"
#include "core/object.h"
#include "user.h"
class UserModel : public Object {
RCPP_OBJECT(UserModel, Object);
public:
virtual Ref<User> get_user(const int id);
virtual Ref<User> get_user(const String &user_name_input);
virtual void save_user(Ref<User> &user);
virtual Vector<Ref<User> > get_all();
virtual Ref<User> create_user();
bool is_username_taken(const String &user_name_input);
bool is_email_taken(const String &email_input);
virtual bool check_password(const Ref<User> &user, const String &p_password);
virtual void create_password(Ref<User> &user, const String &p_password);
virtual String hash_password(const Ref<User> &user, const String &p_password);
virtual void create_table();
virtual void drop_table();
virtual void migrate();
virtual void create_test_users();
static UserModel *get_singleton();
UserModel();
~UserModel();
protected:
static UserModel *_self;
String _file_path;
static String _path;
static String _table_name;
};
#endif