The Battle for Wesnoth  1.17.0-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  * @see server::send_password_request().
41  * @return Whether the hashed password sent by the client matches the hash retrieved from the phpbb database.
42  */
43  bool login(const std::string& name, const std::string& password);
44 
45  /**
46  * Needed because the hashing algorithm used by phpbb requires some info
47  * from the original hash to recreate the same hash
48  *
49  * @return the salt, or an empty string if an error occurs.
50  */
51  std::string extract_salt(const std::string& name);
52 
53  /**
54  * Sets the last login time to the current time.
55  *
56  * @param name The player's username.
57  */
58  void user_logged_in(const std::string& name);
59 
60  /**
61  * @param name The player's username.
62  * @return Whether the player's username is exists in the forum database.
63  */
64  bool user_exists(const std::string& name);
65 
66  /**
67  * @param name The player's username.
68  * @return The phpbb USER_ID value created when the player registers on the forums.
69  * @note wesnothd allows the same player to login with multiple clients using the same username but with different case letters (ie: abc and ABC).
70  * This means that this value is not necessarily unique among all connected clients.
71  */
72  long get_forum_id(const std::string& name);
73 
74  /**
75  * @param name The player's username.
76  * @return Whether the username has been activated.
77  */
78  bool user_is_active(const std::string& name);
79 
80  /**
81  * @param name The player's username.
82  * @return Whether the user is a moderator or not.
83  * @note This can be either from the extra table or whether the player is a member of the MP Moderators groups.
84  */
85  bool user_is_moderator(const std::string& name);
86 
87  /**
88  * Sets or unsets whether the player should be considered a moderator in the extra table.
89  *
90  * @param name The player's username.
91  * @param is_moderator The moderator value to set.
92  */
93  void set_is_moderator(const std::string& name, const bool& is_moderator);
94 
95  /**
96  * @param name The player's username.
97  * @param addr The IP address being checked.
98  * @return Whether the user is banned, and if so then how long. See also @ref user_handler::ban_info().
99  * @note This checks for bans by username, the email associated to the username, and IP address.
100  * @note Glob IP and email address bans are NOT supported yet since they require a different kind of query that isn't supported
101  * by our prepared SQL statement API right now. However, they are basically never used on forums.wesnoth.org,
102  * so this shouldn't be a problem.
103  */
104  ban_info user_is_banned(const std::string& name, const std::string& addr);
105 
106  /**
107  * @param name The player's username.
108  * @return A string containing basic information about the player.
109  */
110  std::string user_info(const std::string& name);
111 
112  /**
113  * @return A unique UUID from the backing database.
114  */
115  std::string get_uuid();
116 
117  /**
118  * @return A list of active tournaments pulled from the Tournaments subforum.
119  */
120  std::string get_tournaments();
121 
122  /**
123  * Runs an asynchronous query to fetch the user's game history data.
124  * The result is then posted back to the main boost::asio thread to be sent to the requesting player.
125  *
126  * @param io_service The boost io_service to use to post the query results back to the main boost::asio thread.
127  * @param s The server instance the player is connected to.
128  * @param player The player iterator used to communicate with the player's client.
129  * @param player_id The forum ID of the player to get the game history for.
130  * @param offset Where to start returning rows to the client from the query results.
131  */
132  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);
133 
134  /**
135  * Inserts game related information.
136  *
137  * @param uuid The value returned by @ref get_uuid().
138  * @param game_id The game's db_id.
139  * @param version The version of wesnothd running this game.
140  * @param name The game's name as entered by the user.
141  * @param reload Whether this game was loaded from the save of a previous game.
142  * @param observers Whether observers are allowed.
143  * @param is_public Whether the game's replay will be publicly available.
144  * @param has_password Whether the game has a password.
145  */
146  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);
147 
148  /**
149  * Update the game related information when the game ends.
150  *
151  * @param uuid The value returned by @ref get_uuid().
152  * @param game_id The game's db_id.
153  * @param replay_location The location of the game's publicly available replay.
154  */
155  void db_update_game_end(const std::string& uuid, int game_id, const std::string& replay_location);
156 
157  /**
158  * Inserts player information per side.
159  *
160  * @param uuid The value returned by @ref get_uuid().
161  * @param game_id The game's db_id.
162  * @param username The username of the player who owns this side.
163  * @param side_number This side's side number.
164  * @param is_host Whether this player is the host.
165  * @param faction The name of this side's faction.
166  * @param version The version of Wesnoth this player is using.
167  * @param source The source where this player downloaded Wesnoth (ie: Steam, SourceForge, etc).
168  * @param current_user The player currently in control of this side.
169  */
170  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);
171 
172  /**
173  * Inserts information about the content being played.
174  *
175  * @param uuid The value returned by @ref get_uuid().
176  * @param game_id The game's db_id.
177  * @param type The add-on content's type (ie: era, scenario, etc).
178  * @param name The name of the content.
179  * @param id The id of the content.
180  * @param source The source add-on for the content.
181  * @param version The version of the source add-on.
182  */
183  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);
184 
185  /**
186  * Sets the OOS flag in the database if wesnothd is told by a client it has detected an OOS error.
187  *
188  * @param uuid The value returned by @ref get_uuid().
189  * @param game_id The game's db_id.
190  */
191  void db_set_oos_flag(const std::string& uuid, int game_id);
192 
193  /**
194  * A simple test query for running a query asynchronously.
195  * 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.
196  *
197  * @param io_service The boost io_service to use to post the query results back to the main boost::asio thread.
198  * @param limit How many recursions to make in the query.
199  */
200  void async_test_query(boost::asio::io_service& io_service, int limit);
201 
202  /**
203  * Checks whether a forum thread with @a topic_id exists.
204  *
205  * @param topic_id The topic id to check for.
206  * @return True if the thread exists or there was a database failure, false if the topic wasn't found.
207  */
208  bool db_topic_id_exists(int topic_id);
209 
210  /**
211  * Inserts information about an uploaded add-on into the database.
212  *
213  * @param instance_version The version of campaignd the add-on was uploaded to.
214  * @param id The add-on's ID (aka directory name).
215  * @param name The add-on's name from the pbl.
216  * @param type The add-on's type from the pbl.
217  * @param version The add-on's version from the pbl.
218  * @param forum_auth Whether the provided author and password should be matched a forum account or not.
219  * @param topic_id The forum topic ID of the add-on's feedback thread, 0 if not present.
220  */
221  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);
222 
223  /**
224  * Inserts into the database for when a player logs in.
225  *
226  * @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.
227  * @param ip The ip address of who logged in.
228  * @param version The version of the client that logged in.
229  */
230  unsigned long long db_insert_login(const std::string& username, const std::string& ip, const std::string& version);
231 
232  /**
233  * Updates the database for when a player logs out.
234  *
235  * @param login_id The generated ID that uniquely identifies the row to be updated.
236  */
237  void db_update_logout(unsigned long long login_id);
238 
239  /**
240  * Searches for all players that logged in using the ip address.
241  * The '%' wildcard can be used to search for partial ip addresses.
242  *
243  * @param ip The ip address to search for.
244  * @param out Where to output the results.
245  */
246  void get_users_for_ip(const std::string& ip, std::ostringstream* out);
247 
248  /**
249  * Searches for all ip addresses used by the player.
250  * The username is converted to lower case to allow a case insensitive select query to be executed while still using an index.
251  * The '%' wildcard can be used to search for partial usernames.
252  *
253  * @param username The username to search for.
254  * @param out Where to output the results.
255  */
256  void get_ips_for_user(const std::string& username, std::ostringstream* out);
257 
258 private:
259  /** An instance of the class responsible for executing the queries and handling the database connection. */
261  /** The name of the phpbb users table */
262  std::string db_users_table_;
263  /** The name of the extras custom table, not part of a phpbb database */
264  std::string db_extra_table_;
265  /** The group ID of the forums MP Moderators group */
267 
268  /**
269  * @param user The player's username.
270  * @return The player's hashed password from the phpbb forum database.
271  */
272  std::string get_hashed_password_from_db(const std::string& user);
273 
274  /**
275  * @param user The player's username.
276  * @return The player's last login time.
277  */
278  std::time_t get_lastlogin(const std::string& user);
279 
280  /**
281  * @param user The player's username.
282  * @return The player's forum registration date.
283  */
284  std::time_t get_registrationdate(const std::string& user);
285 
286  /**
287  * @param name The player's username.
288  * @param group_id The forum group ID to check if the user is part of.
289  * @return Whether the user is a member of the forum group.
290  */
291  bool is_user_in_group(const std::string& name, int group_id);
292 };
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:36
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: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.
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.