diff --git a/CMakeLists.txt b/CMakeLists.txt index 25aff34d46..b090ec3fd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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.") diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake new file mode 100644 index 0000000000..05b7a88b79 --- /dev/null +++ b/deps/wxWidgets/wxWidgets.cmake @@ -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 () \ No newline at end of file diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 24bbe7a5b1..46126a621c 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -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; } diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index b4fb5ce27d..b7d241abcf 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -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 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; + } } } diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 1e6aa1caa1..ddd22f348a 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -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 secret_callback = nullptr); // Enable / disable the "- default -" preset. void set_default_suppressed(bool default_suppressed); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 391db4309e..e47f898082 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -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("")); diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index fea794c943..2ba2a16893 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -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) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 7c28b9eb36..7ca9dc045b 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -23,6 +23,9 @@ //#include #include #include +#if wxUSE_SECRETSTORE +#include +#endif #include #include @@ -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 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()); } diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 69902545a3..8d599efd8c 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,10 @@ #include #include #include +#if wxUSE_SECRETSTORE +#include +#endif +#include #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& 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(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{ "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); diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.hpp b/src/slic3r/GUI/PhysicalPrinterDialog.hpp index 0de8df235f..2a26e1bf1e 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.hpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.hpp @@ -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}; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index bbfbc57088..cd1c5e4ea3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -50,6 +50,9 @@ #include #include #include +#if wxUSE_SECRETSTORE +#include +#endif #include @@ -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; diff --git a/src/slic3r/Utils/Secrets.cpp b/src/slic3r/Utils/Secrets.cpp new file mode 100644 index 0000000000..5ca28aba4e --- /dev/null +++ b/src/slic3r/Utils/Secrets.cpp @@ -0,0 +1,87 @@ +#include "Secrets.hpp" +#include +#if wxUSE_SECRETSTORE +#include +#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 diff --git a/src/slic3r/Utils/Secrets.hpp b/src/slic3r/Utils/Secrets.hpp new file mode 100644 index 0000000000..43cdf206a8 --- /dev/null +++ b/src/slic3r/Utils/Secrets.hpp @@ -0,0 +1,10 @@ +#ifndef PRUSASLICER_SECRETS_HPP +#define PRUSASLICER_SECRETS_HPP + +namespace Slic3r { + +bool check_secrets(); + +} + +#endif // PRUSASLICER_SECRETS_HPP diff --git a/tests/slic3rutils/CMakeLists.txt b/tests/slic3rutils/CMakeLists.txt index f207916f67..ac025ce46c 100644 --- a/tests/slic3rutils/CMakeLists.txt +++ b/tests/slic3rutils/CMakeLists.txt @@ -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 () diff --git a/tests/slic3rutils/secretstore_tests.cpp b/tests/slic3rutils/secretstore_tests.cpp new file mode 100644 index 0000000000..5821305092 --- /dev/null +++ b/tests/slic3rutils/secretstore_tests.cpp @@ -0,0 +1,8 @@ +#include "catch2/catch.hpp" + +#include "slic3r/Utils/Secrets.hpp" + +TEST_CASE("Secret store test", "[secretstore]") { + + REQUIRE(Slic3r::check_secrets()); +}