use context.define(...) instead of setCurrent...

This commit is contained in:
Michael Hoennig 2022-08-28 17:30:27 +02:00
parent 7d4815e2cf
commit 4aa8b85bb6
20 changed files with 601 additions and 212 deletions

View File

@ -191,7 +191,7 @@ jacocoTestCoverageVerification {
'net.hostsharing.hsadminng.generated.**', 'net.hostsharing.hsadminng.generated.**',
'net.hostsharing.hsadminng.HsadminNgApplication', 'net.hostsharing.hsadminng.HsadminNgApplication',
'net.hostsharing.hsadminng.TestController', 'net.hostsharing.hsadminng.TestController',
'net.hostsharing.hsadminng.Mapper', 'net.hostsharing.hsadminng.Mapper'
] ]
limit { limit {
@ -205,7 +205,8 @@ jacocoTestCoverageVerification {
excludes = [ excludes = [
'net.hostsharing.hsadminng.generated.**', 'net.hostsharing.hsadminng.generated.**',
'net.hostsharing.hsadminng.HsadminNgApplication.main', 'net.hostsharing.hsadminng.HsadminNgApplication.main',
'net.hostsharing.hsadminng.TestController.*'] 'net.hostsharing.hsadminng.TestController.*'
]
limit { limit {
counter = 'BRANCH' counter = 'BRANCH'

View File

@ -1,20 +1,33 @@
package net.hostsharing.hsadminng.context; package net.hostsharing.hsadminng.context;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collections;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import static java.util.function.Predicate.not;
import static org.springframework.transaction.annotation.Propagation.MANDATORY; import static org.springframework.transaction.annotation.Propagation.MANDATORY;
@Service @Service
public class Context { public class Context {
private static final Set<String> HEADERS_TO_IGNORE = Set.of(
"accept-encoding",
"connection",
"content-length",
"host",
"user-agent");
@PersistenceContext @PersistenceContext
private EntityManager em; private EntityManager em;
@ -22,81 +35,111 @@ public class Context {
private HttpServletRequest request; private HttpServletRequest request;
@Transactional(propagation = MANDATORY) @Transactional(propagation = MANDATORY)
public void register(final String currentUser, final String assumedRoles) { public void define(final String currentUser) {
if (request != null) { define(currentUser, null);
setCurrentTask(request.getMethod() + " " + request.getRequestURI());
} else {
final Optional<StackWalker.StackFrame> caller =
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
.walk(frames ->
frames.skip(1)
.filter(c -> c.getDeclaringClass()
.getPackageName()
.startsWith("net.hostsharing.hsadminng"))
.filter(c -> !c.getDeclaringClass().getName().contains("BySpringCGLIB$$"))
.findFirst());
final var callerName = caller.map(
c -> c.getDeclaringClass().getSimpleName() + "." + c.getMethodName())
.orElse("unknown");
setCurrentTask(callerName);
}
setCurrentUser(currentUser);
if (!StringUtils.isBlank(assumedRoles)) {
assumeRoles(assumedRoles);
}
} }
@Transactional(propagation = MANDATORY) @Transactional(propagation = MANDATORY)
public void setCurrentTask(final String task) { public void define(final String currentUser, final String assumedRoles) {
final var sql = String.format( define(toTask(request), toCurl(request), currentUser, assumedRoles);
"set local hsadminng.currentTask = '%s';", }
shortenToMaxLength(task, 95)
); @Transactional(propagation = MANDATORY)
em.createNativeQuery(sql).executeUpdate(); public void define(
final String currentTask,
final String currentRequest,
final String currentUser,
final String assumedRoles) {
final var query = em.createNativeQuery(
"call defineContext(:currentTask, :currentRequest, :currentUser, :assumedRoles);");
query.setParameter("currentTask", shortenToMaxLength(currentTask, 96));
query.setParameter("currentRequest", shortenToMaxLength(currentRequest, 512)); // TODO.SPEC: length?
query.setParameter("currentUser", currentUser);
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
query.executeUpdate();
} }
public String getCurrentTask() { public String getCurrentTask() {
return (String) em.createNativeQuery("select current_setting('hsadminng.currentTask');").getSingleResult(); return (String) em.createNativeQuery("select current_setting('hsadminng.currentTask');").getSingleResult();
} }
@Transactional(propagation = MANDATORY)
public void setCurrentUser(final String userName) {
em.createNativeQuery(
String.format(
"set local hsadminng.currentUser = '%s';",
userName
)
).executeUpdate();
assumeNoSpecialRole();
}
public String getCurrentUser() { public String getCurrentUser() {
return String.valueOf(em.createNativeQuery("select currentUser()").getSingleResult()); return String.valueOf(em.createNativeQuery("select currentUser()").getSingleResult());
} }
@Transactional(propagation = MANDATORY)
public void assumeRoles(final String roles) {
em.createNativeQuery(
String.format(
"set local hsadminng.assumedRoles = '%s';",
roles
)
).executeUpdate();
}
@Transactional(propagation = MANDATORY)
public void assumeNoSpecialRole() {
em.createNativeQuery(
"set local hsadminng.assumedRoles = '';"
).executeUpdate();
}
public String[] getAssumedRoles() { public String[] getAssumedRoles() {
return (String[]) em.createNativeQuery("select assumedRoles()").getSingleResult(); return (String[]) em.createNativeQuery("select assumedRoles()").getSingleResult();
} }
private static String shortenToMaxLength(final String task, final int maxLength) { private static String getCallerMethodNameFromStack() {
return task.substring(0, Math.min(task.length(), maxLength)); final Optional<StackWalker.StackFrame> caller =
StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE)
.walk(frames -> frames
.skip(2)
.filter(c -> c.getDeclaringClass() != Context.class)
.filter(c -> c.getDeclaringClass()
.getPackageName()
.startsWith("net.hostsharing.hsadminng"))
.filter(c -> !c.getDeclaringClass().getName().contains("BySpringCGLIB$$"))
.findFirst());
return caller.map(
c -> c.getDeclaringClass().getSimpleName() + "." + c.getMethodName())
.orElse("unknown");
}
private String toTask(final HttpServletRequest request) {
if (isRequestScopeAvailable()) {
return request.getMethod() + " " + request.getRequestURI();
} else {
return getCallerMethodNameFromStack();
}
}
@SneakyThrows
private String toCurl(final HttpServletRequest request) {
if (!isRequestScopeAvailable()) {
return null;
}
var curlCommand = "curl -0 -v";
// append method
curlCommand += " -X " + request.getMethod();
// append request url
curlCommand += " " + request.getRequestURI();
// append headers
final var headers = Collections.list(request.getHeaderNames()).stream()
.filter(not(HEADERS_TO_IGNORE::contains))
.collect(Collectors.toSet());
for (String headerName : headers) {
final var headerValue = request.getHeader(headerName);
curlCommand += " \\" + System.lineSeparator() + String.format("-H '%s:%s'", headerName, headerValue);
}
// body
final String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
if (!StringUtils.isEmpty(body)) {
curlCommand += " \\" + System.lineSeparator() + "--data-binary @- ";
curlCommand +=
"<< EOF" + System.lineSeparator() + System.lineSeparator() + body + System.lineSeparator() + "EOF";
}
return curlCommand;
}
private boolean isRequestScopeAvailable() {
return RequestContextHolder.getRequestAttributes() != null;
}
private static String shortenToMaxLength(final String raw, final int maxLength) {
if (raw == null) {
return "";
}
if (raw.length() <= maxLength) {
return raw;
}
return raw.substring(0, maxLength - 3) + "...";
} }
} }

View File

@ -0,0 +1,45 @@
package net.hostsharing.hsadminng.context;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class HttpServletRequestBodyCache extends ServletInputStream {
private InputStream inputStream;
public HttpServletRequestBodyCache(byte[] body) {
this.inputStream = new ByteArrayInputStream(body);
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public int available() throws IOException {
return inputStream.available();
}
@Override
public boolean isFinished() {
try {
return available() == 0;
} catch (IOException e) {
return true;
}
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(final ReadListener listener) {
throw new RuntimeException("Not implemented");
}
}

View File

@ -0,0 +1,23 @@
package net.hostsharing.hsadminng.context;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class HttpServletRequestBodyCachingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
final HttpServletRequest request,
final HttpServletResponse response,
final FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(new HttpServletRequestWithCachedBody(request), response);
}
}

View File

@ -0,0 +1,33 @@
package net.hostsharing.hsadminng.context;
import org.springframework.util.StreamUtils;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class HttpServletRequestWithCachedBody extends HttpServletRequestWrapper {
private byte[] cachedBody;
public HttpServletRequestWithCachedBody(HttpServletRequest request) throws IOException {
super(request);
final var requestInputStream = request.getInputStream();
this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new HttpServletRequestBodyCache(this.cachedBody);
}
@Override
public BufferedReader getReader() throws IOException {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedBody);
return new BufferedReader(new InputStreamReader(byteArrayInputStream));
}
}

View File

@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.hscustomer;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.generated.api.v1.api.CustomersApi; import net.hostsharing.hsadminng.generated.api.v1.api.CustomersApi;
import net.hostsharing.hsadminng.generated.api.v1.model.CustomerResource; import net.hostsharing.hsadminng.generated.api.v1.model.CustomerResource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -33,7 +32,7 @@ public class CustomerController implements CustomersApi {
String assumedRoles, String assumedRoles,
String prefix String prefix
) { ) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
final var result = customerRepository.findCustomerByOptionalPrefixLike(prefix); final var result = customerRepository.findCustomerByOptionalPrefixLike(prefix);
@ -47,7 +46,7 @@ public class CustomerController implements CustomersApi {
final String assumedRoles, final String assumedRoles,
final CustomerResource customer) { final CustomerResource customer) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
if (customer.getUuid() == null) { if (customer.getUuid() == null) {
customer.setUuid(UUID.randomUUID()); customer.setUuid(UUID.randomUUID());

View File

@ -5,7 +5,6 @@ import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.generated.api.v1.api.PackagesApi; import net.hostsharing.hsadminng.generated.api.v1.api.PackagesApi;
import net.hostsharing.hsadminng.generated.api.v1.model.PackageResource; import net.hostsharing.hsadminng.generated.api.v1.model.PackageResource;
import net.hostsharing.hsadminng.generated.api.v1.model.PackageUpdateResource; import net.hostsharing.hsadminng.generated.api.v1.model.PackageUpdateResource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -33,7 +32,7 @@ public class PackageController implements PackagesApi {
String assumedRoles, String assumedRoles,
String name String name
) { ) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
final var result = packageRepository.findAllByOptionalNameLike(name); final var result = packageRepository.findAllByOptionalNameLike(name);
return ResponseEntity.ok(mapList(result, PackageResource.class)); return ResponseEntity.ok(mapList(result, PackageResource.class));
@ -47,7 +46,7 @@ public class PackageController implements PackagesApi {
final UUID packageUuid, final UUID packageUuid,
final PackageUpdateResource body) { final PackageUpdateResource body) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
final var current = packageRepository.findByUuid(packageUuid); final var current = packageRepository.findByUuid(packageUuid);
OptionalFromJson.of(body.getDescription()).ifPresent(current::setDescription); OptionalFromJson.of(body.getDescription()).ifPresent(current::setDescription);

View File

@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.rbac.rbacgrant;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.generated.api.v1.api.RbacgrantsApi; import net.hostsharing.hsadminng.generated.api.v1.api.RbacgrantsApi;
import net.hostsharing.hsadminng.generated.api.v1.model.RbacGrantResource; import net.hostsharing.hsadminng.generated.api.v1.model.RbacGrantResource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -38,7 +37,7 @@ public class RbacGrantController implements RbacgrantsApi {
final UUID grantedRoleUuid, final UUID grantedRoleUuid,
final UUID granteeUserUuid) { final UUID granteeUserUuid) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
final var id = new RbacGrantId(granteeUserUuid, grantedRoleUuid); final var id = new RbacGrantId(granteeUserUuid, grantedRoleUuid);
final var result = rbacGrantRepository.findById(id); final var result = rbacGrantRepository.findById(id);
@ -54,7 +53,7 @@ public class RbacGrantController implements RbacgrantsApi {
final String currentUser, final String currentUser,
final String assumedRoles) { final String assumedRoles) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
return ResponseEntity.ok(mapList(rbacGrantRepository.findAll(), RbacGrantResource.class)); return ResponseEntity.ok(mapList(rbacGrantRepository.findAll(), RbacGrantResource.class));
} }
@ -66,7 +65,7 @@ public class RbacGrantController implements RbacgrantsApi {
final String assumedRoles, final String assumedRoles,
final RbacGrantResource body) { final RbacGrantResource body) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
final var granted = rbacGrantRepository.save(map(body, RbacGrantEntity.class)); final var granted = rbacGrantRepository.save(map(body, RbacGrantEntity.class));
em.flush(); em.flush();
@ -88,7 +87,7 @@ public class RbacGrantController implements RbacgrantsApi {
final UUID grantedRoleUuid, final UUID grantedRoleUuid,
final UUID granteeUserUuid) { final UUID granteeUserUuid) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeUserUuid, grantedRoleUuid)); rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeUserUuid, grantedRoleUuid));

View File

@ -28,7 +28,7 @@ public class RbacRoleController implements RbacrolesApi {
final String currentUser, final String currentUser,
final String assumedRoles) { final String assumedRoles) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
return ResponseEntity.ok(mapList(rbacRoleRepository.findAll(), RbacRoleResource.class)); return ResponseEntity.ok(mapList(rbacRoleRepository.findAll(), RbacRoleResource.class));
} }

View File

@ -2,15 +2,12 @@ package net.hostsharing.hsadminng.rbac.rbacuser;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.generated.api.v1.api.RbacusersApi; import net.hostsharing.hsadminng.generated.api.v1.api.RbacusersApi;
import net.hostsharing.hsadminng.generated.api.v1.model.RbacGrantResource;
import net.hostsharing.hsadminng.generated.api.v1.model.RbacUserPermissionResource; import net.hostsharing.hsadminng.generated.api.v1.model.RbacUserPermissionResource;
import net.hostsharing.hsadminng.generated.api.v1.model.RbacUserResource; import net.hostsharing.hsadminng.generated.api.v1.model.RbacUserResource;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantId;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import java.util.List; import java.util.List;
@ -33,7 +30,7 @@ public class RbacUserController implements RbacusersApi {
public ResponseEntity<RbacUserResource> createUser( public ResponseEntity<RbacUserResource> createUser(
final RbacUserResource body final RbacUserResource body
) { ) {
context.register(body.getName(), null); context.define(body.getName());
if (body.getUuid() == null) { if (body.getUuid() == null) {
body.setUuid(UUID.randomUUID()); body.setUuid(UUID.randomUUID());
@ -55,7 +52,7 @@ public class RbacUserController implements RbacusersApi {
final String assumedRoles, final String assumedRoles,
final UUID userUuid) { final UUID userUuid) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
final var result = rbacUserRepository.findByUuid(userUuid); final var result = rbacUserRepository.findByUuid(userUuid);
if (result == null) { if (result == null) {
@ -71,7 +68,7 @@ public class RbacUserController implements RbacusersApi {
final String assumedRoles, final String assumedRoles,
final String userName final String userName
) { ) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
return ResponseEntity.ok(mapList(rbacUserRepository.findByOptionalNameLike(userName), RbacUserResource.class)); return ResponseEntity.ok(mapList(rbacUserRepository.findByOptionalNameLike(userName), RbacUserResource.class));
} }
@ -83,8 +80,10 @@ public class RbacUserController implements RbacusersApi {
final String assumedRoles, final String assumedRoles,
final UUID userUuid final UUID userUuid
) { ) {
context.register(currentUser, assumedRoles); context.define(currentUser, assumedRoles);
return ResponseEntity.ok(mapList(rbacUserRepository.findPermissionsOfUserByUuid(userUuid), RbacUserPermissionResource.class)); return ResponseEntity.ok(mapList(
rbacUserRepository.findPermissionsOfUserByUuid(userUuid),
RbacUserPermissionResource.class));
} }
} }

View File

@ -1,10 +1,38 @@
--liquibase formatted sql --liquibase formatted sql
-- ============================================================================
--changeset context-DEFINE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Defines the transaction context.
*/
create or replace procedure defineContext(
currentTask varchar,
currentRequest varchar,
currentUser varchar,
assumedRoles varchar
)
language plpgsql as $$
begin
raise notice 'currentRequest: %', defineContext.currentRequest;
execute format('set local hsadminng.currentTask to %L', currentTask);
execute format('set local hsadminng.currentUser to %L', currentUser);
if length(assumedRoles) > 0 then
execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
else
execute format('set local hsadminng.assumedRoles to %L', '');
end if;
end; $$;
--//
-- ============================================================================ -- ============================================================================
--changeset context-CURRENT-TASK:1 endDelimiter:--// --changeset context-CURRENT-TASK:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Returns the current tas as set by `hsadminng.currentTask`. Returns the current task as set by `hsadminng.currentTask`.
Raises exception if not set. Raises exception if not set.
*/ */
create or replace function currentTask() create or replace function currentTask()

View File

@ -4,8 +4,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.TestInfo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import static org.assertj.core.api.Assertions.assertThat;
public class ContextBasedTest { public class ContextBasedTest {
@Autowired @Autowired
@ -18,18 +16,9 @@ public class ContextBasedTest {
this.test = testInfo; this.test = testInfo;
} }
// TODO: remove the class and check which task is recorded
protected void context(final String currentUser, final String assumedRoles) { protected void context(final String currentUser, final String assumedRoles) {
context.setCurrentTask(test.getDisplayName()); context.define(test.getDisplayName(), null, currentUser, assumedRoles);
context.setCurrentUser(currentUser);
assertThat(context.getCurrentUser()).as("precondition").isEqualTo(currentUser);
if (assumedRoles != null) {
context.assumeRoles(assumedRoles);
assertThat(context.getAssumedRoles()).as("precondition").containsExactly(assumedRoles.split(";"));
// } else {
// context.assumeNoSpecialRole();
}
} }
protected void context(final String currentUser) { protected void context(final String currentUser) {

View File

@ -20,7 +20,7 @@ class ContextIntegrationTests {
@Test @Test
void registerWithoutHttpServletRequestUsesCallStack() { void registerWithoutHttpServletRequestUsesCallStack() {
context.register("current-user", null); context.define("current-user", null);
final var currentTask = context.getCurrentTask(); final var currentTask = context.getCurrentTask();
assertThat(currentTask).isEqualTo("ContextIntegrationTests.registerWithoutHttpServletRequestUsesCallStack"); assertThat(currentTask).isEqualTo("ContextIntegrationTests.registerWithoutHttpServletRequestUsesCallStack");
@ -29,7 +29,7 @@ class ContextIntegrationTests {
@Test @Test
@Transactional @Transactional
void setCurrentUser() { void setCurrentUser() {
context.setCurrentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net");
final var currentUser = context.getCurrentUser(); final var currentUser = context.getCurrentUser();
assertThat(currentUser).isEqualTo("mike@hostsharing.net"); assertThat(currentUser).isEqualTo("mike@hostsharing.net");
@ -41,8 +41,7 @@ class ContextIntegrationTests {
@Test @Test
@Transactional @Transactional
void assumeRoles() { void assumeRoles() {
context.setCurrentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net", "customer#xxx.owner;customer#yyy.owner");
context.assumeRoles("customer#xxx.owner;customer#yyy.owner");
final var currentUser = context.getCurrentUser(); final var currentUser = context.getCurrentUser();
assertThat(currentUser).isEqualTo("mike@hostsharing.net"); assertThat(currentUser).isEqualTo("mike@hostsharing.net");

View File

@ -1,15 +1,25 @@
package net.hostsharing.hsadminng.context; package net.hostsharing.hsadminng.context;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.Query; import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Stream;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.*;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@ -22,16 +32,156 @@ class ContextUnitTest {
@Mock @Mock
Query nativeQuery; Query nativeQuery;
@Nested
class WithoutHttpRequest {
@Mock
EntityManager em;
@Mock
Query nativeQuery;
@InjectMocks @InjectMocks
Context context; Context context;
@BeforeEach
void setup() {
RequestContextHolder.setRequestAttributes(null);
given(em.createNativeQuery(any())).willReturn(nativeQuery);
}
@Test @Test
void registerWithoutHttpServletRequestUsesCallStack() { void registerWithoutHttpServletRequestUsesCallStackForTask() {
given(em.createNativeQuery(any())).willReturn(nativeQuery); given(em.createNativeQuery(any())).willReturn(nativeQuery);
context.register("current-user", null); context.define("current-user");
verify(em).createNativeQuery( verify(em).createNativeQuery("call defineContext(:currentTask, :currentRequest, :currentUser, :assumedRoles);");
"set local hsadminng.currentTask = 'ContextUnitTest.registerWithoutHttpServletRequestUsesCallStack';"); verify(nativeQuery).setParameter(
"currentTask",
"WithoutHttpRequest.registerWithoutHttpServletRequestUsesCallStackForTask");
}
@Test
void registerWithoutHttpServletRequestUsesEmptyStringForRequest() {
given(em.createNativeQuery(any())).willReturn(nativeQuery);
context.define("current-user");
verify(em).createNativeQuery("call defineContext(:currentTask, :currentRequest, :currentUser, :assumedRoles);");
verify(nativeQuery).setParameter("currentRequest", "");
}
}
@Nested
class WithHttpRequest {
@Mock
EntityManager em;
@Mock
Query nativeQuery;
@Mock
HttpServletRequest request;
@Mock
RequestAttributes requestAttributes;
@Mock
BufferedReader requestBodyReader;
@Mock
Stream<String> requestBodyLines;
@InjectMocks
Context context;
@BeforeEach
void setup() {
RequestContextHolder.setRequestAttributes(requestAttributes);
given(em.createNativeQuery(any())).willReturn(nativeQuery);
}
@Test
void registerWithHttpServletRequestUsesRequest() throws IOException {
givenRequest("POST", "http://localhost:9999/api/endpoint", Map.ofEntries(
Map.entry("current-user", "given-user"),
Map.entry("content-type", "application/json"),
Map.entry("user-agent", "given-user-agent")),
"{}");
context.define("current-user");
verify(em).createNativeQuery("call defineContext(:currentTask, :currentRequest, :currentUser, :assumedRoles);");
verify(nativeQuery).setParameter("currentTask", "POST http://localhost:9999/api/endpoint");
}
@Test
void registerWithHttpServletRequestForwardsRequestAsCurl() throws IOException {
givenRequest("POST", "http://localhost:9999/api/endpoint", Map.ofEntries(
Map.entry("current-user", "given-user"),
Map.entry("content-type", "application/json"),
Map.entry("user-agent", "given-user-agent")),
"{}");
context.define("current-user");
verify(em).createNativeQuery("call defineContext(:currentTask, :currentRequest, :currentUser, :assumedRoles);");
verify(nativeQuery).setParameter("currentRequest", """
curl -0 -v -X POST http://localhost:9999/api/endpoint \\
-H 'current-user:given-user' \\
-H 'content-type:application/json' \\
--data-binary @- << EOF
{}
EOF
""".trim());
}
@Test
void shortensCurrentTaskTo96Chars() throws IOException {
givenRequest("GET", "http://localhost:9999/api/endpoint/" + "0123456789".repeat(10),
Map.ofEntries(
Map.entry("current-user", "given-user"),
Map.entry("content-type", "application/json"),
Map.entry("user-agent", "given-user-agent")),
"{}");
context.define("current-user");
verify(em).createNativeQuery("call defineContext(:currentTask, :currentRequest, :currentUser, :assumedRoles);");
verify(nativeQuery).setParameter(eq("currentTask"), argThat((String t) -> t.length() == 96));
}
@Test
void shortensCurrentRequestTo512Chars() throws IOException {
givenRequest("GET", "http://localhost:9999/api/endpoint",
Map.ofEntries(
Map.entry("current-user", "given-user"),
Map.entry("content-type", "application/json"),
Map.entry("user-agent", "given-user-agent")),
"""
{
"dummy": "%s"
}
""".formatted("0123456789".repeat(60)));
context.define("current-user");
verify(em).createNativeQuery("call defineContext(:currentTask, :currentRequest, :currentUser, :assumedRoles);");
verify(nativeQuery).setParameter(eq("currentRequest"), argThat((String t) -> t.length() == 512));
}
private void givenRequest(final String method, final String url, final Map<String, String> headers, final String body)
throws IOException {
given(request.getMethod()).willReturn(method);
given(request.getRequestURI()).willReturn(url);
given(request.getHeaderNames()).willReturn(Collections.enumeration(headers.keySet()));
given(request.getHeader(anyString())).willAnswer(invocation -> headers.get(invocation.getArgument(0).toString()));
given(request.getReader()).willReturn(requestBodyReader);
given(requestBodyReader.lines()).willReturn(requestBodyLines);
given(requestBodyLines.collect(any())).willReturn(body);
}
} }
} }

View File

@ -0,0 +1,111 @@
package net.hostsharing.hsadminng.context;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.spy;
class HttpServletRequestBodyCacheUnitTest {
@Test
void readsTheStream() {
// given
try (final var givenBodyCache = new HttpServletRequestBodyCache("Hallo".getBytes())) {
// when
final var actual = new String(givenBodyCache.readAllBytes());
// then
assertThat(actual).isEqualTo("Hallo");
} catch (final IOException exc) {
throw new AssertionError("unexpected IO exception", exc);
}
}
@Test
void isReadyReturnsTrue() {
// given
try (final var givenBodyCache = new HttpServletRequestBodyCache("Hallo".getBytes())) {
// when
final var actual = givenBodyCache.isReady();
// then
assertThat(actual).isTrue();
} catch (final IOException exc) {
throw new AssertionError("unexpected IO exception", exc);
}
}
@Test
void isFinishedReturnsTrueWhenNotRead() {
// given
try (final var givenBodyCache = new HttpServletRequestBodyCache("Hallo".getBytes())) {
// when
final var actual = givenBodyCache.isFinished();
// then
assertThat(actual).isFalse();
} catch (final IOException exc) {
throw new AssertionError("unexpected IO exception", exc);
}
}
@Test
void isFinishedReturnsTrueWhenRead() {
// given
try (final var givenBodyCache = new HttpServletRequestBodyCache("Hallo".getBytes())) {
givenBodyCache.readAllBytes();
// when
final var actual = givenBodyCache.isFinished();
// then
assertThat(actual).isTrue();
} catch (final IOException exc) {
throw new AssertionError("unexpected IO exception", exc);
}
}
@Test
void isFinishedReturnsTrueOnException() {
// given
try (final var givenBodyCache = spy(new HttpServletRequestBodyCache("".getBytes()))) {
given(givenBodyCache.available()).willThrow(new IOException("fake exception"));
// when
final var actual = givenBodyCache.isFinished();
// then
assertThat(actual).isTrue();
} catch (final IOException exc) {
throw new AssertionError("unexpected IO exception", exc);
}
}
@Test
void setReadListenerThrowsNotImplementedException() {
// given
try (final var givenBodyCache = new HttpServletRequestBodyCache("Hallo".getBytes())) {
// when
final var exception = assertThrows(RuntimeException.class, () -> givenBodyCache.setReadListener(null));
// then
assertThat(exception.getMessage()).isEqualTo("Not implemented");
} catch (final IOException exc) {
throw new AssertionError("unexpected IO exception", exc);
}
}
}

View File

@ -57,7 +57,7 @@ class CustomerControllerAcceptanceTest {
} }
@Test @Test
void hostsharingAdmin_withoutAssumedRoles_canViewMatchingCustomers_ifCriteriaGiven() throws Exception { void hostsharingAdmin_withoutAssumedRoles_canViewMatchingCustomers_ifCriteriaGiven() {
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "mike@hostsharing.net") .header("current-user", "mike@hostsharing.net")
@ -73,7 +73,7 @@ class CustomerControllerAcceptanceTest {
} }
@Test @Test
void hostsharingAdmin_withoutAssumedCustomerAdminRole_canOnlyViewOwnCustomer() throws Exception { void hostsharingAdmin_withoutAssumedCustomerAdminRole_canOnlyViewOwnCustomer() {
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "mike@hostsharing.net") .header("current-user", "mike@hostsharing.net")
@ -90,7 +90,7 @@ class CustomerControllerAcceptanceTest {
} }
@Test @Test
void customerAdmin_withoutAssumedRole_canOnlyViewOwnCustomer() throws Exception { void customerAdmin_withoutAssumedRole_canOnlyViewOwnCustomer() {
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
.header("current-user", "customer-admin@yyy.example.com") .header("current-user", "customer-admin@yyy.example.com")
@ -107,10 +107,10 @@ class CustomerControllerAcceptanceTest {
} }
@Nested @Nested
class CreateCustomer { class AddCustomer {
@Test @Test
void hostsharingAdmin_withoutAssumedRole_canCreateCustomer() throws Exception { void hostsharingAdmin_withoutAssumedRole_canAddCustomer() {
final var location = RestAssured // @formatter:off final var location = RestAssured // @formatter:off
.given() .given()
@ -136,13 +136,13 @@ class CustomerControllerAcceptanceTest {
// finally, the new customer can be viewed by its own admin // finally, the new customer can be viewed by its own admin
final var newUserUuid = UUID.fromString( final var newUserUuid = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1)); location.substring(location.lastIndexOf('/') + 1));
context.setCurrentUser("customer-admin@ttt.example.com"); context.define("customer-admin@ttt.example.com");
assertThat(customerRepository.findByUuid(newUserUuid)) assertThat(customerRepository.findByUuid(newUserUuid))
.hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("ttt")); .hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("ttt"));
} }
@Test @Test
void hostsharingAdmin_withoutAssumedRole_canCreateCustomerWithGivenUuid() { void hostsharingAdmin_withoutAssumedRole_canAddCustomerWithGivenUuid() {
final var givenUuid = UUID.randomUUID(); final var givenUuid = UUID.randomUUID();
@ -171,7 +171,7 @@ class CustomerControllerAcceptanceTest {
// finally, the new customer can be viewed by its own admin // finally, the new customer can be viewed by its own admin
final var newUserUuid = UUID.fromString( final var newUserUuid = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1)); location.substring(location.lastIndexOf('/') + 1));
context.setCurrentUser("customer-admin@vvv.example.com"); context.define("customer-admin@vvv.example.com");
assertThat(customerRepository.findByUuid(newUserUuid)) assertThat(customerRepository.findByUuid(newUserUuid))
.hasValueSatisfying(c -> { .hasValueSatisfying(c -> {
assertThat(c.getPrefix()).isEqualTo("vvv"); assertThat(c.getPrefix()).isEqualTo("vvv");
@ -180,7 +180,7 @@ class CustomerControllerAcceptanceTest {
} }
@Test @Test
void hostsharingAdmin_withAssumedCustomerAdminRole_canNotCreateCustomer() throws Exception { void hostsharingAdmin_withAssumedCustomerAdminRole_canNotAddCustomer() {
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -205,12 +205,12 @@ class CustomerControllerAcceptanceTest {
// @formatter:on // @formatter:on
// finally, the new customer was not created // finally, the new customer was not created
context.setCurrentUser("sven@hostsharing.net"); context.define("sven@hostsharing.net");
assertThat(customerRepository.findCustomerByOptionalPrefixLike("uuu")).hasSize(0); assertThat(customerRepository.findCustomerByOptionalPrefixLike("uuu")).hasSize(0);
} }
@Test @Test
void customerAdmin_withoutAssumedRole_canNotCreateCustomer() throws Exception { void customerAdmin_withoutAssumedRole_canNotAddCustomer() {
RestAssured // @formatter:off RestAssured // @formatter:off
.given() .given()
@ -234,7 +234,7 @@ class CustomerControllerAcceptanceTest {
// @formatter:on // @formatter:on
// finally, the new customer was not created // finally, the new customer was not created
context.setCurrentUser("sven@hostsharing.net"); context.define("sven@hostsharing.net");
assertThat(customerRepository.findCustomerByOptionalPrefixLike("uuu")).hasSize(0); assertThat(customerRepository.findCustomerByOptionalPrefixLike("uuu")).hasSize(0);
} }
} }

View File

@ -185,8 +185,7 @@ class PackageControllerAcceptanceTest {
} }
String getDescriptionOfPackage(final String packageName) { String getDescriptionOfPackage(final String packageName) {
context.setCurrentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net","customer#xxx.admin");
context.assumeRoles("customer#xxx.admin");
return packageRepository.findAllByOptionalNameLike(packageName).get(0).getDescription(); return packageRepository.findAllByOptionalNameLike(packageName).get(0).getDescription();
} }
} }

View File

@ -42,7 +42,7 @@ class PackageRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withoutAssumedRole_canNotViewAnyPackages_becauseThoseGrantsAreNotassumedd() { public void hostsharingAdmin_withoutAssumedRole_canNotViewAnyPackages_becauseThoseGrantsAreNotassumedd() {
// given // given
currentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net");
// when // when
final var result = packageRepository.findAllByOptionalNameLike(null); final var result = packageRepository.findAllByOptionalNameLike(null);
@ -54,8 +54,7 @@ class PackageRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withAssumedHostsharingAdminRole__canNotViewAnyPackages_becauseThoseGrantsAreNotassumedd() { public void hostsharingAdmin_withAssumedHostsharingAdminRole__canNotViewAnyPackages_becauseThoseGrantsAreNotassumedd() {
given: given:
currentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net", "global#hostsharing.admin");
assumedRoles("global#hostsharing.admin");
// when // when
final var result = packageRepository.findAllByOptionalNameLike(null); final var result = packageRepository.findAllByOptionalNameLike(null);
@ -67,7 +66,7 @@ class PackageRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnPackages() { public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnPackages() {
// given: // given:
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com");
// when: // when:
final var result = packageRepository.findAllByOptionalNameLike(null); final var result = packageRepository.findAllByOptionalNameLike(null);
@ -78,8 +77,7 @@ class PackageRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnPackages() { public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnPackages() {
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com", "package#xxx00.admin");
assumedRoles("package#xxx00.admin");
final var result = packageRepository.findAllByOptionalNameLike(null); final var result = packageRepository.findAllByOptionalNameLike(null);
@ -89,8 +87,7 @@ class PackageRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withAssumedAlienPackageAdminRole_cannotViewAnyPackages() { public void customerAdmin_withAssumedAlienPackageAdminRole_cannotViewAnyPackages() {
// given: // given:
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com", "package#yyy00.admin");
assumedRoles("package#yyy00.admin");
// when // when
final var result = attempt( final var result = attempt(
@ -105,7 +102,7 @@ class PackageRepositoryIntegrationTest {
@Test @Test
void unknownUser_withoutAssumedRole_cannotViewAnyPackages() { void unknownUser_withoutAssumedRole_cannotViewAnyPackages() {
currentUser("unknown@example.org"); context.define("unknown@example.org");
final var result = attempt( final var result = attempt(
em, em,
@ -119,8 +116,7 @@ class PackageRepositoryIntegrationTest {
@Test @Test
@Transactional @Transactional
void unknownUser_withAssumedCustomerRole_cannotViewAnyPackages() { void unknownUser_withAssumedCustomerRole_cannotViewAnyPackages() {
currentUser("unknown@example.org"); context.define("unknown@example.org", "customer#xxx.admin");
assumedRoles("customer#xxx.admin");
final var result = attempt( final var result = attempt(
em, em,
@ -172,18 +168,7 @@ class PackageRepositoryIntegrationTest {
} }
private void hostsharingAdminWithAssumedRole(final String assumedRoles) { private void hostsharingAdminWithAssumedRole(final String assumedRoles) {
currentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net", assumedRoles);
assumedRoles(assumedRoles);
}
void currentUser(final String currentUser) {
context.setCurrentUser(currentUser);
assertThat(context.getCurrentUser()).as("precondition").isEqualTo(currentUser);
}
void assumedRoles(final String assumedRoles) {
context.assumeRoles(assumedRoles);
assertThat(context.getAssumedRoles()).as("precondition").containsExactly(assumedRoles.split(";"));
} }
void noPackagesAreReturned(final List<PackageEntity> actualResult) { void noPackagesAreReturned(final List<PackageEntity> actualResult) {

View File

@ -27,7 +27,8 @@ class RbacRoleRepositoryIntegrationTest {
@Autowired @Autowired
RbacRoleRepository rbacRoleRepository; RbacRoleRepository rbacRoleRepository;
@Autowired EntityManager em; @Autowired
EntityManager em;
@Nested @Nested
class FindAllRbacRoles { class FindAllRbacRoles {
@ -53,7 +54,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withoutAssumedRole_canViewAllRbacRoles() { public void hostsharingAdmin_withoutAssumedRole_canViewAllRbacRoles() {
// given // given
currentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net");
// when // when
final var result = rbacRoleRepository.findAll(); final var result = rbacRoleRepository.findAll();
@ -65,8 +66,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withAssumedHostsharingAdminRole_canViewAllRbacRoles() { public void hostsharingAdmin_withAssumedHostsharingAdminRole_canViewAllRbacRoles() {
given: given:
currentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net", "global#hostsharing.admin");
assumedRoles("global#hostsharing.admin");
// when // when
final var result = rbacRoleRepository.findAll(); final var result = rbacRoleRepository.findAll();
@ -78,7 +78,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnRbacRole() { public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnRbacRole() {
// given: // given:
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com");
// when: // when:
final var result = rbacRoleRepository.findAll(); final var result = rbacRoleRepository.findAll();
@ -117,8 +117,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnRbacRole() { public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnRbacRole() {
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com", "package#xxx00.admin");
assumedRoles("package#xxx00.admin");
final var result = rbacRoleRepository.findAll(); final var result = rbacRoleRepository.findAll();
@ -136,8 +135,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withAssumedAlienPackageAdminRole_cannotViewAnyRbacRole() { public void customerAdmin_withAssumedAlienPackageAdminRole_cannotViewAnyRbacRole() {
// given: // given:
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com", "package#yyy00.admin");
assumedRoles("package#yyy00.admin");
// when // when
final var result = attempt( final var result = attempt(
@ -152,7 +150,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
void unknownUser_withoutAssumedRole_cannotViewAnyRbacRoles() { void unknownUser_withoutAssumedRole_cannotViewAnyRbacRoles() {
currentUser("unknown@example.org"); context.define("unknown@example.org");
final var result = attempt( final var result = attempt(
em, em,
@ -165,8 +163,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
void unknownUser_withAssumedRbacRoleRole_cannotViewAnyRbacRoles() { void unknownUser_withAssumedRbacRoleRole_cannotViewAnyRbacRoles() {
currentUser("unknown@example.org"); context.define("unknown@example.org", "RbacRole#xxx.admin");
assumedRoles("RbacRole#xxx.admin");
final var result = attempt( final var result = attempt(
em, em,
@ -183,7 +180,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
void customerAdmin_withoutAssumedRole_canFindItsOwnRolesByName() { void customerAdmin_withoutAssumedRole_canFindItsOwnRolesByName() {
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com");
final var result = rbacRoleRepository.findByRoleName("customer#xxx.admin"); final var result = rbacRoleRepository.findByRoleName("customer#xxx.admin");
@ -195,7 +192,7 @@ class RbacRoleRepositoryIntegrationTest {
@Test @Test
void customerAdmin_withoutAssumedRole_canNotFindAlienRolesByName() { void customerAdmin_withoutAssumedRole_canNotFindAlienRolesByName() {
currentUser("customer-admin@xxx.example.com"); context.define("customer-admin@xxx.example.com");
final var result = rbacRoleRepository.findByRoleName("customer#bbb.admin"); final var result = rbacRoleRepository.findByRoleName("customer#bbb.admin");
@ -203,16 +200,6 @@ class RbacRoleRepositoryIntegrationTest {
} }
} }
void currentUser(final String currentUser) {
context.setCurrentUser(currentUser);
assertThat(context.getCurrentUser()).as("precondition").isEqualTo(currentUser);
}
void assumedRoles(final String assumedRoles) {
context.assumeRoles(assumedRoles);
assertThat(context.getAssumedRoles()).as("precondition").containsExactly(assumedRoles.split(";"));
}
void exactlyTheseRbacRolesAreReturned(final List<RbacRoleEntity> actualResult, final String... expectedRoleNames) { void exactlyTheseRbacRolesAreReturned(final List<RbacRoleEntity> actualResult, final String... expectedRoleNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(RbacRoleEntity::getRoleName) .extracting(RbacRoleEntity::getRoleName)

View File

@ -71,7 +71,7 @@ class RbacUserControllerAcceptanceTest {
// finally, the user can view its own record // finally, the user can view its own record
final var newUserUuid = UUID.fromString( final var newUserUuid = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1)); location.substring(location.lastIndexOf('/') + 1));
context.setCurrentUser("new-user@example.com"); context.define("new-user@example.com");
assertThat(rbacUserRepository.findByUuid(newUserUuid)) assertThat(rbacUserRepository.findByUuid(newUserUuid))
.extracting(RbacUserEntity::getName).isEqualTo("new-user@example.com"); .extracting(RbacUserEntity::getName).isEqualTo("new-user@example.com");
} }
@ -399,7 +399,7 @@ class RbacUserControllerAcceptanceTest {
RbacUserEntity findRbacUserByName(final String userName) { RbacUserEntity findRbacUserByName(final String userName) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.setCurrentUser("mike@hostsharing.net"); context.define("mike@hostsharing.net");
return rbacUserRepository.findByName(userName); return rbacUserRepository.findByName(userName);
}).returnedValue(); }).returnedValue();
} }