mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-18 00:21:12 +00:00
Add ability to allow secondary authors to upload an add-on. (#7268)
* Add ability to allow secondary authors to upload an add-on. The secondary_authors attribute is a comma-delimited list of forum accounts that can also upload updates to an add-on. Secondary authors can't change the primary/secondary authors and can't delete the add-on. The primary author can also make someone else the primary author by: * Putting their username in the secondary_authors attribute * Putting someone else's username in the author attribute * Uploading the add-on while selecting themselves This works since they are still (until the upload is done) the primary author in the database, so they are allowed to change the authors list, including in this case.
This commit is contained in:
parent
e7e6649377
commit
3d7d5dbdbf
@ -54,6 +54,34 @@
|
||||
horizontal_grow = true
|
||||
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
grow_factor = 0
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[label]
|
||||
definition = "default"
|
||||
label = _ "Username:"
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[menu_button]
|
||||
id = "choose_uploader"
|
||||
definition = "default"
|
||||
[/menu_button]
|
||||
|
||||
[/column]
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
@ -300,12 +300,13 @@ bool addons_client::delete_remote_addon(const std::string& id, std::string& resp
|
||||
|
||||
request_body["name"] = id;
|
||||
request_body["passphrase"] = cfg["passphrase"];
|
||||
// needed in case of forum_auth authentication since the author stored on disk on the server is not necessarily the current primary author
|
||||
request_body["uploader"] = cfg["uploader"];
|
||||
|
||||
LOG_ADDONS << "requesting server to delete " << id;
|
||||
|
||||
send_request(request_buf, response_buf);
|
||||
wait_for_transfer_done(VGETTEXT("Removing add-on <i>$addon_title</i> from the server...", i18n_symbols
|
||||
));
|
||||
wait_for_transfer_done(VGETTEXT("Removing add-on <i>$addon_title</i> from the server...", i18n_symbols));
|
||||
|
||||
if(const config& message_cfg = response_buf.child("message")) {
|
||||
response_message = message_cfg["message"].str();
|
||||
|
@ -19,9 +19,11 @@
|
||||
#include "gui/dialogs/addon/addon_auth.hpp"
|
||||
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
#include "gui/widgets/menu_button.hpp"
|
||||
#include "gui/widgets/password_box.hpp"
|
||||
#include "gui/widgets/window.hpp"
|
||||
#include "preferences/credentials.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
||||
namespace gui2::dialogs
|
||||
{
|
||||
@ -42,6 +44,14 @@ void addon_auth::pre_show(window& win)
|
||||
text_box* pwd = find_widget<text_box>(&win, "password", false, true);
|
||||
win.add_to_tab_order(pwd);
|
||||
pwd->set_value(cfg_["passphrase"].str(""));
|
||||
|
||||
std::vector<config> content_list;
|
||||
content_list.emplace_back("label", cfg_["author"].str(""));
|
||||
|
||||
for(const auto& author : utils::split(cfg_["secondary_authors"].str(""), ',')) {
|
||||
content_list.emplace_back("label", author);
|
||||
}
|
||||
find_widget<menu_button>(&win, "choose_uploader", false).set_values(content_list);
|
||||
}
|
||||
|
||||
void addon_auth::post_show(window& win)
|
||||
@ -49,6 +59,7 @@ void addon_auth::post_show(window& win)
|
||||
if(get_retval() == gui2::retval::OK)
|
||||
{
|
||||
cfg_["passphrase"] = find_widget<password_box>(&win, "password", false).get_real_value();
|
||||
cfg_["uploader"] = find_widget<menu_button>(&win, "choose_uploader", false).get_value_string();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -895,6 +895,10 @@ void server::delete_addon(const std::string& id)
|
||||
{
|
||||
config& cfg = get_addon(id);
|
||||
|
||||
if(cfg["forum_auth"].to_bool()) {
|
||||
user_handler_->db_delete_addon_authors(server_id_, cfg["name"].str());
|
||||
}
|
||||
|
||||
if(!cfg) {
|
||||
ERR_CS << "Cannot delete unrecognized add-on '" << id << "'";
|
||||
return;
|
||||
@ -1317,12 +1321,19 @@ ADDON_CHECK_STATUS server::validate_addon(const server::request& req, config*& e
|
||||
LOG_CS << "Validation error: client requested forum authentication but server does not support it";
|
||||
return ADDON_CHECK_STATUS::SERVER_FORUM_AUTH_DISABLED;
|
||||
} else {
|
||||
if(!user_handler_->user_exists(upload["author"].str())) {
|
||||
if(!user_handler_->user_exists(upload["uploader"].str())) {
|
||||
LOG_CS << "Validation error: forum auth requested for an author who doesn't exist";
|
||||
return ADDON_CHECK_STATUS::USER_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if(!authenticate_forum(upload, upload["passphrase"].str())) {
|
||||
for(const std::string& secondary_author : utils::split(upload["secondary_authors"].str(), ',')) {
|
||||
if(!user_handler_->user_exists(secondary_author)) {
|
||||
LOG_CS << "Validation error: forum auth requested for a secondary author who doesn't exist";
|
||||
return ADDON_CHECK_STATUS::USER_DOES_NOT_EXIST;
|
||||
}
|
||||
}
|
||||
|
||||
if(!authenticate_forum(upload, upload["passphrase"].str(), false)) {
|
||||
LOG_CS << "Validation error: forum passphrase does not match";
|
||||
return ADDON_CHECK_STATUS::UNAUTHORIZED;
|
||||
}
|
||||
@ -1499,7 +1510,7 @@ void server::handle_upload(const server::request& req)
|
||||
// Write general metadata attributes
|
||||
|
||||
addon.copy_or_remove_attributes(upload,
|
||||
"title", "name", "author", "description", "version", "icon",
|
||||
"title", "name", "uploader", "author", "secondary_authors", "description", "version", "icon",
|
||||
"translate", "dependencies", "core", "type", "tags", "email", "forum_auth"
|
||||
);
|
||||
|
||||
@ -1528,9 +1539,23 @@ void server::handle_upload(const server::request& req)
|
||||
|
||||
if(user_handler_) {
|
||||
if(addon["forum_auth"].to_bool()) {
|
||||
addon["email"] = user_handler_->get_user_email(upload["author"].str());
|
||||
addon["email"] = user_handler_->get_user_email(upload["uploader"].str());
|
||||
|
||||
// if no author information exists, insert data since that of course means no primary author can be found
|
||||
// or if the author is the primary uploader, replace the author information
|
||||
bool do_authors_exist = user_handler_->db_do_any_authors_exist(server_id_, name);
|
||||
bool is_primary = user_handler_->db_is_user_primary_author(server_id_, name, upload["uploader"].str());
|
||||
if(!do_authors_exist || is_primary) {
|
||||
user_handler_->db_delete_addon_authors(server_id_, name);
|
||||
// author instead of uploader here is intentional, since this allows changing the primary author
|
||||
// if p1 is primary, p2 is secondary, and p1 uploads, then uploader and author are p1 while p2 is a secondary author
|
||||
// if p1 is primary, p2 is secondary, and p2 uploads, then this is skipped because the uploader is not the primary author
|
||||
// if next time p2 is primary, p1 is secondary, and p1 uploads, then p1 is both uploader and secondary author
|
||||
// therefore p2's author information would not be reinserted if the uploader attribute were used instead
|
||||
user_handler_->db_insert_addon_authors(server_id_, name, addon["author"].str(), utils::split(addon["secondary_authors"].str(), ','));
|
||||
}
|
||||
}
|
||||
user_handler_->db_insert_addon_info(server_id_, name, addon["title"].str(), addon["type"].str(), addon["version"].str(), addon["forum_auth"].to_bool(), topic_id);
|
||||
user_handler_->db_insert_addon_info(server_id_, name, addon["title"].str(), addon["type"].str(), addon["version"].str(), addon["forum_auth"].to_bool(), topic_id, upload["uploader"].str());
|
||||
}
|
||||
|
||||
// Copy in any metadata translations provided directly in the .pbl.
|
||||
@ -1824,6 +1849,7 @@ void server::handle_delete(const server::request& req)
|
||||
LOG_CS << req << "Deleting add-on '" << id << "'";
|
||||
|
||||
config& addon = get_addon(id);
|
||||
PLAIN_LOG << erase.debug() << "\n\n" << addon.debug();
|
||||
|
||||
if(!addon) {
|
||||
send_error("The add-on does not exist.", req.sock);
|
||||
@ -1843,7 +1869,7 @@ void server::handle_delete(const server::request& req)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(!authenticate_forum(addon, pass)) {
|
||||
if(!authenticate_forum(erase, pass, true)) {
|
||||
send_error("The passphrase is incorrect.", req.sock);
|
||||
return;
|
||||
}
|
||||
@ -1891,14 +1917,28 @@ void server::handle_change_passphrase(const server::request& req)
|
||||
}
|
||||
}
|
||||
|
||||
bool server::authenticate_forum(const config& addon, const std::string& passphrase) {
|
||||
bool server::authenticate_forum(const config& addon, const std::string& passphrase, bool is_delete) {
|
||||
if(!user_handler_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string author = addon["author"].str();
|
||||
std::string uploader = addon["uploader"].str();
|
||||
std::string id = addon["name"].str();
|
||||
bool do_authors_exist = user_handler_->db_do_any_authors_exist(server_id_, id);
|
||||
bool is_primary = user_handler_->db_is_user_primary_author(server_id_, id, uploader);
|
||||
bool is_secondary = user_handler_->db_is_user_secondary_author(server_id_, id, uploader);
|
||||
|
||||
// allow if there is no author information - this is a new upload
|
||||
// don't allow other people to upload if author information does exist
|
||||
// don't allow secondary authors to remove the add-on from the server
|
||||
if((do_authors_exist && !is_primary && !is_secondary) || (is_secondary && is_delete)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string author = addon["uploader"].str();
|
||||
std::string salt = user_handler_->extract_salt(author);
|
||||
std::string hashed_password = hash_password(passphrase, salt, author);
|
||||
|
||||
return user_handler_->login(author, hashed_password);
|
||||
}
|
||||
|
||||
|
@ -275,9 +275,10 @@ private:
|
||||
*
|
||||
* @param addon The add-on uploaded, which contains the username to use.
|
||||
* @param passphrase The passphrase to use for authentication.
|
||||
* @param is_delete Whether the authentication is being requested for an add-on upload or an add-on deletion.
|
||||
* @return Whether the provided information matches what's in the forum database.
|
||||
*/
|
||||
bool authenticate_forum(const config& addon, const std::string& passphrase);
|
||||
bool authenticate_forum(const config& addon, const std::string& passphrase, bool is_delete);
|
||||
};
|
||||
|
||||
} // end namespace campaignd
|
||||
|
@ -40,6 +40,7 @@ dbconn::dbconn(const config& c)
|
||||
, db_topics_table_(c["db_topics_table"].str())
|
||||
, db_addon_info_table_(c["db_addon_info_table"].str())
|
||||
, db_connection_history_table_(c["db_connection_history_table"].str())
|
||||
, db_addon_authors_table_(c["db_addon_authors_table"].str())
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -364,12 +365,12 @@ bool dbconn::topic_id_exists(int topic_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void dbconn::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)
|
||||
void dbconn::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, const std::string uploader)
|
||||
{
|
||||
try
|
||||
{
|
||||
modify(connection_, "INSERT INTO `"+db_addon_info_table_+"`(INSTANCE_VERSION, ADDON_ID, ADDON_NAME, TYPE, VERSION, FORUM_AUTH, FEEDBACK_TOPIC) VALUES(?, ?, ?, ?, ?, ?, ?)",
|
||||
instance_version, id, name, type, version, forum_auth, topic_id);
|
||||
modify(connection_, "INSERT INTO `"+db_addon_info_table_+"`(INSTANCE_VERSION, ADDON_ID, ADDON_NAME, TYPE, VERSION, FORUM_AUTH, FEEDBACK_TOPIC, UPLOADER) VALUES(?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
instance_version, id, name, type, version, forum_auth, topic_id, uploader);
|
||||
}
|
||||
catch(const mariadb::exception::base& e)
|
||||
{
|
||||
@ -459,6 +460,56 @@ void dbconn::update_addon_download_count(const std::string& instance_version, co
|
||||
}
|
||||
}
|
||||
|
||||
bool dbconn::is_user_author(const std::string& instance_version, const std::string& id, const std::string& username, int is_primary) {
|
||||
try
|
||||
{
|
||||
return exists(connection_, "SELECT 1 FROM `"+db_addon_authors_table_+"` WHERE INSTANCE_VERSION = ? AND ADDON_ID = ? AND AUTHOR = ? AND IS_PRIMARY = ?",
|
||||
instance_version, id, username, is_primary);
|
||||
}
|
||||
catch(const mariadb::exception::base& e)
|
||||
{
|
||||
log_sql_exception("Unable to check whether `"+username+"` is an author of "+id+" for version "+instance_version+".", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void dbconn::delete_addon_authors(const std::string& instance_version, const std::string& id) {
|
||||
try
|
||||
{
|
||||
modify(connection_, "DELETE FROM `"+db_addon_authors_table_+"` WHERE INSTANCE_VERSION = ? AND ADDON_ID = ?",
|
||||
instance_version, id);
|
||||
}
|
||||
catch(const mariadb::exception::base& e)
|
||||
{
|
||||
log_sql_exception("Unable to delete addon authors for "+id+" and version "+instance_version+".", e);
|
||||
}
|
||||
}
|
||||
|
||||
void dbconn::insert_addon_author(const std::string& instance_version, const std::string& id, const std::string author, int is_primary) {
|
||||
try
|
||||
{
|
||||
modify(connection_, "INSERT INTO `"+db_addon_authors_table_+"`(INSTANCE_VERSION, ADDON_ID, AUTHOR, IS_PRIMARY) VALUES(?,?,?,?)",
|
||||
instance_version, id, author, is_primary);
|
||||
}
|
||||
catch(const mariadb::exception::base& e)
|
||||
{
|
||||
log_sql_exception("Unable to delete addon authors for "+id+" and version "+instance_version+".", e);
|
||||
}
|
||||
}
|
||||
|
||||
bool dbconn::do_any_authors_exist(const std::string& instance_version, const std::string& id) {
|
||||
try
|
||||
{
|
||||
return exists(connection_, "SELECT 1 FROM `"+db_addon_authors_table_+"` WHERE INSTANCE_VERSION = ? AND ADDON_ID = ?",
|
||||
instance_version, id);
|
||||
}
|
||||
catch(const mariadb::exception::base& e)
|
||||
{
|
||||
log_sql_exception("Unable to check whether authors exist for "+id+" for version "+instance_version+".", e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// handle complex query results
|
||||
//
|
||||
|
@ -85,7 +85,9 @@ class dbconn
|
||||
bool extra_row_exists(const std::string& name);
|
||||
|
||||
/**
|
||||
* @see forum_user_handler::is_user_in_group().
|
||||
* @param name The player's username.
|
||||
* @param group_id The forum group ID to check if the user is part of.
|
||||
* @return Whether the user is a member of the forum group.
|
||||
*/
|
||||
bool is_user_in_group(const std::string& name, int group_id);
|
||||
|
||||
@ -152,7 +154,7 @@ class dbconn
|
||||
/**
|
||||
* @see forum_user_handler::db_insert_addon_info().
|
||||
*/
|
||||
void 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);
|
||||
void 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, const std::string uploader);
|
||||
|
||||
/**
|
||||
* @see forum_user_handler::db_insert_login().
|
||||
@ -179,6 +181,27 @@ class dbconn
|
||||
*/
|
||||
void update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version);
|
||||
|
||||
/**
|
||||
* @see forum_user_handler::is_user_primary_author().
|
||||
* @see forum_user_handler::is_user_secondary_author().
|
||||
*/
|
||||
bool is_user_author(const std::string& instance_version, const std::string& id, const std::string& username, int is_primary);
|
||||
|
||||
/**
|
||||
* @see forum_user_handler::db_delete_addon_authors().
|
||||
*/
|
||||
void delete_addon_authors(const std::string& instance_version, const std::string& id);
|
||||
|
||||
/**
|
||||
* @see forum_user_handler::db_insert_addon_authors().
|
||||
*/
|
||||
void insert_addon_author(const std::string& instance_version, const std::string& id, const std::string author, int is_primary);
|
||||
|
||||
/**
|
||||
* @see forum_user_handler::do_any_authors_exist().
|
||||
*/
|
||||
bool do_any_authors_exist(const std::string& instance_version, const std::string& id);
|
||||
|
||||
private:
|
||||
/**
|
||||
* The account used to connect to the database.
|
||||
@ -211,6 +234,8 @@ class dbconn
|
||||
std::string db_addon_info_table_;
|
||||
/** The name of the table that contains user connection history. */
|
||||
std::string db_connection_history_table_;
|
||||
/** The name of the table that contains the add-on authors information */
|
||||
std::string db_addon_authors_table_;
|
||||
|
||||
/**
|
||||
* This is used to write out error text when an SQL-related exception occurs.
|
||||
|
@ -247,8 +247,8 @@ bool fuh::db_topic_id_exists(int topic_id) {
|
||||
return conn_.topic_id_exists(topic_id);
|
||||
}
|
||||
|
||||
void fuh::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) {
|
||||
conn_.insert_addon_info(instance_version, id, name, type, version, forum_auth, topic_id);
|
||||
void fuh::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, const std::string uploader) {
|
||||
conn_.insert_addon_info(instance_version, id, name, type, version, forum_auth, topic_id, uploader);
|
||||
}
|
||||
|
||||
unsigned long long fuh::db_insert_login(const std::string& username, const std::string& ip, const std::string& version) {
|
||||
@ -267,4 +267,35 @@ void fuh::get_ips_for_user(const std::string& username, std::ostringstream* out)
|
||||
conn_.get_ips_for_user(username, out);
|
||||
}
|
||||
|
||||
bool fuh::db_is_user_primary_author(const std::string& instance_version, const std::string& id, const std::string& username) {
|
||||
return conn_.is_user_author(instance_version, id, username, 1);
|
||||
}
|
||||
|
||||
bool fuh::db_is_user_secondary_author(const std::string& instance_version, const std::string& id, const std::string& username) {
|
||||
return conn_.is_user_author(instance_version, id, username, 0);
|
||||
}
|
||||
|
||||
void fuh::db_delete_addon_authors(const std::string& instance_version, const std::string& id) {
|
||||
conn_.delete_addon_authors(instance_version, id);
|
||||
}
|
||||
|
||||
void fuh::db_insert_addon_authors(const std::string& instance_version, const std::string& id, const std::string& primary_author, const std::vector<std::string>& secondary_authors) {
|
||||
conn_.insert_addon_author(instance_version, id, primary_author, 1);
|
||||
|
||||
// ignore any duplicate authors
|
||||
std::set<std::string> inserted_authors;
|
||||
inserted_authors.emplace(primary_author);
|
||||
|
||||
for(const std::string& secondary_author : secondary_authors) {
|
||||
if(inserted_authors.count(secondary_author) == 0) {
|
||||
inserted_authors.emplace(secondary_author);
|
||||
conn_.insert_addon_author(instance_version, id, secondary_author, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool fuh::db_do_any_authors_exist(const std::string& instance_version, const std::string& id) {
|
||||
return conn_.do_any_authors_exist(instance_version, id);
|
||||
}
|
||||
|
||||
#endif //HAVE_MYSQLPP
|
||||
|
@ -219,8 +219,9 @@ public:
|
||||
* @param version The add-on's version from the pbl.
|
||||
* @param forum_auth Whether the provided author and password should be matched a forum account or not.
|
||||
* @param topic_id The forum topic ID of the add-on's feedback thread, 0 if not present.
|
||||
* @param uploader The person uploading this version of the add-on.
|
||||
*/
|
||||
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);
|
||||
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, const std::string uploader);
|
||||
|
||||
/**
|
||||
* Inserts into the database for when a player logs in.
|
||||
@ -272,6 +273,53 @@ public:
|
||||
*/
|
||||
void db_update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version);
|
||||
|
||||
/**
|
||||
* Checks whether the provided username is the primary author of the add-on.
|
||||
*
|
||||
* @param instance_version Which major version this is for (1.16, 1.17, etc).
|
||||
* @param id The ID of the add-on.
|
||||
* @param username The username attempting to do something with the add-on.
|
||||
* @return true if the user is the primary author of an addon, false otherwise.
|
||||
*/
|
||||
bool db_is_user_primary_author(const std::string& instance_version, const std::string& id, const std::string& username);
|
||||
|
||||
/**
|
||||
* Checks whether the provided username is a secondary author of the add-on.
|
||||
*
|
||||
* @param instance_version Which major version this is for (1.16, 1.17, etc).
|
||||
* @param id The ID of the add-on.
|
||||
* @param username The username attempting to do something with the add-on.
|
||||
* @return true if the user is a secondary author of an addon, false otherwise.
|
||||
*/
|
||||
bool db_is_user_secondary_author(const std::string& instance_version, const std::string& id, const std::string& username);
|
||||
|
||||
/**
|
||||
* Removes the authors information from addon_author for a particular addon and version.
|
||||
*
|
||||
* @param instance_version Which major version this is for (1.16, 1.17, etc).
|
||||
* @param id The ID of the add-on.
|
||||
*/
|
||||
void db_delete_addon_authors(const std::string& instance_version, const std::string& id);
|
||||
|
||||
/**
|
||||
* Inserts rows for the primary and secondary authors for a particular addon and version.
|
||||
*
|
||||
* @param instance_version Which major version this is for (1.16, 1.17, etc).
|
||||
* @param id The ID of the add-on.
|
||||
* @param primary_author The primary author of the add-on.
|
||||
* @param secondary_authors The secondary authors of the add-on.
|
||||
*/
|
||||
void db_insert_addon_authors(const std::string& instance_version, const std::string& id, const std::string& primary_author, const std::vector<std::string>& secondary_authors);
|
||||
|
||||
/**
|
||||
* Checks whether any author information exists for a particular addon and version, since if there's no author information then of course no primary or secondary authors will ever be found.
|
||||
*
|
||||
* @param instance_version Which major version this is for (1.16, 1.17, etc).
|
||||
* @param id The ID of the add-on.
|
||||
* @return true if any author information exists for this addon, false otherwise.
|
||||
*/
|
||||
bool db_do_any_authors_exist(const std::string& instance_version, const std::string& id);
|
||||
|
||||
private:
|
||||
/** An instance of the class responsible for executing the queries and handling the database connection. */
|
||||
dbconn conn_;
|
||||
@ -299,11 +347,4 @@ private:
|
||||
* @return The player's forum registration date.
|
||||
*/
|
||||
std::time_t get_registrationdate(const std::string& user);
|
||||
|
||||
/**
|
||||
* @param name The player's username.
|
||||
* @param group_id The forum group ID to check if the user is part of.
|
||||
* @return Whether the user is a member of the forum group.
|
||||
*/
|
||||
bool is_user_in_group(const std::string& name, int group_id);
|
||||
};
|
||||
|
@ -147,10 +147,15 @@ public:
|
||||
virtual void db_set_oos_flag(const std::string& uuid, int game_id) = 0;
|
||||
virtual void async_test_query(boost::asio::io_service& io_service, int limit) = 0;
|
||||
virtual bool db_topic_id_exists(int topic_id) = 0;
|
||||
virtual 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) = 0;
|
||||
virtual 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, const std::string uploader) = 0;
|
||||
virtual unsigned long long db_insert_login(const std::string& username, const std::string& ip, const std::string& version) = 0;
|
||||
virtual void db_update_logout(unsigned long long login_id) = 0;
|
||||
virtual void get_users_for_ip(const std::string& ip, std::ostringstream* out) = 0;
|
||||
virtual void get_ips_for_user(const std::string& username, std::ostringstream* out) = 0;
|
||||
virtual void db_update_addon_download_count(const std::string& instance_version, const std::string& id, const std::string& version) = 0;
|
||||
virtual bool db_is_user_primary_author(const std::string& instance_version, const std::string& id, const std::string& username) = 0;
|
||||
virtual bool db_is_user_secondary_author(const std::string& instance_version, const std::string& id, const std::string& username) = 0;
|
||||
virtual void db_delete_addon_authors(const std::string& instance_version, const std::string& id) = 0;
|
||||
virtual void db_insert_addon_authors(const std::string& instance_version, const std::string& id, const std::string& primary_author, const std::vector<std::string>& secondary_authors) = 0;
|
||||
virtual bool db_do_any_authors_exist(const std::string& instance_version, const std::string& id) = 0;
|
||||
};
|
||||
|
@ -135,6 +135,7 @@ create table game_content_info
|
||||
-- UPLOADED_ON: when the addon was uploaded
|
||||
-- FEEDBACK_TOPIC: the forum topic ID where feedback for the addon can be posted, 0 if not set
|
||||
-- DOWNLOAD_COUNT: the number of times the add-on has been downloaded by players (does not count downloads from https://addons.wesnoth.org)
|
||||
-- UPLOADER: the author attribute or the chosen secondary_author from the _server.pbl
|
||||
create table addon_info
|
||||
(
|
||||
INSTANCE_VERSION VARCHAR(255) NOT NULL,
|
||||
@ -146,9 +147,24 @@ create table addon_info
|
||||
UPLOADED_ON TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FEEDBACK_TOPIC INT UNSIGNED NOT NULL,
|
||||
DOWNLOAD_COUNT INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
UPLOADER VARCHAR(255),
|
||||
PRIMARY KEY (INSTANCE_VERSION, ADDON_ID, VERSION)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- listing of the primary author and any secondary authors when forum_auth is used
|
||||
-- INSTANCE_VERSION: the version of the addons server instance
|
||||
-- ADDON_ID: the ID of the addon (folder name)
|
||||
-- AUTHOR: the author attribute or the chosen secondary_author from the _server.pbl
|
||||
-- IS_PRIMARY: whether this is the primary author or not
|
||||
create table addon_authors
|
||||
(
|
||||
INSTANCE_VERSION VARCHAR(255) NOT NULL,
|
||||
ADDON_ID VARCHAR(255) NOT NULL,
|
||||
AUTHOR VARCHAR(255) NOT NULL,
|
||||
IS_PRIMARY BIT(1) NOT NULL,
|
||||
PRIMARY KEY (INSTANCE_VERSION, ADDON_ID, AUTHOR)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
-- history of user sessions
|
||||
-- LOGIN_ID: auto generated ID to use as a primary key
|
||||
-- USER_NAME: the username logged in with
|
||||
|
Loading…
x
Reference in New Issue
Block a user