diff --git a/pom.xml b/pom.xml
index 0f7ffdb..27c0e85 100644
--- a/pom.xml
+++ b/pom.xml
@@ -101,6 +101,12 @@
+
+ org.springframework
+ spring-test
+ ${spring-version}
+ test
+
org.junit.jupiter
junit-jupiter-engine
diff --git a/src/main/java/DNPM/config/PluginConfiguration.java b/src/main/java/DNPM/config/PluginConfiguration.java
index 654d4c4..0042fe4 100644
--- a/src/main/java/DNPM/config/PluginConfiguration.java
+++ b/src/main/java/DNPM/config/PluginConfiguration.java
@@ -1,7 +1,6 @@
package DNPM.config;
import DNPM.database.SettingsRepository;
-import DNPM.security.PersonPoolBasedPermissionEvaluator;
import DNPM.services.*;
import DNPM.services.consent.ConsentManagerServiceFactory;
import DNPM.services.mtb.DefaultMtbService;
@@ -13,7 +12,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
-import org.springframework.security.access.PermissionEvaluator;
import javax.sql.DataSource;
@@ -23,15 +21,10 @@ import javax.sql.DataSource;
* @since 0.0.2
*/
@Configuration
-@ComponentScan(basePackages = "DNPM.analyzer")
+@ComponentScan(basePackages = { "DNPM.analyzer", "DNPM.security" })
@EnableJpaRepositories(basePackages = "DNPM.database")
public class PluginConfiguration {
- @Bean
- public PermissionEvaluator personBasedPermissionEvaluator(final DataSource dataSource) {
- return new PersonPoolBasedPermissionEvaluator(dataSource);
- }
-
@Bean
public FormService formService(final DataSource dataSource) {
return new DefaultFormService(dataSource);
diff --git a/src/main/java/DNPM/security/IllegalSecuredObjectAccessException.java b/src/main/java/DNPM/security/IllegalSecuredObjectAccessException.java
new file mode 100644
index 0000000..542b604
--- /dev/null
+++ b/src/main/java/DNPM/security/IllegalSecuredObjectAccessException.java
@@ -0,0 +1,13 @@
+package DNPM.security;
+
+public class IllegalSecuredObjectAccessException extends RuntimeException {
+
+ public IllegalSecuredObjectAccessException() {
+ super();
+ }
+
+ public IllegalSecuredObjectAccessException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/DNPM/security/PersonPoolBasedPermissionEvaluator.java b/src/main/java/DNPM/security/PersonPoolBasedPermissionEvaluator.java
index 4d895e4..2eac69c 100644
--- a/src/main/java/DNPM/security/PersonPoolBasedPermissionEvaluator.java
+++ b/src/main/java/DNPM/security/PersonPoolBasedPermissionEvaluator.java
@@ -6,6 +6,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.io.Serializable;
@@ -14,6 +15,7 @@ import java.util.List;
/**
* Permission-Evaluator zur Auswertung der Berechtigung auf Objekte aufgrund der Personenstammberechtigung
*/
+@Component
public class PersonPoolBasedPermissionEvaluator implements PermissionEvaluator {
private final JdbcTemplate jdbcTemplate;
@@ -71,7 +73,7 @@ public class PersonPoolBasedPermissionEvaluator implements PermissionEvaluator {
var userDetails = (UserDetails)authentication.getPrincipal();
return jdbcTemplate
- .query(sql, new Object[]{userDetails.getUsername()}, (rs, rowNum) -> rs.getString("id"));
+ .query(sql, new Object[]{userDetails.getUsername()}, (rs, rowNum) -> rs.getString("kennung"));
}
diff --git a/src/main/java/DNPM/security/PersonPoolSecured.java b/src/main/java/DNPM/security/PersonPoolSecured.java
new file mode 100644
index 0000000..cac0f78
--- /dev/null
+++ b/src/main/java/DNPM/security/PersonPoolSecured.java
@@ -0,0 +1,14 @@
+package DNPM.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface PersonPoolSecured {
+
+ PermissionType value() default PermissionType.READ_WRITE;
+
+}
diff --git a/src/main/java/DNPM/security/PersonPoolSecuredResult.java b/src/main/java/DNPM/security/PersonPoolSecuredResult.java
new file mode 100644
index 0000000..0ca8edf
--- /dev/null
+++ b/src/main/java/DNPM/security/PersonPoolSecuredResult.java
@@ -0,0 +1,14 @@
+package DNPM.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface PersonPoolSecuredResult {
+
+ PermissionType value() default PermissionType.READ_WRITE;
+
+}
diff --git a/src/main/java/DNPM/security/SecurityAspects.java b/src/main/java/DNPM/security/SecurityAspects.java
new file mode 100644
index 0000000..a1fcd3f
--- /dev/null
+++ b/src/main/java/DNPM/security/SecurityAspects.java
@@ -0,0 +1,74 @@
+package DNPM.security;
+
+import de.itc.onkostar.api.Patient;
+import de.itc.onkostar.api.Procedure;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+
+@Component
+@Aspect
+public class SecurityAspects {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final PersonPoolBasedPermissionEvaluator permissionEvaluator;
+
+ public SecurityAspects(PersonPoolBasedPermissionEvaluator permissionEvaluator) {
+ this.permissionEvaluator = permissionEvaluator;
+ }
+
+ @AfterReturning(value = "@annotation(PersonPoolSecuredResult) ", returning = "patient")
+ public void afterPatient(Patient patient) {
+ if (
+ null != patient
+ && ! permissionEvaluator.hasPermission(SecurityContextHolder.getContext().getAuthentication(), patient, PermissionType.READ_WRITE)
+ ) {
+ logger.warn("Rückgabe von Patient blockiert: {}", patient.getId());
+ throw new IllegalSecuredObjectAccessException();
+ }
+ }
+
+ @AfterReturning(value = "@annotation(PersonPoolSecuredResult)", returning = "procedure")
+ public void afterProcedure(Procedure procedure) {
+ if (
+ null != procedure
+ && ! permissionEvaluator.hasPermission(SecurityContextHolder.getContext().getAuthentication(), procedure, PermissionType.READ_WRITE)
+ ) {
+ logger.warn("Rückgabe von Prozedur blockiert: {}", procedure.getId());
+ throw new IllegalSecuredObjectAccessException();
+ }
+ }
+
+ @Before(value = "@annotation(PersonPoolSecured)")
+ public void beforePatient(JoinPoint jp) {
+ Arrays.stream(jp.getArgs())
+ .filter(arg -> arg instanceof Patient)
+ .forEach(patient -> {
+ if (! permissionEvaluator.hasPermission(SecurityContextHolder.getContext().getAuthentication(), patient, PermissionType.READ_WRITE)) {
+ logger.warn("Zugriff auf Patient blockiert: {}", ((Patient)patient).getId());
+ throw new IllegalSecuredObjectAccessException();
+ }
+ });
+ }
+
+ @Before(value = "@annotation(PersonPoolSecured)")
+ public void beforeProcedure(JoinPoint jp) {
+ Arrays.stream(jp.getArgs())
+ .filter(arg -> arg instanceof Procedure)
+ .forEach(procedure -> {
+ if (! permissionEvaluator.hasPermission(SecurityContextHolder.getContext().getAuthentication(), procedure, PermissionType.READ_WRITE)) {
+ logger.warn("Zugriff auf Prozedur blockiert: {}", ((Procedure)procedure).getId());
+ throw new IllegalSecuredObjectAccessException();
+ }
+ });
+ }
+
+}