The Battle for Wesnoth  1.17.0-dev
forum_user_handler.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
3  by Thomas Baumhauer <thomas.baumhauer@NOSPAMgmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
19 #include "server/common/dbconn.hpp"
20 
21 #include <vector>
22 #include <memory>
23 #include <ctime>
24 
25 /**
26  * A class to handle the non-SQL logic for connecting to the phpbb forum database.
27  */
28 class fuh : public user_handler
29 {
30 public:
31  /**
32  * Reads wesnothd's config for the data needed to initialize this class and @ref dbconn.
33  */
34  fuh(const config& c);
35 
36  /**
37  * Retrieves the player's hashed password from the phpbb forum database and checks if it matches the hashed password sent by the client.
38  *
39  * @param name The username used to login.
40  * @param password The hashed password sent by the client.
41  * @see server::send_password_request().
42  * @return Whether the hashed password sent by the client matches the hash retrieved from the phpbb database.
43  */
44  bool login(const std::string& name, const std::string& password);
45 
46  /**
47  * Needed because the hashing algorithm used by phpbb requires some info
48  * from the original hash to recreate the same hash
49  *
50  * @return the salt, or an empty string if an error occurs.
51  */
52  std::string extract_salt(const std::string& name);
53 
54  /**
55  * Sets the last login time to the current time.
56  *
57  * @param name The player's username.
58  */
59  void user_logged_in(const std::string& name);
60 
61  /**
62  * @param name The player's username.
63  * @return Whether the player's username is exists in the forum database.
64  */
65  bool user_exists(const std::string& name);
66 
67  /**
68  * @param name The player's username.
69  * @return The phpbb USER_ID value created when the player registers on the forums.
70  * @note wesnothd allows the same player to login with multiple clients using the same username but with different case letters (ie: abc and ABC).
71  * This means that this value is not necessarily unique among all connected clients.
72  */
73  long get_forum_id(const std::string& name);
74 
75  /**
76  * @param name The player's username.
77  * @return Whether the username has been activated.
78  */
79  bool user_is_active(const std::string& name);
80 
81  /**
82  * @param name The player's username.
83  * @return Whether the user is a moderator or not.
84  * @note This can be either from the extra table or whether the player is a member of the MP Moderators groups.
85  */
86  bool user_is_moderator(const std::string& name);
87 
88  /**
89  * Sets or unsets whether the player should be considered a moderator in the extra table.
90  *
91  * @param name The player's username.
92  * @param is_moderator The moderator value to set.
93  */
94  void set_is_moderator(const std::string& name, const bool& is_moderator);
95 
96  /**
97  * @param name The player's username.
98  * @param addr The IP address being checked.
99  * @return Whether the user is banned, and if so then how long. See also @ref user_handler::ban_info().
100  * @note This checks for bans by username, the email associated to the username, and IP address.
101  * @note Glob IP and email address bans are NOT supported yet since they require a different kind of query that isn't supported
102  * by our prepared SQL statement API right now. However, they are basically never used on forums.wesnoth.org,
103  * so this shouldn't be a problem.
104  */
105  ban_info user_is_banned(const std::string& name, const std::string& addr);
106 
107  /**
108  * @param name The player's username.
109  * @return A string containing basic information about the player.
110  */
111  std::string user_info(const std::string& name);
112 
113  /**
114  * @return A unique UUID from the backing database.
115  */
116  std::string get_uuid();
117 
118  /**
119  * @return A list of active tournaments pulled from the Tournaments subforum.
120  */
121  std::string get_tournaments();
122 
123  /**
124  * Runs an asynchronous query to fetch the user's game history data.
125  * The result is then posted back to the main boost::asio thread to be sent to the requesting player.
126  *
127  * @param io_service The boost io_service to use to post the query results back to the main boost::asio thread.
128  * @param s The server instance the player is connected to.
129  * @param player The player iterator used to communicate with the player's client.
130  * @param player_id The forum ID of the player to get the game history for.
131  * @param offset Where to start returning rows to the client from the query results.
132  */
133  void async_get_and_send_game_history(boost::asio::io_service& io_service, wesnothd::server& s, wesnothd::player_iterator player, int player_id, int offset);
134 
135  /**
136  * Inserts game related information.
137  *
138  * @param uuid The value returned by @ref get_uuid().
139  * @param game_id The game's db_id.
140  * @param version The version of wesnothd running this game.
141  * @param name The game's name as entered by the user.
142  * @param reload Whether this game was loaded from the save of a previous game.
143  * @param observers Whether observers are allowed.
144  * @param is_public Whether the game's replay will be publicly available.
145  * @param has_password Whether the game has a password.
146  */
147  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);
148 
149  /**
150  * Update the game related information when the game ends.
151  *
152  * @param uuid The value returned by @ref get_uuid().
153  * @param game_id The game's db_id.
154  * @param replay_location The location of the game's publicly available replay.
155  */
156  void db_update_game_end(const std::string& uuid, int game_id, const std::string& replay_location);
157 
158  /**
159  * Inserts player information per side.
160  *
161  * @param uuid The value returned by @ref get_uuid().
162  * @param game_id The game's db_id.
163  * @param username The username of the player who owns this side.
164  * @param side_number This side's side number.
165  * @param is_host Whether this player is the host.
166  * @param faction The name of this side's faction.
167  * @param version The version of Wesnoth this player is using.
168  * @param source The source where this player downloaded Wesnoth (ie: Steam, SourceForge, etc).
169  * @param current_user The player currently in control of this side.
170  */
171  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& current_user);
172 
173  /**
174  * Inserts information about the content being played.
175  *
176  * @param uuid The value returned by @ref get_uuid().
177  * @param game_id The game's db_id.
178  * @param type The add-on content's type (ie: era, scenario, etc).
179  * @param name The name of the content.
180  * @param id The id of the content.
181  * @param source The source add-on for the content.
182  * @param version The version of the source add-on.
183  */
184  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);
185 
186  /**
187  * Sets the OOS flag in the database if wesnothd is told by a client it has detected an OOS error.
188  *
189  * @param uuid The value returned by @ref get_uuid().
190  * @param game_id The game's db_id.
191  */
192  void db_set_oos_flag(const std::string& uuid, int game_id);
193 
194  /**
195  * A simple test query for running a query asynchronously.
196  * The main point is that it takes a meaningful amount of time to complete so that it's easy to see that multiple are running at once and are finishing out of order.
197  *
198  * @param io_service The boost io_service to use to post the query results back to the main boost::asio thread.
199  * @param limit How many recursions to make in the query.
200  */
201  void async_test_query(boost::asio::io_service& io_service, int limit);
202 
203  /**
204  * Checks whether a forum thread with @a topic_id exists.
205  *
206  * @param topic_id The topic id to check for.
207  * @return True if the thread exists or there was a database failure, false if the topic wasn't found.
208  */
209  bool db_topic_id_exists(int topic_id);
210 
211  /**
212  * Inserts information about an uploaded add-on into the database.
213  *
214  * @param instance_version The version of campaignd the add-on was uploaded to.
215  * @param id The add-on's ID (aka directory name).
216  * @param name The add-on's name from the pbl.
217  * @param type The add-on's type from the pbl.
218  * @param version The add-on's version from the pbl.
219  * @param forum_auth Whether the provided author and password should be matched a forum account or not.
220  * @param topic_id The forum topic ID of the add-on's feedback thread, 0 if not present.
221  */
222  void db_insert_addon_info(const std::string& instance_version, const std::string& id, const std::string& name, const std::string& type, const std::string& version, bool forum_auth, int topic_id);
223 
224  /**
225  * Inserts into the database for when a player logs in.
226  *
227  * @param username The username of who logged in. The username is converted to lower case when inserting in order to allow index usage when querying.
228  * @param ip The ip address of who logged in.
229  * @param version The version of the client that logged in.
230  */
231  unsigned long long db_insert_login(const std::string& username, const std::string& ip, const std::string& version);
232 
233  /**
234  * Updates the database for when a player logs out.
235  *
236  * @param login_id The generated ID that uniquely identifies the row to be updated.
237  */
238  void db_update_logout(unsigned long long login_id);
239 
240  /**
241  * Searches for all players that logged in using the ip address.
242  * The '%' wildcard can be used to search for partial ip addresses.
243  *
244  * @param ip The ip address to search for.
245  * @param out Where to output the results.
246  */
247  void get_users_for_ip(const std::string& ip, std::ostringstream* out);
248 
249  /**
250  * Searches for all ip addresses used by the player.
251  * The username is converted to lower case to allow a case insensitive select query to be executed while still using an index.
252  * The '%' wildcard can be used to search for partial usernames.
253  *
254  * @param username The username to search for.
255  * @param out Where to output the results.
256  */
257  void get_ips_for_user(const std::string& username, std::ostringstream* out);
258 
259 private:
260  /** An instance of the class responsible for executing the queries and handling the database connection. */
262  /** The name of the phpbb users table */
263  std::string db_users_table_;
264  /** The name of the extras custom table, not part of a phpbb database */
265  std::string db_extra_table_;
266  /** The group ID of the forums MP Moderators group */
268 
269  /**
270  * @param user The player's username.
271  * @return The player's hashed password from the phpbb forum database.
272  */
273  std::string get_hashed_password_from_db(const std::string& user);
274 
275  /**
276  * @param user The player's username.
277  * @return The player's last login time.
278  */
279  std::time_t get_lastlogin(const std::string& user);
280 
281  /**
282  * @param user The player's username.
283  * @return The player's forum registration date.
284  */
285  std::time_t get_registrationdate(const std::string& user);
286 
287  /**
288  * @param name The player's username.
289  * @param group_id The forum group ID to check if the user is part of.
290  * @return Whether the user is a member of the forum group.
291  */
292  bool is_user_in_group(const std::string& name, int group_id);
293 };
unsigned long long db_insert_login(const std::string &username, const std::string &ip, const std::string &version)
Inserts into the database for when a player logs in.
std::string get_uuid()
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)
bool user_exists(const std::string &name)
This class is responsible for handling the database connections as well as executing queries and hand...
Definition: dbconn.hpp:37
player_connections::const_iterator player_iterator
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&#39;s config for the data needed to initialize this class and dbconn.
void async_get_and_send_game_history(boost::asio::io_service &io_service, wesnothd::server &s, wesnothd::player_iterator player, int player_id, int offset)
Runs an asynchronous query to fetch the user&#39;s game history data.
long get_forum_id(const std::string &name)
void db_insert_addon_info(const std::string &instance_version, const std::string &id, const std::string &name, const std::string &type, const std::string &version, bool forum_auth, int topic_id)
Inserts information about an uploaded add-on into the database.
dbconn conn_
An instance of the class responsible for executing the queries and handling the database connection...
A class to handle the non-SQL logic for connecting to the phpbb forum database.
ban_info user_is_banned(const std::string &name, const std::string &addr)
bool db_topic_id_exists(int topic_id)
Checks whether a forum thread with topic_id exists.
An interface class to handle nick registration To activate it put a [user_handler] section into the s...
std::string get_tournaments()
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...
std::string db_extra_table_
The name of the extras custom table, not part of a phpbb database.
bool user_is_active(const std::string &name)
static map_location::DIRECTION s
int mp_mod_group_
The group ID of the forums MP Moderators group.
Ban status description.
std::string password(const std::string &server, const std::string &login)
std::time_t get_registrationdate(const std::string &user)
std::string db_users_table_
The name of the phpbb users table.
bool is_user_in_group(const std::string &name, int group_id)
bool user_is_moderator(const std::string &name)
void db_update_logout(unsigned long long login_id)
Updates the database for when a player logs out.
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 get_hashed_password_from_db(const std::string &user)
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.
void get_users_for_ip(const std::string &ip, std::ostringstream *out)
Searches for all players that logged in using the ip address.
int side_number
Definition: game_info.hpp:40
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
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...
mock_char c
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.
bool login(const std::string &name, const std::string &password)
Retrieves the player&#39;s hashed password from the phpbb forum database and checks if it matches the has...
void async_test_query(boost::asio::io_service &io_service, int limit)
A simple test query for running a query asynchronously.
void get_ips_for_user(const std::string &username, std::ostringstream *out)
Searches for all ip addresses used by the player.
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 &current_user)
Inserts player information per side.