mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-03 13:51:37 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
391c53a8da |
@@ -360,7 +360,7 @@ void Layer::simplify_support_entity_collection(ExtrusionEntityCollection* entity
|
||||
//BBS: method to simplify support path
|
||||
void Layer::simplify_support_path(ExtrusionPath * path)
|
||||
{
|
||||
const auto print_config = this->object()->print()->config();
|
||||
const PrintConfig &print_config = this->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -375,7 +375,7 @@ void Layer::simplify_support_path(ExtrusionPath * path)
|
||||
//BBS: method to simplify support path
|
||||
void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath)
|
||||
{
|
||||
const auto print_config = this->object()->print()->config();
|
||||
const PrintConfig &print_config = this->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -392,7 +392,7 @@ void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath)
|
||||
//BBS: method to simplify support path
|
||||
void Layer::simplify_support_loop(ExtrusionLoop* loop)
|
||||
{
|
||||
const auto print_config = this->object()->print()->config();
|
||||
const PrintConfig &print_config = this->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
|
||||
@@ -1074,7 +1074,7 @@ void LayerRegion::simplify_entity_collection(ExtrusionEntityCollection* entity_c
|
||||
|
||||
void LayerRegion::simplify_path(ExtrusionPath* path)
|
||||
{
|
||||
const auto print_config = this->layer()->object()->print()->config();
|
||||
const PrintConfig &print_config = this->layer()->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -1092,7 +1092,7 @@ void LayerRegion::simplify_path(ExtrusionPath* path)
|
||||
|
||||
void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath)
|
||||
{
|
||||
const auto print_config = this->layer()->object()->print()->config();
|
||||
const PrintConfig &print_config = this->layer()->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
@@ -1112,7 +1112,7 @@ void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath)
|
||||
|
||||
void LayerRegion::simplify_loop(ExtrusionLoop* loop)
|
||||
{
|
||||
const auto print_config = this->layer()->object()->print()->config();
|
||||
const PrintConfig &print_config = this->layer()->object()->print()->config();
|
||||
const bool spiral_mode = print_config.spiral_mode;
|
||||
const bool enable_arc_fitting = print_config.enable_arc_fitting;
|
||||
const auto scaled_resolution = scaled<double>(print_config.resolution.value);
|
||||
|
||||
+13
-11
@@ -2604,6 +2604,11 @@ void Print::auto_assign_extruders(ModelObject* model_object) const
|
||||
|
||||
void PrintObject::set_shared_object(PrintObject *object)
|
||||
{
|
||||
// Orca: from now on m_layers / m_support_layers only alias the shared object's layers, so release the
|
||||
// ones this object still owns (it may have sliced itself before it became shareable again).
|
||||
// Both are no-ops once m_shared_object is set, so this cannot free layers owned by another object.
|
||||
clear_support_layers();
|
||||
clear_layers();
|
||||
m_shared_object = object;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, found shared object from %2%")%this%m_shared_object;
|
||||
}
|
||||
@@ -4329,9 +4334,9 @@ bool Print::is_dynamic_group_reorder() const
|
||||
return true;
|
||||
}
|
||||
|
||||
int Print::get_filament_config_indx(int filament_id, int layer_id, bool use_cache)
|
||||
int Print::get_filament_config_indx(int filament_id, int layer_id)
|
||||
{
|
||||
return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, use_cache ? &m_filament_index_map : nullptr);
|
||||
return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, m_filament_index_map);
|
||||
}
|
||||
|
||||
void Print::update_filament_self_index_cache()
|
||||
@@ -4374,7 +4379,7 @@ int Print::get_nozzle_config_index(int filament_id, int layer_id)
|
||||
return get_config_index(filament_id, layer_id, m_default_region_config.print_extruder_variant.values, m_default_region_config.print_extruder_id.values, m_nozzle_index_map);
|
||||
}
|
||||
|
||||
int Print::get_config_index(int filament_id, int layer_id, const std::vector<std::string> &variant_list, const std::vector<int>& self_index_list, FilamentIndexMap *index_map)
|
||||
int Print::get_config_index(int filament_id, int layer_id, const std::vector<std::string> &variant_list, const std::vector<int>& self_index_list, FilamentIndexMap &index_map)
|
||||
{
|
||||
auto group_result = get_layered_nozzle_group_result();
|
||||
// Orca: defensive — when no grouping producer has published a result yet, fall back to the
|
||||
@@ -4385,8 +4390,7 @@ int Print::get_config_index(int filament_id, int layer_id, const std::vector<std
|
||||
if (!nozzle_info.has_value()) {
|
||||
// Orca: this fallback runs per-filament/per-layer in the g-code hot path — log once per filament
|
||||
// (reset each slice) instead of flooding thousands of identical lines that bury the real error.
|
||||
// Without the cache, the log set is left alone too; the cached caller reports the same filament.
|
||||
if (index_map && m_missing_nozzle_group_logged.insert(filament_id).second)
|
||||
if (m_missing_nozzle_group_logged.insert(filament_id).second)
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__
|
||||
<< boost::format(", Line %1%: could not found group_nozzle_info corresponding to filament_id %2%, layer_id %3% (further occurrences for this filament suppressed)") % __LINE__ % filament_id %
|
||||
layer_id;
|
||||
@@ -4395,17 +4399,15 @@ int Print::get_config_index(int filament_id, int layer_id, const std::vector<std
|
||||
|
||||
ExtruderType extruder_type = ExtruderType(m_config.extruder_type.get_at(nozzle_info->extruder_id));
|
||||
NozzleVolumeType nozzle_volume_type = nozzle_info->volume_type;
|
||||
if (!index_map)
|
||||
return get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list);
|
||||
|
||||
FilamentIndexKey key{filament_id, extruder_type, nozzle_volume_type};
|
||||
auto iter = index_map->find(key);
|
||||
if (iter == index_map->end()) {
|
||||
auto iter = index_map.find(key);
|
||||
if (iter == index_map.end()) {
|
||||
int index = get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list);
|
||||
(*index_map)[key] = index;
|
||||
index_map[key] = index;
|
||||
return index;
|
||||
} else {
|
||||
return iter->second;
|
||||
return index_map[key];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -987,6 +987,9 @@ void PrintObject::generate_support_material()
|
||||
this->_generate_support_material();
|
||||
m_print->throw_if_canceled();
|
||||
}
|
||||
// Orca: the tree support collision/avoidance caches and support nodes are only used while this step runs
|
||||
// (detect_overhangs() rebuilds them from scratch), so don't keep them resident until the next slice.
|
||||
this->clear_tree_support_preview_cache();
|
||||
this->set_done(posSupportMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1346,7 +1346,7 @@ void PrintObject::slice_volumes()
|
||||
if (min_growth < 0.f || elfoot > 0.f) {
|
||||
// Apply the negative XY compensation. (the ones that is <0)
|
||||
ExPolygons trimming;
|
||||
static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5);
|
||||
const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5);
|
||||
if (elfoot > 0.f) {
|
||||
ExPolygons expolygons_to_compensate = offset_ex(layer->merged(eps), -eps);
|
||||
lslices_elfoot_uncompensated[layer_id] = expolygons_to_compensate;
|
||||
|
||||
@@ -1820,37 +1820,15 @@ coordf_t TreeSupport::get_radius(const SupportNode* node)
|
||||
return node->radius;
|
||||
}
|
||||
|
||||
ExPolygons TreeSupport::get_avoidance(coordf_t radius, size_t obj_layer_nr)
|
||||
// Orca: these are hit up to several times per node per layer in drop_nodes(), so hand out a
|
||||
// reference into the TreeSupportData cache instead of copying the ExPolygons out of it.
|
||||
const ExPolygons& TreeSupport::get_avoidance(coordf_t radius, size_t obj_layer_nr)
|
||||
{
|
||||
#if USE_SUPPORT_3D
|
||||
if (m_model_volumes) {
|
||||
bool on_build_plate = m_object_config->support_on_build_plate_only.value;
|
||||
const Polygons& avoid_polys = m_model_volumes->getAvoidance(radius, obj_layer_nr, TreeSupport3D::TreeModelVolumes::AvoidanceType::FastSafe, on_build_plate, true);
|
||||
ExPolygons expolys;
|
||||
for (auto& poly : avoid_polys)
|
||||
expolys.emplace_back(std::move(poly));
|
||||
return expolys;
|
||||
}
|
||||
return ExPolygons();
|
||||
#else
|
||||
return m_ts_data->get_avoidance(radius, obj_layer_nr);
|
||||
#endif
|
||||
}
|
||||
ExPolygons TreeSupport::get_collision(coordf_t radius, size_t layer_nr)
|
||||
const ExPolygons& TreeSupport::get_collision(coordf_t radius, size_t layer_nr)
|
||||
{
|
||||
#if USE_SUPPORT_3D
|
||||
if (m_model_volumes) {
|
||||
bool on_build_plate = m_object_config->support_on_build_plate_only.value;
|
||||
const Polygons& collision_polys = m_model_volumes->getCollision(radius, layer_nr, true);
|
||||
ExPolygons expolys;
|
||||
for (auto& poly : collision_polys)
|
||||
expolys.emplace_back(std::move(poly));
|
||||
return expolys;
|
||||
}
|
||||
#else
|
||||
return m_ts_data->get_collision(radius, layer_nr);
|
||||
#endif
|
||||
return ExPolygons();
|
||||
}
|
||||
Polygons TreeSupport::get_collision_polys(coordf_t radius, size_t layer_nr)
|
||||
{
|
||||
@@ -2639,7 +2617,11 @@ void TreeSupport::draw_circles()
|
||||
#endif // SUPPORT_TREE_DEBUG_TO_SVG
|
||||
|
||||
SupportLayerPtrs& ts_layers = m_object->support_layers();
|
||||
auto iter = std::remove_if(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height < EPSILON; });
|
||||
// Orca: the vector owns its layers, so the dropped ones have to be deleted, not just unlinked.
|
||||
// std::stable_partition (unlike std::remove_if) leaves exactly the dropped layers in the tail.
|
||||
auto iter = std::stable_partition(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height >= EPSILON; });
|
||||
for (auto it = iter; it != ts_layers.end(); ++it)
|
||||
delete *it;
|
||||
ts_layers.erase(iter, ts_layers.end());
|
||||
for (int layer_nr = 0; layer_nr < ts_layers.size(); layer_nr++) {
|
||||
ts_layers[layer_nr]->upper_layer = layer_nr != ts_layers.size() - 1 ? ts_layers[layer_nr + 1] : nullptr;
|
||||
@@ -2882,7 +2864,7 @@ void TreeSupport::drop_nodes()
|
||||
//Insert a completely new node and let both original nodes fade.
|
||||
Point next_position = (node.position + neighbours[0]) / 2; //Average position of the two nodes.
|
||||
coordf_t next_radius = calc_radius(node.dist_mm_to_top+height_next);
|
||||
auto avoid_layer = get_avoidance(next_radius, obj_layer_nr_next);
|
||||
const ExPolygons& avoid_layer = get_avoidance(next_radius, obj_layer_nr_next);
|
||||
if (group_index == 0)
|
||||
{
|
||||
//Avoid collisions.
|
||||
@@ -3069,7 +3051,7 @@ void TreeSupport::drop_nodes()
|
||||
}
|
||||
#endif
|
||||
coordf_t next_radius = calc_radius(node.dist_mm_to_top + height_next);
|
||||
auto avoidance_next = get_avoidance(next_radius, obj_layer_nr_next);
|
||||
const ExPolygons& avoidance_next = get_avoidance(next_radius, obj_layer_nr_next);
|
||||
|
||||
Point to_outside = projection_onto(avoidance_next, node.position);
|
||||
Point direction_to_outer = to_outside - node.position;
|
||||
@@ -3123,7 +3105,7 @@ void TreeSupport::drop_nodes()
|
||||
if (is_outside) { next_layer_vertex = candidate_vertex; }
|
||||
}
|
||||
}
|
||||
auto next_collision = get_collision(0, obj_layer_nr_next);
|
||||
const ExPolygons& next_collision = get_collision(0, obj_layer_nr_next);
|
||||
const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[obj_layer_nr_next], next_layer_vertex);
|
||||
// don't increase radius if next node will collide partially with the object (STUDIO-7883)
|
||||
to_outside = projection_onto(next_collision, next_layer_vertex);
|
||||
|
||||
@@ -511,9 +511,9 @@ private:
|
||||
coordf_t calc_branch_radius(coordf_t base_radius, coordf_t mm_to_top, double diameter_angle_scale_factor, bool use_min_distance=true);
|
||||
coordf_t calc_radius(coordf_t mm_to_top);
|
||||
coordf_t get_radius(const SupportNode* node);
|
||||
ExPolygons get_avoidance(coordf_t radius, size_t obj_layer_nr);
|
||||
const ExPolygons& get_avoidance(coordf_t radius, size_t obj_layer_nr);
|
||||
// layer's expolygon expanded by radius+m_xy_distance
|
||||
ExPolygons get_collision(coordf_t radius, size_t layer_nr);
|
||||
const ExPolygons& get_collision(coordf_t radius, size_t layer_nr);
|
||||
// get Polygons instead of ExPolygons
|
||||
Polygons get_collision_polys(coordf_t radius, size_t layer_nr);
|
||||
|
||||
|
||||
@@ -819,9 +819,7 @@ int OrcaCloudServiceAgent::user_logout(bool request)
|
||||
}
|
||||
}
|
||||
|
||||
// An explicit logout also wipes the backend the token storage option is not using, so a token
|
||||
// stranded by switching that option cannot sign the account back in later.
|
||||
clear_session(/*all_backends=*/request);
|
||||
clear_session();
|
||||
return BAMBU_NETWORK_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1606,9 +1604,7 @@ void OrcaCloudServiceAgent::persist_user_secret(const std::string& secret)
|
||||
}
|
||||
}
|
||||
|
||||
if (stored) {
|
||||
secret_stored = true;
|
||||
}
|
||||
(void) stored;
|
||||
}
|
||||
|
||||
bool OrcaCloudServiceAgent::load_user_secret(std::string& out_secret)
|
||||
@@ -1648,7 +1644,6 @@ bool OrcaCloudServiceAgent::load_user_secret(std::string& out_secret)
|
||||
}
|
||||
|
||||
if (integrity_ok && aes256gcm_decrypt(encoded_payload, key, plain) && !plain.empty()) {
|
||||
secret_stored = true;
|
||||
out_secret = plain;
|
||||
// Upgrade legacy payloads to signed format
|
||||
if (payload.rfind("v2:", 0) != 0) {
|
||||
@@ -1666,7 +1661,6 @@ bool OrcaCloudServiceAgent::load_user_secret(std::string& out_secret)
|
||||
if (store.Load(SECRET_STORE_SERVICE, username, secret) && secret.IsOk()) {
|
||||
out_secret.assign(static_cast<const char*>(secret.GetData()), secret.GetSize());
|
||||
if (!out_secret.empty()) {
|
||||
secret_stored = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1676,20 +1670,11 @@ bool OrcaCloudServiceAgent::load_user_secret(std::string& out_secret)
|
||||
return false;
|
||||
}
|
||||
|
||||
void OrcaCloudServiceAgent::clear_user_secret(bool all_backends)
|
||||
void OrcaCloudServiceAgent::clear_user_secret()
|
||||
{
|
||||
// Nothing this process loaded or saved: leave the store alone. Deleting would only cost a
|
||||
// keychain round trip (or a hang while the keychain is unresponsive) and could remove a
|
||||
// login another instance just saved.
|
||||
if (!secret_stored.exchange(false) && !all_backends) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (all_backends || !m_use_encrypted_token_file) {
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
if (store.IsOk()) {
|
||||
store.Delete(SECRET_STORE_SERVICE);
|
||||
}
|
||||
wxSecretStore store = wxSecretStore::GetDefault();
|
||||
if (store.IsOk()) {
|
||||
store.Delete(SECRET_STORE_SERVICE);
|
||||
}
|
||||
|
||||
compute_fallback_path();
|
||||
@@ -2038,13 +2023,13 @@ bool OrcaCloudServiceAgent::set_user_session(const json& session_json, bool noti
|
||||
return success;
|
||||
}
|
||||
|
||||
void OrcaCloudServiceAgent::clear_session(bool all_backends)
|
||||
void OrcaCloudServiceAgent::clear_session()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(session_mutex);
|
||||
session = SessionInfo{};
|
||||
}
|
||||
clear_user_secret(all_backends);
|
||||
clear_user_secret();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -326,7 +326,7 @@ public:
|
||||
|
||||
void persist_user_secret(const std::string& secret);
|
||||
bool load_user_secret(std::string& out_secret);
|
||||
void clear_user_secret(bool all_backends = false);
|
||||
void clear_user_secret();
|
||||
|
||||
// Token refresh helpers
|
||||
bool refresh_if_expiring(std::chrono::seconds skew, const std::string& reason);
|
||||
@@ -344,7 +344,7 @@ public:
|
||||
bool persist = true);
|
||||
// Accepts either nested Orca cloud / GoTrue session JSON or flat WebView token JSON.
|
||||
bool set_user_session(const nlohmann::json& session_json, bool notify_login = true);
|
||||
void clear_session(bool all_backends = false);
|
||||
void clear_session();
|
||||
|
||||
static std::string generate_uuid_for_setting_id(const std::string& name, const std::string& user_id = "");
|
||||
|
||||
@@ -413,11 +413,6 @@ private:
|
||||
// Member variables - auth state
|
||||
PkceBundle pkce_bundle;
|
||||
std::string secret_fallback_path;
|
||||
// Set once this process has read a secret from the store or written one. Unless the user logs
|
||||
// out explicitly, clear_user_secret() only touches the store while it is set, so a logged-out
|
||||
// instance (the GUI polls the login status every 2 s) makes no keychain calls and cannot wipe
|
||||
// a login another instance saved.
|
||||
std::atomic_bool secret_stored{false};
|
||||
SessionHandler session_handler;
|
||||
OnLoginCompleteHandler on_login_complete_handler;
|
||||
SessionInfo session;
|
||||
|
||||
@@ -13,7 +13,6 @@ add_executable(${_TEST_NAME}_tests
|
||||
test_prebuild_queue.cpp
|
||||
test_staged_build.cpp
|
||||
test_network_versions.cpp
|
||||
test_orca_cloud_agent.cpp
|
||||
test_action_source.cpp
|
||||
test_plugin_host_api.cpp
|
||||
# Exercise seam enums and predicates through the embedded Python host API.
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <memory.h>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <pybind11/embed.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
@@ -26,15 +25,8 @@ void ensure_python_initialized()
|
||||
config.parse_argv = 0;
|
||||
|
||||
const auto python_home = boost::dll::program_location().parent_path() / "python";
|
||||
#ifdef _WIN32
|
||||
const auto stdlib = python_home / "Lib";
|
||||
#else
|
||||
const auto stdlib = python_home / "lib" /
|
||||
("python" + std::to_string(PY_MAJOR_VERSION) + "." + std::to_string(PY_MINOR_VERSION));
|
||||
#endif
|
||||
|
||||
// Only a real runtime: a stray python/ folder (packages a test left behind) is not a home.
|
||||
if (boost::filesystem::exists(stdlib / "encodings")) {
|
||||
if (boost::filesystem::exists(python_home)) {
|
||||
const std::string home = python_home.string();
|
||||
const PyStatus status = PyConfig_SetBytesString(&config, &config.home, home.c_str());
|
||||
|
||||
|
||||
@@ -1,6 +1,39 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "slic3r/Utils/Http.hpp"
|
||||
#include "slic3r/Utils/OrcaCloudServiceAgent.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
nlohmann::json flat_session_json(const nlohmann::json& fields)
|
||||
{
|
||||
nlohmann::json session = {
|
||||
{"access_token", "test-token"},
|
||||
{"user_id", "test-user-id"}
|
||||
};
|
||||
session.update(fields);
|
||||
return session;
|
||||
}
|
||||
|
||||
nlohmann::json nested_session_json(const nlohmann::json& metadata)
|
||||
{
|
||||
return {
|
||||
{"access_token", "test-token"},
|
||||
{"user", {
|
||||
{"id", "test-user-id"},
|
||||
{"user_metadata", metadata}
|
||||
}}
|
||||
};
|
||||
}
|
||||
|
||||
std::string resolved_display_name(const nlohmann::json& session)
|
||||
{
|
||||
Slic3r::OrcaCloudServiceAgent agent("");
|
||||
REQUIRE(agent.set_user_session(session, false));
|
||||
return agent.get_user_nickname();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Check SSL certificates paths", "[Http][NotWorking]") {
|
||||
|
||||
@@ -20,6 +53,62 @@ TEST_CASE("Check SSL certificates paths", "[Http][NotWorking]") {
|
||||
REQUIRE(status == 200);
|
||||
}
|
||||
|
||||
TEST_CASE("Orca cloud flat session resolves display name consistently", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"display_name", "Display Name"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Display Name");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Nickname");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"full_name", "Full Name"}
|
||||
})) == "Full Name");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"name", "Provider Name"}
|
||||
})) == "Provider Name");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"}
|
||||
})) == "orca_username");
|
||||
}
|
||||
|
||||
TEST_CASE("Orca cloud nested session resolves display name consistently", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"display_name", "Display Name"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Display Name");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Nickname");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"full_name", "Full Name"}
|
||||
})) == "Full Name");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"name", "Provider Name"}
|
||||
})) == "Provider Name");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"}
|
||||
})) == "orca_username");
|
||||
}
|
||||
|
||||
TEST_CASE("Http digest authentication", "[Http][NotWorking]") {
|
||||
Slic3r::Http g = Slic3r::Http::get("https://httpbingo.org/digest-auth/auth/guest/guest");
|
||||
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "slic3r/Utils/OrcaCloudServiceAgent.hpp"
|
||||
#include "test_utils.hpp"
|
||||
|
||||
using namespace Slic3r;
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace {
|
||||
|
||||
// The encrypted token file is the one secret backend a test can observe without a system
|
||||
// keychain. Every agent pointed at the same directory shares it, like separate app instances
|
||||
// share the keychain entry.
|
||||
std::unique_ptr<OrcaCloudServiceAgent> make_file_backed_agent(const fs::path& dir)
|
||||
{
|
||||
auto agent = std::make_unique<OrcaCloudServiceAgent>(dir.string());
|
||||
agent->set_use_encrypted_token_file(true);
|
||||
agent->set_config_dir(dir.string());
|
||||
return agent;
|
||||
}
|
||||
|
||||
fs::path secret_file(const fs::path& dir) { return dir / secret_constants::USER_SECRET_FILENAME; }
|
||||
|
||||
nlohmann::json flat_session_json(const nlohmann::json& fields)
|
||||
{
|
||||
nlohmann::json session = {
|
||||
{"access_token", "test-token"},
|
||||
{"user_id", "test-user-id"}
|
||||
};
|
||||
session.update(fields);
|
||||
return session;
|
||||
}
|
||||
|
||||
nlohmann::json nested_session_json(const nlohmann::json& metadata)
|
||||
{
|
||||
return {
|
||||
{"access_token", "test-token"},
|
||||
{"user", {
|
||||
{"id", "test-user-id"},
|
||||
{"user_metadata", metadata}
|
||||
}}
|
||||
};
|
||||
}
|
||||
|
||||
// set_user_session() persists the session, so it goes to a throwaway token file rather than the
|
||||
// system keychain of whoever runs the tests.
|
||||
std::string resolved_display_name(const nlohmann::json& session)
|
||||
{
|
||||
ScopedTemporaryDir dir("orca-secret");
|
||||
auto agent = make_file_backed_agent(dir.path());
|
||||
REQUIRE(agent->set_user_session(session, false));
|
||||
return agent->get_user_nickname();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Logging out removes the secret this instance saved", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
ScopedTemporaryDir dir("orca-secret");
|
||||
auto agent = make_file_backed_agent(dir.path());
|
||||
|
||||
agent->persist_user_secret("refresh-token");
|
||||
REQUIRE(fs::exists(secret_file(dir.path())));
|
||||
|
||||
agent->user_logout(false);
|
||||
CHECK_FALSE(fs::exists(secret_file(dir.path())));
|
||||
}
|
||||
|
||||
TEST_CASE("Logging out removes a secret this instance loaded from the store", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
ScopedTemporaryDir dir("orca-secret");
|
||||
make_file_backed_agent(dir.path())->persist_user_secret("refresh-token");
|
||||
|
||||
auto agent = make_file_backed_agent(dir.path());
|
||||
std::string secret;
|
||||
REQUIRE(agent->load_user_secret(secret));
|
||||
CHECK(secret == "refresh-token");
|
||||
|
||||
agent->user_logout(false);
|
||||
CHECK_FALSE(fs::exists(secret_file(dir.path())));
|
||||
}
|
||||
|
||||
TEST_CASE("Logging out leaves a secret this instance never loaded or saved alone", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
ScopedTemporaryDir dir("orca-secret");
|
||||
make_file_backed_agent(dir.path())->persist_user_secret("refresh-token");
|
||||
|
||||
// A logged-out instance is asked to log out on every login-status poll.
|
||||
auto other = make_file_backed_agent(dir.path());
|
||||
other->user_logout(false);
|
||||
other->user_logout(false);
|
||||
CHECK(fs::exists(secret_file(dir.path())));
|
||||
|
||||
std::string secret;
|
||||
REQUIRE(make_file_backed_agent(dir.path())->load_user_secret(secret));
|
||||
CHECK(secret == "refresh-token");
|
||||
}
|
||||
|
||||
TEST_CASE("Logging out leaves a secret this instance could not read alone", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
ScopedTemporaryDir dir("orca-secret");
|
||||
// Written under another encryption key, e.g. by another OS user sharing the data directory.
|
||||
fs::ofstream(secret_file(dir.path())) << "v2:0000:not-a-payload-this-user-can-decrypt";
|
||||
|
||||
auto agent = make_file_backed_agent(dir.path());
|
||||
std::string secret;
|
||||
REQUIRE_FALSE(agent->load_user_secret(secret));
|
||||
|
||||
agent->user_logout(false);
|
||||
CHECK(fs::exists(secret_file(dir.path())));
|
||||
}
|
||||
|
||||
TEST_CASE("Orca cloud flat session resolves display name consistently", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"display_name", "Display Name"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Display Name");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Nickname");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"full_name", "Full Name"}
|
||||
})) == "Full Name");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"name", "Provider Name"}
|
||||
})) == "Provider Name");
|
||||
|
||||
CHECK(resolved_display_name(flat_session_json({
|
||||
{"username", "orca_username"}
|
||||
})) == "orca_username");
|
||||
}
|
||||
|
||||
TEST_CASE("Orca cloud nested session resolves display name consistently", "[OrcaCloudServiceAgent]")
|
||||
{
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"display_name", "Display Name"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Display Name");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"nickname", "Nickname"}
|
||||
})) == "Nickname");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"full_name", "Full Name"}
|
||||
})) == "Full Name");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"},
|
||||
{"name", "Provider Name"}
|
||||
})) == "Provider Name");
|
||||
|
||||
CHECK(resolved_display_name(nested_session_json({
|
||||
{"username", "orca_username"}
|
||||
})) == "orca_username");
|
||||
}
|
||||
@@ -38,9 +38,6 @@ namespace {
|
||||
// before this destructor's shutdown() runs.
|
||||
struct ScopedPluginManager
|
||||
{
|
||||
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
|
||||
// which would otherwise land in the working directory.
|
||||
ScopedDataDir python_data_dir{"plugin-python"};
|
||||
bool initialized = PluginManager::instance().initialize();
|
||||
|
||||
~ScopedPluginManager()
|
||||
|
||||
@@ -31,9 +31,6 @@ namespace {
|
||||
// same as any other plugin.
|
||||
struct ScopedManagerShutdown
|
||||
{
|
||||
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
|
||||
// which would otherwise land in the working directory.
|
||||
ScopedDataDir python_data_dir{"plugin-python"};
|
||||
bool initialized = PluginManager::instance().initialize();
|
||||
|
||||
~ScopedManagerShutdown()
|
||||
|
||||
@@ -42,9 +42,6 @@ namespace {
|
||||
// Declare this FIRST in a test so it is destroyed last.
|
||||
struct ScopedPluginManager
|
||||
{
|
||||
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
|
||||
// which would otherwise land in the working directory.
|
||||
ScopedDataDir python_data_dir{"plugin-python"};
|
||||
bool initialized = false;
|
||||
|
||||
ScopedPluginManager() { initialized = PluginManager::instance().initialize(); }
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "plugin_test_utils.hpp"
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace Slic3r;
|
||||
|
||||
@@ -23,9 +21,6 @@ namespace {
|
||||
// into Python unless PythonInterpreter::instance() reports initialized.
|
||||
struct ScopedPluginManager
|
||||
{
|
||||
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
|
||||
// which would otherwise land in the working directory.
|
||||
ScopedDataDir python_data_dir{"plugin-python"};
|
||||
bool initialized = PluginManager::instance().initialize();
|
||||
|
||||
~ScopedPluginManager()
|
||||
|
||||
@@ -35,9 +35,6 @@ namespace {
|
||||
|
||||
struct ScopedPluginManager
|
||||
{
|
||||
// Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log,
|
||||
// which would otherwise land in the working directory.
|
||||
ScopedDataDir python_data_dir{"plugin-python"};
|
||||
bool initialized = false;
|
||||
|
||||
ScopedPluginManager() { initialized = PluginManager::instance().initialize(); }
|
||||
|
||||
Reference in New Issue
Block a user