The Battle for Wesnoth  1.15.12+dev
forum_user_handler.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Thomas Baumhauer <thomas.baumhauer@NOSPAMgmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
18 #include "server/common/dbconn.hpp"
19 
20 #include <vector>
21 #include <memory>
22 #include <ctime>
23 
24 /**
25  * A class to handle the non-SQL logic for connecting to the phpbb forum database.
26  */
27 class fuh : public user_handler
28 {
29 public:
30  /**
31  * Reads wesnothd's config for the data needed to initialize this class and @ref dbconn.
32  */
33  fuh(const config& c);
34 
35  /**
36  * Retrieves the player's hashed password from the phpbb forum database and checks if it matches the hashed password sent by the client.
37  *
38  * @param name The username used to login.
39  * @param password The hashed password sent by the client.
40  * @param seed The nonce created for this login attempt.
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, const std::string& seed);
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_base The server instance the player is connected to.
129  * @param player_socket The socket use 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, server_base& s_base, socket_ptr player_socket, 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_hash(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 };
std::string get_hash(const std::string &user)
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)
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&#39;s game history data.
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:36
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.
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()
bool login(const std::string &name, const std::string &password, const std::string &seed)
Retrieves the player&#39;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...
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)
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.
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
Definition: server_base.hpp:43
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:39
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
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.
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.