Mercurial > hg > orthanc-authorization
comparison Plugin/Plugin.cpp @ 112:572955904411
added tools/labels + removed forbidden_labels
author | Alain Mazy <am@osimis.io> |
---|---|
date | Thu, 31 Aug 2023 16:51:15 +0200 |
parents | 2b1a95c7d263 |
children | 43154740ea2e |
comparison
equal
deleted
inserted
replaced
111:2b1a95c7d263 | 112:572955904411 |
---|---|
386 } | 386 } |
387 | 387 |
388 return false; | 388 return false; |
389 } | 389 } |
390 | 390 |
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 } | |
391 | 400 |
392 void AdjustToolsFindQueryLabels(Json::Value& query, const OrthancPlugins::IAuthorizationService::UserProfile& profile) | 401 void AdjustToolsFindQueryLabels(Json::Value& query, const OrthancPlugins::IAuthorizationService::UserProfile& profile) |
393 { | 402 { |
394 std::set<std::string> labelsToFind; | 403 std::set<std::string> labelsToFind; |
395 std::string labelsConstraint = "Invalid"; | 404 std::string labelsConstraint = "Invalid"; |
399 Orthanc::SerializationToolbox::ReadSetOfStrings(labelsToFind, query, "Labels"); | 408 Orthanc::SerializationToolbox::ReadSetOfStrings(labelsToFind, query, "Labels"); |
400 labelsConstraint = Orthanc::SerializationToolbox::ReadString(query, "LabelsConstraint"); | 409 labelsConstraint = Orthanc::SerializationToolbox::ReadString(query, "LabelsConstraint"); |
401 } | 410 } |
402 else if (query.isMember("Labels") || query.isMember("LabelsConstraint")) | 411 else if (query.isMember("Labels") || query.isMember("LabelsConstraint")) |
403 { | 412 { |
404 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Auth plugin: unable to transform tools/find query, both 'Labels' and 'LabelsConstraint' must be defined together if one of them is defined."); | 413 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: unable to transform tools/find query, both 'Labels' and 'LabelsConstraint' must be defined together if one of them is defined."); |
405 } | 414 } |
406 | 415 |
407 if (profile.authorizedLabels.size() > 0 || profile.forbiddenLabels.size() > 0) | 416 if (!HasAccessToSomeLabels(profile)) |
417 { | |
418 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: unable to call tools/find when the user does not have access to any labels."); | |
419 } | |
420 else if (profile.authorizedLabels.size() > 0) | |
408 { | 421 { |
409 // if the user has access to all labels: no need to transform the tools/find body, we keep it as is | 422 // if the user has access to all labels: no need to transform the tools/find body, we keep it as is |
410 if (profile.authorizedLabels.find("*") == profile.authorizedLabels.end()) | 423 if (!HasAccessToAllLabels(profile)) |
411 { // the user does not have access to all labels -> transform the tools/find body | 424 { // the user does not have access to all labels -> transform the tools/find body |
412 | 425 |
413 if (labelsToFind.size() == 0) | 426 if (labelsToFind.size() == 0) |
414 { | 427 { |
415 if (profile.authorizedLabels.size() > 0) | 428 if (profile.authorizedLabels.size() > 0) |
416 { | 429 { |
417 Orthanc::SerializationToolbox::WriteSetOfStrings(query, profile.authorizedLabels, "Labels"); | 430 Orthanc::SerializationToolbox::WriteSetOfStrings(query, profile.authorizedLabels, "Labels"); |
418 query["LabelsConstraint"] = "Any"; | 431 query["LabelsConstraint"] = "Any"; |
419 } | 432 } |
420 else if (profile.forbiddenLabels.size() > 0) | |
421 { | |
422 if (labelsToFind.size() == 0) | |
423 { // in this case, we can add a None constraint | |
424 Orthanc::SerializationToolbox::WriteSetOfStrings(query, profile.forbiddenLabels, "Labels"); | |
425 query["LabelsConstraint"] = "None"; | |
426 } | |
427 } | |
428 } | 433 } |
429 else if (labelsConstraint == "All") | 434 else if (labelsConstraint == "All") |
430 { | 435 { |
431 if (profile.authorizedLabels.size() > 0) | 436 if (profile.authorizedLabels.size() > 0) |
432 { | 437 { |
433 if (!Orthanc::Toolbox::IsSetInSet(labelsToFind, profile.authorizedLabels)) | 438 if (!Orthanc::Toolbox::IsSetInSet(labelsToFind, profile.authorizedLabels)) |
434 { | 439 { |
435 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Auth plugin: unable to transform tools/find query with 'All' labels constraint when the user does not have access to all listed labels."); | 440 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: unable to transform tools/find query with 'All' labels constraint when the user does not have access to all listed labels."); |
436 } | 441 } |
437 } | |
438 else if (profile.forbiddenLabels.size() > 0) | |
439 { | |
440 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Auth plugin: unable to transform tools/find query with 'All' labels constraint when the user has forbidden labels."); | |
441 } | 442 } |
442 } | 443 } |
443 else if (labelsConstraint == "Any") | 444 else if (labelsConstraint == "Any") |
444 { | 445 { |
445 if (profile.authorizedLabels.size() > 0) | 446 if (profile.authorizedLabels.size() > 0) |
446 { | 447 { |
447 std::set<std::string> newLabelsToFind; | 448 std::set<std::string> newLabelsToFind; |
448 for (std::set<std::string>::const_iterator itLabel = labelsToFind.begin(); itLabel != labelsToFind.end(); ++itLabel) | 449 Orthanc::Toolbox::GetIntersection(newLabelsToFind, labelsToFind, profile.authorizedLabels); |
449 { | |
450 if (profile.authorizedLabels.find(*itLabel) != profile.authorizedLabels.end()) | |
451 { | |
452 newLabelsToFind.insert(*itLabel); | |
453 } | |
454 } | |
455 | 450 |
456 if (newLabelsToFind.size() == 0) | 451 if (newLabelsToFind.size() == 0) |
457 { | 452 { |
458 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Auth plugin: unable to transform tools/find query with 'All' labels constraint when none of the labels to find is authorized for the user."); | 453 throw Orthanc::OrthancException(Orthanc::ErrorCode_Unauthorized, "Auth plugin: unable to transform tools/find query with 'All' labels constraint when none of the labels to find is authorized for the user."); |
459 } | 454 } |
460 | 455 |
461 query.removeMember("Labels"); | 456 query.removeMember("Labels"); |
462 Orthanc::SerializationToolbox::WriteSetOfStrings(query, newLabelsToFind, "Labels"); | 457 Orthanc::SerializationToolbox::WriteSetOfStrings(query, newLabelsToFind, "Labels"); |
463 } | 458 } |
464 else if (profile.forbiddenLabels.size() > 0) | |
465 { | |
466 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Auth plugin: unable to transform tools/find query with 'Any' labels constraint when the user has forbidden labels."); | |
467 } | |
468 } | 459 } |
469 else if (labelsConstraint == "None") | 460 else if (labelsConstraint == "None") |
470 { | 461 { |
471 if (profile.authorizedLabels.size() > 0) | 462 if (profile.authorizedLabels.size() > 0) |
472 { | 463 { |
473 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, "Auth plugin: unable to transform tools/find query with 'None' labels constraint when the user only has authorized_labels."); | 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."); |
474 } | 465 } |
475 else if (profile.forbiddenLabels.size() > 0) | 466 } |
476 { | 467 } |
477 std::set<std::string> newLabelsToFind = labelsToFind; | 468 } |
478 Orthanc::Toolbox::AppendSets(newLabelsToFind, profile.forbiddenLabels); | 469 else |
479 | 470 { |
480 query.removeMember("Labels"); | 471 // TODO what shall we do if the user has no authorized_labels ??? |
481 Orthanc::SerializationToolbox::WriteSetOfStrings(query, newLabelsToFind, "Labels"); | |
482 } | |
483 } | |
484 } | |
485 } | 472 } |
486 } | 473 } |
487 | 474 |
488 void ToolsFind(OrthancPluginRestOutput* output, | 475 void ToolsFind(OrthancPluginRestOutput* output, |
489 const char* /*url*/, | 476 const char* /*url*/, |
513 | 500 |
514 Json::Value result; | 501 Json::Value result; |
515 if (OrthancPlugins::RestApiPost(result, "/tools/find", body, false)) | 502 if (OrthancPlugins::RestApiPost(result, "/tools/find", body, false)) |
516 { | 503 { |
517 OrthancPlugins::AnswerJson(result, output); | 504 OrthancPlugins::AnswerJson(result, output); |
505 } | |
506 | |
507 } | |
508 else | |
509 { | |
510 OrthancPluginSendHttpStatusCode(context, output, 403); // TODO: check | |
511 } | |
512 } | |
513 } | |
514 | |
515 void ToolsLabels(OrthancPluginRestOutput* output, | |
516 const char* /*url*/, | |
517 const OrthancPluginHttpRequest* request) | |
518 { | |
519 OrthancPluginContext* context = OrthancPlugins::GetGlobalContext(); | |
520 | |
521 if (request->method != OrthancPluginHttpMethod_Get) | |
522 { | |
523 OrthancPluginSendMethodNotAllowed(context, output, "GET"); | |
524 } | |
525 else | |
526 { | |
527 // The filtering to this route is performed by this plugin as it is done for any other route before we get here. | |
528 | |
529 // If the logged in user has restrictions on the labels he can access, modify the tools/labels response before answering | |
530 OrthancPlugins::IAuthorizationService::UserProfile profile; | |
531 if (GetUserProfileInternal(profile, request)) | |
532 { | |
533 if (!HasAccessToSomeLabels(profile)) | |
534 { | |
535 Json::Value emptyLabels; | |
536 OrthancPlugins::AnswerJson(emptyLabels, output); | |
537 return; | |
538 } | |
539 | |
540 Json::Value jsonLabels; | |
541 if (OrthancPlugins::RestApiGet(jsonLabels, "/tools/labels", false)) | |
542 { | |
543 std::set<std::string> allLabels; | |
544 Orthanc::SerializationToolbox::ReadSetOfStrings(allLabels, jsonLabels); | |
545 | |
546 if (!HasAccessToAllLabels(profile)) | |
547 { | |
548 std::set<std::string> authorizedLabels; | |
549 | |
550 Orthanc::Toolbox::GetIntersection(authorizedLabels, allLabels, profile.authorizedLabels); | |
551 Orthanc::SerializationToolbox::WriteSetOfStrings(jsonLabels, authorizedLabels); | |
552 } | |
553 OrthancPlugins::AnswerJson(jsonLabels, output); | |
518 } | 554 } |
519 | 555 |
520 } | 556 } |
521 else | 557 else |
522 { | 558 { |
708 } | 744 } |
709 for (std::set<std::string>::const_iterator it = profile.authorizedLabels.begin(); it != profile.authorizedLabels.end(); ++it) | 745 for (std::set<std::string>::const_iterator it = profile.authorizedLabels.begin(); it != profile.authorizedLabels.end(); ++it) |
710 { | 746 { |
711 jsonProfile["authorized-labels"].append(*it); | 747 jsonProfile["authorized-labels"].append(*it); |
712 } | 748 } |
713 for (std::set<std::string>::const_iterator it = profile.forbiddenLabels.begin(); it != profile.forbiddenLabels.end(); ++it) | |
714 { | |
715 jsonProfile["forbidden-labels"].append(*it); | |
716 } | |
717 | 749 |
718 OrthancPlugins::AnswerJson(jsonProfile, output); | 750 OrthancPlugins::AnswerJson(jsonProfile, output); |
719 } | 751 } |
720 } | 752 } |
721 } | 753 } |
1062 { | 1094 { |
1063 OrthancPlugins::RegisterRestCallback<CreateToken>("/auth/tokens/(.*)", true); | 1095 OrthancPlugins::RegisterRestCallback<CreateToken>("/auth/tokens/(.*)", true); |
1064 } | 1096 } |
1065 | 1097 |
1066 OrthancPlugins::RegisterRestCallback<ToolsFind>("/tools/find", true); | 1098 OrthancPlugins::RegisterRestCallback<ToolsFind>("/tools/find", true); |
1099 OrthancPlugins::RegisterRestCallback<ToolsLabels>("/tools/labels", true); | |
1067 | 1100 |
1068 | 1101 |
1069 if (authorizationParser_.get() != NULL || permissionParser_.get() != NULL) | 1102 if (authorizationParser_.get() != NULL || permissionParser_.get() != NULL) |
1070 { | 1103 { |
1071 if (hasBasicAuthEnabled) | 1104 if (hasBasicAuthEnabled) |