diff --git a/pom.xml b/pom.xml
index 27c0e85..1c5feaa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -137,6 +137,12 @@
4.11.0
test
+
+ org.aspectj
+ aspectjweaver
+ 1.7.1
+ test
+
ca.uhn.hapi
hapi-base
diff --git a/src/test/java/DNPM/security/SecurityAspectsTest.java b/src/test/java/DNPM/security/SecurityAspectsTest.java
new file mode 100644
index 0000000..8416b8a
--- /dev/null
+++ b/src/test/java/DNPM/security/SecurityAspectsTest.java
@@ -0,0 +1,164 @@
+package DNPM.security;
+
+import de.itc.onkostar.api.IOnkostarApi;
+import de.itc.onkostar.api.Patient;
+import de.itc.onkostar.api.Procedure;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+class SecurityAspectsTest {
+
+ private DummyClass dummyClass;
+
+ private IOnkostarApi onkostarApi;
+
+ private PersonPoolBasedPermissionEvaluator permissionEvaluator;
+
+ @BeforeEach
+ void setup(
+ @Mock IOnkostarApi onkostarApi,
+ @Mock PersonPoolBasedPermissionEvaluator permissionEvaluator
+ ) {
+ this.onkostarApi = onkostarApi;
+ this.permissionEvaluator = permissionEvaluator;
+
+ // Create proxied instance of DummyClass as done within Onkostar using Spring AOP
+ var dummyClass = new DummyClass(onkostarApi);
+ AspectJProxyFactory factory = new AspectJProxyFactory(dummyClass);
+ SecurityAspects securityAspects = new SecurityAspects(this.permissionEvaluator);
+ factory.addAspect(securityAspects);
+ this.dummyClass = factory.getProxy();
+ }
+
+ @Test
+ void testShouldPreventSecuredMethodCallWithPatientParam() {
+ when(this.permissionEvaluator.hasPermission(any(), any(Patient.class), any(PermissionType.class)))
+ .thenReturn(false);
+
+ var exception = assertThrows(
+ Exception.class,
+ () -> this.dummyClass.methodWithPatientParam(new Patient(onkostarApi))
+ );
+ assertThat(exception).isExactlyInstanceOf(IllegalSecuredObjectAccessException.class);
+ }
+
+ @Test
+ void testShouldAllowSecuredMethodCallWithPatientParam() {
+ when(this.permissionEvaluator.hasPermission(any(), any(Patient.class), any(PermissionType.class)))
+ .thenReturn(true);
+
+ this.dummyClass.methodWithPatientParam(new Patient(onkostarApi));
+
+ verify(onkostarApi, times(1)).savePatient(any(Patient.class));
+ }
+
+ @Test
+ void testShouldPreventSecuredMethodCallWithProcedureParam() {
+ when(this.permissionEvaluator.hasPermission(any(), any(Procedure.class), any(PermissionType.class)))
+ .thenReturn(false);
+
+ var exception = assertThrows(
+ Exception.class,
+ () -> this.dummyClass.methodWithProcedureParam(new Procedure(onkostarApi))
+ );
+ assertThat(exception).isExactlyInstanceOf(IllegalSecuredObjectAccessException.class);
+ }
+
+ @Test
+ void testShouldAllowSecuredMethodCallWithProcedureParam() throws Exception {
+ when(this.permissionEvaluator.hasPermission(any(), any(Procedure.class), any(PermissionType.class)))
+ .thenReturn(true);
+
+ this.dummyClass.methodWithProcedureParam(new Procedure(onkostarApi));
+
+ verify(onkostarApi, times(1)).saveProcedure(any(Procedure.class), anyBoolean());
+ }
+
+ @Test
+ void testShouldPreventSecuredMethodCallWithPatientReturnValue() {
+ when(this.permissionEvaluator.hasPermission(any(), any(Patient.class), any(PermissionType.class)))
+ .thenReturn(false);
+
+ var exception = assertThrows(
+ Exception.class,
+ () -> this.dummyClass.methodWithPatientReturnValue(1)
+ );
+ assertThat(exception).isExactlyInstanceOf(IllegalSecuredObjectAccessException.class);
+ }
+
+ @Test
+ void testShouldAllowSecuredMethodCallWithPatientReturnValue() {
+ when(this.permissionEvaluator.hasPermission(any(), any(Patient.class), any(PermissionType.class)))
+ .thenReturn(true);
+
+ var actual = this.dummyClass.methodWithPatientReturnValue(1);
+
+ assertThat(actual).isNotNull();
+ }
+
+ @Test
+ void testShouldPreventSecuredMethodCallWithProcedureReturnValue() {
+ when(this.permissionEvaluator.hasPermission(any(), any(Procedure.class), any(PermissionType.class)))
+ .thenReturn(false);
+
+ var exception = assertThrows(
+ Exception.class,
+ () -> this.dummyClass.methodWithProcedureReturnValue(1)
+ );
+ assertThat(exception).isExactlyInstanceOf(IllegalSecuredObjectAccessException.class);
+ }
+
+ @Test
+ void testShouldAllowSecuredMethodCallWithProcedureReturnValue() {
+ when(this.permissionEvaluator.hasPermission(any(), any(Procedure.class), any(PermissionType.class)))
+ .thenReturn(true);
+
+ var actual = this.dummyClass.methodWithProcedureReturnValue(1);
+
+ assertThat(actual).isNotNull();
+ }
+
+}
+
+class DummyClass {
+
+ private final IOnkostarApi onkostarApi;
+
+ DummyClass(final IOnkostarApi onkostarApi) {
+ this.onkostarApi = onkostarApi;
+ }
+
+ @PersonPoolSecured
+ public void methodWithPatientParam(Patient patient) {
+ this.onkostarApi.savePatient(patient);
+ }
+
+ @PersonPoolSecured
+ public void methodWithProcedureParam(Procedure procedure) throws Exception {
+ this.onkostarApi.saveProcedure(procedure, false);
+ }
+
+ @PersonPoolSecuredResult
+ public Patient methodWithPatientReturnValue(int id) {
+ var patient = new Patient(this.onkostarApi);
+ patient.setId(id);
+ return patient;
+ }
+
+ @PersonPoolSecuredResult
+ public Procedure methodWithProcedureReturnValue(int id) {
+ var procedure = new Procedure(this.onkostarApi);
+ procedure.setId(id);
+ return procedure;
+ }
+}