Mercurial > hg > orthanc-authorization
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 } |