comparison Plugin/Plugin.cpp @ 113:43154740ea2e

wip: checking labels
author Alain Mazy <am@osimis.io>
date Tue, 05 Sep 2023 12:48:20 +0200
parents 572955904411
children 546aea509427
comparison
equal deleted inserted replaced
112:572955904411 113:43154740ea2e
71 { 71 {
72 return value_; 72 return value_;
73 } 73 }
74 }; 74 };
75 75
76 bool HasAccessToAllLabels(const OrthancPlugins::IAuthorizationService::UserProfile& profile)
77 {
78 return (profile.authorizedLabels.find("*") != profile.authorizedLabels.end());
79 }
80
81 bool HasAccessToSomeLabels(const OrthancPlugins::IAuthorizationService::UserProfile& profile)
82 {
83 return (profile.authorizedLabels.size() > 0);
84 }
85
86
87 static bool CheckAuthorizedLabelsForResource(const std::string& uri,
88 const OrthancPlugins::AssociativeArray& getArguments,
89 const OrthancPlugins::IAuthorizationService::UserProfile& profile)
90 {
91 if (HasAccessToAllLabels(profile))
92 {
93 return true;
94 }
95
96 if (authorizationParser_.get() != NULL &&
97 authorizationService_.get() != NULL)
98 {
99 // Parse the resources that are accessed through this URI
100 OrthancPlugins::IAuthorizationParser::AccessedResources accesses;
101
102 if (!authorizationParser_->Parse(accesses, uri, getArguments.GetMap()))
103 {
104 return false; // Unable to parse this URI
105 }
106
107 // Loop over all the accessed resources to ensure access is
108 // granted to each of them
109 for (OrthancPlugins::IAuthorizationParser::AccessedResources::const_iterator
110 access = accesses.begin(); access != accesses.end(); ++access)
111 {
112 // Ignored the access levels that are unchecked
113 // (cf. "UncheckedLevels" option)
114 if (uncheckedLevels_.find(access->GetLevel()) == uncheckedLevels_.end())
115 {
116 std::string msg = std::string("Testing whether access to ") + OrthancPlugins::EnumerationToString(access->GetLevel()) + " \"" + access->GetOrthancId() + "\" is allowed wrt Labels for User '" + profile.name + "'";
117 const std::set<std::string>& resourceLabels = access->GetLabels();
118 std::set<std::string> authorizedResourceLabels;
119
120 Orthanc::Toolbox::GetIntersection(authorizedResourceLabels, resourceLabels, profile.authorizedLabels);
121
122 if (authorizedResourceLabels.size() == 0)
123 {
124 LOG(INFO) << msg << " -> not granted, no authorized labels";
125 return false;
126 }
127 else
128 {
129 LOG(INFO) << msg << " -> granted, at least one authorized labels";
130 return true;
131 }
132 }
133 }
134
135 // Access is granted to all the resources that are 'unchecked'
136 return true;
137 }
138
139 return false; // TODO or true ???
140 }
76 141
77 static int32_t FilterHttpRequests(OrthancPluginHttpMethod method, 142 static int32_t FilterHttpRequests(OrthancPluginHttpMethod method,
78 const char *uri, 143 const char *uri,
79 const char *ip, 144 const char *ip,
80 uint32_t headersCount, 145 uint32_t headersCount,
152 if (permissionParser_->Parse(requiredPermissions, matchedPattern, method, uri)) 217 if (permissionParser_->Parse(requiredPermissions, matchedPattern, method, uri))
153 { 218 {
154 if (authTokens.empty()) 219 if (authTokens.empty())
155 { 220 {
156 std::string msg = std::string("Testing whether anonymous user has any of the required permissions '") + JoinStrings(requiredPermissions) + "'"; 221 std::string msg = std::string("Testing whether anonymous user has any of the required permissions '") + JoinStrings(requiredPermissions) + "'";
157 LOG(INFO) << msg; 222
158 if (authorizationService_->HasAnonymousUserPermission(validity, requiredPermissions)) 223 // TODO: how to handle anonymous user ?
159 { 224
160 LOG(INFO) << msg << " -> granted"; 225 // LOG(INFO) << msg;
161 return 1; 226 // if (authorizationService_->HasAnonymousUserPermission(validity, requiredPermissions))
162 } 227 // {
163 else 228 // // TODO: check labels permissions
164 { 229 // LOG(INFO) << msg << " -> granted";
165 LOG(INFO) << msg << " -> not granted"; 230
166 } 231 // if (CheckAuthorizedLabelsForResource(uri, getArguments, profile))
232 // {
233 // return 1;
234 // }
235 // }
236 // else
237 // {
238 // LOG(INFO) << msg << " -> not granted";
239 // }
240 LOG(INFO) << msg << " -> not granted, TODO ????";
241 return 0;
167 } 242 }
168 else 243 else
169 { 244 {
170 for (size_t i = 0; i < authTokens.size(); ++i) 245 for (size_t i = 0; i < authTokens.size(); ++i)
171 { 246 {
172 std::string msg = std::string("Testing whether user has the required permissions '") + JoinStrings(requiredPermissions) + "' based on the HTTP header '" + authTokens[i].GetToken().GetKey() + "' required to match '" + matchedPattern + "'"; 247 std::string msg = std::string("Testing whether user has the required permissions '") + JoinStrings(requiredPermissions) + "' based on the HTTP header '" + authTokens[i].GetToken().GetKey() + "' required to match '" + matchedPattern + "'";
173 248
174 LOG(INFO) << msg; 249 LOG(INFO) << msg;
175 if (authorizationService_->HasUserPermission(validity, requiredPermissions, authTokens[i].GetToken(), authTokens[i].GetValue())) 250
251 OrthancPlugins::IAuthorizationService::UserProfile profile;
252 unsigned int validityNotUsed;
253 authorizationService_->GetUserProfile(validityNotUsed, profile, authTokens[i].GetToken(), authTokens[i].GetValue());
254
255 if (authorizationService_->HasUserPermission(validity, requiredPermissions, profile))
176 { 256 {
177 // TODO: check labels permissions
178 LOG(INFO) << msg << " -> granted"; 257 LOG(INFO) << msg << " -> granted";
179 return 1; 258
259 // check labels permissions
260 if (CheckAuthorizedLabelsForResource(uri, getArguments, profile))
261 {
262 return 1;
263 }
264 // not granted, but continue and check if a resource tokens grant access
180 } 265 }
181 else 266 else
182 { 267 {
183 LOG(INFO) << msg << " -> not granted"; 268 LOG(INFO) << msg << " -> not granted"; // but continue and check if a resource tokens grant access
184 } 269 }
185 } 270 }
186 } 271 }
187 } 272 }
188 } 273 }
386 } 471 }
387 472
388 return false; 473 return false;
389 } 474 }
390 475
391 bool HasAccessToAllLabels(const OrthancPlugins::IAuthorizationService::UserProfile& profile)
392 {
393 return (profile.authorizedLabels.find("*") != profile.authorizedLabels.end());
394 }
395
396 bool HasAccessToSomeLabels(const OrthancPlugins::IAuthorizationService::UserProfile& profile)
397 {
398 return (profile.authorizedLabels.size() > 0);
399 }
400
401 void AdjustToolsFindQueryLabels(Json::Value& query, const OrthancPlugins::IAuthorizationService::UserProfile& profile) 476 void AdjustToolsFindQueryLabels(Json::Value& query, const OrthancPlugins::IAuthorizationService::UserProfile& profile)
402 { 477 {
403 std::set<std::string> labelsToFind; 478 std::set<std::string> labelsToFind;
404 std::string labelsConstraint = "Invalid"; 479 std::string labelsConstraint = "Invalid";
405 480
459 } 534 }
460 else if (labelsConstraint == "None") 535 else if (labelsConstraint == "None")
461 { 536 {
462 if (profile.authorizedLabels.size() > 0) 537 if (profile.authorizedLabels.size() > 0)
463 { 538 {
464 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: unable to transform tools/find query with 'None' labels constraint when the user only has authorized_labels."); 539 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: unable to transform tools/find query with 'None' labels constraint when the user only has authorized_labels.");
465 } 540 }
466 } 541 }
467 } 542 }
468 }
469 else
470 {
471 // TODO what shall we do if the user has no authorized_labels ???
472 } 543 }
473 } 544 }
474 545
475 void ToolsFind(OrthancPluginRestOutput* output, 546 void ToolsFind(OrthancPluginRestOutput* output,
476 const char* /*url*/, 547 const char* /*url*/,
505 } 576 }
506 577
507 } 578 }
508 else 579 else
509 { 580 {
510 OrthancPluginSendHttpStatusCode(context, output, 403); // TODO: check 581 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: no user profile found, access to tools/find is forbidden.");
511 } 582 }
512 } 583 }
513 } 584 }
514 585
515 void ToolsLabels(OrthancPluginRestOutput* output, 586 void ToolsLabels(OrthancPluginRestOutput* output,
554 } 625 }
555 626
556 } 627 }
557 else 628 else
558 { 629 {
559 OrthancPluginSendHttpStatusCode(context, output, 403); // TODO: check 630 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: no user profile found, access to tools/labels is forbidden.");
560 } 631 }
561
562
563 } 632 }
564 } 633 }
565 634
566 635
567 void CreateToken(OrthancPluginRestOutput* output, 636 void CreateToken(OrthancPluginRestOutput* output,
943 } 1012 }
944 1013
945 if (!urlTokenCreationBase.empty()) 1014 if (!urlTokenCreationBase.empty())
946 { 1015 {
947 LOG(WARNING) << "Authorization plugin: base url defined for Token Creation : " << urlTokenCreationBase; 1016 LOG(WARNING) << "Authorization plugin: base url defined for Token Creation : " << urlTokenCreationBase;
948 // TODO Token Creation
949 } 1017 }
950 else 1018 else
951 { 1019 {
952 LOG(WARNING) << "Authorization plugin: no base url defined for Token Creation"; 1020 LOG(WARNING) << "Authorization plugin: no base url defined for Token Creation";
953 } 1021 }
1010 if (pluginConfiguration.LookupStringValue(checkedLevelString, "CheckedLevel")) 1078 if (pluginConfiguration.LookupStringValue(checkedLevelString, "CheckedLevel"))
1011 { 1079 {
1012 OrthancPlugins::AccessLevel checkedLevel = OrthancPlugins::StringToAccessLevel(checkedLevelString); 1080 OrthancPlugins::AccessLevel checkedLevel = OrthancPlugins::StringToAccessLevel(checkedLevelString);
1013 if (checkedLevel == OrthancPlugins::AccessLevel_Instance) 1081 if (checkedLevel == OrthancPlugins::AccessLevel_Instance)
1014 { 1082 {
1083 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_System);
1015 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Patient); 1084 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Patient);
1016 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Study); 1085 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Study);
1017 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Series); 1086 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Series);
1018 } 1087 }
1019 else if (checkedLevel == OrthancPlugins::AccessLevel_Series) 1088 else if (checkedLevel == OrthancPlugins::AccessLevel_Series)
1020 { 1089 {
1090 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_System);
1021 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Patient); 1091 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Patient);
1022 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Study); 1092 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Study);
1023 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Instance); 1093 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Instance);
1024 } 1094 }
1025 else if (checkedLevel == OrthancPlugins::AccessLevel_Study) 1095 else if (checkedLevel == OrthancPlugins::AccessLevel_Study)
1026 { 1096 {
1097 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_System);
1027 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Patient); 1098 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Patient);
1028 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Series); 1099 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Series);
1029 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Instance); 1100 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Instance);
1030 } 1101 }
1031 else if (checkedLevel == OrthancPlugins::AccessLevel_Patient) 1102 else if (checkedLevel == OrthancPlugins::AccessLevel_Patient)
1032 { 1103 {
1104 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_System);
1033 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Study); 1105 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Study);
1034 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Series); 1106 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Series);
1035 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Instance); 1107 uncheckedLevels_.insert(OrthancPlugins::AccessLevel_Instance);
1036 } 1108 }
1037 } 1109 }