-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser.h
149 lines (126 loc) · 4.52 KB
/
user.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once
#include "database.h"
#include "file.h"
#include <json.h>
#include <mutex>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
#define USERS_DATABASE "data/users.db"
#define USER_DIR_FRAGMENT "data/users/"
#define USER_FILE_FRAGMENT "/user.json"
namespace user
{
inline SQLite::Database &get_database()
{
static auto &database = []() -> SQLite::Database &
{
static SQLite::Database database(file::get_data_root() + USERS_DATABASE,
SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE | SQLite::OPEN_FULLMUTEX);
database.exec("CREATE TABLE IF NOT EXISTS users("
"name TEXT PRIMARY KEY NOT NULL,"
"id TEXT NOT NULL,"
"password TEXT NOT NULL)");
return database;
}();
return database;
}
inline bool does_user_id_exist(const std::string &user_id)
{
return database::exec_steps<std::string>(get_database(), "SELECT 1 FROM users WHERE id=@id",
{ "@id", user_id });
}
inline std::string get_user_name(const std::string &user_id)
{
std::string result;
database::exec_steps<std::string>(get_database(), "SELECT name FROM users WHERE id=@id", { "@id", user_id },
[&](const SQLite::Statement &statement)
{
if (result.empty())
result = statement.getColumn(0).getString();
});
return result;
}
inline bool does_user_name_exist(const std::string &user_name)
{
return database::exec_steps<std::string>(get_database(), "SELECT 1 FROM users WHERE UPPER(name)=UPPER(@user_name)",
{ "@user_name", user_name });
}
inline std::string get_user_id(const std::string &user_name)
{
std::string result;
database::exec_steps<std::string>(get_database(), "SELECT id FROM users WHERE UPPER(name)=UPPER(@user_name)",
{ "@user_name", user_name },
[&](const SQLite::Statement &statement)
{
if (result.empty())
result = statement.getColumn(0).getString();
});
return result;
}
inline nlohmann::json get_user_json(const std::string &user_id)
{
return file::read_json_file(USER_DIR_FRAGMENT + user_id + USER_FILE_FRAGMENT);
}
template <typename t = nlohmann::json>
inline t get_user_attribute(const std::string &user_id, const std::string &attribute)
{
return get_user_json(user_id)[attribute];
}
inline bool contains_user_attribute(const std::string &user_id, const std::string &attribute)
{
return get_user_json(user_id).contains(attribute);
}
inline void write_user_json(const std::string &user_id, const nlohmann::json &json)
{
file::write_file(USER_DIR_FRAGMENT + user_id + USER_FILE_FRAGMENT, json.dump(4));
}
inline void set_user_attribute(const std::string &user_id, const std::string &attribute, auto value)
{
auto user_json = get_user_json(user_id);
user_json[attribute] = value;
write_user_json(user_id, user_json);
}
template <typename t> struct user_attribute
{
std::string attribute;
t value;
user_attribute(std::string attribute, t value) : attribute(attribute), value(value)
{
}
};
template <typename... t>
inline void set_user_attributes(const std::string &user_id, const user_attribute<t> &...attributes)
{
auto user_json = get_user_json(user_id);
(
[&]
{
user_json[attributes.attribute] = attributes.value;
}(),
...);
write_user_json(user_id, user_json);
}
inline void erase_user_attribute(const std::string &user_id, const std::string &attribute)
{
auto user_json = get_user_json(user_id);
user_json.erase(attribute);
write_user_json(user_id, user_json);
}
template <typename... t> inline void erase_user_attributes(const std::string &user_id, const t &...attributes)
{
auto user_json = get_user_json(user_id);
for (const auto &attribute : { attributes... })
user_json.erase(attribute);
write_user_json(user_id, user_json);
}
inline bool is_user_admin(const std::string &user_id)
{
return contains_user_attribute(user_id, "is_admin");
}
inline bool can_user_modify_submission(const std::string &user_id, const std::string &submission_id)
{
return is_user_admin(user_id) || get_user_attribute(user_id, "submissions").contains(submission_id);
}
}