diff --git a/doc/man/wesnothd.6 b/doc/man/wesnothd.6 index c076b0aa9cc..d12be691852 100644 --- a/doc/man/wesnothd.6 +++ b/doc/man/wesnothd.6 @@ -252,6 +252,12 @@ section is present in the configuration the server will run without any nick reg .B db_game_modification_info_table (for user_handler=forum) The name of the table in which wesnothd will save its own data about the modifications used in a game. .TP +.B db_group_table +(for user_handler=forum) The name of the table in which your phpbb forums saves its user group data. Most likely this will be _user_group (e.g. phpbb3_user_group). +.TP +.B mp_mod_group +(for user_handler=forum) The ID of the forum group to be considered as having moderation authority. +.TP .B user_expiration (for user_handler=sample) The time after which a registered nick expires (in days). .RE @@ -297,3 +303,4 @@ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR P .SH SEE ALSO . .BR wesnoth (6) + diff --git a/src/server/forum_user_handler.cpp b/src/server/forum_user_handler.cpp index ce55b9c97f1..33791f1282b 100644 --- a/src/server/forum_user_handler.cpp +++ b/src/server/forum_user_handler.cpp @@ -45,6 +45,8 @@ fuh::fuh(const config& c) , db_game_info_table_(c["db_game_info_table"].str()) , db_game_player_info_table_(c["db_game_player_info_table"].str()) , db_game_modification_info_table_(c["db_game_modification_info_table"].str()) + , db_group_table_(c["db_group_table"].str()) + , mp_mod_group_(std::stoi(c["mp_mod_group"])) , conn(mysql_init(nullptr)) { mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8mb4"); @@ -157,9 +159,9 @@ bool fuh::user_is_moderator(const std::string& name) { if(!user_exists(name)) return false; try { - return get_writable_detail_for_user(name, "user_is_moderator") == 1; + return get_writable_detail_for_user(name, "user_is_moderator") == 1 || is_user_in_group(name, mp_mod_group_); } catch (const sql_error& e) { - ERR_UH << "Could not query user_is_moderator for user '" << name << "' :" << e.message << std::endl; + ERR_UH << "Could not query user_is_moderator/MP Moderators group for user '" << name << "' :" << e.message << std::endl; // If the database is down mark nobody as a mod return false; } @@ -406,6 +408,15 @@ void fuh::write_detail(const std::string& name, const std::string& detail, T&& v } } +bool fuh::is_user_in_group(const std::string& name, unsigned int group_id) { + try { + return prepared_statement("SELECT 1 FROM `" + db_users_table_ + "` u, `" + db_group_table_ + "` ug WHERE UPPER(u.username)=UPPER(?) AND u.USER_ID = ug.USER_ID AND ug.GROUP_ID = ?", name, group_id); + } catch (const sql_error& e) { + ERR_UH << "Could not execute test query for user group '" << group_id << "' and username '" << name << "'" << e.message << std::endl; + return false; + } +} + bool fuh::extra_row_exists(const std::string& name) { // Make a test query for this username @@ -428,7 +439,7 @@ std::string fuh::get_uuid(){ void fuh::db_insert_game_info(const std::string& uuid, int game_id, const std::string& version, const std::string& name){ try { - prepared_statement("insert into `" + db_game_info_table_ + "`(INSTANCE_UUID, GAME_ID, INSTANCE_VERSION, GAME_NAME) values(?, ?, ?, ?)", + prepared_statement("INSERT INTO `" + db_game_info_table_ + "`(INSTANCE_UUID, GAME_ID, INSTANCE_VERSION, GAME_NAME) VALUES(?, ?, ?, ?)", uuid, game_id, version, name); } catch (const sql_error& e) { ERR_UH << "Could not insert into table `" + db_game_info_table_ + "`:" << e.message << std::endl; @@ -437,7 +448,7 @@ void fuh::db_insert_game_info(const std::string& uuid, int game_id, const std::s void fuh::db_update_game_start(const std::string& uuid, int game_id, const std::string& map_name, const std::string& era_name){ try { - prepared_statement("update `" + db_game_info_table_ + "` set START_TIME = CURRENT_TIMESTAMP, MAP_NAME = ?, ERA_NAME = ? where INSTANCE_UUID = ? and GAME_ID = ?", + prepared_statement("UPDATE `" + db_game_info_table_ + "` SET START_TIME = CURRENT_TIMESTAMP, MAP_NAME = ?, ERA_NAME = ? WHERE INSTANCE_UUID = ? AND GAME_ID = ?", map_name, era_name, uuid, game_id); } catch (const sql_error& e) { ERR_UH << "Could not update the game's starting information on table `" + db_game_info_table_ + "`:" << e.message << std::endl; @@ -446,7 +457,7 @@ void fuh::db_update_game_start(const std::string& uuid, int game_id, const std:: void fuh::db_update_game_end(const std::string& uuid, int game_id, const std::string& replay_location){ try { - prepared_statement("update `" + db_game_info_table_ + "` set END_TIME = CURRENT_TIMESTAMP, REPLAY_NAME = ? where INSTANCE_UUID = ? and GAME_ID = ?", + prepared_statement("UPDATE `" + db_game_info_table_ + "` SET END_TIME = CURRENT_TIMESTAMP, REPLAY_NAME = ? WHERE INSTANCE_UUID = ? AND GAME_ID = ?", replay_location, uuid, game_id); } catch (const sql_error& e) { ERR_UH << "Could not update the game's ending information on table `" + db_game_info_table_ + "`:" << e.message << std::endl; @@ -455,7 +466,7 @@ void fuh::db_update_game_end(const std::string& uuid, int game_id, const std::st void fuh::db_insert_game_player_info(const std::string& uuid, int game_id, const std::string& username, int side_number, const std::string& is_host, const std::string& faction){ try { - prepared_statement("insert into `" + db_game_player_info_table_ + "`(INSTANCE_UUID, GAME_ID, USER_ID, SIDE_NUMBER, IS_HOST, FACTION) values(?, ?, IFNULL((select user_id from `"+db_users_table_+"` where username = ?), -1), ?, ?, ?)", + prepared_statement("INSERT INTO `" + db_game_player_info_table_ + "`(INSTANCE_UUID, GAME_ID, USER_ID, SIDE_NUMBER, IS_HOST, FACTION) VALUES(?, ?, IFNULL((SELECT user_id FROM `"+db_users_table_+"` WHERE username = ?), -1), ?, ?, ?)", uuid, game_id, username, side_number, is_host, faction); } catch (const sql_error& e) { ERR_UH << "Could not insert the game's player information on table `" + db_game_player_info_table_ + "`:" << e.message << std::endl; @@ -464,7 +475,7 @@ void fuh::db_insert_game_player_info(const std::string& uuid, int game_id, const void fuh::db_insert_modification_info(const std::string& uuid, int game_id, const std::string& modification_name){ try { - prepared_statement("insert into `" + db_game_modification_info_table_ + "`(INSTANCE_UUID, GAME_ID, MODIFICATION_NAME) values(?, ?, ?)", + prepared_statement("INSERT INTO `" + db_game_modification_info_table_ + "`(INSTANCE_UUID, GAME_ID, MODIFICATION_NAME) VALUES(?, ?, ?)", uuid, game_id, modification_name); } catch (const sql_error& e) { ERR_UH << "Could not insert the game's modification information on table `" + db_game_modification_info_table_ + "`:" << e.message << std::endl; diff --git a/src/server/forum_user_handler.hpp b/src/server/forum_user_handler.hpp index 66d116cf201..edfda375570 100644 --- a/src/server/forum_user_handler.hpp +++ b/src/server/forum_user_handler.hpp @@ -105,7 +105,8 @@ class fuh : public user_handler { std::time_t retrieve_ban_duration_internal(const std::string& col, const std::string& detail); std::time_t retrieve_ban_duration_internal(const std::string& col, unsigned int detail); - std::string db_name_, db_host_, db_user_, db_password_, db_users_table_, db_banlist_table_, db_extra_table_, db_game_info_table_, db_game_player_info_table_, db_game_modification_info_table_; + std::string db_name_, db_host_, db_user_, db_password_, db_users_table_, db_banlist_table_, db_extra_table_, db_game_info_table_, db_game_player_info_table_, db_game_modification_info_table_, db_group_table_; + unsigned int mp_mod_group_; MYSQL *conn; @@ -123,4 +124,7 @@ class fuh : public user_handler { // Same as user_exists() but checks if we have a row for this user in the extra table bool extra_row_exists(const std::string& name); + + bool is_user_in_group(const std::string& name, unsigned int group_id); }; + diff --git a/utils/mp-server/table_definitions.sql b/utils/mp-server/table_definitions.sql index 660fa5fdbc0..62681b0487b 100644 --- a/utils/mp-server/table_definitions.sql +++ b/utils/mp-server/table_definitions.sql @@ -10,6 +10,14 @@ -- KEY user_type (user_type) -- ) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +-- a minimal groups table, if not using a phpbb3 installation +-- CREATE TABLE user_groups +-- ( +-- group_id mediumint(8) unsigned NOT NULL, +-- user_id mediumint(8) unsigned NOT NULL, +-- PRIMARY KEY (user_id, group_id) +-- ) ENGINE=InnoDB; + -- table which the forum inserts bans into, which wesnothd checks during login -- CREATE TABLE ban -- (