From ce06fc6cb7bc09df8fcc18b006b780f9f16da9d0 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Tue, 8 Sep 2020 15:30:59 +0200 Subject: Added networking support for SL1 Digest authorization. Renamed login/password/authorization_type to printhost_user/printhost_password/printhost_authorization_type. Added initialization of physical printer preset with default values. --- src/libslic3r/Preset.cpp | 34 ++++++++++++++++++++------------ src/libslic3r/Preset.hpp | 17 ++++++++-------- src/libslic3r/PrintConfig.cpp | 8 ++++---- src/slic3r/GUI/Field.cpp | 2 +- src/slic3r/GUI/GUI.cpp | 2 +- src/slic3r/GUI/OptionsGroup.cpp | 2 +- src/slic3r/GUI/PhysicalPrinterDialog.cpp | 24 +++++++++++----------- src/slic3r/Utils/Http.cpp | 10 ++++++++++ src/slic3r/Utils/Http.hpp | 2 ++ src/slic3r/Utils/OctoPrint.cpp | 23 +++++++++++++++++++++ src/slic3r/Utils/OctoPrint.hpp | 15 ++++++++++++-- 11 files changed, 98 insertions(+), 41 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 7aaa96c8c..284c37435 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1365,9 +1365,10 @@ const std::vector& PhysicalPrinter::printer_options() "print_host", "printhost_apikey", "printhost_cafile", - "authorization_type", - "login", - "password" + "printhost_authorization_type", + // HTTP digest authentization (RFC 2617) + "printhost_user", + "printhost_password" }; } return s_opts; @@ -1412,11 +1413,11 @@ const std::set& PhysicalPrinter::get_preset_names() const bool PhysicalPrinter::has_empty_config() const { - return config.opt_string("print_host" ).empty() && - config.opt_string("printhost_apikey").empty() && - config.opt_string("printhost_cafile").empty() && - config.opt_string("login" ).empty() && - config.opt_string("password" ).empty(); + return config.opt_string("print_host" ).empty() && + config.opt_string("printhost_apikey" ).empty() && + config.opt_string("printhost_cafile" ).empty() && + config.opt_string("printhost_user" ).empty() && + config.opt_string("printhost_password").empty(); } void PhysicalPrinter::update_preset_names_in_config() @@ -1441,7 +1442,7 @@ void PhysicalPrinter::save(const std::string& file_name_from, const std::string& void PhysicalPrinter::update_from_preset(const Preset& preset) { - config.apply_only(preset.config, printer_options(), false); + config.apply_only(preset.config, printer_options(), true); // add preset names to the options list auto ret = preset_names.emplace(preset.name); update_preset_names_in_config(); @@ -1476,8 +1477,8 @@ bool PhysicalPrinter::delete_preset(const std::string& preset_name) return preset_names.erase(preset_name) > 0; } -PhysicalPrinter::PhysicalPrinter(const std::string& name, const Preset& preset) : - name(name) +PhysicalPrinter::PhysicalPrinter(const std::string& name, const DynamicPrintConfig &default_config, const Preset& preset) : + name(name), config(default_config) { update_from_preset(preset); } @@ -1514,6 +1515,13 @@ std::string PhysicalPrinter::get_preset_name(std::string name) PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector& keys) { + // Default config for a physical printer containing all key/value pairs of PhysicalPrinter::printer_options(). + for (const std::string &key : keys) { + const ConfigOptionDef *opt = print_config_def.get(key); + assert(opt); + assert(opt->default_value); + m_default_config.set_key_value(key, opt->default_value->clone()); + } } // Load all printers found in dir_path. @@ -1539,7 +1547,7 @@ void PhysicalPrinterCollection::load_printers(const std::string& dir_path, const continue; } try { - PhysicalPrinter printer(name); + PhysicalPrinter printer(name, this->default_config()); printer.file = dir_entry.path().string(); // Load the preset file, apply preset values on top of defaults. try { @@ -1590,7 +1598,7 @@ void PhysicalPrinterCollection::load_printers_from_presets(PrinterPresetCollecti new_printer_name = (boost::format("Printer %1%") % ++cnt).str(); // create new printer from this preset - PhysicalPrinter printer(new_printer_name, preset); + PhysicalPrinter printer(new_printer_name, this->default_config(), preset); printer.loaded = true; save_printer(printer); } diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 30edfc859..ec11d59fa 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -460,8 +460,7 @@ private: // If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name. std::deque::iterator find_preset_internal(const std::string &name) { - Preset key(m_type, name); - auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key); + auto it = Slic3r::lower_bound_by_predicate(m_presets.begin() + m_num_default_presets, m_presets.end(), [&name](const auto& l) { return l.name < name; }); if (it == m_presets.end() || it->name != name) { // Preset has not been not found in the sorted list of non-default presets. Try the defaults. for (size_t i = 0; i < m_num_default_presets; ++ i) @@ -539,9 +538,8 @@ namespace PresetUtils { class PhysicalPrinter { public: - PhysicalPrinter() {} - PhysicalPrinter(const std::string& name) : name(name){} - PhysicalPrinter(const std::string& name, const Preset& preset); + PhysicalPrinter(const std::string& name, const DynamicPrintConfig &default_config) : name(name), config(default_config) {} + PhysicalPrinter(const std::string& name, const DynamicPrintConfig &default_config, const Preset& preset); void set_name(const std::string &name); // Name of the Physical Printer, usually derived form the file name. @@ -698,6 +696,8 @@ public: // Generate a file path from a profile name. Add the ".ini" suffix if it is missing. std::string path_from_name(const std::string& new_name) const; + const DynamicPrintConfig& default_config() const { return m_default_config; } + private: PhysicalPrinterCollection& operator=(const PhysicalPrinterCollection& other); @@ -707,9 +707,7 @@ private: // If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name. std::deque::iterator find_printer_internal(const std::string& name) { - PhysicalPrinter printer(name); - auto it = std::lower_bound(m_printers.begin(), m_printers.end(), printer); - return it; + return Slic3r::lower_bound_by_predicate(m_printers.begin(), m_printers.end(), [&name](const auto& l) { return l.name < name; }); } std::deque::const_iterator find_printer_internal(const std::string& name) const { @@ -723,6 +721,9 @@ private: // so that the addresses of the presets don't change during resizing of the container. std::deque m_printers; + // Default config for a physical printer containing all key/value pairs of PhysicalPrinter::printer_options(). + DynamicPrintConfig m_default_config; + // Selected printer. size_t m_idx_selected = size_t(-1); // The name of the preset which is currently select for this printer diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 770983ad5..239969a1d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -133,13 +133,13 @@ void PrintConfigDef::init_common_params() // Options used by physical printers - def = this->add("login", coString); - def->label = L("Login"); + def = this->add("printhost_user", coString); + def->label = L("User"); // def->tooltip = L(""); def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); - def = this->add("password", coString); + def = this->add("printhost_password", coString); def->label = L("Password"); // def->tooltip = L(""); def->mode = comAdvanced; @@ -151,7 +151,7 @@ void PrintConfigDef::init_common_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionString("")); - def = this->add("authorization_type", coEnum); + def = this->add("printhost_authorization_type", coEnum); def->label = L("Authorization Type"); // def->tooltip = L(""); def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 9cb3d726d..a21826205 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -1080,7 +1080,7 @@ boost::any& Choice::get_value() m_value = static_cast(ret_enum); else if (m_opt_id.compare("support_pillar_connection_mode") == 0) m_value = static_cast(ret_enum); - else if (m_opt_id == "authorization_type") + else if (m_opt_id == "printhost_authorization_type") m_value = static_cast(ret_enum); } else if (m_opt.gui_type == "f_enum_open") { diff --git a/src/slic3r/GUI/GUI.cpp b/src/slic3r/GUI/GUI.cpp index 913716dfd..6c76b6227 100644 --- a/src/slic3r/GUI/GUI.cpp +++ b/src/slic3r/GUI/GUI.cpp @@ -194,7 +194,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); else if(opt_key.compare("support_pillar_connection_mode") == 0) config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); - else if(opt_key == "authorization_type") + else if(opt_key == "printhost_authorization_type") config.set_key_value(opt_key, new ConfigOptionEnum(boost::any_cast(value))); } break; diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index cc10d815f..dd00b3d68 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -755,7 +755,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config else if (opt_key == "support_pillar_connection_mode") { ret = static_cast(config.option>(opt_key)->value); } - else if (opt_key == "authorization_type") { + else if (opt_key == "printhost_authorization_type") { ret = static_cast(config.option>(opt_key)->value); } } diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 12d1cd287..ca2d62556 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -155,8 +155,9 @@ void PresetForPrinter::msw_rescale() // PhysicalPrinterDialog //------------------------------------------ -PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name) - : DPIDialog(NULL, wxID_ANY, _L("Physical Printer"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name) : + DPIDialog(NULL, wxID_ANY, _L("Physical Printer"), wxDefaultPosition, wxSize(45 * wxGetApp().em_unit(), -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + m_printer("", wxGetApp().preset_bundle->physical_printers.default_config()) { SetFont(wxGetApp().normal_font()); SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); @@ -186,7 +187,8 @@ PhysicalPrinterDialog::PhysicalPrinterDialog(wxString printer_name) PhysicalPrinter* printer = printers.find_printer(into_u8(printer_name)); if (!printer) { const Preset& preset = wxGetApp().preset_bundle->printers.get_edited_preset(); - printer = new PhysicalPrinter(into_u8(printer_name), preset); + //FIXME Vojtech: WTF??? Memory leak? + printer = new PhysicalPrinter(into_u8(printer_name), m_printer.config, preset); // if printer_name is empty it means that new printer is created, so enable all items in the preset list m_presets.emplace_back(new PresetForPrinter(this, preset.name)); } @@ -249,7 +251,7 @@ PhysicalPrinterDialog::~PhysicalPrinterDialog() void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgroup) { m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { - if (opt_key == "authorization_type") + if (opt_key == "printhost_authorization_type") this->update(); }; @@ -308,7 +310,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr host_line.append_widget(print_host_test); m_optgroup->append_line(host_line); - m_optgroup->append_single_option_line("authorization_type"); + m_optgroup->append_single_option_line("printhost_authorization_type"); option = m_optgroup->get_option("printhost_apikey"); option.opt.width = Field::def_width_wider(); @@ -368,7 +370,7 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr m_optgroup->append_line(line); } - for (const std::string& opt_key : std::vector{ "login", "password" }) { + 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(); m_optgroup->append_single_option_line(option); @@ -385,20 +387,20 @@ void PhysicalPrinterDialog::update() // Only offer the host type selection for FFF, for SLA it's always the SL1 printer (at the moment) if (tech == ptFFF) { m_optgroup->show_field("host_type"); - m_optgroup->hide_field("authorization_type"); - for (const std::string& opt_key : std::vector{ "login", "password" }) + m_optgroup->hide_field("printhost_authorization_type"); + for (const std::string& opt_key : std::vector{ "printhost_user", "printhost_password" }) m_optgroup->hide_field(opt_key); } else { m_optgroup->set_value("host_type", int(PrintHostType::htOctoPrint), false); m_optgroup->hide_field("host_type"); - m_optgroup->show_field("authorization_type"); + m_optgroup->show_field("printhost_authorization_type"); - AuthorizationType auth_type = m_config->option>("authorization_type")->value; + AuthorizationType auth_type = m_config->option>("printhost_authorization_type")->value; m_optgroup->show_field("printhost_apikey", auth_type == AuthorizationType::atKeyPassword); - for (const std::string& opt_key : std::vector{ "login", "password" }) + for (const std::string& opt_key : std::vector{ "printhost_user", "printhost_password" }) m_optgroup->show_field(opt_key, auth_type == AuthorizationType::atUserPassword); } diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index a16aac5b5..e55c21fe1 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -415,6 +415,16 @@ Http& Http::remove_header(std::string name) return *this; } +// Authorization by HTTP digest, based on RFC2617. +Http& Http::auth_digest(const std::string &user, const std::string &password) +{ + curl_easy_setopt(p->curl, CURLOPT_USERNAME, user.c_str()); + curl_easy_setopt(p->curl, CURLOPT_PASSWORD, password.c_str()); + curl_easy_setopt(p->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + + return *this; +} + Http& Http::ca_file(const std::string &name) { if (p && priv::ca_file_supported(p->curl)) { diff --git a/src/slic3r/Utils/Http.hpp b/src/slic3r/Utils/Http.hpp index f16236279..ae3660fbf 100644 --- a/src/slic3r/Utils/Http.hpp +++ b/src/slic3r/Utils/Http.hpp @@ -64,6 +64,8 @@ public: Http& header(std::string name, const std::string &value); // Removes a header field. Http& remove_header(std::string name); + // Authorization by HTTP digest, based on RFC2617. + Http& auth_digest(const std::string &user, const std::string &password); // Sets a CA certificate file for usage with HTTPS. This is only supported on some backends, // specifically, this is supported with OpenSSL and NOT supported with Windows and OS X native certificate store. // See also ca_file_supported(). diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index ee87f822f..82d8a6bb6 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -170,6 +170,13 @@ std::string OctoPrint::make_url(const std::string &path) const } } +SL1Host::SL1Host(DynamicPrintConfig *config) : + OctoPrint(config), + authorization_type(dynamic_cast*>(config->option("printhost_authorization_type"))->value), + username(config->opt_string("printhost_user")), + password(config->opt_string("printhost_password")) +{ +} // SL1Host const char* SL1Host::get_name() const { return "SL1Host"; } @@ -191,4 +198,20 @@ bool SL1Host::validate_version_text(const boost::optional &version_ return version_text ? boost::starts_with(*version_text, "Prusa SLA") : false; } +void SL1Host::set_auth(Http &http) const +{ + switch (authorization_type) { + case atKeyPassword: + http.header("X-Api-Key", get_apikey()); + break; + case atUserPassword: + http.auth_digest(username, password); + break; + } + + if (! get_cafile().empty()) { + http.ca_file(get_cafile()); + } +} + } diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index 965019d85..4f8e4819f 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -29,6 +29,8 @@ public: bool can_test() const override { return true; } bool can_start_print() const override { return true; } std::string get_host() const override { return host; } + const std::string& get_apikey() const { return apikey; } + const std::string& get_cafile() const { return cafile; } protected: virtual bool validate_version_text(const boost::optional &version_text) const; @@ -38,14 +40,14 @@ private: std::string apikey; std::string cafile; - void set_auth(Http &http) const; + virtual void set_auth(Http &http) const; std::string make_url(const std::string &path) const; }; class SL1Host: public OctoPrint { public: - SL1Host(DynamicPrintConfig *config) : OctoPrint(config) {} + SL1Host(DynamicPrintConfig *config); ~SL1Host() override = default; const char* get_name() const override; @@ -56,6 +58,15 @@ public: protected: bool validate_version_text(const boost::optional &version_text) const override; + +private: + void set_auth(Http &http) const override; + + // Host authorization type. + AuthorizationType authorization_type; + // username and password for HTTP Digest Authentization (RFC RFC2617) + std::string username; + std::string password; }; } -- cgit v1.2.3