26 #define ERR_UH LOG_STREAM(err, log_mp_user_handler)
27 #define WRN_UH LOG_STREAM(warn, log_mp_user_handler)
28 #define LOG_UH LOG_STREAM(info, log_mp_user_handler)
29 #define DBG_UH LOG_STREAM(debug, log_mp_user_handler)
32 const int USER_INACTIVE = 1;
33 const int USER_IGNORE = 2;
37 : db_name_(c[
"db_name"].str())
38 , db_host_(c[
"db_host"].str())
39 , db_user_(c[
"db_user"].str())
40 , db_password_(c[
"db_password"].str())
41 , db_users_table_(c[
"db_users_table"].str())
42 , db_extra_table_(c[
"db_extra_table"].str())
43 , conn(mysql_init(nullptr))
45 if(!conn || !mysql_real_connect(conn, db_host_.c_str(), db_user_.c_str(), db_password_.c_str(), db_name_.c_str(), 0,
nullptr, 0)) {
46 ERR_UH <<
"Could not connect to database: " << mysql_errno(conn) <<
": " << mysql_error(conn) << std::endl;
55 throw error(
"For now please register at http://forum.wesnoth.org");
59 throw error(
"'Dropping your nickname is currently impossible");
70 hash = get_hash(name);
72 ERR_UH <<
"Could not retrieve hash for user '" << name <<
"' :" << e.message << std::endl;
78 ERR_UH <<
"Invalid hash for user '" << name <<
"'" << std::endl;
84 if(password == valid_hash)
return true;
92 if(!(user_exists(name))) {
99 hash = get_hash(name);
101 ERR_UH <<
"Could not retrieve hash for user '" << name <<
"' :" << e.message << std::endl;
107 return hash.substr(0,12);
111 set_lastlogin(name, time(
nullptr));
118 mysql_result
res = db_query(
"SELECT username FROM " + db_users_table_ +
" WHERE UPPER(username)=UPPER('" + name +
"')");
119 return mysql_fetch_row(res.get());
121 ERR_UH <<
"Could not execute test query for user '" << name <<
"' :" << e.message << std::endl;
129 int user_type = std::stoi(get_detail_for_user(name,
"user_type"));
130 return user_type != USER_INACTIVE && user_type != USER_IGNORE;
132 ERR_UH <<
"Could not retrieve user type for user '" << name <<
"' :" << e.message << std::endl;
139 if(!user_exists(name))
return false;
142 return get_writable_detail_for_user(name,
"user_is_moderator") ==
"1";
144 ERR_UH <<
"Could not query user_is_moderator for user '" << name <<
"' :" << e.message << std::endl;
152 if(!user_exists(name))
return;
155 write_detail(name,
"user_is_moderator", is_moderator ?
"1" :
"0");
157 ERR_UH <<
"Could not set is_moderator for user '" << name <<
"' :" << e.message << std::endl;
162 throw error(
"For now please use the password recovery "
163 "function provided at http://forum.wesnoth.org");
167 if(!user_exists(name)) {
168 throw error(
"No user with the name '" + name +
"' exists.");
171 time_t reg_date = get_registrationdate(name);
172 time_t ll_date = get_lastlogin(name);
178 ll_string = ctime(&ll_date);
180 ll_string =
"Never\n";
183 std::stringstream
info;
184 info <<
"Name: " << name <<
"\n"
185 <<
"Registered: " << reg_string
186 <<
"Last login: " << ll_string;
187 if(!user_is_active(name)) {
188 info <<
"This account is currently inactive.\n";
195 throw error(
"For now this is a 'read-only' user_handler");
199 return "For now this is a 'read-only' user_handler";
204 return get_detail_for_user(user,
"user_password");
206 ERR_UH <<
"Could not retrieve password for user '" << user <<
"' :" << e.message << std::endl;
213 return get_detail_for_user(user,
"user_email");
215 ERR_UH <<
"Could not retrieve email for user '" << user <<
"' :" << e.message << std::endl;
222 int time_int = std::stoi(get_writable_detail_for_user(user,
"user_lastvisit"));
223 return time_t(time_int);
225 ERR_UH <<
"Could not retrieve last visit for user '" << user <<
"' :" << e.message << std::endl;
232 int time_int = std::stoi(get_detail_for_user(user,
"user_regdate"));
233 return time_t(time_int);
235 ERR_UH <<
"Could not retrieve registration date for user '" << user <<
"' :" << e.message << std::endl;
242 std::stringstream ss;
246 write_detail(user,
"user_lastvisit", ss.str());
248 ERR_UH <<
"Could not set last visit for user '" << user <<
"' :" << e.message << std::endl;
253 if(mysql_query(conn, sql.c_str())) {
254 WRN_UH <<
"not connected to database, reconnecting..." << std::endl;
256 if(!mysql_real_connect(conn, db_host_.c_str(), db_user_.c_str(), db_password_.c_str(), db_name_.c_str(), 0,
nullptr, 0)
257 || mysql_query(conn, sql.c_str())) {
258 ERR_UH <<
"Could not connect to database: " << mysql_errno(conn) <<
": " << mysql_error(conn) << std::endl;
259 throw error(
"Error querying database.");
262 return mysql_result(mysql_store_result(conn), mysql_free_result);
266 mysql_result res = db_query(sql);
272 return db_query_to_string(
"SELECT " + detail +
" FROM " + db_users_table_ +
" WHERE UPPER(username)=UPPER('" + name +
"')");
276 if(!extra_row_exists(name))
return "";
277 return db_query_to_string(
"SELECT " + detail +
" FROM " + db_extra_table_ +
" WHERE UPPER(username)=UPPER('" + name +
"')");
283 if(!extra_row_exists(name)) {
285 db_query(
"INSERT INTO " + db_extra_table_ +
" VALUES('" + name +
"','" + value +
"','0')");
287 db_query(
"UPDATE " + db_extra_table_ +
" SET " + detail +
"='" + value +
"' WHERE UPPER(username)=UPPER('" + name +
"')");
289 ERR_UH <<
"Could not set detail for user '" << name <<
"': " << e.message << std::endl;
297 mysql_result res = db_query(
"SELECT username FROM " + db_extra_table_ +
" WHERE UPPER(username)=UPPER('" + name +
"')");
298 return mysql_fetch_row(res.get());
300 ERR_UH <<
"Could not execute test query for user '" << name <<
"' :" << e.message << std::endl;
305 #endif //HAVE_MYSQLPP
std::string get_hash(const std::string &user)
std::string db_query_to_string(const std::string &query)
void password_reminder(const std::string &name)
Send a password reminder email to the given user.
void set_user_detail(const std::string &user, const std::string &detail, const std::string &value)
Set data for a given user name.
std::string create_pepper(const std::string &name)
Needed because the hashing algorithm used by phpbb requires some info from the original hash to recre...
std::unique_ptr< MYSQL_RES, decltype(&mysql_free_result)> mysql_result
static l_noret error(LoadState *S, const char *why)
void user_logged_in(const std::string &name)
Executed when the user with the given name logged in.
void set_lastlogin(const std::string &user, const time_t &lastlogin)
void add_user(const std::string &name, const std::string &mail, const std::string &password)
Adds a user.
std::string user_info(const std::string &name)
Returns a string containing info like the last login of this user.
bool user_exists(const std::string &name)
Returns true if a user with the given name exists.
void set_is_moderator(const std::string &name, const bool &is_moderator)
Mark this user as a moderator.
mysql_result db_query(const std::string &query)
std::string create_hash(const std::string &password, const std::string &salt, int iteration_count)
bool extra_row_exists(const std::string &name)
std::string get_writable_detail_for_user(const std::string &name, const std::string &detail)
GLsizei const GLfloat * value
time_t get_lastlogin(const std::string &user)
bool is_valid_hash(const std::string &hash)
bool login(const std::string &name, const std::string &password, const std::string &seed)
Return true if the given password matches the password for the given user.
bool user_is_active(const std::string &name)
Returns true if the specified user account is usable for logins.
time_t get_registrationdate(const std::string &user)
bool user_is_moderator(const std::string &name)
Returns true if this user is a moderator on this server.
GLuint const GLchar * name
void write_detail(const std::string &name, const std::string &detail, const std::string &value)
std::string get_mail(const std::string &user)
Used in send_mail().
void remove_user(const std::string &name)
Removes a user.
A config object defines a single node in a WML file, with access to child nodes.
std::string get_valid_details()
List of details that can be set for this user_handler.
GLsizei const GLcharARB ** string
std::string get_detail_for_user(const std::string &name, const std::string &detail)