introduce Context service

This commit is contained in:
Michael Hoennig 2022-07-29 14:24:50 +02:00
parent 2b630aadbc
commit 414149f0a1
8 changed files with 132 additions and 44 deletions

View File

@ -30,6 +30,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.liquibase:liquibase-core'
implementation 'org.springframework.data:spring-data-rest-hal-explorer'
implementation 'com.vladmihalcea:hibernate-types-55:2.17.1'
compileOnly 'org.projectlombok:lombok'

View File

@ -0,0 +1,13 @@
package net.hostsharing.hsadminng.config;
import com.vladmihalcea.hibernate.type.array.StringArrayType;
import org.hibernate.dialect.PostgreSQL95Dialect;
@SuppressWarnings("unused") // configured in application.yml
public class PostgreSQL95CustomDialect extends PostgreSQL95Dialect {
public PostgreSQL95CustomDialect() {
this.registerHibernateType(2003, StringArrayType.class.getName());
}
}

View File

@ -0,0 +1,51 @@
package net.hostsharing.hsadminng.context;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
@Service
public class Context {
@PersistenceContext
private EntityManager em;
@Transactional(Transactional.TxType.MANDATORY)
public void setCurrentUser(final String userName) {
em.createNativeQuery(
String.format(
"set local hsadminng.currentUser = '%s';",
userName
)
).executeUpdate();
assumeNoSpecialRole();
}
public String getCurrentUser() {
return String.valueOf(em.createNativeQuery("select currentUser()").getSingleResult());
}
@Transactional(Transactional.TxType.MANDATORY)
public void assumeRoles(final String roles) {
em.createNativeQuery(
String.format(
"set local hsadminng.assumedRoles = '%s';",
roles
)
).executeUpdate();
}
@Transactional(Transactional.TxType.MANDATORY)
public void assumeNoSpecialRole() {
em.createNativeQuery(
"set local hsadminng.assumedRoles = '';"
).executeUpdate();
}
public String[] getAssumedRoles() {
return (String[]) em.createNativeQuery("select assumedRoles()").getSingleResult();
}
}

View File

@ -1,5 +1,7 @@
package net.hostsharing.hsadminng;
package net.hostsharing.hsadminng.controller;
import net.hostsharing.hsadminng.context.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@ -15,6 +17,9 @@ public class TestController {
@PersistenceContext
private EntityManager em;
@Autowired
private Context context;
@ResponseBody
@RequestMapping(value = "/api/ping", method = RequestMethod.GET)
public String ping() {
@ -25,8 +30,8 @@ public class TestController {
@ResponseBody
@RequestMapping(value = "/api/currentUser", method = RequestMethod.GET)
public String currentUser() {
em.createNativeQuery("SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net';").executeUpdate();
em.createNativeQuery("SET LOCAL hsadminng.assumedRoles = '';").executeUpdate();
context.setCurrentUser("mike@hostsharing.net");
final var query = em.createNativeQuery("select currentUser()");
return query.getSingleResult() + "\n";
}

View File

@ -10,5 +10,10 @@ spring:
init:
mode: never
jpa:
properties:
hibernate:
dialect: net.hostsharing.hsadminng.config.PostgreSQL95CustomDialect
liquibase:
contexts: dev

View File

@ -1,26 +0,0 @@
package net.hostsharing.hsadminng;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
@DataJpaTest
class RbacIntegrationTests {
@PersistenceContext
private EntityManager em;
@Test
@Transactional
void currentUser() {
em.createNativeQuery("SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net';").executeUpdate();
em.createNativeQuery("SET LOCAL hsadminng.assumedRoles = '';").executeUpdate();
final var result = em.createNativeQuery("select currentUser()").getSingleResult();
Assertions.assertThat(result).isEqualTo("mike@hostsharing.net");
}
}

View File

@ -0,0 +1,43 @@
package net.hostsharing.hsadminng.context;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.ComponentScan;
import javax.transaction.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
@ComponentScan(basePackageClasses = Context.class)
class ContextIntegrationTests {
@Autowired
private Context context;
@Test
@Transactional
void setCurrentUser() {
context.setCurrentUser("mike@hostsharing.net");
final var currentUser = context.getCurrentUser();
assertThat(currentUser).isEqualTo("mike@hostsharing.net");
final var assumedRoles = context.getAssumedRoles();
assertThat(assumedRoles).isEmpty();
}
@Test
@Transactional
void assumeRoles() {
context.setCurrentUser("mike@hostsharing.net");
context.assumeRoles("customer#aaa.owner;customer#aab.owner");
final var currentUser = context.getCurrentUser();
assertThat(currentUser).isEqualTo("mike@hostsharing.net");
final var assumedRoles = context.getAssumedRoles();
assertThat(assumedRoles).containsExactlyInAnyOrder("customer#aaa.owner", "customer#aab.owner");
}
}

View File

@ -12,7 +12,7 @@ spring:
properties:
hibernate:
default_schema: public
dialect: org.hibernate.dialect.PostgreSQLDialect
dialect: net.hostsharing.hsadminng.config.PostgreSQL95CustomDialect
hibernate:
ddl-auto: none
show-sql: true
@ -29,9 +29,5 @@ logging:
level:
liquibase: INFO
# spring.datasource.driver-class-name=org.postgresql.Driver
# spring.datasource.url=${DB_URL}
# spring.datasource.username=${DB_USERNAME}
# spring.datasource.password=${DB_PASSWORD}
# spring.jpa.properties.hibernate.default-schema=public
liquibase:
contexts: dev,tc