Mercurial > hg > orthanc-wsi
view ViewerPlugin/Annotations/UserLayer.cpp @ 613:617f25e606d6 default tip
back to mainline
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Thu, 10 Sep 2026 10:35:58 +0200 |
| parents | 11f795017763 |
| children |
line wrap: on
line source
/** * Orthanc - A Lightweight, RESTful DICOM Store * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017-2023 Osimis S.A., Belgium * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "../../Framework/PrecompiledHeadersWSI.h" #include "UserLayer.h" #include "../ViewerConfiguration.h" #include <OrthancException.h> #include <SerializationToolbox.h> #include <Toolbox.h> #include <cassert> static const char* const KEY_COLOR = "color"; static const char* const KEY_ID = "id"; static const char* const KEY_NAME = "name"; static const char* const KEY_PUBLIC = "public"; static const char* const KEY_SHARED_WITH = "shared_with"; static const char* const KEY_VISIBLE = "visible"; namespace OrthancWSI { UserLayer::UserLayer(const BackgroundColor& color, const std::string& name) : isVisible_(true), color_(color), id_(Orthanc::Toolbox::GenerateUuid()), name_(name), isPublic_(false) { } UserLayer::UserLayer(const Json::Value& serialized) { if (!serialized.isObject() || !serialized.isMember(KEY_SHARED_WITH) || !serialized[KEY_SHARED_WITH].isArray()) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } isVisible_ = Orthanc::SerializationToolbox::ReadBoolean(serialized, KEY_VISIBLE); color_ = BackgroundColor::FromHexadecimalString(Orthanc::SerializationToolbox::ReadString(serialized, KEY_COLOR)); id_ = Orthanc::SerializationToolbox::ReadString(serialized, KEY_ID); name_ = Orthanc::SerializationToolbox::ReadString(serialized, KEY_NAME); isPublic_ = Orthanc::SerializationToolbox::ReadBoolean(serialized, KEY_PUBLIC); const Json::Value& v = serialized[KEY_SHARED_WITH]; for (Json::Value::ArrayIndex i = 0; i < v.size(); i++) { sharedWith_.insert(UserId(v[i])); } } bool UserLayer::IsSharedWith(ProjectRole authorRole, const UserId& viewerId, ProjectRole viewerRole) const { /** Instructors can see: - All layers tagged "publicly shared with instructors" (i.e. public), created by anyone (instructors or learners). - Any layer explicitly shared with them, by anyone. Learners can see: - All layers tagged public that were created by instructors (this is true "class-wide public" for instructor content). - Any instructor layer explicitly shared with them. - Any learner layer explicitly shared with them by name, only if learner-to-learner sharing is enabled (cf. configuration option "EnableLearnerToLearnerSharing"). Note 1: Learner layers tagged "public" are visible only to instructors, never to other learners, regardless of the learner-to-learner sharing configuration. This is a deliberate asymmetry: for a learner, "public" means "submitted/visible to instructors," not "visible to the class." This prevents one learner's work from becoming broadcast to the whole cohort, while still allowing small, named-group collaboration (e.g., project teams) through explicit sharing. Note 2: Learner-to-learner sharing (configuration option) governs only the explicit-share-list channel between learners. It has no effect on instructor visibility and no effect on the behavior of the "public" tag (public learner layers are never learner-visible whether this option is "true" or "false"). **/ if (viewerId.GetType() != UserId::Type_Standard) { return false; } const bool explicitlyShared = sharedWith_.find(viewerId) != sharedWith_.end(); switch (authorRole) { case ProjectRole_Instructor: // Instructor layers: "public" truly means public to everyone, // and explicit sharing is unconditional return isPublic_ || explicitlyShared; case ProjectRole_Learner: switch (viewerRole) { case ProjectRole_Instructor: // Instructors see public learner layers, and anything shared with them return isPublic_ || explicitlyShared; case ProjectRole_Learner: // Learner viewing another learner's layer: "public" never applies, // explicit sharing is gated by the configuration switch. return explicitlyShared && ViewerConfiguration::GetInstance().IsLearnerToLearnerSharingEnabled(); case ProjectRole_Guest: throw Orthanc::OrthancException(Orthanc::ErrorCode_ForbiddenAccess); default: throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } case ProjectRole_Guest: throw Orthanc::OrthancException(Orthanc::ErrorCode_ForbiddenAccess); default: throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } } void UserLayer::Assign(const UserLayer& other) { if (other.GetId() != id_) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } else { isVisible_ = other.isVisible_; color_ = other.color_; name_ = other.name_; sharedWith_ = other.sharedWith_; isPublic_ = other.isPublic_; } } void UserLayer::Serialize(Json::Value& serialized) const { Json::Value sharedWith = Json::arrayValue; for (std::set<UserId>::const_iterator it = sharedWith_.begin(); it != sharedWith_.end(); ++it) { Json::Value item; it->Serialize(item); sharedWith.append(item); } serialized = Json::objectValue; serialized[KEY_VISIBLE] = isVisible_; serialized[KEY_COLOR] = color_.ToHexadecimalString(); serialized[KEY_ID] = id_; serialized[KEY_NAME] = name_; serialized[KEY_PUBLIC] = isPublic_; serialized[KEY_SHARED_WITH] = sharedWith; } }
