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