mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 16:21:58 +08:00
Store PrusaLink passwords in wxsecretstore
This commit is contained in:
parent
fad42fb8f3
commit
f624c55f6f
@ -41,8 +41,8 @@ option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1)
|
||||
option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1)
|
||||
option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0)
|
||||
option(SLIC3R_UBSAN "Enable UBSan on Clang and GCC" 0)
|
||||
option(SLIC3R_ENABLE_FORMAT_STEP "Enable compilation of STEP file support" ON)
|
||||
# If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, othrewise variable.
|
||||
option(SLIC3R_ENABLE_FORMAT_STEP "Enable compilation of STEP file support" 1)
|
||||
# If SLIC3R_FHS is 1 -> SLIC3R_DESKTOP_INTEGRATION is always 0, otherwise variable.
|
||||
CMAKE_DEPENDENT_OPTION(SLIC3R_DESKTOP_INTEGRATION "Allow perfoming desktop integration during runtime" 1 "NOT SLIC3R_FHS" 0)
|
||||
|
||||
set(OPENVDB_FIND_MODULE_PATH "" CACHE PATH "Path to OpenVDB installation's find modules.")
|
||||
|
47
deps/wxWidgets/wxWidgets.cmake
vendored
Normal file
47
deps/wxWidgets/wxWidgets.cmake
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
set(_wx_toolkit "")
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(_gtk_ver 2)
|
||||
if (DEP_WX_GTK3)
|
||||
set(_gtk_ver 3)
|
||||
endif ()
|
||||
set(_wx_toolkit "-DwxBUILD_TOOLKIT=gtk${_gtk_ver}")
|
||||
endif()
|
||||
|
||||
set(_unicode_utf8 OFF)
|
||||
if (UNIX AND NOT APPLE) # wxWidgets will not use char as the underlying type for wxString unless its forced to.
|
||||
set (_unicode_utf8 ON)
|
||||
endif()
|
||||
|
||||
prusaslicer_add_cmake_project(wxWidgets
|
||||
URL https://github.com/prusa3d/wxWidgets/archive/78aa2dc0ea7ce99dc19adc1140f74c3e2e3f3a26.zip
|
||||
URL_HASH SHA256=94b7d972373503e380e5a8b0ca63b1ccb956da4006402298dd89a0c5c7041b1e
|
||||
DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} dep_TIFF dep_JPEG dep_NanoSVG
|
||||
CMAKE_ARGS
|
||||
-DwxBUILD_PRECOMP=ON
|
||||
${_wx_toolkit}
|
||||
"-DCMAKE_DEBUG_POSTFIX:STRING="
|
||||
-DwxBUILD_DEBUG_LEVEL=0
|
||||
-DwxUSE_MEDIACTRL=OFF
|
||||
-DwxUSE_DETECT_SM=OFF
|
||||
-DwxUSE_UNICODE=ON
|
||||
-DwxUSE_UNICODE_UTF8=${_unicode_utf8}
|
||||
-DwxUSE_OPENGL=ON
|
||||
-DwxUSE_LIBPNG=sys
|
||||
-DwxUSE_ZLIB=sys
|
||||
-DwxUSE_NANOSVG=sys
|
||||
-DwxUSE_NANOSVG_EXTERNAL=ON
|
||||
-DwxUSE_REGEX=OFF
|
||||
-DwxUSE_LIBXPM=builtin
|
||||
-DwxUSE_LIBJPEG=sys
|
||||
-DwxUSE_LIBTIFF=sys
|
||||
-DwxUSE_EXPAT=sys
|
||||
-DwxUSE_LIBSDL=OFF
|
||||
-DwxUSE_XTEST=OFF
|
||||
-DwxUSE_GLCANVAS_EGL=OFF
|
||||
-DwxUSE_WEBREQUEST=OFF
|
||||
-DwxUSE_SECRETSTORE=ON
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
add_debug_dep(dep_wxWidgets)
|
||||
endif ()
|
@ -1990,6 +1990,8 @@ public:
|
||||
one_string,
|
||||
// Close parameter, string value could be one of the list values.
|
||||
select_close,
|
||||
// Password, string vaule is hidden by asterisk.
|
||||
password,
|
||||
};
|
||||
static bool is_gui_type_enum_open(const GUIType gui_type)
|
||||
{ return gui_type == ConfigOptionDef::GUIType::i_enum_open || gui_type == ConfigOptionDef::GUIType::f_enum_open || gui_type == ConfigOptionDef::GUIType::select_open; }
|
||||
|
@ -1947,7 +1947,7 @@ void PresetBundle::update_compatible(PresetSelectCompatibleType select_other_pri
|
||||
}
|
||||
}
|
||||
|
||||
void PresetBundle::export_configbundle(const std::string &path, bool export_system_settings, bool export_physical_printers/* = false*/)
|
||||
void PresetBundle::export_configbundle(const std::string &path, bool export_system_settings, bool export_physical_printers/* = false*/, std::function<bool(const std::string&, const std::string&, std::string&)> secret_callback)
|
||||
{
|
||||
boost::nowide::ofstream c;
|
||||
c.open(path, std::ios::out | std::ios::trunc);
|
||||
@ -1974,8 +1974,14 @@ void PresetBundle::export_configbundle(const std::string &path, bool export_syst
|
||||
if (export_physical_printers) {
|
||||
for (const PhysicalPrinter& ph_printer : this->physical_printers) {
|
||||
c << std::endl << "[physical_printer:" << ph_printer.name << "]" << std::endl;
|
||||
for (const std::string& opt_key : ph_printer.config.keys())
|
||||
c << opt_key << " = " << ph_printer.config.opt_serialize(opt_key) << std::endl;
|
||||
for (const std::string& opt_key : ph_printer.config.keys()) {
|
||||
std::string opt_val = ph_printer.config.opt_serialize(opt_key);
|
||||
if (opt_val == "stored") {
|
||||
secret_callback(ph_printer.name, opt_key, opt_val);
|
||||
}
|
||||
|
||||
c << opt_key << " = " << opt_val << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ public:
|
||||
const std::string &path, LoadConfigBundleAttributes flags, ForwardCompatibilitySubstitutionRule compatibility_rule);
|
||||
|
||||
// Export a config bundle file containing all the presets and the names of the active presets.
|
||||
void export_configbundle(const std::string &path, bool export_system_settings = false, bool export_physical_printers = false);
|
||||
void export_configbundle(const std::string &path, bool export_system_settings = false, bool export_physical_printers = false, std::function<bool(const std::string&, const std::string&, std::string&)> secret_callback = nullptr);
|
||||
|
||||
// Enable / disable the "- default -" preset.
|
||||
void set_default_suppressed(bool default_suppressed);
|
||||
|
@ -393,6 +393,7 @@ void PrintConfigDef::init_common_params()
|
||||
def = this->add("printhost_password", coString);
|
||||
def->label = L("Password");
|
||||
// def->tooltip = L("");
|
||||
def->gui_type = ConfigOptionDef::GUIType::password;
|
||||
def->mode = comAdvanced;
|
||||
def->cli = ConfigOptionDef::nocli;
|
||||
def->set_default_value(new ConfigOptionString(""));
|
||||
|
@ -335,6 +335,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
Utils/WxFontUtils.hpp
|
||||
Utils/WifiScanner.hpp
|
||||
Utils/WifiScanner.cpp
|
||||
Utils/Secrets.hpp
|
||||
Utils/Secrets.cpp
|
||||
)
|
||||
|
||||
find_package(NanoSVG REQUIRED)
|
||||
|
@ -23,6 +23,9 @@
|
||||
//#include <wx/glcanvas.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/debug.h>
|
||||
#if wxUSE_SECRETSTORE
|
||||
#include <wx/secretstore.h>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
@ -1789,9 +1792,54 @@ void MainFrame::export_configbundle(bool export_physical_printers /*= false*/)
|
||||
file = dlg.GetPath();
|
||||
if (!file.IsEmpty()) {
|
||||
// Export the config bundle.
|
||||
|
||||
bool passwords_to_plain = false;
|
||||
bool passwords_dialog_shown = false;
|
||||
// callback function thats going to be passed to preset bundle (so preset bundle doesnt have to include WX secret lib)
|
||||
std::function<bool(const std::string&, const std::string&, std::string&)> load_password = [&](const std::string& printer_id, const std::string& opt, std::string& out_psswd)->bool{
|
||||
out_psswd = std::string();
|
||||
#if wxUSE_SECRETSTORE
|
||||
// First password prompts user with dialog
|
||||
if (!passwords_dialog_shown) {
|
||||
//wxString msg = GUI::format_wxstr(L"%1%\n%2%", _L("Some of the exported printers contains passwords, which are stored in the system password store."), _L("Do you wish to include the passwords to the exported file in the plain text form?"));
|
||||
wxString msg = _L("Some of the exported printers contains passwords, which are stored in the system password store."
|
||||
" Do you wish to include the passwords in the plain text form to the exported file?");
|
||||
MessageDialog dlg_psswd(this, msg, wxMessageBoxCaptionStr, wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION);
|
||||
if (dlg_psswd.ShowModal() == wxID_YES)
|
||||
passwords_to_plain = true;
|
||||
passwords_dialog_shown = true;
|
||||
}
|
||||
if (!passwords_to_plain)
|
||||
return false;
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
wxString errmsg;
|
||||
if (!store.IsOk(&errmsg)) {
|
||||
std::string msg = GUI::format("%1% (%2%).", _u8L("Failed to load credentials from the system secret store."), errmsg);
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
// Do not try again. System store is not reachable.
|
||||
passwords_to_plain = false;
|
||||
return false;
|
||||
}
|
||||
const wxString service = GUI::format_wxstr(L"%1%/PhysicalPrinter/%2%/%3%", SLIC3R_APP_NAME, printer_id, opt);
|
||||
wxString username;
|
||||
wxSecretValue password;
|
||||
if (!store.Load(service, username, password)) {
|
||||
std::string msg = GUI::format(_u8L("Failed to load credentials from the system secret store for the printer %1%."), printer_id);
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
return false;
|
||||
}
|
||||
out_psswd = into_u8(password.GetAsString());
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif // wxUSE_SECRETSTORE
|
||||
};
|
||||
|
||||
wxGetApp().app_config->update_config_dir(get_dir_name(file));
|
||||
try {
|
||||
wxGetApp().preset_bundle->export_configbundle(file.ToUTF8().data(), false, export_physical_printers);
|
||||
wxGetApp().preset_bundle->export_configbundle(file.ToUTF8().data(), false, export_physical_printers, load_password);
|
||||
} catch (const std::exception &ex) {
|
||||
show_error(this, ex.what());
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
@ -16,6 +17,10 @@
|
||||
#include <wx/button.h>
|
||||
#include <wx/statbox.h>
|
||||
#include <wx/wupdlock.h>
|
||||
#if wxUSE_SECRETSTORE
|
||||
#include <wx/secretstore.h>
|
||||
#endif
|
||||
#include <wx/clipbrd.h>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
@ -153,6 +158,78 @@ void PresetForPrinter::on_sys_color_changed()
|
||||
m_delete_preset_btn->sys_color_changed();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool is_secret_store_ok()
|
||||
{
|
||||
#if wxUSE_SECRETSTORE
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
wxString errmsg;
|
||||
if (!store.IsOk(&errmsg)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "wxSecretStore is not supported: " << errmsg;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
bool save_secret(const std::string& id, const std::string& opt, const std::string& usr, const std::string& psswd)
|
||||
{
|
||||
#if wxUSE_SECRETSTORE
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
wxString errmsg;
|
||||
if (!store.IsOk(&errmsg)) {
|
||||
std::string msg = GUI::format("%1% (%2%).", _u8L("This system doesn't support storing passwords securely"), errmsg);
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
return false;
|
||||
}
|
||||
const wxString service = GUI::format_wxstr(L"%1%/PhysicalPrinter/%2%/%3%", SLIC3R_APP_NAME, id, opt);
|
||||
const wxString username = boost::nowide::widen(usr);
|
||||
const wxSecretValue password(boost::nowide::widen(psswd));
|
||||
if (!store.Save(service, username, password)) {
|
||||
std::string msg(_u8L("Failed to save credentials to the system secret store."));
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
BOOST_LOG_TRIVIAL(error) << "wxUSE_SECRETSTORE not supported. Cannot save password to the system store.";
|
||||
return false;
|
||||
#endif // wxUSE_SECRETSTORE
|
||||
}
|
||||
bool load_secret(const std::string& id, const std::string& opt, std::string& usr, std::string& psswd)
|
||||
{
|
||||
#if wxUSE_SECRETSTORE
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
wxString errmsg;
|
||||
if (!store.IsOk(&errmsg)) {
|
||||
std::string msg = GUI::format("%1% (%2%).", _u8L("This system doesn't support storing passwords securely"), errmsg);
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
return false;
|
||||
}
|
||||
const wxString service = GUI::format_wxstr(L"%1%/PhysicalPrinter/%2%/%3%", SLIC3R_APP_NAME, id, opt);
|
||||
wxString username;
|
||||
wxSecretValue password;
|
||||
if (!store.Load(service, username, password)) {
|
||||
std::string msg(_u8L("Failed to load credentials from the system secret store."));
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
return false;
|
||||
}
|
||||
usr = into_u8(username);
|
||||
psswd = into_u8(password.GetAsString());
|
||||
return true;
|
||||
#else
|
||||
BOOST_LOG_TRIVIAL(error) << "wxUSE_SECRETSTORE not supported. Cannot load password from the system store.";
|
||||
return false;
|
||||
#endif // wxUSE_SECRETSTORE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------
|
||||
// PhysicalPrinterDialog
|
||||
@ -202,6 +279,20 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxWindow* parent, wxString printer_
|
||||
const std::set<std::string>& preset_names = printer->get_preset_names();
|
||||
for (const std::string& preset_name : preset_names)
|
||||
m_presets.emplace_back(new PresetForPrinter(this, preset_name));
|
||||
// "stored" indicates data are stored secretly, load them from store.
|
||||
if (m_printer.config.opt_string("printhost_password") == "stored" && m_printer.config.opt_string("printhost_password") == "stored") {
|
||||
std::string username;
|
||||
std::string password;
|
||||
if (load_secret(m_printer.name, "printhost_password", username, password)) {
|
||||
if (!username.empty())
|
||||
m_printer.config.opt_string("printhost_user") = username;
|
||||
if (!password.empty())
|
||||
m_printer.config.opt_string("printhost_password") = password;
|
||||
} else {
|
||||
m_printer.config.opt_string("printhost_user") = std::string();
|
||||
m_printer.config.opt_string("printhost_password") = std::string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_presets.size() == 1)
|
||||
@ -348,6 +439,20 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
||||
return sizer;
|
||||
};
|
||||
|
||||
auto api_key_copy = [=](wxWindow* parent) {
|
||||
auto sizer = create_sizer_with_btn(parent, &m_api_key_copy_btn, "copy", _L("Copy"));
|
||||
m_api_key_copy_btn->Bind(wxEVT_BUTTON, [=](wxCommandEvent& e) {
|
||||
if (Field* apikey_field = m_optgroup->get_field("printhost_apikey"); apikey_field) {
|
||||
if (wxTextCtrl* temp = dynamic_cast<wxTextCtrl*>(apikey_field->getWindow()); temp ) {
|
||||
wxTheClipboard->Open();
|
||||
wxTheClipboard->SetData(new wxTextDataObject(temp->GetValue()));
|
||||
wxTheClipboard->Close();
|
||||
}
|
||||
}
|
||||
});
|
||||
return sizer;
|
||||
};
|
||||
|
||||
// Set a wider width for a better alignment
|
||||
Option option = m_optgroup->get_option("print_host");
|
||||
option.opt.width = Field::def_width_wider();
|
||||
@ -360,7 +465,9 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
||||
|
||||
option = m_optgroup->get_option("printhost_apikey");
|
||||
option.opt.width = Field::def_width_wider();
|
||||
m_optgroup->append_single_option_line(option);
|
||||
Line apikey_line = m_optgroup->create_single_option_line(option);
|
||||
apikey_line.append_widget(api_key_copy);
|
||||
m_optgroup->append_line(apikey_line);
|
||||
|
||||
option = m_optgroup->get_option("printhost_port");
|
||||
option.opt.width = Field::def_width_wider();
|
||||
@ -422,6 +529,38 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr
|
||||
m_optgroup->append_line(line);
|
||||
}
|
||||
|
||||
// Text line with info how passwords and api keys are stored
|
||||
if (is_secret_store_ok()) {
|
||||
Line line{ "", "" };
|
||||
line.full_width = 1;
|
||||
line.widget = [ca_file_hint](wxWindow* parent) {
|
||||
wxString info = GUI::format_wxstr(L"%1%:\n\t%2%\n"
|
||||
, _L("Storing passwords")
|
||||
, GUI::format_wxstr(_L("On this system, %1% uses the system password store to safely store and read passwords and API keys."), SLIC3R_APP_NAME));
|
||||
auto txt = new wxStaticText(parent, wxID_ANY, info);
|
||||
txt->SetFont(wxGetApp().normal_font());
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(txt, 1, wxEXPAND);
|
||||
return sizer;
|
||||
};
|
||||
m_optgroup->append_line(line);
|
||||
} else {
|
||||
Line line{ "", "" };
|
||||
line.full_width = 1;
|
||||
line.widget = [ca_file_hint](wxWindow* parent) {
|
||||
wxString info = GUI::format_wxstr(L"%1%:\n\t%2%\n\t%3%\n"
|
||||
, _L("Storing passwords")
|
||||
, GUI::format_wxstr(_L("On this system, %1% cannot access the system password store."), SLIC3R_APP_NAME)
|
||||
, _L("Passwords and API keys are stored in plain text."));
|
||||
auto txt = new wxStaticText(parent, wxID_ANY, info);
|
||||
txt->SetFont(wxGetApp().normal_font());
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(txt, 1, wxEXPAND);
|
||||
return sizer;
|
||||
};
|
||||
m_optgroup->append_line(line);
|
||||
}
|
||||
|
||||
for (const std::string& opt_key : std::vector<std::string>{ "printhost_user", "printhost_password" }) {
|
||||
option = m_optgroup->get_option(opt_key);
|
||||
option.opt.width = Field::def_width_wider();
|
||||
@ -810,6 +949,13 @@ void PhysicalPrinterDialog::OnOK(wxEvent& event)
|
||||
//update printer name, if it was changed
|
||||
m_printer.set_name(into_u8(printer_name));
|
||||
|
||||
// save access data secretly
|
||||
if (!m_printer.config.opt_string("printhost_password").empty()) {
|
||||
if (save_secret(m_printer.name, "printhost_password", m_printer.config.opt_string("printhost_user"), m_printer.config.opt_string("printhost_password"))) {
|
||||
m_printer.config.opt_string("printhost_password", false) = "stored";
|
||||
}
|
||||
}
|
||||
|
||||
// save new physical printer
|
||||
printers.save_printer(m_printer, renamed_from);
|
||||
|
||||
|
@ -76,6 +76,7 @@ class PhysicalPrinterDialog : public DPIDialog
|
||||
ScalableButton* m_printhost_test_btn {nullptr};
|
||||
ScalableButton* m_printhost_cafile_browse_btn {nullptr};
|
||||
ScalableButton* m_printhost_port_browse_btn {nullptr};
|
||||
ScalableButton* m_api_key_copy_btn {nullptr};
|
||||
|
||||
wxBoxSizer* m_presets_sizer {nullptr};
|
||||
|
||||
|
@ -50,6 +50,9 @@
|
||||
#include <wx/debug.h>
|
||||
#include <wx/busyinfo.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#if wxUSE_SECRETSTORE
|
||||
#include <wx/secretstore.h>
|
||||
#endif
|
||||
|
||||
#include <LibBGCode/convert/convert.hpp>
|
||||
|
||||
@ -5700,6 +5703,37 @@ void Plater::reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &
|
||||
this->reslice_until_step_inner(SLAPrintObjectStep(step), object, postpone_error_messages);
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool load_secret(const std::string& id, const std::string& opt, std::string& usr, std::string& psswd)
|
||||
{
|
||||
#if wxUSE_SECRETSTORE
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
wxString errmsg;
|
||||
if (!store.IsOk(&errmsg)) {
|
||||
std::string msg = GUI::format("%1% (%2%).", _u8L("This system doesn't support storing passwords securely"), errmsg);
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
return false;
|
||||
}
|
||||
const wxString service = GUI::format_wxstr(L"%1%/PhysicalPrinter/%2%/%3%", SLIC3R_APP_NAME, id, opt);
|
||||
wxString username;
|
||||
wxSecretValue password;
|
||||
if (!store.Load(service, username, password)) {
|
||||
std::string msg(_u8L("Failed to load credentials from the system secret store."));
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
show_error(nullptr, msg);
|
||||
return false;
|
||||
}
|
||||
usr = into_u8(username);
|
||||
psswd = into_u8(password.GetAsString());
|
||||
return true;
|
||||
#else
|
||||
BOOST_LOG_TRIVIAL(error) << "wxUSE_SECRETSTORE not supported. Cannot load password from the system store.";
|
||||
return false;
|
||||
#endif // wxUSE_SECRETSTORE
|
||||
}
|
||||
}
|
||||
|
||||
void Plater::send_gcode()
|
||||
{
|
||||
// if physical_printer is selected, send gcode for this printer
|
||||
@ -5707,6 +5741,33 @@ void Plater::send_gcode()
|
||||
if (! physical_printer_config || p->model.objects.empty())
|
||||
return;
|
||||
|
||||
// Passwords and API keys
|
||||
// "stored" indicates data are stored secretly, load them from store.
|
||||
std::string printer_name = wxGetApp().preset_bundle->physical_printers.get_selected_printer().name;
|
||||
if (physical_printer_config->opt_string("printhost_password") == "stored" && physical_printer_config->opt_string("printhost_password") == "stored") {
|
||||
std::string username;
|
||||
std::string password;
|
||||
if (load_secret(printer_name, "printhost_password", username, password)) {
|
||||
if (!username.empty())
|
||||
physical_printer_config->opt_string("printhost_user") = username;
|
||||
if (!password.empty())
|
||||
physical_printer_config->opt_string("printhost_password") = password;
|
||||
}
|
||||
else {
|
||||
physical_printer_config->opt_string("printhost_user") = std::string();
|
||||
physical_printer_config->opt_string("printhost_password") = std::string();
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (physical_printer_config->opt_string("printhost_apikey") == "stored") {
|
||||
std::string username;
|
||||
std::string password;
|
||||
if (load_secret(printer_name, "printhost_apikey", username, password) && !password.empty())
|
||||
physical_printer_config->opt_string("printhost_apikey") = password;
|
||||
else
|
||||
physical_printer_config->opt_string("printhost_apikey") = std::string();
|
||||
}
|
||||
*/
|
||||
PrintHostJob upload_job(physical_printer_config);
|
||||
if (upload_job.empty())
|
||||
return;
|
||||
|
87
src/slic3r/Utils/Secrets.cpp
Normal file
87
src/slic3r/Utils/Secrets.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
#include "Secrets.hpp"
|
||||
#include <stdio.h>
|
||||
#if wxUSE_SECRETSTORE
|
||||
#include <wx/secretstore.h>
|
||||
#endif
|
||||
namespace Slic3r {
|
||||
|
||||
#if wxUSE_SECRETSTORE
|
||||
|
||||
static bool PrintResult(bool ok)
|
||||
{
|
||||
wxPuts(ok ? "ok" : "ERROR");
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool SelfTest(wxSecretStore& store, const wxString& service)
|
||||
{
|
||||
wxPrintf("Running the tests...\n");
|
||||
|
||||
const wxString userTest("test");
|
||||
const wxSecretValue secret1(6, "secret");
|
||||
|
||||
wxPrintf("Storing the password:\t");
|
||||
bool ok = store.Save(service, userTest, secret1);
|
||||
if ( !PrintResult(ok) )
|
||||
{
|
||||
// The rest of the tests will probably fail too, no need to continue.
|
||||
wxPrintf("Bailing out.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
wxPrintf("Loading the password:\t");
|
||||
wxSecretValue secret;
|
||||
wxString user;
|
||||
ok = PrintResult(store.Load(service, user, secret) &&
|
||||
user == userTest &&
|
||||
secret == secret1);
|
||||
|
||||
// Overwriting the password should work.
|
||||
const wxSecretValue secret2(6, "privet");
|
||||
|
||||
wxPrintf("Changing the password:\t");
|
||||
if ( PrintResult(store.Save(service, user, secret2)) )
|
||||
{
|
||||
wxPrintf("Reloading the password:\t");
|
||||
if ( !PrintResult(store.Load(service, user, secret) &&
|
||||
secret == secret2) )
|
||||
ok = false;
|
||||
}
|
||||
else
|
||||
ok = false;
|
||||
|
||||
wxPrintf("Deleting the password:\t");
|
||||
if ( !PrintResult(store.Delete(service)) )
|
||||
ok = false;
|
||||
|
||||
// This is supposed to fail now.
|
||||
wxPrintf("Deleting it again:\t");
|
||||
if ( !PrintResult(!store.Delete(service)) )
|
||||
ok = false;
|
||||
|
||||
// And loading should fail too.
|
||||
wxPrintf("Loading after deleting:\t");
|
||||
if ( !PrintResult(!store.Load(service, user, secret)) )
|
||||
ok = false;
|
||||
|
||||
if ( ok )
|
||||
wxPrintf("All tests passed!\n");
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
#endif //wxUSE_SECRETSTORE
|
||||
|
||||
bool check_secrets()
|
||||
{
|
||||
#if wxUSE_SECRETSTORE
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
|
||||
return SelfTest(store, "prusaslicer");
|
||||
#else
|
||||
printf("wxSecret not supported.\n");
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
10
src/slic3r/Utils/Secrets.hpp
Normal file
10
src/slic3r/Utils/Secrets.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef PRUSASLICER_SECRETS_HPP
|
||||
#define PRUSASLICER_SECRETS_HPP
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
bool check_secrets();
|
||||
|
||||
}
|
||||
|
||||
#endif // PRUSASLICER_SECRETS_HPP
|
@ -4,10 +4,12 @@ add_executable(${_TEST_NAME}_tests
|
||||
slic3r_jobs_tests.cpp
|
||||
slic3r_version_tests.cpp
|
||||
slic3r_arrangejob_tests.cpp
|
||||
secretstore_tests.cpp
|
||||
)
|
||||
|
||||
# mold linker for successful linking needs also to link TBB library and link it before libslic3r.
|
||||
target_link_libraries(${_TEST_NAME}_tests test_common TBB::tbb TBB::tbbmalloc libslic3r_gui libslic3r)
|
||||
|
||||
if (MSVC)
|
||||
target_link_libraries(${_TEST_NAME}_tests Setupapi.lib)
|
||||
endif ()
|
||||
|
8
tests/slic3rutils/secretstore_tests.cpp
Normal file
8
tests/slic3rutils/secretstore_tests.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
#include "slic3r/Utils/Secrets.hpp"
|
||||
|
||||
TEST_CASE("Secret store test", "[secretstore]") {
|
||||
|
||||
REQUIRE(Slic3r::check_secrets());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user