001package ca.uhn.fhir.rest.server.interceptor.auth;
002
003/*-
004 * #%L
005 * HAPI FHIR - Server Framework
006 * %%
007 * Copyright (C) 2014 - 2022 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.interceptor.api.Pointcut;
024import ca.uhn.fhir.model.primitive.IdDt;
025import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
026import ca.uhn.fhir.rest.api.server.RequestDetails;
027import ca.uhn.fhir.rest.api.server.bulk.BulkDataExportOptions;
028import org.hl7.fhir.instance.model.api.IBaseResource;
029import org.hl7.fhir.instance.model.api.IIdType;
030
031import java.util.Collection;
032import java.util.Objects;
033import java.util.Set;
034
035import static org.apache.commons.lang3.StringUtils.isNotBlank;
036
037public class RuleBulkExportImpl extends BaseRule {
038        private String myGroupId;
039        private BulkDataExportOptions.ExportStyle myWantExportStyle;
040        private Collection<String> myResourceTypes;
041        private boolean myWantAnyStyle;
042
043        RuleBulkExportImpl(String theRuleName) {
044                super(theRuleName);
045        }
046
047        @Override
048        public AuthorizationInterceptor.Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource, IRuleApplier theRuleApplier, Set<AuthorizationFlagsEnum> theFlags, Pointcut thePointcut) {
049                if (thePointcut != Pointcut.STORAGE_INITIATE_BULK_EXPORT) {
050                        return null;
051                }
052
053                if (theRequestDetails == null) {
054                        return null;
055                }
056
057                BulkDataExportOptions options = (BulkDataExportOptions) theRequestDetails.getAttribute(AuthorizationInterceptor.REQUEST_ATTRIBUTE_BULK_DATA_EXPORT_OPTIONS);
058
059                if (!myWantAnyStyle && options.getExportStyle() != myWantExportStyle) {
060                        return null;
061                }
062
063                if (myResourceTypes != null && !myResourceTypes.isEmpty()) {
064                        if (options.getResourceTypes() == null) {
065                                return null;
066                        }
067                        for (String next : options.getResourceTypes()) {
068                                if (!myResourceTypes.contains(next)) {
069                                        return new AuthorizationInterceptor.Verdict(PolicyEnum.DENY,this);
070                                }
071                        }
072                }
073
074                if (myWantAnyStyle || myWantExportStyle == BulkDataExportOptions.ExportStyle.SYSTEM) {
075                        return newVerdict(theOperation, theRequestDetails, theInputResource, theInputResourceId, theOutputResource);
076                }
077
078                if (isNotBlank(myGroupId) && options.getGroupId() != null) {
079                        String expectedGroupId = new IdDt(myGroupId).toUnqualifiedVersionless().getValue();
080                        String actualGroupId = options.getGroupId().toUnqualifiedVersionless().getValue();
081                        if (Objects.equals(expectedGroupId, actualGroupId)) {
082                                return newVerdict(theOperation, theRequestDetails, theInputResource, theInputResourceId, theOutputResource);
083                        } else {
084                                return new AuthorizationInterceptor.Verdict(PolicyEnum.DENY,this);
085                        }
086                }
087
088                return null;
089        }
090
091        public void setAppliesToGroupExportOnGroup(String theGroupId) {
092                myWantExportStyle = BulkDataExportOptions.ExportStyle.GROUP;
093                myGroupId = theGroupId;
094        }
095
096        public void setAppliesToPatientExportOnGroup(String theGroupId) {
097                myWantExportStyle = BulkDataExportOptions.ExportStyle.PATIENT;
098                myGroupId = theGroupId;
099        }
100
101        public void setAppliesToSystem() {
102                myWantExportStyle = BulkDataExportOptions.ExportStyle.SYSTEM;
103        }
104
105        public void setResourceTypes(Collection<String> theResourceTypes) {
106                myResourceTypes = theResourceTypes;
107        }
108
109        public void setAppliesToAny() {
110                myWantAnyStyle = true;
111        }
112
113        String getGroupId() {
114                return myGroupId;
115        }
116
117        BulkDataExportOptions.ExportStyle getWantExportStyle() {
118                return myWantExportStyle;
119        }
120}