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.
This commit is contained in:
Pentarctagon 2021-03-19 00:33:52 -05:00 committed by Pentarctagon
parent 5fc4b235a9
commit 6b97a76109
9 changed files with 296 additions and 16 deletions

View File

@ -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]

View File

@ -1441,6 +1441,13 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|x64'">$(IntDir)Gui\Core\Window_Builder\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|x64'">$(IntDir)Gui\Core\Window_Builder\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\gui\dialogs\addon\addon_auth.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)Gui\Dialogs\Addon\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='ReleaseDEBUG|x64'">$(IntDir)Gui\Dialogs\Addon\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)Gui\Dialogs\Addon\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|x64'">$(IntDir)Gui\Dialogs\Addon\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|x64'">$(IntDir)Gui\Dialogs\Addon\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\gui\dialogs\addon\connect.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)Gui\Dialogs\Addon\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='ReleaseDEBUG|x64'">$(IntDir)Gui\Dialogs\Addon\</ObjectFileName>
@ -3782,6 +3789,7 @@
<ClInclude Include="..\..\src\gui\core\window_builder.hpp" />
<ClInclude Include="..\..\src\gui\core\window_builder\helper.hpp" />
<ClInclude Include="..\..\src\gui\core\window_builder\instance.hpp" />
<ClInclude Include="..\..\src\gui\dialogs\addon\addon_auth.hpp" />
<ClInclude Include="..\..\src\gui\dialogs\addon\connect.hpp" />
<ClInclude Include="..\..\src\gui\dialogs\addon\install_dependencies.hpp" />
<ClInclude Include="..\..\src\gui\dialogs\addon\license_prompt.hpp" />

View File

@ -695,6 +695,9 @@
<ClCompile Include="..\..\src\gui\dialogs\wml_message.cpp">
<Filter>Gui\Dialogs</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gui\dialogs\addon\addon_auth.cpp">
<Filter>Gui\Dialogs\Addon</Filter>
</ClCompile>
<ClCompile Include="..\..\src\gui\dialogs\addon\connect.cpp">
<Filter>Gui\Dialogs\Addon</Filter>
</ClCompile>
@ -2138,6 +2141,9 @@
<ClInclude Include="..\..\src\gui\dialogs\wml_message.hpp">
<Filter>Gui\Dialogs</Filter>
</ClInclude>
<ClCompile Include="..\..\gui\dialogs\addon\addon_auth.hpp">
<Filter>Gui\Dialogs\Addon</Filter>
</ClCompile>
<ClInclude Include="..\..\src\gui\dialogs\addon\connect.hpp">
<Filter>Gui\Dialogs\Addon</Filter>
</ClInclude>

View File

@ -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

View File

@ -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"];

View File

@ -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 <functional>
#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<password_box>(&win, "password", false, true));
}
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();
}
}
} // namespace dialogs

View File

@ -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

View File

@ -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)) {

View File

@ -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<addon_auth>();
test<addon_connect>();
test<addon_license_prompt>();
//test<addon_manager>();
@ -569,6 +571,16 @@ BOOST_AUTO_TEST_CASE(test_make_test_fake)
namespace {
template<>
struct dialog_tester<addon_auth>
{
config cfg;
addon_auth* create()
{
return new addon_auth(cfg);
}
};
template<>
struct dialog_tester<addon_connect>
{