22 #include <boost/asio/post.hpp> 28 #define ERR_UH LOG_STREAM(err, log_mp_user_handler) 29 #define WRN_UH LOG_STREAM(warn, log_mp_user_handler) 30 #define LOG_UH LOG_STREAM(info, log_mp_user_handler) 31 #define DBG_UH LOG_STREAM(debug, log_mp_user_handler) 34 const int USER_INACTIVE = 1;
35 const int USER_IGNORE = 2;
40 , db_users_table_(c[
"db_users_table"].str())
41 , db_extra_table_(c[
"db_extra_table"].str())
45 mp_mod_group_ = std::stoi(c[
"mp_mod_group"].str());
47 ERR_UH <<
"Failed to convert the mp_mod_group value of '" << c[
"mp_mod_group"].str() <<
"' into an int! Defaulting to " << mp_mod_group_ <<
"." << std::endl;
56 hash = get_hash(name);
58 ERR_UH <<
"Could not retrieve hash for user '" << name <<
"' :" << e.message << std::endl;
62 std::string valid_hash;
65 valid_hash =
utils::md5(hash.substr(12,34), seed).base64_digest();
69 ERR_UH <<
"Invalid hash for user '" << name <<
"'" << std::endl;
73 if(password == valid_hash)
return true;
88 hash = get_hash(name);
89 }
catch (
const error& e) {
90 ERR_UH <<
"Could not retrieve hash for user '" << name <<
"' :" << e.message << std::endl;
95 return hash.substr(0,12);
101 ERR_UH <<
"Error getting salt from hash of user '" << name <<
"': " << err.
what() << std::endl;
110 conn_.write_user_int(
"user_lastvisit", name, static_cast<int>(std::time(
nullptr)));
114 return conn_.user_exists(name);
118 return conn_.get_forum_id(name);
122 int user_type = conn_.get_user_int(
db_users_table_,
"user_type", name);
123 return user_type != USER_INACTIVE && user_type != USER_IGNORE;
130 return conn_.get_user_int(
db_extra_table_,
"user_is_moderator", name) == 1 || (mp_mod_group_ != 0 && conn_.is_user_in_group(name, mp_mod_group_));
137 conn_.write_user_int(
"user_is_moderator", name, is_moderator);
148 LOG_UH <<
"User '" << name <<
"' ip " << addr <<
" banned by IP address\n";
151 LOG_UH <<
"User '" << name <<
"' uid " << b.
get_user_id() <<
" banned by uid\n";
154 LOG_UH <<
"User '" << name <<
"' email " << b.
get_email() <<
" banned by email address\n";
157 ERR_UH <<
"Invalid ban type '" << b.
get_ban_type() <<
"' returned for user '" << name <<
"'\n";
164 throw error(
"No user with the name '" + name +
"' exists.");
167 std::time_t reg_date = get_registrationdate(name);
168 std::time_t ll_date = get_lastlogin(name);
170 std::string reg_string = ctime(®_date);
171 std::string ll_string;
174 ll_string = ctime(&ll_date);
176 ll_string =
"Never\n";
179 std::stringstream
info;
180 info <<
"Name: " << name <<
"\n" 181 <<
"Registered: " << reg_string
182 <<
"Last login: " << ll_string;
183 if(!user_is_active(name)) {
184 info <<
"This account is currently inactive.\n";
195 return std::time_t(conn_.get_user_int(
db_extra_table_,
"user_lastvisit", user));
199 return std::time_t(conn_.get_user_int(
db_users_table_,
"user_regdate", user));
203 return conn_.get_uuid();
207 return conn_.get_tournaments();
211 boost::asio::post([
this, &s_base, player_socket, player_id, offset, &io_service] {
212 boost::asio::post(io_service, [player_socket, &s_base, doc = conn_.get_game_history(player_id, offset)]{
218 void fuh::db_insert_game_info(
const std::string& uuid,
int game_id,
const std::string& version,
const std::string& name,
int reload,
int observers,
int is_public,
int has_password){
219 conn_.insert_game_info(uuid, game_id, version, name, reload, observers, is_public, has_password);
223 conn_.update_game_end(uuid, game_id, replay_location);
226 void fuh::db_insert_game_player_info(
const std::string& uuid,
int game_id,
const std::string& username,
int side_number,
int is_host,
const std::string& faction,
const std::string& version,
const std::string& source,
const std::string& current_user){
227 conn_.insert_game_player_info(uuid, game_id, username, side_number, is_host, faction, version, source, current_user);
230 void fuh::db_insert_game_content_info(
const std::string& uuid,
int game_id,
const std::string&
type,
const std::string& name,
const std::string&
id,
const std::string& source,
const std::string& version){
231 conn_.insert_game_content_info(uuid, game_id, type, name,
id, source, version);
235 conn_.set_oos_flag(uuid, game_id);
239 boost::asio::post([
this, limit, &io_service] {
240 ERR_UH <<
"async test query starts!" << std::endl;
241 int i = conn_.async_test_query(limit);
242 boost::asio::post(io_service, [i]{ ERR_UH <<
"async test query output: " << i << std::endl; });
246 #endif //HAVE_MYSQLPP std::string get_hash(const std::string &user)
virtual std::string base64_digest() const override
static l_noret error(LoadState *S, const char *why)
static bool is_valid_prefix(const std::string &hash)
void user_logged_in(const std::string &name)
Sets the last login time to the current time.
std::time_t get_lastlogin(const std::string &user)
std::string user_info(const std::string &name)
void async_get_and_send_game_history(boost::asio::io_service &io_service, server_base &s_base, socket_ptr player_socket, int player_id, int offset)
Runs an asynchronous query to fetch the user's game history data.
bool user_exists(const std::string &name)
void set_is_moderator(const std::string &name, const bool &is_moderator)
Sets or unsets whether the player should be considered a moderator in the extra table.
fuh(const config &c)
Reads wesnothd's config for the data needed to initialize this class and dbconn.
long get_forum_id(const std::string &name)
static bool is_valid_hash(const std::string &hash)
ban_info user_is_banned(const std::string &name, const std::string &addr)
const char * what() const noexcept
std::string get_tournaments()
bool login(const std::string &name, const std::string &password, const std::string &seed)
Retrieves the player's hashed password from the phpbb forum database and checks if it matches the has...
void db_set_oos_flag(const std::string &uuid, int game_id)
Sets the OOS flag in the database if wesnothd is told by a client it has detected an OOS error...
bool user_exists(const std::string &name)
bool user_is_active(const std::string &name)
std::string password(const std::string &server, const std::string &login)
static bcrypt from_hash_string(const std::string &input)
std::time_t get_registrationdate(const std::string &user)
void async_send_doc_queued(socket_ptr socket, simple_wml::document &doc)
High level wrapper for sending a WML document.
bool user_is_moderator(const std::string &name)
void db_insert_game_info(const std::string &uuid, int game_id, const std::string &version, const std::string &name, int reload, int observers, int is_public, int has_password)
Inserts game related information.
std::string db_users_table_
The name of the table that contains forum user information.
void db_insert_game_content_info(const std::string &uuid, int game_id, const std::string &type, const std::string &name, const std::string &id, const std::string &source, const std::string &version)
Inserts information about the content being played.
std::shared_ptr< boost::asio::ip::tcp::socket > socket_ptr
std::string get_salt() const
A config object defines a single node in a WML file, with access to child nodes.
std::string extract_salt(const std::string &name)
Needed because the hashing algorithm used by phpbb requires some info from the original hash to recre...
void db_update_game_end(const std::string &uuid, int game_id, const std::string &replay_location)
Update the game related information when the game ends.
void async_test_query(boost::asio::io_service &io_service, int limit)
A simple test query for running a query asynchronously.
void db_insert_game_player_info(const std::string &uuid, int game_id, const std::string &username, int side_number, int is_host, const std::string &faction, const std::string &version, const std::string &source, const std::string ¤t_user)
Inserts player information per side.
std::string db_extra_table_
The name of the table that contains additional user information.