introduce currentTask and ContextBasedTest

This commit is contained in:
Michael Hoennig 2022-08-24 11:32:51 +02:00
parent 81cfbc62e4
commit cb641eb8c6
14 changed files with 131 additions and 120 deletions

View File

@ -132,9 +132,9 @@ do language plpgsql $$
select * from package where uuid = uu.packageUuid into pac; select * from package where uuid = uu.packageUuid into pac;
pacAdmin = 'admin@' || pac.name || '.example.com'; pacAdmin = 'admin@' || pac.name || '.example.com';
set local hsadminng.currentUser to pacAdmin; execute format('set local hsadminng.currentTask to %L', currentTask);
execute format('set local hsadminng.currentUser to %L', pacAdmin);
set local hsadminng.assumedRoles = ''; set local hsadminng.assumedRoles = '';
set local hsadminng.currentTask to currentTask;
insert insert
into Domain (name, unixUserUuid) into Domain (name, unixUserUuid)

View File

@ -114,9 +114,9 @@ do language plpgsql $$
raise notice 'task: %', currentTask; raise notice 'task: %', currentTask;
pacAdmin = 'admin@' || dom.packageName || '.example.com'; pacAdmin = 'admin@' || dom.packageName || '.example.com';
set local hsadminng.currentUser to pacAdmin; execute format('set local hsadminng.currentTask to %L', currentTask);
execute format('set local hsadminng.currentUser to %L', pacAdmin);
set local hsadminng.assumedRoles = ''; set local hsadminng.assumedRoles = '';
set local hsadminng.currentTask to currentTask;
insert insert
into EMailAddress (localPart, domainUuid) into EMailAddress (localPart, domainUuid)

View File

@ -14,6 +14,16 @@ public class Context {
@PersistenceContext @PersistenceContext
private EntityManager em; private EntityManager em;
@Transactional(propagation = MANDATORY)
public void setCurrentTask(final String task) {
em.createNativeQuery(
String.format(
"set local hsadminng.currentTask = '%s';",
task
)
).executeUpdate();
}
@Transactional(propagation = MANDATORY) @Transactional(propagation = MANDATORY)
public void setCurrentUser(final String userName) { public void setCurrentUser(final String userName) {
em.createNativeQuery( em.createNativeQuery(

View File

@ -66,6 +66,7 @@ public class RbacGrantController implements RbacgrantsApi {
final String assumedRoles, final String assumedRoles,
final RbacGrantResource body) { final RbacGrantResource body) {
context.setCurrentTask("granting role to user");
context.setCurrentUser(currentUser); context.setCurrentUser(currentUser);
if (assumedRoles != null && !assumedRoles.isBlank()) { if (assumedRoles != null && !assumedRoles.isBlank()) {
context.assumeRoles(assumedRoles); context.assumeRoles(assumedRoles);
@ -89,6 +90,7 @@ public class RbacGrantController implements RbacgrantsApi {
final UUID grantedRoleUuid, final UUID grantedRoleUuid,
final UUID granteeUserUuid) { final UUID granteeUserUuid) {
context.setCurrentTask("revoking role from user");
context.setCurrentUser(currentUser); context.setCurrentUser(currentUser);
if (assumedRoles != null && !assumedRoles.isBlank()) { if (assumedRoles != null && !assumedRoles.isBlank()) {
context.assumeRoles(assumedRoles); context.assumeRoles(assumedRoles);

View File

@ -34,6 +34,8 @@ public class RbacUserController implements RbacusersApi {
public ResponseEntity<RbacUserResource> createUser( public ResponseEntity<RbacUserResource> createUser(
@RequestBody final RbacUserResource body @RequestBody final RbacUserResource body
) { ) {
context.setCurrentTask("creating new user: " + body.getName());
if (body.getUuid() == null) { if (body.getUuid() == null) {
body.setUuid(UUID.randomUUID()); body.setUuid(UUID.randomUUID());
} }
@ -52,7 +54,7 @@ public class RbacUserController implements RbacusersApi {
final String currentUser, final String currentUser,
final String assumedRoles, final String assumedRoles,
final String userName) { final String userName) {
return null; return null; // TODO implement getUserById
} }
@Override @Override

View File

@ -21,6 +21,8 @@ grant select on global to restricted;
/** /**
A single row to be referenced as a global object. A single row to be referenced as a global object.
*/ */
set local hsadminng.currentUser to 'init';
set local hsadminng.currentTask to 'initializing table "global"';
insert insert
into RbacObject (objecttable) values ('global'); into RbacObject (objecttable) values ('global');
insert insert
@ -91,6 +93,9 @@ create or replace function hostsharingAdmin()
language sql as $$ language sql as $$
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType; select 'global', (select uuid from RbacObject where objectTable = 'global'), 'admin'::RbacRoleType;
$$; $$;
set local hsadminng.currentUser to 'init';
set local hsadminng.currentTask to 'creating Hostsharing admin role';
select createRole(hostsharingAdmin()); select createRole(hostsharingAdmin());
-- ============================================================================ -- ============================================================================
@ -103,6 +108,9 @@ do language plpgsql $$
declare declare
admins uuid ; admins uuid ;
begin begin
set local hsadminng.currentUser to 'init';
set local hsadminng.currentTask to 'creating fake Hostsharing admin users';
admins = findRoleId(hostsharingAdmin()); admins = findRoleId(hostsharingAdmin());
call grantRoleToUserUnchecked(admins, admins, createRbacUser('mike@hostsharing.net')); call grantRoleToUserUnchecked(admins, admins, createRbacUser('mike@hostsharing.net'));
call grantRoleToUserUnchecked(admins, admins, createRbacUser('sven@hostsharing.net')); call grantRoleToUserUnchecked(admins, admins, createRbacUser('sven@hostsharing.net'));

View File

@ -206,6 +206,9 @@ do language plpgsql $$
hostsharingObjectUuid uuid; hostsharingObjectUuid uuid;
hsAdminRoleUuid uuid ; hsAdminRoleUuid uuid ;
begin begin
set local hsadminng.currentUser to 'init';
set local hsadminng.currentTask to 'granting global add-customer permission to Hostsharing admin role';
hsAdminRoleUuid := findRoleId(hostsharingAdmin()); hsAdminRoleUuid := findRoleId(hostsharingAdmin());
hostsharingObjectUuid := (select uuid from global); hostsharingObjectUuid := (select uuid from global);
addCustomerPermissions := createPermissions(hostsharingObjectUuid, array ['add-customer']); addCustomerPermissions := createPermissions(hostsharingObjectUuid, array ['add-customer']);

View File

@ -31,9 +31,9 @@ begin
currentTask = 'creating RBAC test unixuser #' || t || ' for package ' || pac.name || ' #' || pac.uuid; currentTask = 'creating RBAC test unixuser #' || t || ' for package ' || pac.name || ' #' || pac.uuid;
raise notice 'task: %', currentTask; raise notice 'task: %', currentTask;
pacAdmin = 'admin@' || pac.name || '.example.com'; pacAdmin = 'admin@' || pac.name || '.example.com';
set local hsadminng.currentUser to 'mike@hostsharing.net'; -- TODO: use a package-admin execute format('set local hsadminng.currentTask to %L', currentTask);
execute format('set local hsadminng.currentUser to %L', pacAdmin);
set local hsadminng.assumedRoles = ''; set local hsadminng.assumedRoles = '';
set local hsadminng.currentTask to currentTask;
insert insert
into unixuser (name, packageUuid) into unixuser (name, packageUuid)

View File

@ -0,0 +1,38 @@
package net.hostsharing.hsadminng.context;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import org.springframework.beans.factory.annotation.Autowired;
import static org.assertj.core.api.Assertions.assertThat;
public class ContextBasedTest {
@Autowired
Context context;
TestInfo test;
@BeforeEach
void init(TestInfo testInfo) {
this.test = testInfo;
}
protected void context(final String currentUser, final String assumedRoles) {
context.setCurrentTask(test.getDisplayName());
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) {
context(currentUser, null);
}
}

View File

@ -1,6 +1,7 @@
package net.hostsharing.hsadminng.hs.hscustomer; package net.hostsharing.hsadminng.hs.hscustomer;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -21,10 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest @DataJpaTest
@ComponentScan(basePackageClasses = { Context.class, CustomerRepository.class }) @ComponentScan(basePackageClasses = { Context.class, CustomerRepository.class })
@DirtiesContext @DirtiesContext
class CustomerRepositoryIntegrationTest { class CustomerRepositoryIntegrationTest extends ContextBasedTest {
@Autowired
Context context;
@Autowired @Autowired
CustomerRepository customerRepository; CustomerRepository customerRepository;
@ -37,7 +35,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withoutAssumedRole_canCreateNewCustomer() { public void hostsharingAdmin_withoutAssumedRole_canCreateNewCustomer() {
// given // given
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", null);
final var count = customerRepository.count(); final var count = customerRepository.count();
// when // when
@ -58,8 +56,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withAssumedCustomerRole_cannotCreateNewCustomer() { public void hostsharingAdmin_withAssumedCustomerRole_cannotCreateNewCustomer() {
// given // given
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", "customer#aaa.admin");
assumedRoles("customer#aaa.admin");
// when // when
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
@ -77,7 +74,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_cannotCreateNewCustomer() { public void customerAdmin_withoutAssumedRole_cannotCreateNewCustomer() {
// given // given
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", null);
// when // when
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
@ -105,7 +102,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withoutAssumedRole_canViewAllCustomers() { public void hostsharingAdmin_withoutAssumedRole_canViewAllCustomers() {
// given // given
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", null);
// when // when
final var result = customerRepository.findCustomerByOptionalPrefixLike(null); final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
@ -117,8 +114,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withAssumedHostsharingAdminRole_canViewAllCustomers() { public void hostsharingAdmin_withAssumedHostsharingAdminRole_canViewAllCustomers() {
given: given:
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", "global#hostsharing.admin");
assumedRoles("global#hostsharing.admin");
// when // when
final var result = customerRepository.findCustomerByOptionalPrefixLike(null); final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
@ -130,7 +126,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnCustomer() { public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnCustomer() {
// given: // given:
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", null);
// when: // when:
final var result = customerRepository.findCustomerByOptionalPrefixLike(null); final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
@ -141,8 +137,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnCustomer() { public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyItsOwnCustomer() {
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "package#aaa00.admin");
assumedRoles("package#aaa00.admin");
final var result = customerRepository.findCustomerByOptionalPrefixLike(null); final var result = customerRepository.findCustomerByOptionalPrefixLike(null);
@ -152,8 +147,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withAssumedAlienPackageAdminRole_cannotViewAnyCustomer() { public void customerAdmin_withAssumedAlienPackageAdminRole_cannotViewAnyCustomer() {
// given: // given:
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "package#aab00.admin");
assumedRoles("package#aab00.admin");
// when // when
final var result = attempt( final var result = attempt(
@ -168,7 +162,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
void unknownUser_withoutAssumedRole_cannotViewAnyCustomers() { void unknownUser_withoutAssumedRole_cannotViewAnyCustomers() {
currentUser("unknown@example.org"); context("unknown@example.org", null);
final var result = attempt( final var result = attempt(
em, em,
@ -182,8 +176,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
@Transactional @Transactional
void unknownUser_withAssumedCustomerRole_cannotViewAnyCustomers() { void unknownUser_withAssumedCustomerRole_cannotViewAnyCustomers() {
currentUser("unknown@example.org"); context("unknown@example.org", "customer#aaa.admin");
assumedRoles("customer#aaa.admin");
final var result = attempt( final var result = attempt(
em, em,
@ -202,7 +195,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withoutAssumedRole_canViewAllCustomers() { public void hostsharingAdmin_withoutAssumedRole_canViewAllCustomers() {
// given // given
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", null);
// when // when
final var result = customerRepository.findCustomerByOptionalPrefixLike("aab"); final var result = customerRepository.findCustomerByOptionalPrefixLike("aab");
@ -214,7 +207,7 @@ class CustomerRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnCustomer() { public void customerAdmin_withoutAssumedRole_canViewOnlyItsOwnCustomer() {
// given: // given:
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", null);
// when: // when:
final var result = customerRepository.findCustomerByOptionalPrefixLike("aab"); final var result = customerRepository.findCustomerByOptionalPrefixLike("aab");
@ -224,16 +217,6 @@ class CustomerRepositoryIntegrationTest {
} }
} }
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 exactlyTheseCustomersAreReturned(final List<CustomerEntity> actualResult, final String... customerPrefixes) { void exactlyTheseCustomersAreReturned(final List<CustomerEntity> actualResult, final String... customerPrefixes) {
assertThat(actualResult) assertThat(actualResult)
.hasSize(customerPrefixes.length) .hasSize(customerPrefixes.length)

View File

@ -5,7 +5,7 @@ import io.restassured.http.ContentType;
import io.restassured.response.ValidatableResponse; import io.restassured.response.ValidatableResponse;
import net.hostsharing.hsadminng.Accepts; import net.hostsharing.hsadminng.Accepts;
import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity; import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity;
@ -35,7 +35,7 @@ import static org.hamcrest.CoreMatchers.is;
) )
@Accepts({ "GRT:S(Schema)" }) @Accepts({ "GRT:S(Schema)" })
@Transactional(readOnly = true, propagation = Propagation.NEVER) @Transactional(readOnly = true, propagation = Propagation.NEVER)
class RbacGrantControllerAcceptanceTest { class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
@LocalServerPort @LocalServerPort
Integer port; Integer port;
@ -43,9 +43,6 @@ class RbacGrantControllerAcceptanceTest {
@Autowired @Autowired
EntityManager em; EntityManager em;
@Autowired
Context context;
@Autowired @Autowired
RbacUserRepository rbacUserRepository; RbacUserRepository rbacUserRepository;
@ -360,29 +357,29 @@ class RbacGrantControllerAcceptanceTest {
List<RbacGrantEntity> findAllGrantsOf(final Subject grantingSubject) { List<RbacGrantEntity> findAllGrantsOf(final Subject grantingSubject) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.setCurrentUser(grantingSubject.currentUser); context(grantingSubject.currentUser, null);
return rbacGrantRepository.findAll(); return rbacGrantRepository.findAll();
}).returnedValue(); }).returnedValue();
} }
RbacUserEntity createRBacUser() { RbacUserEntity createRBacUser() {
return jpaAttempt.transacted(() -> return jpaAttempt.transacted(() -> {
rbacUserRepository.create(new RbacUserEntity( final String newUserName = "test-user-" + RandomStringUtils.randomAlphabetic(8) + "@example.com";
UUID.randomUUID(), context(newUserName, null);
"test-user-" + RandomStringUtils.randomAlphabetic(8) + "@example.com")) return rbacUserRepository.create(new RbacUserEntity(UUID.randomUUID(), newUserName));
).returnedValue(); }).returnedValue();
} }
RbacUserEntity findRbacUserByName(final String userName) { RbacUserEntity findRbacUserByName(final String userName) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.setCurrentUser("mike@hostsharing.net"); context("mike@hostsharing.net", null);
return rbacUserRepository.findByName(userName); return rbacUserRepository.findByName(userName);
}).returnedValue(); }).returnedValue();
} }
RbacRoleEntity findRbacRoleByName(final String roleName) { RbacRoleEntity findRbacRoleByName(final String roleName) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.setCurrentUser("mike@hostsharing.net"); context("mike@hostsharing.net", null);
return rbacRoleRepository.findByRoleName(roleName); return rbacRoleRepository.findByRoleName(roleName);
}).returnedValue(); }).returnedValue();
} }

View File

@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.rbac.rbacgrant;
import net.hostsharing.hsadminng.Accepts; import net.hostsharing.hsadminng.Accepts;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity; import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity;
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository; import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
@ -27,7 +28,7 @@ import static org.assertj.core.api.Assumptions.assumeThat;
@DataJpaTest @DataJpaTest
@ComponentScan(basePackageClasses = { RbacGrantRepository.class, Context.class, JpaAttempt.class }) @ComponentScan(basePackageClasses = { RbacGrantRepository.class, Context.class, JpaAttempt.class })
@DirtiesContext @DirtiesContext
class RbacGrantRepositoryIntegrationTest { class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
@Autowired @Autowired
Context context; Context context;
@ -54,7 +55,7 @@ class RbacGrantRepositoryIntegrationTest {
@Accepts({ "GRT:L(List)" }) @Accepts({ "GRT:L(List)" })
public void packageAdmin_canViewItsRbacGrants() { public void packageAdmin_canViewItsRbacGrants() {
// given // given
currentUser("aaa00@aaa.example.com"); context("aaa00@aaa.example.com", null);
// when // when
final var result = rbacGrantRepository.findAll(); final var result = rbacGrantRepository.findAll();
@ -69,7 +70,7 @@ class RbacGrantRepositoryIntegrationTest {
@Accepts({ "GRT:L(List)" }) @Accepts({ "GRT:L(List)" })
public void customerAdmin_canViewItsRbacGrants() { public void customerAdmin_canViewItsRbacGrants() {
// given // given
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", null);
// when // when
final var result = rbacGrantRepository.findAll(); final var result = rbacGrantRepository.findAll();
@ -87,8 +88,7 @@ class RbacGrantRepositoryIntegrationTest {
@Accepts({ "GRT:L(List)" }) @Accepts({ "GRT:L(List)" })
public void customerAdmin_withAssumedRole_canOnlyViewRbacGrantsVisibleByAssumedRole() { public void customerAdmin_withAssumedRole_canOnlyViewRbacGrantsVisibleByAssumedRole() {
// given: // given:
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "package#aaa00.admin");
assumedRoles("package#aaa00.admin");
// when // when
final var result = rbacGrantRepository.findAll(); final var result = rbacGrantRepository.findAll();
@ -106,8 +106,7 @@ class RbacGrantRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() { public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() {
// given // given
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "customer#aaa.admin");
assumedRoles("customer#aaa.admin");
final var givenArbitraryUserUuid = rbacUserRepository.findByName("aac00@aac.example.com").getUuid(); final var givenArbitraryUserUuid = rbacUserRepository.findByName("aac00@aac.example.com").getUuid();
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("package#aaa00.admin").getUuid(); final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("package#aaa00.admin").getUuid();
@ -135,18 +134,17 @@ class RbacGrantRepositoryIntegrationTest {
record Given(RbacUserEntity arbitraryUser, UUID packageOwnerRoleUuid) {} record Given(RbacUserEntity arbitraryUser, UUID packageOwnerRoleUuid) {}
final var given = jpaAttempt.transacted(() -> { final var given = jpaAttempt.transacted(() -> {
// to find the uuids of we need to have access rights to these // to find the uuids of we need to have access rights to these
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", null);
return new Given( return new Given(
createNewUser(), createNewUser(),
rbacRoleRepository.findByRoleName("package#aaa00.owner").getUuid() rbacRoleRepository.findByRoleName("package#aaa00.owner").getUuid()
); );
}).returnedValue(); }).assumeSuccessful().returnedValue();
// when // when
final var attempt = jpaAttempt.transacted(() -> { final var attempt = jpaAttempt.transacted(() -> {
// now we try to use these uuids as a less privileged user // now we try to use these uuids as a less privileged user
currentUser("aaa00@aaa.example.com"); context("aaa00@aaa.example.com", "package#aaa00.admin");
assumedRoles("package#aaa00.admin");
final var grant = RbacGrantEntity.builder() final var grant = RbacGrantEntity.builder()
.granteeUserUuid(given.arbitraryUser.getUuid()) .granteeUserUuid(given.arbitraryUser.getUuid())
.grantedRoleUuid(given.packageOwnerRoleUuid) .grantedRoleUuid(given.packageOwnerRoleUuid)
@ -162,7 +160,7 @@ class RbacGrantRepositoryIntegrationTest {
+ " forbidden for {package#aaa00.admin}"); + " forbidden for {package#aaa00.admin}");
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
// finally, we use the new user to make sure, no roles were granted // finally, we use the new user to make sure, no roles were granted
currentUser(given.arbitraryUser.getName()); context(given.arbitraryUser.getName(), null);
assertThat(rbacGrantRepository.findAll()) assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::toDisplay) .extracting(RbacGrantEntity::toDisplay)
.hasSize(0); .hasSize(0);
@ -181,15 +179,13 @@ class RbacGrantRepositoryIntegrationTest {
.grantingRole("package#aaa00.admin").toUser("aac00@aac.example.com")); .grantingRole("package#aaa00.admin").toUser("aac00@aac.example.com"));
// when // when
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "customer#aaa.admin");
assumedRoles("customer#aaa.admin");
final var revokeAttempt = attempt(em, () -> { final var revokeAttempt = attempt(em, () -> {
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()); rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId());
}); });
// then // then
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "customer#aaa.admin");
assumedRoles("customer#aaa.admin");
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull(); assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
assertThat(rbacGrantRepository.findAll()) assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::getGranteeUserName) .extracting(RbacGrantEntity::getGranteeUserName)
@ -204,16 +200,14 @@ class RbacGrantRepositoryIntegrationTest {
.grantingRole("package#aaa00.admin").toUser(createNewUser().getName())); .grantingRole("package#aaa00.admin").toUser(createNewUser().getName()));
// when // when
currentUser("aaa00@aaa.example.com"); context("aaa00@aaa.example.com", "package#aaa00.admin");
assumedRoles("package#aaa00.admin");
final var revokeAttempt = attempt(em, () -> { final var revokeAttempt = attempt(em, () -> {
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()); rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId());
}); });
// then // then
assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull(); assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull();
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "customer#aaa.admin");
assumedRoles("customer#aaa.admin");
assertThat(rbacGrantRepository.findAll()) assertThat(rbacGrantRepository.findAll())
.extracting(RbacGrantEntity::getGranteeUserName) .extracting(RbacGrantEntity::getGranteeUserName)
.doesNotContain("aac00@aac.example.com"); .doesNotContain("aac00@aac.example.com");
@ -228,8 +222,7 @@ class RbacGrantRepositoryIntegrationTest {
final var grantedByRole = rbacRoleRepository.findByRoleName("package#aaa00.owner"); final var grantedByRole = rbacRoleRepository.findByRoleName("package#aaa00.owner");
// when // when
currentUser("aaa00@aaa.example.com"); context("aaa00@aaa.example.com", "package#aaa00.admin");
assumedRoles("package#aaa00.admin");
final var revokeAttempt = attempt(em, () -> { final var revokeAttempt = attempt(em, () -> {
rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId()); rbacGrantRepository.deleteByRbacGrantId(grant.getRbacGrantId());
}); });
@ -243,8 +236,7 @@ class RbacGrantRepositoryIntegrationTest {
} }
private RbacGrantEntity create(GrantBuilder with) { private RbacGrantEntity create(GrantBuilder with) {
currentUser(with.byUserName); context(with.byUserName, with.assumedRole);
assumedRoles(with.assumedRole);
final var givenArbitraryUserUuid = rbacUserRepository.findByName(with.granteeUserName).getUuid(); final var givenArbitraryUserUuid = rbacUserRepository.findByName(with.granteeUserName).getUuid();
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName(with.grantedRole).getUuid(); final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName(with.grantedRole).getUuid();
@ -304,16 +296,6 @@ class RbacGrantRepositoryIntegrationTest {
new RbacUserEntity(null, "test-user-" + System.currentTimeMillis() + "@example.com")); new RbacUserEntity(null, "test-user-" + System.currentTimeMillis() + "@example.com"));
} }
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 exactlyTheseRbacGrantsAreReturned(final List<RbacGrantEntity> actualResult, final String... expectedGrant) { void exactlyTheseRbacGrantsAreReturned(final List<RbacGrantEntity> actualResult, final String... expectedGrant) {
assertThat(actualResult) assertThat(actualResult)
.filteredOn(g -> !g.getGranteeUserName().startsWith("test-user-")) // ignore test-users created by other tests .filteredOn(g -> !g.getGranteeUserName().startsWith("test-user-")) // ignore test-users created by other tests

View File

@ -1,6 +1,7 @@
package net.hostsharing.hsadminng.rbac.rbacuser; package net.hostsharing.hsadminng.rbac.rbacuser;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.test.Array; import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt; import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
@ -23,10 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest @DataJpaTest
@ComponentScan(basePackageClasses = { RbacUserRepository.class, Context.class, JpaAttempt.class }) @ComponentScan(basePackageClasses = { RbacUserRepository.class, Context.class, JpaAttempt.class })
@DirtiesContext @DirtiesContext
class RbacUserRepositoryIntegrationTest { class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
@Autowired
Context context;
@Autowired @Autowired
RbacUserRepository rbacUserRepository; RbacUserRepository rbacUserRepository;
@ -43,6 +41,7 @@ class RbacUserRepositoryIntegrationTest {
public void anyoneCanCreateTheirOwnUser() { public void anyoneCanCreateTheirOwnUser() {
// given // given
final var givenNewUserName = "test-user-" + System.currentTimeMillis() + "@example.com"; final var givenNewUserName = "test-user-" + System.currentTimeMillis() + "@example.com";
context(givenNewUserName, null);
// when // when
final var result = rbacUserRepository.create( final var result = rbacUserRepository.create(
@ -52,7 +51,7 @@ class RbacUserRepositoryIntegrationTest {
assertThat(result).isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName); assertThat(result).isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName);
// and the new user entity can be fetched by the user itself // and the new user entity can be fetched by the user itself
currentUser(givenNewUserName); context(givenNewUserName);
assertThat(em.find(RbacUserEntity.class, result.getUuid())) assertThat(em.find(RbacUserEntity.class, result.getUuid()))
.isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName); .isNotNull().extracting(RbacUserEntity::getName).isEqualTo(givenNewUserName);
} }
@ -67,7 +66,7 @@ class RbacUserRepositoryIntegrationTest {
// when: // when:
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com");
return rbacUserRepository.create(new RbacUserEntity(givenUuid, newUserName)); return rbacUserRepository.create(new RbacUserEntity(givenUuid, newUserName));
}); });
@ -76,7 +75,7 @@ class RbacUserRepositoryIntegrationTest {
assertThat(result.returnedValue()).isNotNull() assertThat(result.returnedValue()).isNotNull()
.extracting(RbacUserEntity::getUuid).isEqualTo(givenUuid); .extracting(RbacUserEntity::getUuid).isEqualTo(givenUuid);
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
currentUser(newUserName); context(newUserName);
assertThat(em.find(RbacUserEntity.class, givenUuid)) assertThat(em.find(RbacUserEntity.class, givenUuid))
.isNotNull().extracting(RbacUserEntity::getName).isEqualTo(newUserName); .isNotNull().extracting(RbacUserEntity::getName).isEqualTo(newUserName);
}); });
@ -101,7 +100,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withoutAssumedRole_canViewAllRbacUsers() { public void hostsharingAdmin_withoutAssumedRole_canViewAllRbacUsers() {
// given // given
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net");
// when // when
final var result = rbacUserRepository.findByOptionalNameLike(null); final var result = rbacUserRepository.findByOptionalNameLike(null);
@ -113,8 +112,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withAssumedHostsharingAdminRole_canViewAllRbacUsers() { public void hostsharingAdmin_withAssumedHostsharingAdminRole_canViewAllRbacUsers() {
given: given:
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", "global#hostsharing.admin");
assumedRoles("global#hostsharing.admin");
// when // when
final var result = rbacUserRepository.findByOptionalNameLike(null); final var result = rbacUserRepository.findByOptionalNameLike(null);
@ -126,8 +124,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withAssumedCustomerAdminRole_canViewOnlyUsersHavingRolesInThatCustomersRealm() { public void hostsharingAdmin_withAssumedCustomerAdminRole_canViewOnlyUsersHavingRolesInThatCustomersRealm() {
given: given:
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", "customer#aaa.admin");
assumedRoles("customer#aaa.admin");
// when // when
final var result = rbacUserRepository.findByOptionalNameLike(null); final var result = rbacUserRepository.findByOptionalNameLike(null);
@ -143,7 +140,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canViewOnlyUsersHavingRolesInThatCustomersRealm() { public void customerAdmin_withoutAssumedRole_canViewOnlyUsersHavingRolesInThatCustomersRealm() {
// given: // given:
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com");
// when: // when:
final var result = rbacUserRepository.findByOptionalNameLike(null); final var result = rbacUserRepository.findByOptionalNameLike(null);
@ -158,8 +155,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyUsersHavingRolesInThatPackage() { public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyUsersHavingRolesInThatPackage() {
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com", "package#aaa00.admin");
assumedRoles("package#aaa00.admin");
final var result = rbacUserRepository.findByOptionalNameLike(null); final var result = rbacUserRepository.findByOptionalNameLike(null);
@ -168,7 +164,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void packageAdmin_withoutAssumedRole_canViewOnlyUsersHavingRolesInThatPackage() { public void packageAdmin_withoutAssumedRole_canViewOnlyUsersHavingRolesInThatPackage() {
currentUser("aaa00@aaa.example.com"); context("aaa00@aaa.example.com");
final var result = rbacUserRepository.findByOptionalNameLike(null); final var result = rbacUserRepository.findByOptionalNameLike(null);
@ -231,7 +227,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withoutAssumedRole_canViewTheirOwnPermissions() { public void hostsharingAdmin_withoutAssumedRole_canViewTheirOwnPermissions() {
// given // given
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net");
// when // when
final var result = rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net"); final var result = rbacUserRepository.findPermissionsOfUser("mike@hostsharing.net");
@ -243,8 +239,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void hostsharingAdmin_withAssumedHostmastersRole_willThrowException() { public void hostsharingAdmin_withAssumedHostmastersRole_willThrowException() {
// given // given
currentUser("mike@hostsharing.net"); context("mike@hostsharing.net", "global#hostsharing.admin");
assumedRoles("global#hostsharing.admin");
// when // when
final var result = attempt(em, () -> final var result = attempt(em, () ->
@ -260,7 +255,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canViewTheirOwnPermissions() { public void customerAdmin_withoutAssumedRole_canViewTheirOwnPermissions() {
// given // given
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com");
// when // when
final var result = rbacUserRepository.findPermissionsOfUser("admin@aaa.example.com"); final var result = rbacUserRepository.findPermissionsOfUser("admin@aaa.example.com");
@ -302,7 +297,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_isNotAllowedToViewGlobalAdminsPermissions() { public void customerAdmin_withoutAssumedRole_isNotAllowedToViewGlobalAdminsPermissions() {
// given // given
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com");
// when // when
final var result = attempt(em, () -> final var result = attempt(em, () ->
@ -318,7 +313,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canViewAllPermissionsWithinThePacketsRealm() { public void customerAdmin_withoutAssumedRole_canViewAllPermissionsWithinThePacketsRealm() {
// given // given
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com");
// when // when
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com"); final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
@ -354,7 +349,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void customerAdmin_withoutAssumedRole_canNotViewPermissionsOfUnrelatedUsers() { public void customerAdmin_withoutAssumedRole_canNotViewPermissionsOfUnrelatedUsers() {
// given // given
currentUser("admin@aaa.example.com"); context("admin@aaa.example.com");
// when // when
final var result = rbacUserRepository.findPermissionsOfUser("aab00@aab.example.com"); final var result = rbacUserRepository.findPermissionsOfUser("aab00@aab.example.com");
@ -366,7 +361,7 @@ class RbacUserRepositoryIntegrationTest {
@Test @Test
public void packetAdmin_withoutAssumedRole_canViewAllPermissionsWithinThePacketsRealm() { public void packetAdmin_withoutAssumedRole_canViewAllPermissionsWithinThePacketsRealm() {
// given // given
currentUser("aaa00@aaa.example.com"); context("aaa00@aaa.example.com");
// when // when
final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com"); final var result = rbacUserRepository.findPermissionsOfUser("aaa00@aaa.example.com");
@ -401,16 +396,6 @@ class RbacUserRepositoryIntegrationTest {
} }
} }
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 exactlyTheseRbacUsersAreReturned(final List<RbacUserEntity> actualResult, final String... expectedUserNames) { void exactlyTheseRbacUsersAreReturned(final List<RbacUserEntity> actualResult, final String... expectedUserNames) {
assertThat(actualResult) assertThat(actualResult)
.filteredOn(u -> !u.getName().startsWith("test-user-")) .filteredOn(u -> !u.getName().startsWith("test-user-"))

View File

@ -132,8 +132,9 @@ public class JpaAttempt {
} }
} }
public void assertSuccessful() { public JpaResult<T> assumeSuccessful() {
assertThat(exception).isNull();; assertThat(exception).isNull();;
return this;
} }
private String firstRootCauseMessageLineOf(final RuntimeException exception) { private String firstRootCauseMessageLineOf(final RuntimeException exception) {