Version bump to 3.3.0-SNAPSHOT
This commit is contained in:
parent
4fd3e20d06
commit
16038ece26
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>hapi-fhir-standalone-overlay-example</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
|||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class AuthorizationInterceptors {
|
||||
|
||||
public class PatientResourceProvider implements IResourceProvider
|
||||
|
@ -35,6 +36,7 @@ public class AuthorizationInterceptors {
|
|||
}
|
||||
|
||||
//START SNIPPET: patientAndAdmin
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class PatientAndAdminAuthorizationInterceptor extends AuthorizationInterceptor {
|
||||
|
||||
@Override
|
||||
|
@ -127,5 +129,16 @@ public class AuthorizationInterceptors {
|
|||
}
|
||||
//END SNIPPET: conditionalUpdate
|
||||
|
||||
|
||||
public void authorizeTenantAction() {
|
||||
//START SNIPPET: authorizeTenantAction
|
||||
new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder()
|
||||
.allow().read().resourcesOfType(Patient.class).withAnyId().forTenantIds("TENANTA").andThen()
|
||||
.build();
|
||||
}
|
||||
};
|
||||
//END SNIPPET: authorizeTenantAction
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-cli</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-cli</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -26,42 +26,42 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2.1</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -494,6 +494,17 @@
|
|||
<groupId>de.juplo</groupId>
|
||||
<artifactId>hibernate-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>derby107</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>create</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<dialect>org.hibernate.dialect.DerbyTenSevenDialect</dialect>
|
||||
<outputFile>${project.build.directory}/classes/ca/uhn/hapi/fhir/jpa/docs/database/persistence_create_derby107.sql</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>postgres94</id>
|
||||
<phase>process-classes</phase>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -20,6 +20,15 @@ package ca.uhn.fhir.rest.server.interceptor.auth;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IAuthRuleBuilderRuleOpClassifierFinished extends IAuthRuleFinished {
|
||||
// nothing
|
||||
|
||||
IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId forTenantIds(String... theTenantId);
|
||||
|
||||
IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId forTenantIds(Collection<String> theTenantId);
|
||||
|
||||
IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId notForTenantIds(String... theTenantIds);
|
||||
|
||||
IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId notForTenantIds(Collection<String> theTenantIds);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package ca.uhn.fhir.rest.server.interceptor.auth;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Server Framework
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2018 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
public interface IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId extends IAuthRuleFinished {
|
||||
|
||||
}
|
|
@ -20,23 +20,19 @@ package ca.uhn.fhir.rest.server.interceptor.auth;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor.Verdict;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
class OperationRule extends BaseRule implements IAuthRule {
|
||||
|
||||
public OperationRule(String theRuleName) {
|
||||
super(theRuleName);
|
||||
}
|
||||
|
||||
private RuleBuilder.ITenantApplicabilityChecker myTenentApplicabilityChecker;
|
||||
private String myOperationName;
|
||||
private boolean myAppliesToServer;
|
||||
private HashSet<Class<? extends IBaseResource>> myAppliesToTypes;
|
||||
|
@ -44,22 +40,44 @@ class OperationRule extends BaseRule implements IAuthRule {
|
|||
private HashSet<Class<? extends IBaseResource>> myAppliesToInstancesOfType;
|
||||
private boolean myAppliesToAnyType;
|
||||
private boolean myAppliesToAnyInstance;
|
||||
|
||||
/**
|
||||
* Must include the leading $
|
||||
*/
|
||||
public void setOperationName(String theOperationName) {
|
||||
myOperationName = theOperationName;
|
||||
public OperationRule(String theRuleName) {
|
||||
super(theRuleName);
|
||||
}
|
||||
|
||||
public String getOperationName() {
|
||||
return myOperationName;
|
||||
public void appliesToAnyInstance() {
|
||||
myAppliesToAnyInstance = true;
|
||||
}
|
||||
|
||||
public void appliesToAnyType() {
|
||||
myAppliesToAnyType = true;
|
||||
}
|
||||
|
||||
public void appliesToInstances(List<IIdType> theAppliesToIds) {
|
||||
myAppliesToIds = theAppliesToIds;
|
||||
}
|
||||
|
||||
public void appliesToInstancesOfType(HashSet<Class<? extends IBaseResource>> theAppliesToTypes) {
|
||||
myAppliesToInstancesOfType = theAppliesToTypes;
|
||||
}
|
||||
|
||||
public void appliesToServer() {
|
||||
myAppliesToServer = true;
|
||||
}
|
||||
|
||||
public void appliesToTypes(HashSet<Class<? extends IBaseResource>> theAppliesToTypes) {
|
||||
myAppliesToTypes = theAppliesToTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource, IRuleApplier theRuleApplier) {
|
||||
FhirContext ctx = theRequestDetails.getServer().getFhirContext();
|
||||
|
||||
if (myTenentApplicabilityChecker != null) {
|
||||
if (!myTenentApplicabilityChecker.applies(theRequestDetails)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean applies = false;
|
||||
switch (theOperation) {
|
||||
case EXTENDED_OPERATION_SERVER:
|
||||
|
@ -121,28 +139,19 @@ class OperationRule extends BaseRule implements IAuthRule {
|
|||
return newVerdict();
|
||||
}
|
||||
|
||||
public void appliesToServer() {
|
||||
myAppliesToServer = true;
|
||||
public String getOperationName() {
|
||||
return myOperationName;
|
||||
}
|
||||
|
||||
public void appliesToTypes(HashSet<Class<? extends IBaseResource>> theAppliesToTypes) {
|
||||
myAppliesToTypes = theAppliesToTypes;
|
||||
/**
|
||||
* Must include the leading $
|
||||
*/
|
||||
public void setOperationName(String theOperationName) {
|
||||
myOperationName = theOperationName;
|
||||
}
|
||||
|
||||
public void appliesToInstances(List<IIdType> theAppliesToIds) {
|
||||
myAppliesToIds = theAppliesToIds;
|
||||
}
|
||||
|
||||
public void appliesToInstancesOfType(HashSet<Class<? extends IBaseResource>> theAppliesToTypes) {
|
||||
myAppliesToInstancesOfType = theAppliesToTypes;
|
||||
}
|
||||
|
||||
public void appliesToAnyInstance() {
|
||||
myAppliesToAnyInstance = true;
|
||||
}
|
||||
|
||||
public void appliesToAnyType() {
|
||||
myAppliesToAnyType = true;
|
||||
public void setTenentApplicabilityChecker(RuleBuilder.ITenantApplicabilityChecker theTenentApplicabilityChecker) {
|
||||
myTenentApplicabilityChecker = theTenentApplicabilityChecker;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,21 +19,25 @@ package ca.uhn.fhir.rest.server.interceptor.auth;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import java.util.*;
|
||||
|
||||
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
||||
|
||||
public class RuleBuilder implements IAuthRuleBuilder {
|
||||
|
||||
public static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
private ArrayList<IAuthRule> myRules;
|
||||
|
||||
public RuleBuilder() {
|
||||
myRules = new ArrayList<IAuthRule>();
|
||||
myRules = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,8 +57,9 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinished allowAll(String theRuleName) {
|
||||
myRules.add(new RuleImplOp(theRuleName).setOp(RuleOpEnum.ALLOW_ALL));
|
||||
return new RuleBuilderFinished();
|
||||
RuleImplOp rule = new RuleImplOp(theRuleName);
|
||||
myRules.add(rule.setOp(RuleOpEnum.ALLOW_ALL));
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -79,11 +84,26 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinished denyAll(String theRuleName) {
|
||||
myRules.add(new RuleImplOp(theRuleName).setOp(RuleOpEnum.DENY_ALL));
|
||||
return new RuleBuilderFinished();
|
||||
RuleImplOp rule = new RuleImplOp(theRuleName);
|
||||
myRules.add(rule.setOp(RuleOpEnum.DENY_ALL));
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
private class RuleBuilderFinished implements IAuthRuleFinished, IAuthRuleBuilderRuleOpClassifierFinished {
|
||||
private class RuleBuilderFinished implements IAuthRuleFinished, IAuthRuleBuilderRuleOpClassifierFinished, IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId {
|
||||
|
||||
private final RuleImplOp myOpRule;
|
||||
private final OperationRule myOperationRule;
|
||||
protected ITenantApplicabilityChecker myTenantApplicabilityChecker;
|
||||
|
||||
RuleBuilderFinished(RuleImplOp theRule) {
|
||||
myOpRule = theRule;
|
||||
myOperationRule = null;
|
||||
}
|
||||
|
||||
public RuleBuilderFinished(OperationRule theRule) {
|
||||
myOpRule = null;
|
||||
myOperationRule = theRule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilder andThen() {
|
||||
|
@ -103,6 +123,43 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
protected void doBuildRule() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId forTenantIds(String... theTenantIds) {
|
||||
return forTenantIds(Arrays.asList(defaultIfNull(theTenantIds, EMPTY_STRING_ARRAY)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId forTenantIds(final Collection<String> theTenantIds) {
|
||||
myTenantApplicabilityChecker = new ITenantApplicabilityChecker(){
|
||||
@Override
|
||||
public boolean applies(RequestDetails theRequest) {
|
||||
return theTenantIds.contains(theRequest.getTenantId());
|
||||
}
|
||||
};
|
||||
if (myOpRule != null) {
|
||||
myOpRule.setTenantApplicabilityChecker(myTenantApplicabilityChecker);
|
||||
}
|
||||
if (myOperationRule != null) {
|
||||
myOperationRule.setTenentApplicabilityChecker(myTenantApplicabilityChecker);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId notForTenantIds(String... theTenantIds) {
|
||||
return notForTenantIds(Arrays.asList(defaultIfNull(theTenantIds, EMPTY_STRING_ARRAY)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinishedWithTenantId notForTenantIds(Collection<String> theTenantIds) {
|
||||
return null;// TODO: implement method body
|
||||
}
|
||||
}
|
||||
|
||||
public interface ITenantApplicabilityChecker
|
||||
{
|
||||
boolean applies(RequestDetails theRequest);
|
||||
}
|
||||
|
||||
private class RuleBuilderRule implements IAuthRuleBuilderRule {
|
||||
|
@ -111,7 +168,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
private String myRuleName;
|
||||
private RuleOpEnum myRuleOp;
|
||||
|
||||
public RuleBuilderRule(PolicyEnum theRuleMode, String theRuleName) {
|
||||
RuleBuilderRule(PolicyEnum theRuleMode, String theRuleName) {
|
||||
myRuleMode = theRuleMode;
|
||||
myRuleName = theRuleName;
|
||||
}
|
||||
|
@ -138,7 +195,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
rule.setOp(RuleOpEnum.METADATA);
|
||||
rule.setMode(myRuleMode);
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -176,7 +233,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
private Set<?> myAppliesToTypes;
|
||||
private RestOperationTypeEnum myOperationType;
|
||||
|
||||
public RuleBuilderRuleConditional(RestOperationTypeEnum theOperationType) {
|
||||
RuleBuilderRuleConditional(RestOperationTypeEnum theOperationType) {
|
||||
myOperationType = theOperationType;
|
||||
}
|
||||
|
||||
|
@ -196,6 +253,10 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
|
||||
public class RuleBuilderRuleConditionalClassifier extends RuleBuilderFinished implements IAuthRuleBuilderRuleConditionalClassifier {
|
||||
|
||||
public RuleBuilderRuleConditionalClassifier() {
|
||||
super((RuleImplOp) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBuildRule() {
|
||||
RuleImplConditional rule = new RuleImplConditional(myRuleName);
|
||||
|
@ -203,6 +264,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
rule.setOperationType(myOperationType);
|
||||
rule.setAppliesTo(myAppliesTo);
|
||||
rule.setAppliesToTypes(myAppliesToTypes);
|
||||
rule.setTenantApplicabilityChecker(myTenantApplicabilityChecker);
|
||||
myRules.add(rule);
|
||||
|
||||
}
|
||||
|
@ -221,6 +283,21 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
return new RuleBuilderRuleOpClassifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished instance(String theId) {
|
||||
Validate.notBlank(theId, "theId must not be null or empty");
|
||||
return instance(new IdDt(theId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished instance(IIdType theId) {
|
||||
Validate.notNull(theId, "theId must not be null");
|
||||
Validate.notBlank(theId.getValue(), "theId.getValue() must not be null or empty");
|
||||
Validate.notBlank(theId.getIdPart(), "theId must contain an ID part");
|
||||
|
||||
return new RuleBuilderRuleOpClassifier(Arrays.asList(theId)).finished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifier resourcesOfType(Class<? extends IBaseResource> theType) {
|
||||
Validate.notNull(theType, "theType must not be null");
|
||||
|
@ -239,14 +316,14 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public RuleBuilderRuleOpClassifier() {
|
||||
RuleBuilderRuleOpClassifier() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public RuleBuilderRuleOpClassifier(List<IIdType> theAppliesToInstances) {
|
||||
RuleBuilderRuleOpClassifier(List<IIdType> theAppliesToInstances) {
|
||||
myAppliesToInstances = theAppliesToInstances;
|
||||
myAppliesTo = AppliesTypeEnum.INSTANCES;
|
||||
}
|
||||
|
@ -264,7 +341,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
rule.setClassifierCompartmentOwners(myInCompartmentOwners);
|
||||
myRules.add(rule);
|
||||
|
||||
return new RuleBuilderFinished();
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -303,21 +380,6 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished instance(String theId) {
|
||||
Validate.notBlank(theId, "theId must not be null or empty");
|
||||
return instance(new IdDt(theId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished instance(IIdType theId) {
|
||||
Validate.notNull(theId, "theId must not be null");
|
||||
Validate.notBlank(theId.getValue(), "theId.getValue() must not be null or empty");
|
||||
Validate.notBlank(theId.getIdPart(), "theId must contain an ID part");
|
||||
|
||||
return new RuleBuilderRuleOpClassifier(Arrays.asList(theId)).finished();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class RuleBuilderRuleOperation implements IAuthRuleBuilderOperation {
|
||||
|
@ -352,6 +414,22 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
return rule;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished onAnyInstance() {
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToAnyInstance();
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished onAnyType() {
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToAnyType();
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinished onInstance(IIdType theInstanceId) {
|
||||
Validate.notNull(theInstanceId, "theInstanceId must not be null");
|
||||
|
@ -363,29 +441,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
ids.add(theInstanceId);
|
||||
rule.appliesToInstances(ids);
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinished onServer() {
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToServer();
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinished onType(Class<? extends IBaseResource> theType) {
|
||||
validateType(theType);
|
||||
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToTypes(toTypeSet(theType));
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
}
|
||||
|
||||
private void validateType(Class<? extends IBaseResource> theType) {
|
||||
Validate.notNull(theType, "theType must not be null");
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -395,7 +451,25 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
OperationRule rule = createRule();
|
||||
rule.appliesToInstancesOfType(toTypeSet(theType));
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinished onServer() {
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToServer();
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleBuilderRuleOpClassifierFinished onType(Class<? extends IBaseResource> theType) {
|
||||
validateType(theType);
|
||||
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToTypes(toTypeSet(theType));
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
private HashSet<Class<? extends IBaseResource>> toTypeSet(Class<? extends IBaseResource> theType) {
|
||||
|
@ -404,20 +478,8 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
return appliesToTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished onAnyType() {
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToAnyType();
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAuthRuleFinished onAnyInstance() {
|
||||
OperationRule rule = createRule();
|
||||
rule.appliesToAnyInstance();
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
private void validateType(Class<? extends IBaseResource> theType) {
|
||||
Validate.notNull(theType, "theType must not be null");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -440,7 +502,7 @@ public class RuleBuilder implements IAuthRuleBuilder {
|
|||
rule.setOp(myRuleOp);
|
||||
rule.setTransactionAppliesToOp(TransactionAppliesToEnum.ANY_OPERATION);
|
||||
myRules.add(rule);
|
||||
return new RuleBuilderFinished();
|
||||
return new RuleBuilderFinished(rule);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,22 +20,22 @@ package ca.uhn.fhir.rest.server.interceptor.auth;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor.Verdict;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class RuleImplConditional extends BaseRule implements IAuthRule {
|
||||
|
||||
private AppliesTypeEnum myAppliesTo;
|
||||
private Set<?> myAppliesToTypes;
|
||||
private RestOperationTypeEnum myOperationType;
|
||||
private RuleBuilder.ITenantApplicabilityChecker myTenantApplicabilityChecker;
|
||||
|
||||
public RuleImplConditional(String theRuleName) {
|
||||
RuleImplConditional(String theRuleName) {
|
||||
super(theRuleName);
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,12 @@ public class RuleImplConditional extends BaseRule implements IAuthRule {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (myTenantApplicabilityChecker != null) {
|
||||
if (!myTenantApplicabilityChecker.applies(theRequestDetails)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return newVerdict();
|
||||
}
|
||||
|
||||
|
@ -81,4 +87,8 @@ public class RuleImplConditional extends BaseRule implements IAuthRule {
|
|||
myOperationType = theOperationType;
|
||||
}
|
||||
|
||||
public void setTenantApplicabilityChecker(RuleBuilder.ITenantApplicabilityChecker theTenantApplicabilityChecker) {
|
||||
myTenantApplicabilityChecker = theTenantApplicabilityChecker;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
|
|||
private RuleOpEnum myOp;
|
||||
private TransactionAppliesToEnum myTransactionAppliesToOp;
|
||||
private List<IIdType> myAppliesToInstances;
|
||||
private RuleBuilder.ITenantApplicabilityChecker myTenantApplicabilityChecker;
|
||||
|
||||
public RuleImplOp(String theRuleName) {
|
||||
super(theRuleName);
|
||||
|
@ -60,6 +61,13 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
|
|||
@Override
|
||||
public Verdict applyRule(RestOperationTypeEnum theOperation, RequestDetails theRequestDetails, IBaseResource theInputResource, IIdType theInputResourceId, IBaseResource theOutputResource,
|
||||
IRuleApplier theRuleApplier) {
|
||||
|
||||
if (myTenantApplicabilityChecker != null) {
|
||||
if (!myTenantApplicabilityChecker.applies(theRequestDetails)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
FhirContext ctx = theRequestDetails.getServer().getFhirContext();
|
||||
|
||||
IBaseResource appliesToResource;
|
||||
|
@ -275,6 +283,10 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
|
|||
return newVerdict();
|
||||
}
|
||||
|
||||
public void setTenantApplicabilityChecker(RuleBuilder.ITenantApplicabilityChecker theTenantApplicabilityChecker) {
|
||||
myTenantApplicabilityChecker = theTenantApplicabilityChecker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
|
@ -282,6 +294,7 @@ class RuleImplOp extends BaseRule /* implements IAuthRule */ {
|
|||
builder.append("transactionAppliesToOp", myTransactionAppliesToOp);
|
||||
builder.append("appliesTo", myAppliesTo);
|
||||
builder.append("appliesToTypes", myAppliesToTypes);
|
||||
builder.append("appliesToTenant", myTenantApplicabilityChecker);
|
||||
builder.append("classifierCompartmentName", myClassifierCompartmentName);
|
||||
builder.append("classifierCompartmentOwners", myClassifierCompartmentOwners);
|
||||
builder.append("classifierType", myClassifierType);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-spring-boot-sample-server-jpa</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-spring-boot</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor;
|
|||
import ca.uhn.fhir.rest.server.interceptor.auth.IAuthRule;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.PolicyEnum;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.RuleBuilder;
|
||||
import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
@ -65,9 +66,10 @@ public class AuthorizationInterceptorR4Test {
|
|||
@Before
|
||||
public void before() {
|
||||
ourCtx.setAddProfileTagWhenEncoding(AddProfileTagEnum.NEVER);
|
||||
for (IServerInterceptor next : new ArrayList<IServerInterceptor>(ourServlet.getInterceptors())) {
|
||||
for (IServerInterceptor next : new ArrayList<>(ourServlet.getInterceptors())) {
|
||||
ourServlet.unregisterInterceptor(next);
|
||||
}
|
||||
ourServlet.setTenantIdentificationStrategy(null);
|
||||
ourReturn = null;
|
||||
ourHitMethod = false;
|
||||
ourConditionalCreateId = "1123";
|
||||
|
@ -236,6 +238,50 @@ public class AuthorizationInterceptorR4Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllowAllForTenant() throws Exception {
|
||||
ourServlet.setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
|
||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder()
|
||||
.deny("Rule 1").read().resourcesOfType(Patient.class).withAnyId().forTenantIds("TENANTA").andThen()
|
||||
.allowAll("Default Rule")
|
||||
.build();
|
||||
}
|
||||
});
|
||||
|
||||
HttpGet httpGet;
|
||||
HttpResponse status;
|
||||
String response;
|
||||
|
||||
ourHitMethod = false;
|
||||
ourReturn = Collections.singletonList(createObservation(10, "Patient/2"));
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Observation/10");
|
||||
status = ourClient.execute(httpGet);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
ourHitMethod = false;
|
||||
ourReturn = Collections.singletonList(createPatient(2));
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient/1");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
ourLog.info(response);
|
||||
assertThat(response, containsString("Access denied by rule: Rule 1"));
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient/1/$validate");
|
||||
status = ourClient.execute(httpGet);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* #528
|
||||
*/
|
||||
|
@ -244,7 +290,10 @@ public class AuthorizationInterceptorR4Test {
|
|||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder().allow("Rule 1").read().allResources().inCompartment("Patient", new IdType("Patient/845bd9f1-3635-4866-a6c8-1ca085df5c1a")).andThen().denyAll().build();
|
||||
return new RuleBuilder()
|
||||
.allow("Rule 1").read().allResources().inCompartment("Patient", new IdType("Patient/845bd9f1-3635-4866-a6c8-1ca085df5c1a"))
|
||||
.andThen().denyAll()
|
||||
.build();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -269,6 +318,40 @@ public class AuthorizationInterceptorR4Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllowByCompartmentWithAnyTypeWithTenantId() throws Exception {
|
||||
ourServlet.setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
|
||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder()
|
||||
.allow("Rule 1").read().allResources().inCompartment("Patient", new IdType("Patient/845bd9f1-3635-4866-a6c8-1ca085df5c1a")).forTenantIds("TENANTA")
|
||||
.andThen().denyAll()
|
||||
.build();
|
||||
}
|
||||
});
|
||||
|
||||
HttpGet httpGet;
|
||||
HttpResponse status;
|
||||
|
||||
ourHitMethod = false;
|
||||
ourReturn = Collections.singletonList(createCarePlan(10, "845bd9f1-3635-4866-a6c8-1ca085df5c1a"));
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/CarePlan/135154");
|
||||
status = ourClient.execute(httpGet);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
ourHitMethod = false;
|
||||
ourReturn = Collections.singletonList(createCarePlan(10, "FOO"));
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/CarePlan/135154");
|
||||
status = ourClient.execute(httpGet);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* #528
|
||||
*/
|
||||
|
@ -521,6 +604,42 @@ public class AuthorizationInterceptorR4Test {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* #528
|
||||
*/
|
||||
@Test
|
||||
public void testDenyActionsNotOnTenant() throws Exception {
|
||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.ALLOW) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder().denyAll().notForTenantIds("TENANTA", "TENANTB").build();
|
||||
}
|
||||
});
|
||||
|
||||
HttpGet httpGet;
|
||||
HttpResponse status;
|
||||
String response;
|
||||
|
||||
ourReturn = Collections.singletonList(createPatient(2));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient/1");
|
||||
status = ourClient.execute(httpGet);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
ourReturn = Collections.singletonList(createObservation(10, "Patient/2"));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTC/Patient/1");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
ourLog.info(response);
|
||||
assertThat(response, containsString("Access denied by default policy (no applicable rules)"));
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertFalse(ourHitMethod);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* #528
|
||||
*/
|
||||
|
@ -660,7 +779,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidInstanceIds() throws Exception {
|
||||
public void testInvalidInstanceIds() {
|
||||
try {
|
||||
new RuleBuilder().allow("Rule 1").write().instance((String) null);
|
||||
fail();
|
||||
|
@ -1176,6 +1295,43 @@ public class AuthorizationInterceptorR4Test {
|
|||
assertFalse(ourHitMethod);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationTypeLevelWithTenant() throws Exception {
|
||||
ourServlet.setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
|
||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder()
|
||||
.allow("RULE 1").operation().named("opName").onType(Patient.class).forTenantIds("TENANTA").andThen()
|
||||
.build();
|
||||
}
|
||||
});
|
||||
|
||||
HttpGet httpGet;
|
||||
HttpResponse status;
|
||||
String response;
|
||||
|
||||
// Right Tenant
|
||||
ourHitMethod = false;
|
||||
ourReturn = Collections.singletonList(createPatient(2));
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient/$opName");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
ourLog.info(response);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
// Wrong Tenant
|
||||
ourHitMethod = false;
|
||||
ourReturn = Collections.singletonList(createObservation(10, "Patient/2"));
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTC/Patient/$opName");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
assertThat(response, containsString("Access denied by default policy"));
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertFalse(ourHitMethod);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOperationTypeLevelWildcard() throws Exception {
|
||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
|
@ -1307,6 +1463,79 @@ public class AuthorizationInterceptorR4Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadByAnyIdWithTenantId() throws Exception {
|
||||
ourServlet.setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
|
||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder()
|
||||
.allow("Rule 1").read().resourcesOfType(Patient.class).withAnyId().forTenantIds("TENANTA")
|
||||
.build();
|
||||
}
|
||||
});
|
||||
|
||||
HttpGet httpGet;
|
||||
HttpResponse status;
|
||||
String response;
|
||||
|
||||
ourReturn = Collections.singletonList(createPatient(2));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient/1");
|
||||
status = ourClient.execute(httpGet);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
ourReturn = Collections.singletonList(createPatient(2));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTB/Patient/1");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
assertThat(response, containsString("Access denied by default policy (no applicable rules)"));
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertFalse(ourHitMethod);
|
||||
|
||||
ourReturn = Collections.singletonList(createPatient(2));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient/1/_history/222");
|
||||
status = ourClient.execute(httpGet);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
ourReturn = Collections.singletonList(createObservation(10, "Patient/2"));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Observation/10");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
ourLog.info(response);
|
||||
assertThat(response, containsString("Access denied by default policy (no applicable rules)"));
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertFalse(ourHitMethod);
|
||||
|
||||
ourReturn = Arrays.asList(createPatient(1), createObservation(10, "Patient/2"));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
ourLog.info(response);
|
||||
assertThat(response, containsString("Access denied by default policy (no applicable rules)"));
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
ourReturn = Arrays.asList(createPatient(2), createObservation(10, "Patient/1"));
|
||||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/TENANTA/Patient");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
ourLog.info(response);
|
||||
assertThat(response, containsString("Access denied by default policy (no applicable rules)"));
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadByCompartmentRight() throws Exception {
|
||||
ourServlet.registerInterceptor(new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
|
@ -1438,7 +1667,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation/900");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
|
@ -1446,7 +1675,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
ourHitMethod = false;
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/901");
|
||||
status = ourClient.execute(httpGet);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
|
@ -1551,7 +1780,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
ourHitMethod = false;
|
||||
httpGet = new HttpGet(respBundle.getLink("next").getUrl());
|
||||
status = ourClient.execute(httpGet);
|
||||
respString = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertFalse(ourHitMethod);
|
||||
|
||||
|
@ -1640,7 +1869,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
httpPost = new HttpPost("http://localhost:" + ourPort + "/Observation");
|
||||
httpPost.setEntity(createFhirResourceEntity(createObservation(null, "Patient/1")));
|
||||
status = ourClient.execute(httpPost);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
}
|
||||
|
@ -1886,7 +2115,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
httpPost = new HttpPut("http://localhost:" + ourPort + "/Patient?foo=bar");
|
||||
httpPost.setEntity(createFhirResourceEntity(createPatient(null)));
|
||||
status = ourClient.execute(httpPost);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
|
@ -1924,7 +2153,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
httpPost = new HttpPut("http://localhost:" + ourPort + "/Patient?foo=bar");
|
||||
httpPost.setEntity(createFhirResourceEntity(createPatient(null)));
|
||||
status = ourClient.execute(httpPost);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
|
@ -1961,7 +2190,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
httpPost = new HttpPut("http://localhost:" + ourPort + "/Observation/900");
|
||||
httpPost.setEntity(createFhirResourceEntity(createObservation(900, "Patient/12")));
|
||||
status = ourClient.execute(httpPost);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
|
@ -1969,7 +2198,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
httpPost = new HttpPut("http://localhost:" + ourPort + "/Observation/901");
|
||||
httpPost.setEntity(createFhirResourceEntity(createObservation(901, "Patient/12")));
|
||||
status = ourClient.execute(httpPost);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
|
@ -2008,7 +2237,6 @@ public class AuthorizationInterceptorR4Test {
|
|||
|
||||
HttpEntityEnclosingRequestBase httpPost;
|
||||
HttpResponse status;
|
||||
String response;
|
||||
|
||||
String input = "[ { \"op\": \"replace\", \"path\": \"/gender\", \"value\": \"male\" } ]";
|
||||
|
||||
|
@ -2016,7 +2244,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
httpPost = new HttpPatch("http://localhost:" + ourPort + "/Patient/900");
|
||||
httpPost.setEntity(new StringEntity(input, ContentType.parse("application/json-patch+json")));
|
||||
status = ourClient.execute(httpPost);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(204, status.getStatusLine().getStatusCode());
|
||||
assertTrue(ourHitMethod);
|
||||
|
||||
|
@ -2024,7 +2252,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
httpPost = new HttpPatch("http://localhost:" + ourPort + "/Patient/999");
|
||||
httpPost.setEntity(new StringEntity(input, ContentType.parse("application/json-patch+json")));
|
||||
status = ourClient.execute(httpPost);
|
||||
response = extractResponseAndClose(status);
|
||||
extractResponseAndClose(status);
|
||||
assertEquals(403, status.getStatusLine().getStatusCode());
|
||||
assertFalse(ourHitMethod);
|
||||
}
|
||||
|
@ -2085,6 +2313,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class DummyEncounterResourceProvider implements IResourceProvider {
|
||||
|
||||
@Operation(name = "everything", idempotent = true)
|
||||
|
@ -2103,6 +2332,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class DummyObservationResourceProvider implements IResourceProvider {
|
||||
|
||||
@Create()
|
||||
|
@ -2118,8 +2348,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
@Delete()
|
||||
public MethodOutcome delete(@IdParam IdType theId) {
|
||||
ourHitMethod = true;
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
return retVal;
|
||||
return new MethodOutcome();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2201,8 +2430,7 @@ public class AuthorizationInterceptorR4Test {
|
|||
for (IBaseResource next : ourReturn) {
|
||||
theRequestOperationCallback.resourceDeleted(next);
|
||||
}
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
return retVal;
|
||||
return new MethodOutcome();
|
||||
}
|
||||
|
||||
@Operation(name = "everything", idempotent = true)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -11,7 +11,7 @@
|
|||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<name>HAPI-FHIR</name>
|
||||
<url>https://hapifhir.io</url>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -7,6 +7,20 @@
|
|||
</properties>
|
||||
<body>
|
||||
<release version="3.3.0" date="TBD">
|
||||
<action type="add">
|
||||
This release corrects an ineffiency in the JPA Server, but requires a schema
|
||||
change in order to update. Prior to this version of HAPI FHIR, a CLOB column
|
||||
containing the complete resource body was stored in two
|
||||
tables: HFJ_RESOURCE and HFJ_RES_VER. Because the same content was stored in two
|
||||
places, the database consumed more space than is needed to.
|
||||
<![CDATA[<br/><br/>]]>
|
||||
In order to reduce this duplication, the columns have been removed from the
|
||||
HFJ_RESOURCE column. This means that on any database that is being upgraded
|
||||
to HAPI FHIR 3.2.0, you will need to remove the columns
|
||||
<![CDATA[<code>RES_TEXT</code> and <code>RES_ENCODING</code>]]> (or
|
||||
set them to nullable if you want an easy means of rolling back). Naturally
|
||||
you should back your database up prior to making this change.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Fix a crash in the JSON parser when parsing extensions on repeatable
|
||||
elements (e.g. Patient.address.line) where there is an extension on the
|
||||
|
|
|
@ -215,6 +215,20 @@
|
|||
|
||||
</subsection>
|
||||
|
||||
<subsection name="Authorizing Multitenant Servers">
|
||||
|
||||
<p>
|
||||
The AuthorizationInterceptor has the ability to direct individual
|
||||
rules as only applying to a single tenant in a multitenant
|
||||
server. The following example shows such a rule.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="authorizeTenantAction" />
|
||||
<param name="file" value="examples/src/main/java/example/AuthorizationInterceptors.java" />
|
||||
</macro>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
|
Loading…
Reference in New Issue