Fixed some bugs, added user registration, tweaked syntax of admin control commands
This commit is contained in:
parent
7de352ce1c
commit
632d4069ac
@ -1,30 +1,81 @@
|
||||
#include "server_data_interact.h"
|
||||
#include <engine_engine_number_9/baza_throw.h>
|
||||
#include <engine_engine_number_9/baza.h>
|
||||
#include "../str_fields.h"
|
||||
#include <string.h>
|
||||
|
||||
namespace iu9cawebchat {
|
||||
/* nagative `forced_id` means id isn't forced */
|
||||
void add_user(SqliteConnection& conn, const std::string& nickname, const std::string& name,
|
||||
const std::string& password, const std::string& bio, int64_t forced_id) {
|
||||
if (!check_nickname(nickname))
|
||||
een9_THROW("Bad user nickname " + nickname + ". Can't reg");
|
||||
if (!check_name(name))
|
||||
een9_THROW("Bad user name " + name + ". Can't reg");
|
||||
if (!check_strong_password(password))
|
||||
een9_THROW("Bad user password. Can't reg");
|
||||
if (!is_orthodox_string(bio))
|
||||
een9_THROW("Bad user bio. Can't reg");
|
||||
if (is_nickname_taken(conn, nickname))
|
||||
een9_THROW("Nickname taken already. Can't reg");
|
||||
reserve_nickname(conn, nickname);
|
||||
SqliteStatement req(conn,
|
||||
"INSERT INTO `user` (`id`, `nickname`, `name`, `chatList_HistoryId`, `password`, `bio`) "
|
||||
"VALUES (?1, ?2, ?3, 0, ?4, ?5)", {}, {{2, nickname}, {3, name}, {4, password}, {5, bio}});
|
||||
if (forced_id >= 0)
|
||||
sqlite_stmt_bind_int64(req, 1, forced_id);
|
||||
int must_be_done = sqlite_stmt_step(req, {}, {});
|
||||
if (must_be_done != SQLITE_DONE)
|
||||
een9_THROW("sqlite error");
|
||||
}
|
||||
|
||||
std::string admin_control_procedure(SqliteConnection& conn, const std::string& req, bool& termination) {
|
||||
if (req == "hello") {
|
||||
size_t nid = 0;
|
||||
auto read_thing = [&]() -> std::string {
|
||||
while (nid < req.size() && isSPACE(req[nid]))
|
||||
nid++;
|
||||
std::string result;
|
||||
bool esc = false;
|
||||
while (nid < req.size() && (esc || !isSPACE(req[nid]))) {
|
||||
if (esc) {
|
||||
result += req[nid];
|
||||
esc = false;
|
||||
} else if (req[nid] == '\\') {
|
||||
esc = true;
|
||||
} else {
|
||||
result += req[nid];
|
||||
}
|
||||
nid++;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
std::string cmd = read_thing();
|
||||
if (cmd == "hello") {
|
||||
return ":0 omg! hiii!! Hewwou :3 !!!!\n";
|
||||
}
|
||||
if (req == "8") {
|
||||
if (cmd == "8") {
|
||||
termination = true;
|
||||
return "Bye\n";
|
||||
}
|
||||
std::string updaterootpw_pref = "updaterootpw";
|
||||
if (een9::beginsWith(req, "updaterootpw")) {
|
||||
size_t nid = updaterootpw_pref.size();
|
||||
if (nid >= req.size() || !isSPACE(req[nid]))
|
||||
return "Bad command syntax. Missing whitespace\n";
|
||||
std::string new_password = req.substr(nid + 1);
|
||||
if (!check_password(new_password))
|
||||
een9_THROW("Bad password");
|
||||
const char* adduser_pref = "adduser";
|
||||
if (cmd == "updaterootpw") {
|
||||
|
||||
std::string new_password = read_thing();
|
||||
if (!check_strong_password(new_password))
|
||||
return "Bad password. Can't update";
|
||||
sqlite_nooutput(conn,
|
||||
"UPDATE `user` SET `password` = ?1 WHERE `id` = 0 ",
|
||||
{}, {{1, new_password}});
|
||||
"UPDATE `user` SET `password` = ?1 WHERE `id` = 0", {}, {{1, new_password}});
|
||||
return "Successul update\n";
|
||||
}
|
||||
/* adduser <nickname> <name> <password> <bio> */
|
||||
if (cmd == "adduser") {
|
||||
std::string nickname = read_thing();
|
||||
std::string name = read_thing();
|
||||
std::string password = read_thing();
|
||||
std::string bio = read_thing();
|
||||
add_user(conn, nickname, name, password, bio);
|
||||
return "User " + nickname + " successfully registered";
|
||||
}
|
||||
return "Incorrect command\n";
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,8 @@ namespace iu9cawebchat {
|
||||
json::JSON internalapi_leaveChat(SqliteConnection& conn, int64_t uid, const json::JSON& Sent);
|
||||
|
||||
/**/
|
||||
void add_user(SqliteConnection& conn, const std::string& nickname, const std::string& name,
|
||||
const std::string& password, const std::string& bio, int64_t forced_id = -1);
|
||||
std::string admin_control_procedure(SqliteConnection& conn, const std::string& req, bool& termination);
|
||||
}
|
||||
|
||||
|
@ -34,18 +34,22 @@ namespace iu9cawebchat {
|
||||
|
||||
bool chat_members = (path_segs[0] == "chat-members");
|
||||
|
||||
|
||||
// todo: do not throw id chat not found, catch exception and return 404
|
||||
json::JSON openedchat;
|
||||
RowChat_Content chatInfo = lookup_chat_content_by_nickname(*wgd.db, chat_nickname);
|
||||
RowChat_Content chatInfo;
|
||||
try {
|
||||
chatInfo = lookup_chat_content_by_nickname(*wgd.db, chat_nickname);
|
||||
} catch (const std::exception& e) {
|
||||
return page_E404(wgd);
|
||||
}
|
||||
if (get_role_of_user_in_chat(*wgd.db, userinfo["id"].asInteger().get_int(), chatInfo.id) == user_chat_role_deleted) {
|
||||
return page_E404(wgd);
|
||||
}
|
||||
|
||||
openedchat["name"] = json::JSON(chatInfo.name);
|
||||
openedchat["nickname"] = json::JSON(chatInfo.nickname);
|
||||
openedchat["id"] = json::JSON(chatInfo.id);
|
||||
openedchat["selectedMessageId"] = json::JSON(selected_message_id); // -1 means that nothing was selected
|
||||
json::JSON openedchat;
|
||||
openedchat["name"].asString() = chatInfo.name;
|
||||
openedchat["nickname"].asString() = chatInfo.nickname;
|
||||
openedchat["id"].asInteger() = json::Integer(chatInfo.id);
|
||||
// -1 means that nothing was selected
|
||||
openedchat["selectedMessageId"].asInteger() = json::Integer(selected_message_id);
|
||||
json::JSON initial_chatUpdResp = poll_update_chat_ONE_MSG_resp(*wgd.db, chatInfo.id, selected_message_id);
|
||||
if (chat_members)
|
||||
return http_R200("chat", wgd, {&config_presentation, &userinfo, &openedchat, &initial_chatUpdResp});
|
||||
|
@ -50,8 +50,12 @@ namespace iu9cawebchat {
|
||||
return page_E404(wgd);
|
||||
}
|
||||
// todo: in libjsonincpp: fix '999999 problem'
|
||||
int64_t myuid = userinfo["uid"].asInteger().get_int();
|
||||
bool can_edit = (alien.id == myuid);
|
||||
bool can_edit = false;
|
||||
int64_t myuid = -1;
|
||||
if (userinfo.isDictionary()) {
|
||||
myuid = userinfo["uid"].asInteger().get_int();
|
||||
can_edit = (alien.id == myuid && myuid >= 0);
|
||||
}
|
||||
if (req.method == "POST") {
|
||||
std::vector<std::pair<std::string, std::string>> response_hlines;
|
||||
try {
|
||||
@ -73,17 +77,23 @@ namespace iu9cawebchat {
|
||||
if (!bio.empty()) {
|
||||
if (!is_orthodox_string(bio) || bio.size() > 100000)
|
||||
een9_THROW("Incorrect `bio`");
|
||||
sqlite_nooutput(conn, "UPDATE `user` SET `bio` = ?1", {}, {{1, bio}});
|
||||
sqlite_nooutput(conn,
|
||||
"UPDATE `user` SET `bio` = ?1 WHERE `id` = ?2",
|
||||
{{2, alien.id}}, {{1, bio}});
|
||||
}
|
||||
if (!name.empty()) {
|
||||
if (!check_name(name))
|
||||
een9_THROW("Incorrect `name`");
|
||||
sqlite_nooutput(conn, "UPDATE `user` SET `name` = ?1", {}, {{1, name}});
|
||||
sqlite_nooutput(conn,
|
||||
"UPDATE `user` SET `name` = ?1 WHERE `id` = ?2",
|
||||
{{2, alien.id}}, {{1, name}});
|
||||
}
|
||||
if (!password.empty()) {
|
||||
if (!check_strong_password(password))
|
||||
een9_THROW("Incorrect `password`");
|
||||
sqlite_nooutput(conn, "UPDATE `user` SET `password` = ?1", {}, {{1, password}});
|
||||
sqlite_nooutput(conn,
|
||||
"UPDATE `user` SET `password` = ?1 WHERE `id` = ?2",
|
||||
{{2, alien.id}}, {{1, password}});
|
||||
if (alien.id == myuid) {
|
||||
LoginCookie new_login_cookie = create_login_cookie(userinfo["nickname"].asString(), password);
|
||||
add_set_cookie_headers_to_login(login_cookies, response_hlines, new_login_cookie);
|
||||
|
@ -7,24 +7,27 @@
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "sqlite3_wrapper.h"
|
||||
#include "backend_logic/server_data_interact.h"
|
||||
|
||||
namespace iu9cawebchat {
|
||||
void initialize_website(const json::JSON& config, const std::string& root_pw) {
|
||||
printf("Initialization...\n");
|
||||
een9_ASSERT(check_password(root_pw), "Bad root password");
|
||||
if (!check_strong_password(root_pw))
|
||||
een9_THROW("Bad root password");
|
||||
std::string db_path;
|
||||
int ret;
|
||||
ret = find_db_sqlite_file_path(config, db_path);
|
||||
een9_ASSERT(ret == 0, "Invalid settings[\"database\"] field");
|
||||
if (ret != 0)
|
||||
een9_THROW("Invalid settings[\"database\"] field");
|
||||
if (een9::isRegularFile(db_path)) {
|
||||
// todo: plaese, don't do this
|
||||
ret = unlink(db_path.c_str());
|
||||
een9_ASSERT_pl(ret == 0);
|
||||
if (ret != 0)
|
||||
een9_THROW("unlink");
|
||||
}
|
||||
een9_ASSERT(!een9::isRegularFile(db_path), "Database file exists prior to initialization. "
|
||||
"Can't preceed withut harming existing data");
|
||||
if (een9::isRegularFile(db_path))
|
||||
een9_THROW("Database file exists prior to initialization. Can't preceed withut harming existing data");
|
||||
SqliteConnection conn(db_path.c_str());
|
||||
assert(sqlite3_errcode(conn.hand) == SQLITE_OK);
|
||||
/* Role of memeber of chat:
|
||||
* 1 - admin
|
||||
* 2 - regular
|
||||
@ -72,10 +75,7 @@ namespace iu9cawebchat {
|
||||
"`chat_IncHistoryId` INTEGER NOT NULL,"
|
||||
"PRIMARY KEY (`chatId`, `id`)"
|
||||
")");
|
||||
sqlite_nooutput(conn, "INSERT INTO `nickname` VALUES (?1)", {}, {{1, "root"}});
|
||||
sqlite_nooutput(conn, "INSERT INTO `user` (`id`, `nickname`, `name`, `chatList_HistoryId`, `password`, "
|
||||
"`bio` ) VALUES (0, ?1, ?2, 0, ?3, ?4)", {},
|
||||
{{1, "root"}, {2, "Rootov Root Rootovich"}, {3, root_pw}, {4, "One admin to rule them all"}});
|
||||
add_user(conn, "root", "Rootov Root Rootovich", root_pw, "One admin to rule them all", 0);
|
||||
sqlite_nooutput(conn, "END");
|
||||
} catch (const std::exception& e) {
|
||||
sqlite_nooutput(conn, "ROLLBACK", {}, {});
|
||||
|
Loading…
Reference in New Issue
Block a user