001package ca.cdr.api.model.enm; 002 003/* 004 * #%L 005 * Smile CDR - CDR 006 * %% 007 * Copyright (C) 2016 - 2025 Smile CDR, Inc. 008 * %% 009 * All rights reserved. 010 * #L% 011 */ 012 013import ca.cdr.api.security.permission.PermissionArgumentFormat; 014import ca.cdr.api.security.permission.PermissionArgumentFormats; 015import jakarta.annotation.Nonnull; 016import org.apache.commons.text.StringTokenizer; 017 018import java.util.ArrayList; 019import java.util.Arrays; 020import java.util.Collection; 021import java.util.Collections; 022import java.util.EnumSet; 023import java.util.List; 024import java.util.Locale; 025import java.util.Optional; 026import java.util.Set; 027import java.util.stream.Collectors; 028 029import static org.apache.commons.lang3.StringUtils.isBlank; 030import static org.apache.commons.lang3.StringUtils.isNotBlank; 031import static org.apache.commons.lang3.StringUtils.trim; 032 033public enum PermissionEnum { 034 035 /* 036 * Sorting agnostic, but don't change which one is first because swagger uses it as an example. 037 */ 038 039 /** 040 * User has permission to change password 041 */ 042 CHANGE_OWN_PASSWORD(PermissionCategoryEnum.USER_MANAGER), 043 044 /** 045 * User can log in to EasyShare 046 */ 047 ACCESS_EASYSHARE(PermissionCategoryEnum.EASYSHARE), 048 049 /** 050 * User can create a SMART Health Link using EasyShare 051 */ 052 EASYSHARE_CREATE_SMART_HEALTH_LINK( 053 PermissionCategoryEnum.EASYSHARE, new PermissionEnum[] {PermissionEnum.ACCESS_EASYSHARE}), 054 055 // TODO: add this once this UI is created 056 // /** 057 // * User can manage SMART Health Links in EasyShare 058 // */ 059 // EASYSHARE_MANAGE_ALL_SMART_HEALTH_LINKS( 060 // PermissionCategoryEnum.EASYSHARE, new PermissionEnum[] {PermissionEnum.ACCESS_EASYSHARE}), 061 062 /** 063 * User can update their own launch contexts 064 */ 065 CHANGE_OWN_DEFAULT_LAUNCH_CONTEXTS(PermissionCategoryEnum.USER_MANAGER), 066 067 /** 068 * User can change their own TFA key 069 */ 070 CHANGE_OWN_TFA_KEY(PermissionCategoryEnum.USER_MANAGER), 071 072 /** 073 * User is allowed to log into the web admin console 074 */ 075 ACCESS_ADMIN_WEB(PermissionCategoryEnum.ADMIN, new PermissionEnum[] {CHANGE_OWN_PASSWORD}), 076 077 /** 078 * User is allowed to use the JSON Admin API services 079 */ 080 ACCESS_ADMIN_JSON(PermissionCategoryEnum.ADMIN), 081 082 /** 083 * User is allowed to access FHIR services 084 */ 085 ACCESS_FHIR_ENDPOINT(PermissionCategoryEnum.FHIR_CLIENT), 086 087 /** 088 * User has permission to log into the FHIRWeb console 089 */ 090 ACCESS_FHIRWEB(PermissionCategoryEnum.ADMIN), 091 092 /** 093 * User can access internal metrics API, including thread dump API 094 */ 095 VIEW_METRICS(PermissionCategoryEnum.ADMIN), 096 097 /** 098 * User can see (but not change) status information about modules. This includes running/stopped status, health checks, etc., but does not give access to more sensitive details such as logs. 099 */ 100 VIEW_MODULE_STATUS(PermissionCategoryEnum.ADMIN), 101 102 /** 103 * User can see (but not change) module configuration information (not including database passwords) 104 */ 105 VIEW_MODULE_CONFIG(PermissionCategoryEnum.ADMIN, new PermissionEnum[] {VIEW_MODULE_STATUS}), 106 107 /** 108 * User can archive module 109 */ 110 ARCHIVE_MODULE(PermissionCategoryEnum.ADMIN, new PermissionEnum[] {VIEW_MODULE_CONFIG}), 111 112 /** 113 * User can reinstate module 114 */ 115 REINSTATE_MODULE(PermissionCategoryEnum.ADMIN, new PermissionEnum[] {VIEW_MODULE_CONFIG}), 116 117 /** 118 * User is allowed to view existing OpenID Connect client list 119 */ 120 OPENID_CONNECT_VIEW_CLIENT_LIST(PermissionCategoryEnum.ADMIN), 121 122 /** 123 * User is allowed to view existing OpenID Connect server list 124 */ 125 OPENID_CONNECT_VIEW_SERVER_LIST(PermissionCategoryEnum.ADMIN), 126 127 /** 128 * User is allowed to create OpenID Connect clients 129 */ 130 OPENID_CONNECT_ADD_CLIENT(PermissionCategoryEnum.ADMIN), 131 132 /** 133 * User is allowed to create OpenID Connect clients with pre-set permissions 134 */ 135 OIDC_CLIENT_PRESET_PERMISSION( 136 PermissionCategoryEnum.ADMIN, 137 OPENID_CONNECT_ADD_CLIENT, 138 TakesArgumentEnum.YES, 139 PermissionArgumentFormats.NO_ARGUMENT_FORMAT), 140 141 /** 142 * User is allowed to add OpenID Connect servers 143 */ 144 OPENID_CONNECT_ADD_SERVER(PermissionCategoryEnum.ADMIN), 145 146 /** 147 * User is allowed to edit OpenID Connect servers 148 */ 149 OPENID_CONNECT_EDIT_SERVER(PermissionCategoryEnum.ADMIN), 150 151 /** 152 * User is allowed to edit existing OpenID Connect clients 153 */ 154 OPENID_CONNECT_EDIT_CLIENT(PermissionCategoryEnum.ADMIN), 155 156 /** 157 * User is allows to manage other users' OIDC sessions (view active sessions and revoke them). 158 */ 159 OPENID_CONNECT_MANAGE_GLOBAL_SESSIONS(PermissionCategoryEnum.ADMIN), 160 161 /** 162 * User is allowed to manage (view/create/update/delete) OIDC Keystore definitions 163 */ 164 OPENID_CONNECT_MANAGE_KEYSTORES(PermissionCategoryEnum.ADMIN), 165 166 /** 167 * User can create other users 168 */ 169 CREATE_USER(PermissionCategoryEnum.USER_MANAGER), 170 171 /** 172 * User can update existing users other than themself 173 */ 174 UPDATE_USER(PermissionCategoryEnum.USER_MANAGER), 175 176 /** 177 * User can view list of users 178 */ 179 VIEW_USERS(PermissionCategoryEnum.USER_MANAGER), 180 181 /** 182 * User can view, create, and update users 183 */ 184 SAVE_USER(PermissionCategoryEnum.USER_MANAGER, new PermissionEnum[] {CREATE_USER, UPDATE_USER, VIEW_USERS}), 185 186 /** 187 * User is allowed to use a FHIR client 188 */ 189 ROLE_FHIR_CLIENT(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] {ACCESS_FHIR_ENDPOINT}), 190 191 /** 192 * Actions performed by the system itself. 193 * Implied permissions are populated internally and not explicitly defined in the constructor. 194 */ 195 ROLE_SYSTEM(PermissionCategoryEnum.SYSTEM), 196 197 /** 198 * Actions performed by the system itself during initialization 199 */ 200 ROLE_SYSTEM_INITIALIZATION(PermissionCategoryEnum.SYSTEM, new PermissionEnum[] {ROLE_SYSTEM}), 201 202 /** 203 * User is allowed to view the audit log 204 */ 205 VIEW_AUDIT_LOG(PermissionCategoryEnum.ADMIN), 206 207 /** 208 * User is allowed to view the transaction log 209 */ 210 VIEW_TRANSACTION_LOG(PermissionCategoryEnum.ADMIN), 211 212 /** 213 * User is allowed to view entries in the transaction log 214 */ 215 VIEW_TRANSACTION_LOG_EVENT(PermissionCategoryEnum.ADMIN), 216 217 /** 218 * User is allows to modify a module's configuration 219 */ 220 UPDATE_MODULE_CONFIG(PermissionCategoryEnum.ADMIN, new PermissionEnum[] {VIEW_MODULE_CONFIG}), 221 222 /** 223 * User is allowed to start/stop modules 224 */ 225 START_STOP_MODULE(PermissionCategoryEnum.ADMIN), 226 227 /** 228 * User can start/stop/restart modules 229 */ 230 CONTROL_MODULE(PermissionCategoryEnum.ADMIN, new PermissionEnum[] {VIEW_MODULE_CONFIG, START_STOP_MODULE}), 231 232 /** 233 * User is allowed to create new modules 234 */ 235 CREATE_MODULE(PermissionCategoryEnum.ADMIN, new PermissionEnum[] {VIEW_MODULE_CONFIG}), 236 237 /** 238 * User is allowed to create, reconfigure and start/stop modules 239 */ 240 MODULE_ADMIN(PermissionCategoryEnum.ADMIN, new PermissionEnum[] { 241 CREATE_MODULE, 242 UPDATE_MODULE_CONFIG, 243 CONTROL_MODULE, 244 REINSTATE_MODULE, 245 ARCHIVE_MODULE, 246 START_STOP_MODULE, 247 VIEW_MODULE_CONFIG 248 }), 249 250 /** 251 * User is allowed to access (includes both read and write operations) data in all 252 * partitions. Note that this permission does not actually authorize any specific read/write 253 * operations, it simply implies access to the partitions. 254 */ 255 FHIR_ACCESS_PARTITION_ALL(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 256 257 /** 258 * User is allowed to access (includes both read and write operations) data in the given 259 * partition. Note that this permission does not actually authorize any specific read/write 260 * operations, it simply implies access to the given partition. 261 */ 262 FHIR_ACCESS_PARTITION_NAME( 263 PermissionCategoryEnum.FHIR_CLIENT, 264 ROLE_FHIR_CLIENT, 265 TakesArgumentEnum.YES, 266 PermissionArgumentFormats.NO_ARGUMENT_FORMAT), 267 268 /** 269 * User is allowed to invoke the $binary-access-XXX operation (note that the user 270 * will also need permission to read/write the individual resource that is 271 * actually being accessed) 272 */ 273 FHIR_OP_BINARY_ACCESS_READ(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 274 275 /** 276 * User is allowed to invoke the $binary-access-XXX operation (note that the user 277 * will also need permission to read/write the individual resource that is 278 * actually being accessed) 279 */ 280 FHIR_OP_BINARY_ACCESS_WRITE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 281 282 /** 283 * User is allowed to initiate a bulk data export using the $export operation 284 */ 285 FHIR_OP_INITIATE_BULK_DATA_EXPORT( 286 PermissionCategoryEnum.FHIR_CLIENT, 287 ROLE_FHIR_CLIENT, 288 TakesArgumentEnum.OPTIONAL, 289 PermissionArgumentFormats.EXPORT_RESOURCE_TYPES_FORMAT), 290 291 /** 292 * User is allowed to initiate a bulk data import using the $import operation 293 */ 294 FHIR_OP_INITIATE_BULK_DATA_IMPORT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 295 296 /** 297 * Bulk export - group Level 298 */ 299 FHIR_OP_INITIATE_BULK_DATA_EXPORT_GROUP( 300 PermissionCategoryEnum.FHIR_CLIENT, 301 ROLE_FHIR_CLIENT, 302 TakesArgumentEnum.YES, 303 PermissionArgumentFormats.COMPARTMENT_WITH_EXPORT_RESOURCE_TYPES_FORMAT), 304 305 /** 306 * Bulk export - Patient Level 307 * 308 * @deprecated In favour of FHIR_OP_INITIATE_BULK_DATA_EXPORT_PATIENTS and FHIR_OP_INITIATE_BULK_DATA_EXPORT_ALL_PATIENTS 309 */ 310 @Deprecated 311 FHIR_OP_INITIATE_BULK_DATA_EXPORT_PATIENT( 312 PermissionCategoryEnum.FHIR_CLIENT, 313 ROLE_FHIR_CLIENT, 314 TakesArgumentEnum.OPTIONAL, 315 PermissionArgumentFormats.COMPARTMENT_WITH_EXPORT_RESOURCE_TYPES_FORMAT), 316 317 /** 318 * Bulk Export for a list of patient IDs and resource types 319 */ 320 FHIR_OP_INITIATE_BULK_DATA_EXPORT_PATIENTS( 321 PermissionCategoryEnum.FHIR_CLIENT, 322 ROLE_FHIR_CLIENT, 323 TakesArgumentEnum.OPTIONAL, 324 PermissionArgumentFormats.COMPARTMENTS_WITH_EXPORT_RESOURCE_TYPES_FORMAT), 325 326 /** 327 * Bulk Export for all patients 328 */ 329 FHIR_OP_INITIATE_BULK_DATA_EXPORT_ALL_PATIENTS( 330 PermissionCategoryEnum.FHIR_CLIENT, 331 ROLE_FHIR_CLIENT, 332 TakesArgumentEnum.NO, 333 PermissionArgumentFormats.OPTIONAL_FILTER_FORMAT), 334 335 /** 336 * Bulk export - System Level 337 */ 338 FHIR_OP_INITIATE_BULK_DATA_EXPORT_SYSTEM( 339 PermissionCategoryEnum.FHIR_CLIENT, 340 ROLE_FHIR_CLIENT, 341 TakesArgumentEnum.OPTIONAL, 342 PermissionArgumentFormats.EXPORT_RESOURCE_TYPES_FORMAT), 343 344 /** 345 * User is allowed to read search parameters 346 */ 347 FHIR_READ_SEARCH_PARAMETERS( 348 PermissionCategoryEnum.FHIR_CLIENT, 349 new PermissionEnum[] { 350 // does not imply FHIR_CLIENT since this can be used for JSON Admin functions too 351 }), 352 353 /** 354 * User is allowed to create, update, and delete search parameters 355 */ 356 FHIR_MODIFY_SEARCH_PARAMETERS( 357 PermissionCategoryEnum.FHIR_CLIENT, 358 new PermissionEnum[] { 359 // does not imply FHIR_CLIENT since this can be used for JSON Admin functions too 360 }), 361 362 /** 363 * User is allowed to read any resources in the given compartment 364 */ 365 FHIR_READ_ALL_IN_COMPARTMENT( 366 PermissionCategoryEnum.FHIR_CLIENT, 367 ROLE_FHIR_CLIENT, 368 TakesArgumentEnum.YES, 369 PermissionArgumentFormats.COMPARTMENT_WITH_OPTIONAL_FILTER_FORMAT), 370 371 /** 372 * User is allowed to write any resources in the given compartment 373 */ 374 FHIR_WRITE_ALL_IN_COMPARTMENT( 375 PermissionCategoryEnum.FHIR_CLIENT, 376 ROLE_FHIR_CLIENT, 377 TakesArgumentEnum.YES, 378 PermissionArgumentFormats.COMPARTMENT_WITH_OPTIONAL_FILTER_FORMAT), 379 380 /** 381 * User is allowed to read any resources of the given type in the given compartment 382 */ 383 FHIR_READ_TYPE_IN_COMPARTMENT( 384 PermissionCategoryEnum.FHIR_CLIENT, 385 ROLE_FHIR_CLIENT, 386 TakesArgumentEnum.YES, 387 PermissionArgumentFormats.TYPE_IN_COMPARTMENT_WITH_OPTIONAL_FILTER_FORMAT), 388 389 /** 390 * User is allowed to write any resources of the given type in the given compartment 391 */ 392 FHIR_WRITE_TYPE_IN_COMPARTMENT( 393 PermissionCategoryEnum.FHIR_CLIENT, 394 ROLE_FHIR_CLIENT, 395 TakesArgumentEnum.YES, 396 PermissionArgumentFormats.TYPE_IN_COMPARTMENT_WITH_OPTIONAL_FILTER_FORMAT), 397 398 /** 399 * User is allowed to read any resources of the given type 400 */ 401 FHIR_READ_ALL_OF_TYPE( 402 PermissionCategoryEnum.FHIR_CLIENT, 403 ROLE_FHIR_CLIENT, 404 TakesArgumentEnum.YES, 405 PermissionArgumentFormats.RESOURCE_TYPE_OPTIONAL_FILTER_FORMAT), 406 407 /** 408 * User is allowed to write any resources of the given type 409 */ 410 FHIR_WRITE_ALL_OF_TYPE( 411 PermissionCategoryEnum.FHIR_CLIENT, 412 ROLE_FHIR_CLIENT, 413 TakesArgumentEnum.YES, 414 PermissionArgumentFormats.RESOURCE_TYPE_OPTIONAL_FILTER_FORMAT), 415 416 /** 417 * User is allowed to read a specific resource instance by ID 418 */ 419 FHIR_READ_INSTANCE( 420 PermissionCategoryEnum.FHIR_CLIENT, 421 ROLE_FHIR_CLIENT, 422 TakesArgumentEnum.YES, 423 PermissionArgumentFormats.INSTANCE_WITH_OPTIONAL_FILTER_FORMAT), 424 425 /** 426 * User is allowed to write a specific resource instance by ID 427 */ 428 FHIR_WRITE_INSTANCE( 429 PermissionCategoryEnum.FHIR_CLIENT, 430 ROLE_FHIR_CLIENT, 431 TakesArgumentEnum.YES, 432 PermissionArgumentFormats.INSTANCE_WITH_OPTIONAL_FILTER_FORMAT), 433 434 /** 435 * User is allowed to access resources with a code 436 */ 437 BLOCK_FHIR_READ_UNLESS_CODE_IN_VS( 438 PermissionCategoryEnum.FHIR_CLIENT, 439 new PermissionEnum[] {ROLE_FHIR_CLIENT}, 440 TakesArgumentEnum.YES, 441 true, 442 PermissionArgumentFormats.CODE_IN_VALUE_SET_FILTER_FORMAT), 443 444 /** 445 * User is allowed to access resources with a code 446 */ 447 BLOCK_FHIR_READ_UNLESS_CODE_NOT_IN_VS( 448 PermissionCategoryEnum.FHIR_CLIENT, 449 new PermissionEnum[] {ROLE_FHIR_CLIENT}, 450 TakesArgumentEnum.YES, 451 true, 452 PermissionArgumentFormats.CODE_IN_VALUE_SET_FILTER_FORMAT), 453 454 /** 455 * User is permitted to invoke the $expunge operation with expungeDeletedResources=true 456 */ 457 FHIR_EXPUNGE_DELETED(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 458 459 /** 460 * User is permitted to invoke the $expunge operation with expungePreviousVersions=true 461 */ 462 FHIR_EXPUNGE_PREVIOUS_VERSIONS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 463 464 /** 465 * User is permitted to invoke the $expunge operation with expungeEverything=true 466 */ 467 FHIR_EXPUNGE_EVERYTHING(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 468 469 /** 470 * User is permitted to invoke the $delete-expunge operation 471 */ 472 FHIR_DELETE_EXPUNGE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 473 474 /** 475 * User is permitted to invoke the $livebundle-watchlist-add, $livebundle-watchlist-delete, $livebundle-watchlist, and $livebundle operations 476 */ 477 FHIR_LIVEBUNDLE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 478 479 /** 480 * User is permitted to invoke the operations 481 * $partition-management-create-partition, 482 * $partition-management-read-partition, 483 * $partition-management-update-partition, 484 * $partition-management-delete-partition, 485 * $partition-management-list-partitions, 486 */ 487 FHIR_MANAGE_PARTITIONS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 488 489 /** 490 * User is permitted to invoke the $meta, $meta-add, and $meta-delete operations on 491 * any resource. 492 */ 493 FHIR_META_OPERATIONS_SUPERUSER(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 494 495 /** 496 * User may invoke any kind of operation 497 */ 498 FHIR_EXTENDED_OPERATION_SUPERUSER(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 499 500 /** 501 * User may invoke operation with name specified by argument (e.g. $fooOperation) 502 */ 503 FHIR_EXTENDED_OPERATION_ON_SERVER( 504 PermissionCategoryEnum.FHIR_CLIENT, 505 ROLE_FHIR_CLIENT, 506 TakesArgumentEnum.YES, 507 PermissionArgumentFormats.OPERATION_FORMAT), 508 509 /** 510 * User may invoke operation at the type level with type and name specified by argument (e.g. Patient/$fooOperation) 511 */ 512 FHIR_EXTENDED_OPERATION_ON_TYPE( 513 PermissionCategoryEnum.FHIR_CLIENT, 514 ROLE_FHIR_CLIENT, 515 TakesArgumentEnum.YES, 516 PermissionArgumentFormats.OPERATION_ON_RESOURCE_TYPE_FORMAT), 517 518 /** 519 * User may invoke operation at the instance level for any type with name specified by argument (e.g. $fooOperation) 520 */ 521 FHIR_EXTENDED_OPERATION_ON_ANY_INSTANCE( 522 PermissionCategoryEnum.FHIR_CLIENT, 523 ROLE_FHIR_CLIENT, 524 TakesArgumentEnum.YES, 525 PermissionArgumentFormats.OPERATION_FORMAT), 526 527 /** 528 * User may invoke operation at the instance level with type and name specified by argument (e.g. Patient/$fooOperation) 529 */ 530 FHIR_EXTENDED_OPERATION_ON_ANY_INSTANCE_OF_TYPE( 531 PermissionCategoryEnum.FHIR_CLIENT, 532 ROLE_FHIR_CLIENT, 533 TakesArgumentEnum.YES, 534 PermissionArgumentFormats.OPERATION_ON_RESOURCE_TYPE_FORMAT), 535 536 /** 537 * User may invoke the MDM $match operation on a Patient 538 */ 539 FHIR_OP_PATIENT_MATCH(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 540 541 /** 542 * User may invoke the MDM $mdm-merge-golden-resources operation on Golden Resources 543 */ 544 FHIR_OP_MDM_MERGE_GOLDEN_RESOURCES(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 545 546 /** 547 * User may invoke the MDM $mdm-update-link operation on a Golden Resource 548 */ 549 FHIR_OP_MDM_UPDATE_LINK(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 550 551 /** 552 * User may invoke the MDM $mdm-create-link operation on a Golden Resource 553 */ 554 FHIR_OP_MDM_CREATE_LINK(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 555 556 /** 557 * User may invoke the MDM $mdm-query-links operation 558 */ 559 FHIR_OP_MDM_QUERY_LINKS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 560 561 /** 562 * User may invoke the MDM $mdm-query-links operation 563 */ 564 FHIR_OP_MDM_LINK_HISTORY(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 565 566 /** 567 * User may invoke the MDM $mdm-duplicate-golden-resources 568 */ 569 FHIR_OP_MDM_DUPLICATE_GOLDEN_RESOURCES(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 570 571 /** 572 * User may invoke the MDM $mdm-not-duplicate 573 */ 574 FHIR_OP_MDM_NOT_DUPLICATE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 575 576 /** 577 * User may invoke the MDM $mdm-clear Operation 578 */ 579 FHIR_OP_MDM_CLEAR(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 580 581 /** 582 * User may invoke the MDM $mdm-submit operation 583 */ 584 FHIR_OP_MDM_SUBMIT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 585 586 /** 587 * User may perform all MDM operations 588 */ 589 FHIR_MDM_ADMIN(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] { 590 FHIR_OP_MDM_SUBMIT, 591 FHIR_OP_MDM_CLEAR, 592 FHIR_OP_MDM_DUPLICATE_GOLDEN_RESOURCES, 593 FHIR_OP_MDM_NOT_DUPLICATE, 594 FHIR_OP_MDM_MERGE_GOLDEN_RESOURCES, 595 FHIR_OP_MDM_QUERY_LINKS, 596 FHIR_OP_MDM_LINK_HISTORY, 597 FHIR_OP_MDM_UPDATE_LINK, 598 FHIR_OP_MDM_CREATE_LINK 599 }), 600 601 /** 602 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 603 */ 604 FHIR_OP_EMPI_MERGE_PERSONS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 605 606 /** 607 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 608 */ 609 FHIR_OP_EMPI_UPDATE_LINK(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 610 611 /** 612 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 613 */ 614 FHIR_OP_EMPI_QUERY_LINKS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 615 616 /** 617 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 618 */ 619 FHIR_OP_EMPI_DUPLICATE_PERSONS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 620 621 /** 622 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 623 */ 624 FHIR_OP_EMPI_CLEAR(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 625 626 /** 627 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 628 */ 629 FHIR_OP_EMPI_SUBMIT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 630 631 /** 632 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 633 */ 634 FHIR_EMPI_ADMIN(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] { 635 FHIR_OP_EMPI_SUBMIT, 636 FHIR_OP_EMPI_CLEAR, 637 FHIR_OP_EMPI_DUPLICATE_PERSONS, 638 FHIR_OP_EMPI_MERGE_PERSONS, 639 FHIR_OP_EMPI_QUERY_LINKS, 640 FHIR_OP_EMPI_UPDATE_LINK 641 }), 642 643 /** 644 * CQL Permission for evaluate-measure operation. 645 */ 646 FHIR_OP_EVALUATE_MEASURE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 647 /** 648 * Permission for submit-data operation. 649 */ 650 FHIR_OP_SUBMIT_DATA(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 651 /** 652 * Permission for care-gaps operation. 653 */ 654 FHIR_OP_CARE_GAPS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 655 /** 656 * Permission for evaluate operation. 657 */ 658 FHIR_OP_EVALUATE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 659 /** 660 * Permission for $collect-data operation. 661 */ 662 FHIR_OP_COLLECTDATA(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 663 /** 664 * Permission for $data-requirements operation. 665 */ 666 FHIR_OP_DATAREQUIREMENTS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 667 /** 668 * Permission for cql operation. 669 */ 670 FHIR_OP_CQL(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 671 /** 672 * Permission for evaluate-measures operation. 673 */ 674 FHIR_OP_EVALUATE_MEASURES(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] {ROLE_FHIR_CLIENT}), 675 /** 676 * Permission for qpp-build operation. 677 */ 678 DQM_QPP_BUILD(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 679 /** 680 * Permission for job-analytics operation 681 */ 682 BATCH_JOB_ANALYTICS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 683 684 /** 685 * User is permitted to call the $apply operation 686 */ 687 FHIR_OP_APPLY(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 688 689 /** 690 * User is permitted to call the $prepopulate operation 691 */ 692 FHIR_OP_PREPOPULATE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 693 694 /** 695 * User is permitted to call the $populate operation 696 */ 697 FHIR_OP_POPULATE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 698 699 /** 700 * User is permitted to call the $extract operation 701 */ 702 FHIR_OP_EXTRACT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 703 704 /** 705 * User is permitted to call the $package operation 706 */ 707 FHIR_OP_PACKAGE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 708 709 /** 710 * User is permitted to call the $hapi.fhir.replace-references operation 711 */ 712 FHIR_OP_REPLACE_REFERENCES(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 713 714 /** 715 * User is permitted to call the $merge operation 716 */ 717 FHIR_OP_MERGE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 718 719 /** 720 * User may perform all DTR operations 721 */ 722 FHIR_DTR_USER(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] {FHIR_OP_PACKAGE, FHIR_OP_POPULATE}), 723 724 /** 725 * User is allowed to perform any FHIR read/access-to-data operation, e.g. `read`, `search`, `history`, etc 726 */ 727 FHIR_ALL_READ( 728 PermissionCategoryEnum.FHIR_CLIENT, 729 new PermissionEnum[] {ROLE_FHIR_CLIENT, FHIR_READ_SEARCH_PARAMETERS}, 730 TakesArgumentEnum.NO, 731 false, 732 PermissionArgumentFormats.OPTIONAL_FILTER_FORMAT), 733 734 /** 735 * User is allowed to perform FHIR transactions 736 */ 737 FHIR_TRANSACTION(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 738 739 /** 740 * User is allowed to perform FHIR GraphQL Operations 741 */ 742 FHIR_GRAPHQL(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 743 744 /** 745 * User is allowed to perform FHIR transactions 746 */ 747 FHIR_BATCH(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 748 749 /** 750 * User is allowed to perform FHIR PATCH operations 751 * 752 * @deprecated FHIR_PATCH will be removed: Users should instead be granted more granular write permissions that cover PATCH operations. 753 */ 754 @Deprecated 755 FHIR_PATCH(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 756 757 /** 758 * User is allowed to perform any FHIR write/modify operation, e.g. `create`, `update`, etc 759 */ 760 FHIR_ALL_WRITE( 761 PermissionCategoryEnum.FHIR_CLIENT, 762 new PermissionEnum[] {ROLE_FHIR_CLIENT, FHIR_MODIFY_SEARCH_PARAMETERS, FHIR_META_OPERATIONS_SUPERUSER}, 763 TakesArgumentEnum.NO, 764 false, 765 PermissionArgumentFormats.OPTIONAL_FILTER_FORMAT), 766 767 /** 768 * User is allowed to perform any FHIR delete operation 769 */ 770 FHIR_ALL_DELETE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 771 772 /** 773 * User is allowed to perform any FHIR delete operation on the given type 774 */ 775 FHIR_DELETE_ALL_OF_TYPE( 776 PermissionCategoryEnum.FHIR_CLIENT, 777 ROLE_FHIR_CLIENT, 778 TakesArgumentEnum.YES, 779 PermissionArgumentFormats.RESOURCE_TYPE_OPTIONAL_FILTER_FORMAT), 780 781 /** 782 * User is allowed to perform any FHIR delete operation on a given compartment 783 */ 784 FHIR_DELETE_ALL_IN_COMPARTMENT( 785 PermissionCategoryEnum.FHIR_CLIENT, 786 ROLE_FHIR_CLIENT, 787 TakesArgumentEnum.YES, 788 PermissionArgumentFormats.COMPARTMENT_WITH_OPTIONAL_FILTER_FORMAT), 789 790 /** 791 * User is allowed to perform any FHIR delete operation on a given compartment 792 */ 793 FHIR_DELETE_TYPE_IN_COMPARTMENT( 794 PermissionCategoryEnum.FHIR_CLIENT, 795 ROLE_FHIR_CLIENT, 796 TakesArgumentEnum.YES, 797 PermissionArgumentFormats.TYPE_IN_COMPARTMENT_WITH_OPTIONAL_FILTER_FORMAT), 798 799 /** 800 * Any delete permissions granted to the user may be applied to cascaded deletes 801 * as well as normal deletes. Note that this permission allows cascaded deletes 802 * to occur, but does not actually grant any permission to delete resources in 803 * the first place. This permission must be combined with other permissions that 804 * grant the ability to cascade deletes. 805 */ 806 FHIR_DELETE_CASCADE_ALLOWED(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 807 808 /** 809 * User is allowed to access the server capability statement 810 */ 811 FHIR_CAPABILITIES(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 812 813 /** 814 * User is allowed to invoke the `$validate` operation to validate resources 815 */ 816 FHIR_MANUAL_VALIDATION(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 817 818 /** 819 * User is allowed to invoke the `$process-message` operation to accept a message 820 */ 821 FHIR_PROCESS_MESSAGE(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 822 823 /** 824 * User is permitted to upload external code systems 825 */ 826 FHIR_UPLOAD_EXTERNAL_TERMINOLOGY(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 827 828 /** 829 * User is permitted to call the $get-resource-counts operation 830 */ 831 FHIR_GET_RESOURCE_COUNTS(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 832 833 /** 834 * User is allowed to invoke the $trigger-subscription operation 835 */ 836 FHIR_TRIGGER_SUBSCRIPTION(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 837 838 /** 839 * User is permitted to call read-only terminology methods, such as 840 * $lookup, $validate-code 841 */ 842 ROLE_FHIR_TERMINOLOGY_READ_CLIENT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 843 844 /* 845 * I started creating these two, realized it wouldn't be trivial like i had thought, 846 * but that I could create these anyhow by using FHIR_CLIENT_SUPERUSER. I'll leave them 847 * there so I can finish them later 848 */ 849 // /** 850 // * User is allowed to create a subscription with the `rest-hook` channel type 851 // */ 852 // FHIR_CREATE_SUBSCRIPTION_REST_HOOK(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] { 853 // ROLE_FHIR_CLIENT 854 // }), 855 // 856 // /** 857 // * User is allowed to update a subscription with the `rest-hook` channel type 858 // */ 859 // FHIR_UPDATE_SUBSCRIPTION_REST_HOOK(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] { 860 // ROLE_FHIR_CLIENT 861 // }), 862 863 /** 864 * User is allowed to perform the patient $everything operation 865 */ 866 FHIR_OP_PATIENT_EVERYTHING(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 867 868 /** 869 * User is allowed to perform the patient $everything operation with `Access All` permission 870 */ 871 FHIR_OP_PATIENT_EVERYTHING_ACCESS_ALL( 872 PermissionCategoryEnum.FHIR_CLIENT, 873 ROLE_FHIR_CLIENT, 874 TakesArgumentEnum.YES, 875 PermissionArgumentFormats.INSTANCE_WITH_OPTIONAL_FILTER_FORMAT), 876 877 /** 878 * User is allowed to perform the patient $summary operation 879 */ 880 FHIR_OP_PATIENT_SUMMARY(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 881 882 /** 883 * User is allowed to perform the encounter $everything operation 884 */ 885 FHIR_OP_ENCOUNTER_EVERYTHING(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 886 887 /** 888 * User is allowed to perform the $snapshot operation 889 */ 890 FHIR_OP_STRUCTUREDEFINITION_SNAPSHOT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 891 892 /** 893 * User is allowed to perform the $member-match operation 894 */ 895 FHIR_OP_MEMBER_MATCH(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 896 897 /** 898 * User is allowed to execute HFQL queries 899 */ 900 HFQL_EXECUTE(), 901 902 /** 903 * Any read functions 904 */ 905 ROLE_FHIR_CLIENT_SUPERUSER_RO(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] { 906 FHIR_CAPABILITIES, 907 FHIR_ALL_READ, 908 FHIR_TRANSACTION, 909 FHIR_GRAPHQL, 910 FHIR_BATCH, 911 FHIR_OP_ENCOUNTER_EVERYTHING, 912 FHIR_OP_PATIENT_EVERYTHING, 913 FHIR_OP_PATIENT_SUMMARY, 914 FHIR_OP_BINARY_ACCESS_READ, 915 FHIR_GET_RESOURCE_COUNTS, 916 ROLE_FHIR_TERMINOLOGY_READ_CLIENT, 917 FHIR_OP_INITIATE_BULK_DATA_EXPORT 918 }), 919 920 /** 921 * User has permission to perform any standard FHIR client operation (does not imply superuser status for other parts of the CDR, e.g. user management, FHIR search parameter modification, etc) 922 * Implied permissions are populated internally and not explicitly defined in the constructor. 923 */ 924 ROLE_FHIR_CLIENT_SUPERUSER(PermissionCategoryEnum.FHIR_CLIENT), 925 926 /** 927 * User has all permissions to do anything 928 * Implied permissions are populated internally and not explicitly defined in the constructor. 929 */ 930 ROLE_SUPERUSER(PermissionCategoryEnum.ADMIN), 931 932 /** 933 * User is not logged in or has not supplied credentials 934 */ 935 ROLE_ANONYMOUS(), 936 937 /** 938 * User is allowed to initiate processing an ETL job 939 */ 940 ETL_IMPORT_PROCESS_FILE(), 941 942 /** 943 * User is allowed to view CDA Document Templates 944 */ 945 VIEW_CDA_TEMPLATE(PermissionCategoryEnum.CDA), 946 947 /** 948 * User is allowed to create new CDA Document Templates 949 */ 950 CREATE_CDA_TEMPLATE(PermissionCategoryEnum.CDA, PermissionEnum.VIEW_CDA_TEMPLATE), 951 952 /** 953 * User is allowed to delete CDA Document Templates 954 */ 955 DELETE_CDA_TEMPLATE(PermissionCategoryEnum.CDA, PermissionEnum.VIEW_CDA_TEMPLATE), 956 957 /** 958 * User is allowed to use CDA Document Templates, 959 * potentially persisting a Composition, Bundle, and returning sensitive information in the resultant XML 960 */ 961 USE_CDA_TEMPLATE(PermissionCategoryEnum.CDA, PermissionEnum.VIEW_CDA_TEMPLATE), 962 963 /** 964 * User can set/update MDM match rules 965 */ 966 MDM_UPDATE_MATCH_RULES(PermissionCategoryEnum.MDM), 967 968 /** 969 * User can see MDM match rules 970 */ 971 MDM_VIEW_MATCH_RULES(PermissionCategoryEnum.MDM), 972 973 /** 974 * User can perform any MDM operations 975 */ 976 MDM_ADMIN( 977 PermissionCategoryEnum.MDM, 978 new PermissionEnum[] {PermissionEnum.MDM_VIEW_MATCH_RULES, PermissionEnum.MDM_UPDATE_MATCH_RULES}), 979 980 /** 981 * User will have MDM expansion performed automatically on all queries 982 */ 983 FHIR_AUTO_MDM(PermissionCategoryEnum.MDM), 984 985 /** 986 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 987 */ 988 EMPI_UPDATE_MATCH_RULES(PermissionCategoryEnum.EMPI), 989 990 /** 991 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 992 */ 993 EMPI_VIEW_MATCH_RULES(PermissionCategoryEnum.EMPI), 994 995 /** 996 * Legacy permission for backward compatibility. Use corresponding MDM permission instead. 997 */ 998 EMPI_ADMIN( 999 PermissionCategoryEnum.EMPI, 1000 new PermissionEnum[] {PermissionEnum.EMPI_VIEW_MATCH_RULES, PermissionEnum.EMPI_UPDATE_MATCH_RULES}), 1001 1002 /** 1003 * User can perform read operations from the package registry 1004 */ 1005 PACKAGE_REGISTRY_READ(PermissionCategoryEnum.PACKAGE_REGISTRY), 1006 1007 /** 1008 * User can perform read operations from the package registry 1009 */ 1010 PACKAGE_REGISTRY_WRITE(PermissionCategoryEnum.PACKAGE_REGISTRY), 1011 1012 /** 1013 * User can call CDS Hooks 1014 */ 1015 INVOKE_CDS_HOOKS(PermissionCategoryEnum.CDS_HOOKS), 1016 1017 /** 1018 * User can perform read operations from the appSphere Admin Console 1019 */ 1020 AG_ADMIN_CONSOLE_READ(PermissionCategoryEnum.AG_ADMIN_CONSOLE), 1021 1022 /** 1023 * User can perform write operations from the appSphere Admin Console 1024 */ 1025 AG_ADMIN_CONSOLE_WRITE(PermissionCategoryEnum.AG_ADMIN_CONSOLE), 1026 1027 /** 1028 * User can perform read operations from the appSphere Developer Portal 1029 */ 1030 AG_DEV_PORTAL_READ(PermissionCategoryEnum.AG_DEV_PORTAL), 1031 1032 /** 1033 * User can perform write operations from the appSphere Developer Portal 1034 */ 1035 AG_DEV_PORTAL_WRITE(PermissionCategoryEnum.AG_DEV_PORTAL), 1036 1037 /** 1038 * User has permission to view batch jobs 1039 */ 1040 VIEW_BATCH_JOBS(PermissionCategoryEnum.ADMIN), 1041 1042 /** 1043 * User has permission to manage (modify) batch jobs 1044 */ 1045 MANAGE_BATCH_JOBS(PermissionCategoryEnum.ADMIN), 1046 1047 /** 1048 * User can perform a docref operation 1049 */ 1050 DOCREF(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 1051 1052 /** 1053 * User can perform a CDA Import operation 1054 */ 1055 CDA_IMPORT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 1056 1057 /** 1058 * User can perform an update on the historical version of a resource 1059 */ 1060 FHIR_UPDATE_REWRITE_HISTORY(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 1061 1062 SUBMIT_ATTACHMENT(PermissionCategoryEnum.FHIR_CLIENT, ROLE_FHIR_CLIENT), 1063 1064 /** 1065 * User can see (but not change) module configuration information (not including database passwords) 1066 * for a specific module id for a node id 1067 */ 1068 VIEW_MODULE_CONFIG_FOR_MODULE( 1069 PermissionCategoryEnum.ADMIN, 1070 new PermissionEnum[] {}, 1071 TakesArgumentEnum.YES, 1072 false, 1073 PermissionArgumentFormats.NODE_AND_MODULE_ID_PERMISSION_ARGUMENT_FORMAT), 1074 /** 1075 * User is allowed to modify a specific module id's configuration for a node id 1076 */ 1077 UPDATE_MODULE_CONFIG_FOR_MODULE( 1078 PermissionCategoryEnum.ADMIN, 1079 new PermissionEnum[] {VIEW_MODULE_CONFIG_FOR_MODULE}, 1080 TakesArgumentEnum.YES, 1081 false, 1082 PermissionArgumentFormats.NODE_AND_MODULE_ID_PERMISSION_ARGUMENT_FORMAT), 1083 /** 1084 * User is allowed to start/stop a specific module id for a node id 1085 */ 1086 START_STOP_MODULE_FOR_MODULE( 1087 PermissionCategoryEnum.ADMIN, 1088 new PermissionEnum[] {}, 1089 TakesArgumentEnum.YES, 1090 false, 1091 PermissionArgumentFormats.NODE_AND_MODULE_ID_PERMISSION_ARGUMENT_FORMAT), 1092 /** 1093 * User can start/stop/restart a specific module id for a node id 1094 */ 1095 CONTROL_MODULE_FOR_MODULE( 1096 PermissionCategoryEnum.ADMIN, 1097 new PermissionEnum[] {VIEW_MODULE_CONFIG_FOR_MODULE, START_STOP_MODULE_FOR_MODULE}, 1098 TakesArgumentEnum.YES, 1099 false, 1100 PermissionArgumentFormats.NODE_AND_MODULE_ID_PERMISSION_ARGUMENT_FORMAT), 1101 1102 /** 1103 * User is allowed to reconfigure and start/stop a specific module id for a node id 1104 */ 1105 MODULE_ADMIN_FOR_MODULE( 1106 PermissionCategoryEnum.ADMIN, 1107 new PermissionEnum[] { 1108 UPDATE_MODULE_CONFIG_FOR_MODULE, 1109 CONTROL_MODULE_FOR_MODULE, 1110 START_STOP_MODULE_FOR_MODULE, 1111 VIEW_MODULE_CONFIG_FOR_MODULE 1112 }, 1113 TakesArgumentEnum.YES, 1114 false, 1115 PermissionArgumentFormats.NODE_AND_MODULE_ID_PERMISSION_ARGUMENT_FORMAT), 1116 ROLE_MDMUI_DATASTEWARD_FHIR(PermissionCategoryEnum.FHIR_CLIENT, new PermissionEnum[] { 1117 FHIR_ALL_READ, 1118 FHIR_BATCH, 1119 FHIR_TRANSACTION, 1120 FHIR_OP_MDM_DUPLICATE_GOLDEN_RESOURCES, 1121 FHIR_OP_MDM_LINK_HISTORY, 1122 FHIR_OP_MDM_MERGE_GOLDEN_RESOURCES, 1123 FHIR_OP_MDM_NOT_DUPLICATE, 1124 FHIR_OP_MDM_QUERY_LINKS, 1125 FHIR_OP_MDM_UPDATE_LINK, 1126 ROLE_FHIR_TERMINOLOGY_READ_CLIENT 1127 }), 1128 ROLE_MDMUI_ADMIN_FHIR( 1129 PermissionCategoryEnum.FHIR_CLIENT, 1130 new PermissionEnum[] {ROLE_MDMUI_DATASTEWARD_FHIR, FHIR_OP_MDM_CLEAR, FHIR_OP_MDM_SUBMIT}); 1131 1132 private static final Set<PermissionEnum> ROLES = getRoles(); 1133 1134 static { 1135 ROLE_SYSTEM.myImplies = getAllPermissions(); 1136 ROLE_SUPERUSER.myImplies = getAllSuperuserPermissions(); 1137 ROLE_FHIR_CLIENT_SUPERUSER.myImplies = getAllFhirSuperuserPermissions(); 1138 1139 /* 1140 * Creating EnumSet with enum elements that have not been initialized fails (not a bug). 1141 * Use a static block to replace Set with EnumSet once everything is initialized. 1142 * {@link https://bugs.openjdk.org/browse/JDK-8211749}. 1143 */ 1144 for (PermissionEnum next : values()) { 1145 next.myImplies = unmodifiableEnumSet(next.myImplies.toArray(new PermissionEnum[0])); 1146 } 1147 } 1148 1149 private final TakesArgumentEnum myTakesArgument; 1150 private final boolean myNegativePermission; 1151 private Set<PermissionEnum> myImplies; 1152 private final PermissionCategoryEnum myCategory; 1153 /** 1154 * The format for the argument - defaults to no argument 1155 */ 1156 private final PermissionArgumentFormat<?> myFormat; 1157 1158 /** 1159 * Constructor for permissions with just a name 1160 */ 1161 PermissionEnum() { 1162 this(null); 1163 } 1164 1165 /** 1166 * Constructor for permissions with an assigned category 1167 */ 1168 PermissionEnum(PermissionCategoryEnum theCategory) { 1169 this(theCategory, new PermissionEnum[] {}); 1170 } 1171 1172 /** 1173 * Constructor for permissions that have implied (underlying) permissions 1174 */ 1175 PermissionEnum(PermissionCategoryEnum theCategory, PermissionEnum... theImplies) { 1176 this(theCategory, theImplies, TakesArgumentEnum.NO, false, PermissionArgumentFormats.NO_ARGUMENT_FORMAT); 1177 } 1178 1179 /** 1180 * Constructor for permissions with arguments. 1181 */ 1182 PermissionEnum( 1183 PermissionCategoryEnum theCategory, 1184 PermissionEnum theImplied, 1185 TakesArgumentEnum theTakesArgument, 1186 PermissionArgumentFormat<?> theFormat) { 1187 this(theCategory, new PermissionEnum[] {theImplied}, theTakesArgument, false, theFormat); 1188 } 1189 1190 /** 1191 * Constructor for permissions with implied (underlying) permissions and/or with arguments. 1192 */ 1193 PermissionEnum( 1194 PermissionCategoryEnum theCategory, 1195 PermissionEnum[] theImplies, 1196 TakesArgumentEnum theTakesArgument, 1197 boolean theNegativePermission, 1198 PermissionArgumentFormat<?> theFormat) { 1199 assert theTakesArgument != null; 1200 assert !theNegativePermission || name().startsWith("BLOCK_"); 1201 myImplies = Set.of(theImplies); 1202 myCategory = theCategory; 1203 myTakesArgument = theTakesArgument; 1204 myNegativePermission = theNegativePermission; 1205 myFormat = theFormat; 1206 validateInheritedPermissionsFormat(theImplies, theFormat); 1207 } 1208 1209 public static void validateInheritedPermissionsFormat( 1210 PermissionEnum[] theImplies, PermissionArgumentFormat<?> theFormat) { 1211 if (Arrays.stream(theImplies).anyMatch(x -> x.isRequiresArgument() && (x.getFormat() != theFormat))) { 1212 throw new IllegalArgumentException( 1213 "Implied Permissions with arguments must accept the same argument format as Parent permission. " 1214 + theFormat); 1215 } 1216 } 1217 1218 @Deprecated(since = "7.2.0") 1219 public Set<PermissionCategoryEnum> getCategories() { 1220 return Set.of(myCategory); 1221 } 1222 1223 public PermissionCategoryEnum getCategory() { 1224 return myCategory; 1225 } 1226 1227 public Set<PermissionEnum> getImplies() { 1228 return myImplies; 1229 } 1230 1231 public boolean isSystemPermission() { 1232 return this == ROLE_SYSTEM_INITIALIZATION || this == ROLE_SYSTEM; 1233 } 1234 1235 public boolean isTakesArgument() { 1236 return myTakesArgument != TakesArgumentEnum.NO; 1237 } 1238 1239 public boolean isRequiresArgument() { 1240 return myTakesArgument == TakesArgumentEnum.YES; 1241 } 1242 1243 public boolean isArgumentOptional() { 1244 return myTakesArgument == TakesArgumentEnum.OPTIONAL; 1245 } 1246 1247 public boolean isNegative() { 1248 return myNegativePermission; 1249 } 1250 1251 /** 1252 * The format for the argument - defaults to NoArgument format 1253 */ 1254 public PermissionArgumentFormat getFormat() { 1255 return myFormat; 1256 } 1257 1258 private enum TakesArgumentEnum { 1259 YES, 1260 NO, 1261 OPTIONAL 1262 } 1263 1264 @Nonnull 1265 public static Optional<PermissionEnum> find(String thePermission) { 1266 try { 1267 return Optional.of(PermissionEnum.valueOf(thePermission.toUpperCase(Locale.ROOT))); 1268 } catch (NullPointerException | IllegalArgumentException e) { 1269 return Optional.empty(); 1270 } 1271 } 1272 1273 @Nonnull 1274 public static List<PermissionEnum> findAll(List<String> thePermissions) { 1275 return Optional.ofNullable(thePermissions).stream() 1276 .flatMap(Collection::stream) 1277 .map(PermissionEnum::find) 1278 .filter(Optional::isPresent) 1279 .map(Optional::get) 1280 .collect(Collectors.toList()); 1281 } 1282 1283 private static <T extends Enum<T>> Set<T> unmodifiableEnumSet(T[] theValues) { 1284 if (theValues.length == 0) { 1285 return Collections.emptySet(); 1286 } 1287 Set<T> set = EnumSet.of(theValues[0], theValues); 1288 return Collections.unmodifiableSet(set); 1289 } 1290 1291 @Deprecated(since = "7.2.0") 1292 public static Set<PermissionEnum> roles() { 1293 return ROLES; 1294 } 1295 1296 public static String extractFirstSpaceSeparatedArgument(String theArgument) { 1297 if (isNotBlank(theArgument)) { 1298 int spaceIdx = theArgument.indexOf(' '); 1299 if (spaceIdx != -1) { 1300 return trim(theArgument.substring(0, spaceIdx)); 1301 } else { 1302 return theArgument; 1303 } 1304 } 1305 return null; 1306 } 1307 1308 public static Collection<String> extractSpaceSeparatedResourceTypesFromArgument(String theArgument) { 1309 return extractSpaceSeparatedResourceTypesFromArgument(theArgument, 0); 1310 } 1311 1312 public static Collection<String> extractSpaceSeparatedResourceTypesFromArgument( 1313 String theArgument, int theFromOffsetIndex) { 1314 if (isBlank(theArgument)) { 1315 return null; 1316 } 1317 StringTokenizer tok = new StringTokenizer(theArgument, " "); 1318 List<String> retVal = new ArrayList<>(); 1319 while (tok.hasNext()) { 1320 String next = tok.next(); 1321 next = trim(next); 1322 if (isNotBlank(next)) { 1323 if (theFromOffsetIndex > 0) { 1324 theFromOffsetIndex--; 1325 continue; 1326 } 1327 retVal.add(next); 1328 } 1329 } 1330 return retVal; 1331 } 1332 1333 private static Set<PermissionEnum> getAllPermissions() { 1334 return Arrays.stream(values()) 1335 .filter(p -> !p.isRole()) 1336 .filter(p -> !p.isRequiresArgument()) 1337 .collect(Collectors.toSet()); 1338 } 1339 1340 private static Set<PermissionEnum> getAllSuperuserPermissions() { 1341 return Arrays.stream(values()) 1342 .filter(p -> !p.isRole()) 1343 .filter(p -> !p.isExpungePermission()) 1344 .filter(p -> !p.isRequiresArgument()) 1345 .collect(Collectors.toSet()); 1346 } 1347 1348 private static Set<PermissionEnum> getAllFhirSuperuserPermissions() { 1349 Set<PermissionEnum> permissions = getAllSuperuserPermissions().stream() 1350 .filter(PermissionEnum::isFhirPermission) 1351 .collect(Collectors.toSet()); 1352 permissions.add(ACCESS_FHIRWEB); 1353 return permissions; 1354 } 1355 1356 private static Set<PermissionEnum> getRoles() { 1357 Set<PermissionEnum> roles = Arrays.stream(values()) 1358 .filter(PermissionEnum::isRole) 1359 .collect(Collectors.toCollection(() -> EnumSet.noneOf(PermissionEnum.class))); 1360 return Collections.unmodifiableSet(roles); 1361 } 1362 1363 boolean isRole() { 1364 // unlike other roles, the terminology role is involved in the logic that checks the access 1365 return name().startsWith("ROLE_") && this != ROLE_FHIR_TERMINOLOGY_READ_CLIENT; 1366 } 1367 1368 public boolean isExpungePermission() { 1369 return name().toLowerCase().contains("expunge"); 1370 } 1371 1372 /** 1373 * Determines if this is a FHIR delete permission. 1374 * 1375 * @return true if FHIR delete, false otherwise 1376 */ 1377 public boolean isSuperuser() { 1378 return name().toLowerCase().contains("superuser"); 1379 } 1380 1381 /** 1382 * Determines if this is a FHIR related permission. 1383 * 1384 * @return true if FHIR permission, false otherwise 1385 */ 1386 public boolean isFhirPermission() { 1387 return PermissionCategoryEnum.FHIR_CLIENT.equals(myCategory); 1388 } 1389}