From 6b97a761098456709bb53d7e623e13b74666688c Mon Sep 17 00:00:00 2001 From: Pentarctagon Date: Fri, 19 Mar 2021 00:33:52 -0500 Subject: [PATCH] Add a prompt to allow entering an add-on's password at upload time. This is an alternative to needing to store the plaintext password in the _server.pbl. --- data/gui/window/addon_auth.cfg | 150 ++++++++++++++++++++++ projectfiles/VC16/wesnoth.vcxproj | 10 +- projectfiles/VC16/wesnoth.vcxproj.filters | 8 +- source_lists/wesnoth | 1 + src/addon/client.cpp | 25 ++-- src/gui/dialogs/addon/addon_auth.cpp | 48 +++++++ src/gui/dialogs/addon/addon_auth.hpp | 50 ++++++++ src/gui/dialogs/addon/manager.cpp | 8 ++ src/tests/gui/test_gui2.cpp | 12 ++ 9 files changed, 296 insertions(+), 16 deletions(-) create mode 100644 data/gui/window/addon_auth.cfg create mode 100644 src/gui/dialogs/addon/addon_auth.cpp create mode 100644 src/gui/dialogs/addon/addon_auth.hpp diff --git a/data/gui/window/addon_auth.cfg b/data/gui/window/addon_auth.cfg new file mode 100644 index 00000000000..1653013dab2 --- /dev/null +++ b/data/gui/window/addon_auth.cfg @@ -0,0 +1,150 @@ +#textdomain wesnoth-lib +### +### Definition of the window to provide authentication information when uploading an add-on +### + +[window] + id = "addon_auth" + description =_ "Add-on upload authentication dialog" + + [resolution] + definition = "default" + + automatic_placement = true + vertical_placement = "center" + horizontal_placement = "center" + + maximum_width = 800 + + [tooltip] + id = "tooltip" + [/tooltip] + + [helptip] + id = "tooltip" + [/helptip] + + [grid] + + [row] + grow_factor = 0 + + [column] + grow_factor = 1 + + border = "all" + border_size = 5 + horizontal_alignment = "left" + [label] + definition = "title" + + label = _ "Authenticate" + [/label] + + [/column] + + [/row] + + [row] + grow_factor = 1 + + [column] + grow_factor = 1 + + horizontal_grow = true + + [grid] + + [row] + grow_factor = 1 + + [column] + grow_factor = 0 + + border = "all" + border_size = 5 + horizontal_alignment = "left" + + [label] + definition = "default" + + label = _ "Password:" + [/label] + + [/column] + + [column] + grow_factor = 1 + + border = "all" + border_size = 5 + horizontal_alignment = "right" + + [password_box] + id = "password" + definition = "default" + [/password_box] + + [/column] + + [/row] + + [/grid] + + [/column] + + [/row] + + [row] + grow_factor = 0 + + [column] + grow_factor = 0 + horizontal_alignment = "right" + + [grid] + + [row] + grow_factor = 0 + + [column] + border = "all" + border_size = 5 + horizontal_alignment = "right" + + [button] + id = "ok" + definition = "default" + + label = _ "OK" + [/button] + + [/column] + + [column] + border = "all" + border_size = 5 + horizontal_alignment = "right" + + [button] + id = "cancel" + definition = "default" + + label = _ "Cancel" + [/button] + + [/column] + + [/row] + + [/grid] + + [/column] + + [/row] + + [/grid] + + [/resolution] + +[/window] diff --git a/projectfiles/VC16/wesnoth.vcxproj b/projectfiles/VC16/wesnoth.vcxproj index 2d80476f0aa..9dcb6585b41 100644 --- a/projectfiles/VC16/wesnoth.vcxproj +++ b/projectfiles/VC16/wesnoth.vcxproj @@ -1441,6 +1441,13 @@ $(IntDir)Gui\Core\Window_Builder\ $(IntDir)Gui\Core\Window_Builder\ + + $(IntDir)Gui\Dialogs\Addon\ + $(IntDir)Gui\Dialogs\Addon\ + $(IntDir)Gui\Dialogs\Addon\ + $(IntDir)Gui\Dialogs\Addon\ + $(IntDir)Gui\Dialogs\Addon\ + $(IntDir)Gui\Dialogs\Addon\ $(IntDir)Gui\Dialogs\Addon\ @@ -3782,6 +3789,7 @@ + @@ -4173,4 +4181,4 @@ - \ No newline at end of file + diff --git a/projectfiles/VC16/wesnoth.vcxproj.filters b/projectfiles/VC16/wesnoth.vcxproj.filters index d248b1c856b..134209d9735 100644 --- a/projectfiles/VC16/wesnoth.vcxproj.filters +++ b/projectfiles/VC16/wesnoth.vcxproj.filters @@ -695,6 +695,9 @@ Gui\Dialogs + + Gui\Dialogs\Addon + Gui\Dialogs\Addon @@ -2138,6 +2141,9 @@ Gui\Dialogs + + Gui\Dialogs\Addon + Gui\Dialogs\Addon @@ -3096,4 +3102,4 @@ Tests\Utils - \ No newline at end of file + diff --git a/source_lists/wesnoth b/source_lists/wesnoth index b3462ba41c6..a1d837b22c1 100644 --- a/source_lists/wesnoth +++ b/source_lists/wesnoth @@ -162,6 +162,7 @@ gui/core/widget_definition.cpp gui/core/window_builder.cpp gui/core/window_builder/helper.cpp gui/core/window_builder/instance.cpp +gui/dialogs/addon/addon_auth.cpp gui/dialogs/addon/connect.cpp gui/dialogs/addon/install_dependencies.cpp gui/dialogs/addon/license_prompt.cpp diff --git a/src/addon/client.cpp b/src/addon/client.cpp index cefd9157c3b..1b6708bdc44 100644 --- a/src/addon/client.cpp +++ b/src/addon/client.cpp @@ -21,6 +21,7 @@ #include "font/pango/escape.hpp" #include "formula/string_utils.hpp" #include "gettext.hpp" +#include "gui/dialogs/addon/addon_auth.hpp" #include "gui/dialogs/addon/install_dependencies.hpp" #include "gui/dialogs/message.hpp" #include "gui/widgets/retval.hpp" @@ -169,20 +170,6 @@ bool addons_client::upload_addon(const std::string& id, std::string& response_me return false; } - std::string passphrase = cfg["passphrase"]; - // generate a random passphrase and write it to disk - // if the .pbl file doesn't provide one already - if(passphrase.empty()) { - passphrase.resize(16); - for(std::size_t n = 0; n < passphrase.size(); ++n) { - passphrase[n] = randomness::generator->get_random_int('a', 'z'); - } - cfg["passphrase"] = passphrase; - set_addon_pbl_info(id, cfg); - - LOG_ADDONS << "automatically generated an initial passphrase for " << id << '\n'; - } - cfg["name"] = id; config addon_data; @@ -288,6 +275,16 @@ bool addons_client::delete_remote_addon(const std::string& id, std::string& resp config request_buf, response_buf; config& request_body = request_buf.add_child("delete"); + // the passphrase isn't provided, prompt for it + if(cfg["passphrase"].empty()) { + if(!gui2::dialogs::addon_auth::execute(cfg)) { + config dummy; + config& error = dummy.add_child("error"); + error["message"] = "Password not provided."; + return !update_last_error(dummy); + } + } + request_body["name"] = id; request_body["passphrase"] = cfg["passphrase"]; diff --git a/src/gui/dialogs/addon/addon_auth.cpp b/src/gui/dialogs/addon/addon_auth.cpp new file mode 100644 index 00000000000..e0624e6870a --- /dev/null +++ b/src/gui/dialogs/addon/addon_auth.cpp @@ -0,0 +1,48 @@ +/* + Part of the Battle for Wesnoth Project https://www.wesnoth.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#define GETTEXT_DOMAIN "wesnoth-lib" + +#include + +#include "gui/dialogs/addon/addon_auth.hpp" + +#include "gui/auxiliary/find_widget.hpp" +#include "gui/widgets/password_box.hpp" +#include "gui/widgets/window.hpp" + +namespace gui2::dialogs +{ + +REGISTER_DIALOG(addon_auth) + +addon_auth::addon_auth(config& cfg) + : cfg_(cfg) +{ + +} + +void addon_auth::pre_show(window& win) +{ + win.add_to_tab_order(find_widget(&win, "password", false, true)); +} + +void addon_auth::post_show(window& win) +{ + if(get_retval() == gui2::retval::OK) + { + cfg_["passphrase"] = find_widget(&win, "password", false).get_real_value(); + } +} + +} // namespace dialogs diff --git a/src/gui/dialogs/addon/addon_auth.hpp b/src/gui/dialogs/addon/addon_auth.hpp new file mode 100644 index 00000000000..0b075ac00df --- /dev/null +++ b/src/gui/dialogs/addon/addon_auth.hpp @@ -0,0 +1,50 @@ +/* + Part of the Battle for Wesnoth Project https://www.wesnoth.org/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#pragma once + +#include "gui/dialogs/modal_dialog.hpp" + +namespace gui2::dialogs +{ + +/** + * @ingroup GUIWindowDefinitionWML + * + * This shows the dialog to provide a password when uploading an add-on. + * + * Key |Type |Mandatory|Description + * ------------------|---------------|---------|----------- + * password | text_box |yes |The password used to verify the uploader. + */ +class addon_auth : public modal_dialog +{ +public: + addon_auth(config& cfg_); + + DEFINE_SIMPLE_EXECUTE_WRAPPER(addon_auth) + +private: + /** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */ + virtual const std::string& window_id() const override; + + /** Inherited from modal_dialog. */ + virtual void pre_show(window& window) override; + + /** Inherited from modal_dialog. */ + virtual void post_show(window& window) override; + + config& cfg_; +}; + +} // namespace gui2::dialogs diff --git a/src/gui/dialogs/addon/manager.cpp b/src/gui/dialogs/addon/manager.cpp index 02c0e373e34..0ed13f513a4 100644 --- a/src/gui/dialogs/addon/manager.cpp +++ b/src/gui/dialogs/addon/manager.cpp @@ -28,6 +28,7 @@ #include "gui/auxiliary/filter.hpp" #include "gui/auxiliary/find_widget.hpp" #include "gui/dialogs/addon/license_prompt.hpp" +#include "gui/dialogs/addon/addon_auth.hpp" #include "gui/dialogs/message.hpp" #include "gui/dialogs/transient_message.hpp" #include "gui/widgets/button.hpp" @@ -738,6 +739,13 @@ void addon_manager::publish_addon(const addon_info& addon) } } + // the passphrase isn't provided, prompt for it + if(cfg["passphrase"].empty()) { + if(!gui2::dialogs::addon_auth::execute(cfg)) { + return; + } + } + if(!::image::exists(cfg["icon"].str())) { gui2::show_error_message(_("Invalid icon path. Make sure the path points to a valid image.")); } else if(!client_.request_distribution_terms(server_msg)) { diff --git a/src/tests/gui/test_gui2.cpp b/src/tests/gui/test_gui2.cpp index 01ccfb3ec36..bad63bc6cb0 100644 --- a/src/tests/gui/test_gui2.cpp +++ b/src/tests/gui/test_gui2.cpp @@ -31,6 +31,7 @@ #include "generators/map_create.hpp" #include "gettext.hpp" #include "gui/core/layout_exception.hpp" +#include "gui/dialogs/addon/addon_auth.hpp" #include "gui/dialogs/addon/connect.hpp" #include "gui/dialogs/addon/install_dependencies.hpp" #include "gui/dialogs/addon/license_prompt.hpp" @@ -413,6 +414,7 @@ BOOST_AUTO_TEST_CASE(test_gui2) /**** Run the tests. *****/ /* The modal_dialog classes. */ + test(); test(); test(); //test(); @@ -569,6 +571,16 @@ BOOST_AUTO_TEST_CASE(test_make_test_fake) namespace { +template<> +struct dialog_tester +{ + config cfg; + addon_auth* create() + { + return new addon_auth(cfg); + } +}; + template<> struct dialog_tester {