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)