introduce Context service
This commit is contained in:
		@@ -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'
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								src/main/java/net/hostsharing/hsadminng/context/Context.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/main/java/net/hostsharing/hsadminng/context/Context.java
									
									
									
									
									
										Normal 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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -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";
 | 
			
		||||
    }
 | 
			
		||||
@@ -1,14 +1,19 @@
 | 
			
		||||
spring:
 | 
			
		||||
 | 
			
		||||
  datasource:
 | 
			
		||||
    driver-class-name: org.postgresql.Driver
 | 
			
		||||
    password: password
 | 
			
		||||
    url: jdbc:postgresql://localhost:5432/postgres
 | 
			
		||||
    username: postgres
 | 
			
		||||
    datasource:
 | 
			
		||||
        driver-class-name: org.postgresql.Driver
 | 
			
		||||
        password: password
 | 
			
		||||
        url: jdbc:postgresql://localhost:5432/postgres
 | 
			
		||||
        username: postgres
 | 
			
		||||
 | 
			
		||||
  sql:
 | 
			
		||||
    init:
 | 
			
		||||
      mode: never
 | 
			
		||||
    sql:
 | 
			
		||||
        init:
 | 
			
		||||
            mode: never
 | 
			
		||||
 | 
			
		||||
    jpa:
 | 
			
		||||
        properties:
 | 
			
		||||
            hibernate:
 | 
			
		||||
                dialect: net.hostsharing.hsadminng.config.PostgreSQL95CustomDialect
 | 
			
		||||
 | 
			
		||||
liquibase:
 | 
			
		||||
    contexts: dev
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user