master #6

Open
karimov-adel wants to merge 39 commits from master into adel_branch_2.0
5 changed files with 103 additions and 36 deletions
Showing only changes of commit 632d4069ac - Show all commits

View File

@ -1,30 +1,81 @@
#include "server_data_interact.h" #include "server_data_interact.h"
#include <engine_engine_number_9/baza_throw.h> #include <engine_engine_number_9/baza_throw.h>
#include <engine_engine_number_9/baza.h>
#include "../str_fields.h" #include "../str_fields.h"
#include <string.h>
namespace iu9cawebchat { 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) { 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"; return ":0 omg! hiii!! Hewwou :3 !!!!\n";
} }
if (req == "8") { if (cmd == "8") {
termination = true; termination = true;
return "Bye\n"; return "Bye\n";
} }
std::string updaterootpw_pref = "updaterootpw"; const char* adduser_pref = "adduser";
if (een9::beginsWith(req, "updaterootpw")) { if (cmd == "updaterootpw") {
size_t nid = updaterootpw_pref.size();
if (nid >= req.size() || !isSPACE(req[nid])) std::string new_password = read_thing();
return "Bad command syntax. Missing whitespace\n"; if (!check_strong_password(new_password))
std::string new_password = req.substr(nid + 1); return "Bad password. Can't update";
if (!check_password(new_password))
een9_THROW("Bad password");
sqlite_nooutput(conn, sqlite_nooutput(conn,
"UPDATE `user` SET `password` = ?1 WHERE `id` = 0 ", "UPDATE `user` SET `password` = ?1 WHERE `id` = 0", {}, {{1, new_password}});
{}, {{1, new_password}});
return "Successul update\n"; 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"; return "Incorrect command\n";
} }
} }

View File

@ -79,6 +79,8 @@ namespace iu9cawebchat {
json::JSON internalapi_leaveChat(SqliteConnection& conn, int64_t uid, const json::JSON& Sent); 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); std::string admin_control_procedure(SqliteConnection& conn, const std::string& req, bool& termination);
} }

View File

@ -34,18 +34,22 @@ namespace iu9cawebchat {
bool chat_members = (path_segs[0] == "chat-members"); bool chat_members = (path_segs[0] == "chat-members");
RowChat_Content chatInfo;
// todo: do not throw id chat not found, catch exception and return 404 try {
json::JSON openedchat; chatInfo = lookup_chat_content_by_nickname(*wgd.db, chat_nickname);
RowChat_Content 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) { if (get_role_of_user_in_chat(*wgd.db, userinfo["id"].asInteger().get_int(), chatInfo.id) == user_chat_role_deleted) {
return page_E404(wgd); return page_E404(wgd);
} }
openedchat["name"] = json::JSON(chatInfo.name); json::JSON openedchat;
openedchat["nickname"] = json::JSON(chatInfo.nickname); openedchat["name"].asString() = chatInfo.name;
openedchat["id"] = json::JSON(chatInfo.id); openedchat["nickname"].asString() = chatInfo.nickname;
openedchat["selectedMessageId"] = json::JSON(selected_message_id); // -1 means that nothing was selected 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); json::JSON initial_chatUpdResp = poll_update_chat_ONE_MSG_resp(*wgd.db, chatInfo.id, selected_message_id);
if (chat_members) if (chat_members)
return http_R200("chat", wgd, {&config_presentation, &userinfo, &openedchat, &initial_chatUpdResp}); return http_R200("chat", wgd, {&config_presentation, &userinfo, &openedchat, &initial_chatUpdResp});

View File

@ -50,8 +50,12 @@ namespace iu9cawebchat {
return page_E404(wgd); return page_E404(wgd);
} }
// todo: in libjsonincpp: fix '999999 problem' // todo: in libjsonincpp: fix '999999 problem'
int64_t myuid = userinfo["uid"].asInteger().get_int(); bool can_edit = false;
bool can_edit = (alien.id == myuid); int64_t myuid = -1;
if (userinfo.isDictionary()) {
myuid = userinfo["uid"].asInteger().get_int();
can_edit = (alien.id == myuid && myuid >= 0);
}
if (req.method == "POST") { if (req.method == "POST") {
std::vector<std::pair<std::string, std::string>> response_hlines; std::vector<std::pair<std::string, std::string>> response_hlines;
try { try {
@ -73,17 +77,23 @@ namespace iu9cawebchat {
if (!bio.empty()) { if (!bio.empty()) {
if (!is_orthodox_string(bio) || bio.size() > 100000) if (!is_orthodox_string(bio) || bio.size() > 100000)
een9_THROW("Incorrect `bio`"); 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 (!name.empty()) {
if (!check_name(name)) if (!check_name(name))
een9_THROW("Incorrect `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 (!password.empty()) {
if (!check_strong_password(password)) if (!check_strong_password(password))
een9_THROW("Incorrect `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) { if (alien.id == myuid) {
LoginCookie new_login_cookie = create_login_cookie(userinfo["nickname"].asString(), password); LoginCookie new_login_cookie = create_login_cookie(userinfo["nickname"].asString(), password);
add_set_cookie_headers_to_login(login_cookies, response_hlines, new_login_cookie); add_set_cookie_headers_to_login(login_cookies, response_hlines, new_login_cookie);

View File

@ -7,24 +7,27 @@
#include <unistd.h> #include <unistd.h>
#include <assert.h> #include <assert.h>
#include "sqlite3_wrapper.h" #include "sqlite3_wrapper.h"
#include "backend_logic/server_data_interact.h"
namespace iu9cawebchat { namespace iu9cawebchat {
void initialize_website(const json::JSON& config, const std::string& root_pw) { void initialize_website(const json::JSON& config, const std::string& root_pw) {
printf("Initialization...\n"); 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; std::string db_path;
int ret; int ret;
ret = find_db_sqlite_file_path(config, db_path); 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)) { if (een9::isRegularFile(db_path)) {
// todo: plaese, don't do this // todo: plaese, don't do this
ret = unlink(db_path.c_str()); 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. " if (een9::isRegularFile(db_path))
"Can't preceed withut harming existing data"); een9_THROW("Database file exists prior to initialization. Can't preceed withut harming existing data");
SqliteConnection conn(db_path.c_str()); SqliteConnection conn(db_path.c_str());
assert(sqlite3_errcode(conn.hand) == SQLITE_OK);
/* Role of memeber of chat: /* Role of memeber of chat:
* 1 - admin * 1 - admin
* 2 - regular * 2 - regular
@ -72,10 +75,7 @@ namespace iu9cawebchat {
"`chat_IncHistoryId` INTEGER NOT NULL," "`chat_IncHistoryId` INTEGER NOT NULL,"
"PRIMARY KEY (`chatId`, `id`)" "PRIMARY KEY (`chatId`, `id`)"
")"); ")");
sqlite_nooutput(conn, "INSERT INTO `nickname` VALUES (?1)", {}, {{1, "root"}}); add_user(conn, "root", "Rootov Root Rootovich", root_pw, "One admin to rule them all", 0);
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"}});
sqlite_nooutput(conn, "END"); sqlite_nooutput(conn, "END");
} catch (const std::exception& e) { } catch (const std::exception& e) {
sqlite_nooutput(conn, "ROLLBACK", {}, {}); sqlite_nooutput(conn, "ROLLBACK", {}, {});