changeset 285:0b0222d3a7f9 default tip

new permissions for /modalities/../configuration + unit tests for permissions
author Alain Mazy <am@orthanc.team>
date Thu, 28 Aug 2025 09:46:10 +0200
parents a9af7e0fa172
children
files Plugin/DefaultConfiguration.json UnitTestsSources/UnitTestsMain.cpp
diffstat 2 files changed, 57 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/Plugin/DefaultConfiguration.json	Tue Aug 26 12:10:48 2025 +0200
+++ b/Plugin/DefaultConfiguration.json	Thu Aug 28 09:46:10 2025 +0200
@@ -94,8 +94,9 @@
             ["get" , "^/jobs/([a-f0-9-]+)$", "all|send|modify|anonymize|q-r-remote-modalities"],
 
             // interacting with peers/modalities/dicomweb
-            ["post", "^/(peers|modalities)/(.*)/store$", "all|send"],
+            ["post", "^/(peers|modalities)/(.*)/(store|store-straight)$", "all|send"],
             ["get" , "^/(peers|modalities)$", "all|send|q-r-remote-modalities"],
+            ["get" , "^/(peers|modalities)/(.*)/configuration$", "all|send|q-r-remote-modalities"],
             ["post", "^/modalities/(.*)/echo$", "all|send|q-r-remote-modalities"],
             ["post", "^/modalities/(.*)/query$", "all|q-r-remote-modalities"],
             ["get", "^/queries/([a-f0-9-]+)/answers$", "all|q-r-remote-modalities"],
--- a/UnitTestsSources/UnitTestsMain.cpp	Tue Aug 26 12:10:48 2025 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Thu Aug 28 09:46:10 2025 +0200
@@ -30,6 +30,10 @@
 #include "../Plugin/MemoryCache.h"
 #include "../Plugin/PermissionParser.h"
 #include "../Plugin/ResourceHierarchyCache.h"
+#include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h"
+#include <Logging.h>
+#include <EmbeddedResources.h>
+
 
 extern void AdjustToolsFindQueryLabels(Json::Value& query, const OrthancPlugins::IAuthorizationService::UserProfile& profile);
 
@@ -586,108 +590,71 @@
   }
 }
 
-// TEST(ToolsFindLabels, AdjustQueryForUserWithForbiddenLabelsRestrictions)
-// {
-//   // user who has forbidden access to "b" and "c"
-//   OrthancPlugins::IAuthorizationService::UserProfile profile;
-//   profile.forbiddenLabels.insert("b");
-//   profile.forbiddenLabels.insert("c");
+void TestPermissions(PermissionParser& permParser, const std::string& uri, OrthancPluginHttpMethod method, const std::string& expectedPermissions)
+{
+  LOG(WARNING) << "testing permission on '" << uri << "'";
+  std::set<std::string> permissions;
+  std::vector<std::string> expectedPermissions_;
+  Orthanc::Toolbox::SplitString(expectedPermissions_, expectedPermissions, '|');
+  std::string matchedPattern;
 
-//   { // no labels before transformation -> "b", "c" label after (with a 'None' constraint)
-//     Json::Value query;
-//     query["Query"] = Json::objectValue;
-//     query["Query"]["PatientID"] = "*";
-
-//     AdjustToolsFindQueryLabels(query, profile);
-
-//     ASSERT_EQ(2u, query["Labels"].size());
-//     ASSERT_TRUE(IsInJsonArray("b", query["Labels"]));
-//     ASSERT_TRUE(IsInJsonArray("c", query["Labels"]));
-//     ASSERT_EQ("None", query["LabelsConstraint"].asString());
-//   }
+  ASSERT_TRUE(permParser.Parse(permissions, matchedPattern, method, uri));
+  ASSERT_EQ(expectedPermissions_.size(), permissions.size());
 
-//   { // missing LabelsConstraint -> throw
-//     Json::Value query;
-//     query["Query"] = Json::objectValue;
-//     query["Query"]["PatientID"] = "*";
-//     query["Labels"] = Json::arrayValue;
-//     query["Labels"].append("a");
-
-//     ASSERT_THROW(AdjustToolsFindQueryLabels(query, profile), Orthanc::OrthancException);
-//   }
+  for (size_t i = 0; i < expectedPermissions_.size(); ++i)
+  {
+    ASSERT_TRUE(permissions.find(expectedPermissions_[i]) != permissions.end());
+  }
+}
 
-//   { // 'All' label constraint can not be modified for user with forbidden labels
-//     Json::Value query;
-//     query["Query"] = Json::objectValue;
-//     query["Query"]["PatientID"] = "*";
-//     query["Labels"] = Json::arrayValue;
-//     query["Labels"].append("b");
-//     query["Labels"].append("c");
-//     query["LabelsConstraint"] = "All";
-
-//     ASSERT_THROW(AdjustToolsFindQueryLabels(query, profile), Orthanc::OrthancException);
-//   }
+TEST(PermissionParser, Basic)
+{
+  MemoryCache::Factory factory(10);
+  DefaultAuthorizationParser authorizationParser(factory, "/dicom-web/");
 
-//   { // 'Any' label constraint can not be modified for user with forbidden labels
-//     Json::Value query;
-//     query["Query"] = Json::objectValue;
-//     query["Query"]["PatientID"] = "*";
-//     query["Labels"] = Json::arrayValue;
-//     query["Labels"].append("b");
-//     query["Labels"].append("c");
-//     query["LabelsConstraint"] = "Any";
-
-//     ASSERT_THROW(AdjustToolsFindQueryLabels(query, profile), Orthanc::OrthancException);
-//   }
+  std::string defaultConfigurationFileContent;
+  Orthanc::EmbeddedResources::GetFileResource(defaultConfigurationFileContent, Orthanc::EmbeddedResources::DEFAULT_CONFIGURATION);
+  Json::Value pluginJsonDefaultConfiguration;
+  OrthancPlugins::ReadJsonWithoutComments(pluginJsonDefaultConfiguration, defaultConfigurationFileContent);
+  
+  PermissionParser permParser("/dicom-web/", "/ui/");
 
-//   { // 'Any' label constraint can not be modified for user with forbidden labels
-//     Json::Value query;
-//     query["Query"] = Json::objectValue;
-//     query["Query"]["PatientID"] = "*";
-//     query["Labels"] = Json::arrayValue;
-//     query["Labels"].append("a");
-//     query["LabelsConstraint"] = "Any";
+  permParser.Add(pluginJsonDefaultConfiguration["Authorization"]["Permissions"], &authorizationParser);
 
-//     ASSERT_THROW(AdjustToolsFindQueryLabels(query, profile), Orthanc::OrthancException);
-//   }
+  
 
+  { // test modalities
 
-//   { // 'None' label constraint are modified to always contain at least all forbidden_labels of the user
-//     Json::Value query;
-//     query["Query"] = Json::objectValue;
-//     query["Query"]["PatientID"] = "*";
-//     query["Labels"] = Json::arrayValue;
-//     query["Labels"].append("b");
-//     query["LabelsConstraint"] = "None";
-
-//     AdjustToolsFindQueryLabels(query, profile);
-//     ASSERT_EQ(2u, query["Labels"].size());
-//     ASSERT_TRUE(IsInJsonArray("b", query["Labels"]));
-//     ASSERT_TRUE(IsInJsonArray("c", query["Labels"]));
-//     ASSERT_EQ("None", query["LabelsConstraint"].asString());
-//   }
+    TestPermissions(permParser, "/modalities", OrthancPluginHttpMethod_Get, "all|send|q-r-remote-modalities");  // list modalities
+    TestPermissions(permParser, "/modalities/alias", OrthancPluginHttpMethod_Put, "admin-permissions");  // add modalities
+    TestPermissions(permParser, "/modalities/alias", OrthancPluginHttpMethod_Delete, "admin-permissions");  // delete modalities
+    TestPermissions(permParser, "/modalities/alias/move", OrthancPluginHttpMethod_Post, "all|q-r-remote-modalities");  // trigger a c-move on distant modality
+    TestPermissions(permParser, "/modalities/alias/store", OrthancPluginHttpMethod_Post, "all|send");  // trigger a c-move on distant modality
+    TestPermissions(permParser, "/modalities/alias/store-straight", OrthancPluginHttpMethod_Post, "all|send");  // trigger a c-move on distant modality
+    TestPermissions(permParser, "/modalities/alias/echo", OrthancPluginHttpMethod_Post, "all|send|q-r-remote-modalities");  // echo
+    TestPermissions(permParser, "/modalities/alias/configuration", OrthancPluginHttpMethod_Get, "all|send|q-r-remote-modalities");  // see configuration
 
-//   { // 'None' label constraint are modified to always contain at least all forbidden_labels of the user
-//     Json::Value query;
-//     query["Query"] = Json::objectValue;
-//     query["Query"]["PatientID"] = "*";
-//     query["Labels"] = Json::arrayValue;
-//     query["Labels"].append("d");
-//     query["LabelsConstraint"] = "None";
+  }
 
-//     AdjustToolsFindQueryLabels(query, profile);
-//     ASSERT_EQ(3u, query["Labels"].size());
-//     ASSERT_TRUE(IsInJsonArray("b", query["Labels"]));
-//     ASSERT_TRUE(IsInJsonArray("c", query["Labels"]));
-//     ASSERT_TRUE(IsInJsonArray("d", query["Labels"]));
-//     ASSERT_EQ("None", query["LabelsConstraint"].asString());
-//   }
-// }
+            //   ["post", "^/modalities/(.*)/echo$", "all|send|q-r-remote-modalities"],
+            // ["post", "^/modalities/(.*)/query$", "all|q-r-remote-modalities"],
+            // ["get", "^/queries/([a-f0-9-]+)/answers$", "all|q-r-remote-modalities"],
+            // ["get", "^/queries/([a-f0-9-]+)/answers/([0-9]+)/content$", "all|q-r-remote-modalities"],
+            // ["post", "^/queries/([a-f0-9-]+)/answers/([0-9]+)/retrieve$", "all|q-r-remote-modalities"],
+            // ["post", "^/modalities/(.*)/move$", "all|q-r-remote-modalities"],
+
+}
 
 }
 
 int main(int argc, char **argv)
 {
+  Orthanc::Logging::Initialize();
+
   ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
+  int result = RUN_ALL_TESTS();
+
+  Orthanc::Logging::Finalize();
+
+  return result;
 }