test role-creation, grant+revoke for contact+person

This commit is contained in:
Michael Hoennig 2022-09-08 11:21:54 +02:00
parent ec00e445a0
commit 765d3c689e
4 changed files with 158 additions and 3 deletions

View File

@ -2,6 +2,8 @@ package net.hostsharing.hsadminng.hs.admin.contact;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest; import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.test.JpaAttempt; import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
@ -19,8 +21,11 @@ import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import static net.hostsharing.hsadminng.hs.admin.contact.TestHsAdminContact.hsAdminContact; import static net.hostsharing.hsadminng.hs.admin.contact.TestHsAdminContact.hsAdminContact;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantDisplayExtractor.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleNameExtractor.roleNamesOf;
import static net.hostsharing.test.JpaAttempt.attempt; import static net.hostsharing.test.JpaAttempt.attempt;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
@DataJpaTest @DataJpaTest
@ComponentScan(basePackageClasses = { HsAdminContactRepository.class, Context.class, JpaAttempt.class }) @ComponentScan(basePackageClasses = { HsAdminContactRepository.class, Context.class, JpaAttempt.class })
@ -30,6 +35,12 @@ class HsAdminContactRepositoryIntegrationTest extends ContextBasedTest {
@Autowired @Autowired
HsAdminContactRepository contactRepo; HsAdminContactRepository contactRepo;
@Autowired
RbacRoleRepository roleRepo;
@Autowired
RbacGrantRepository grantRepo;
@Autowired @Autowired
EntityManager em; EntityManager em;
@ -77,6 +88,33 @@ class HsAdminContactRepositoryIntegrationTest extends ContextBasedTest {
assertThat(contactRepo.count()).isEqualTo(count + 1); assertThat(contactRepo.count()).isEqualTo(count + 1);
} }
@Test
public void createsAndGrantsRoles() {
// given
context("drew@hostsharing.org");
final var count = contactRepo.count();
final var initialRoleCount = roleRepo.findAll().size();
final var initialGrantCount = grantRepo.findAll().size();
// when
attempt(em, () -> contactRepo.save(
hsAdminContact("another new contact", "another-new-contact@example.com"))
).assumeSuccessful();
// then
final var roles = roleRepo.findAll();
assertThat(roleNamesOf(roles)).containsAll(List.of(
"hs_admin_contact#anothernewcontact.admin",
"hs_admin_contact#anothernewcontact.tenant"));
assertThat(roles.size()).as("invalid number of roles created")
.isEqualTo(initialRoleCount + 2);
final var grants = grantRepo.findAll();
assertThat(grantDisplaysOf(grants)).containsAll(List.of(
"{ grant assumed role hs_admin_contact#anothernewcontact.admin to user drew@hostsharing.org by role global#global.admin }"));
assertThat(grants.size()).as("invalid number of grants created")
.isEqualTo(initialGrantCount + 1);
}
private void assertThatContactIsPersisted(final HsAdminContactEntity saved) { private void assertThatContactIsPersisted(final HsAdminContactEntity saved) {
final var found = contactRepo.findByUuid(saved.getUuid()); final var found = contactRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved); assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved);
@ -147,6 +185,7 @@ class HsAdminContactRepositoryIntegrationTest extends ContextBasedTest {
@Test @Test
public void globalAdmin_withoutAssumedRole_canDeleteAnyContact() { public void globalAdmin_withoutAssumedRole_canDeleteAnyContact() {
// given // given
context("alex@hostsharing.net", null);
final var givenContact = givenSomeTemporaryContact("drew@hostsharing.org"); final var givenContact = givenSomeTemporaryContact("drew@hostsharing.org");
// when // when
@ -181,6 +220,31 @@ class HsAdminContactRepositoryIntegrationTest extends ContextBasedTest {
return contactRepo.findContactByOptionalLabelLike(givenContact.getLabel()); return contactRepo.findContactByOptionalLabelLike(givenContact.getLabel());
}).assertSuccessful().returnedValue()).hasSize(0); }).assertSuccessful().returnedValue()).hasSize(0);
} }
@Test
public void deletingAContactAlsoDeletesRelatedRolesAndGrants() {
// given
context("drew@hostsharing.org", null);
final var initialRoleCount = roleRepo.findAll().size();
final var initialGrantCount = grantRepo.findAll().size();
final var givenContact = givenSomeTemporaryContact("drew@hostsharing.org");
assumeThat(roleRepo.findAll().size()).as("unexpected number of roles created")
.isEqualTo(initialRoleCount + 2);
assumeThat(grantRepo.findAll().size()).as("unexpected number of grants created")
.isEqualTo(initialGrantCount + 1);
// when
final var result = jpaAttempt.transacted(() -> {
context("drew@hostsharing.org", null);
contactRepo.deleteByUuid(givenContact.getUuid());
}).assumeSuccessful();
// then
assertThat(roleRepo.findAll().size()).as("invalid number of roles deleted")
.isEqualTo(initialRoleCount);
assertThat(grantRepo.findAll().size()).as("invalid number of grants revoked")
.isEqualTo(initialGrantCount);
}
} }
private HsAdminContactEntity givenSomeTemporaryContact( private HsAdminContactEntity givenSomeTemporaryContact(

View File

@ -2,6 +2,8 @@ package net.hostsharing.hsadminng.hs.admin.person;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest; import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.test.JpaAttempt; import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
@ -16,13 +18,14 @@ import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.List; import java.util.List;
import java.util.Random;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.random.RandomGenerator;
import static net.hostsharing.hsadminng.hs.admin.person.TestHsAdminPerson.hsAdminPerson; import static net.hostsharing.hsadminng.hs.admin.person.TestHsAdminPerson.hsAdminPerson;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantDisplayExtractor.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleNameExtractor.roleNamesOf;
import static net.hostsharing.test.JpaAttempt.attempt; import static net.hostsharing.test.JpaAttempt.attempt;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
@DataJpaTest @DataJpaTest
@ComponentScan(basePackageClasses = { HsAdminPersonRepository.class, Context.class, JpaAttempt.class }) @ComponentScan(basePackageClasses = { HsAdminPersonRepository.class, Context.class, JpaAttempt.class })
@ -32,6 +35,12 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
@Autowired @Autowired
HsAdminPersonRepository personRepo; HsAdminPersonRepository personRepo;
@Autowired
RbacRoleRepository roleRepo;
@Autowired
RbacGrantRepository grantRepo;
@Autowired @Autowired
EntityManager em; EntityManager em;
@ -79,6 +88,33 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
assertThat(personRepo.count()).isEqualTo(count + 1); assertThat(personRepo.count()).isEqualTo(count + 1);
} }
@Test
public void createsAndGrantsRoles() {
// given
context("drew@hostsharing.org");
final var count = personRepo.count();
final var initialRoleCount = roleRepo.findAll().size();
final var initialGrantCount = grantRepo.findAll().size();
// when
attempt(em, () -> personRepo.save(
hsAdminPerson("another new person"))
).assumeSuccessful();
// then
final var roles = roleRepo.findAll();
assertThat(roleNamesOf(roles)).containsAll(List.of(
"hs_admin_person#anothernewperson.admin",
"hs_admin_person#anothernewperson.tenant"));
assertThat(roles.size()).as("invalid number of roles created")
.isEqualTo(initialRoleCount + 2);
final var grants = grantRepo.findAll();
assertThat(grantDisplaysOf(grants)).containsAll(List.of(
"{ grant assumed role hs_admin_person#anothernewperson.admin to user drew@hostsharing.org by role global#global.admin }"));
assertThat(grants.size()).as("invalid number of grants created")
.isEqualTo(initialGrantCount + 1);
}
private void assertThatPersonIsPersisted(final HsAdminPersonEntity saved) { private void assertThatPersonIsPersisted(final HsAdminPersonEntity saved) {
final var found = personRepo.findByUuid(saved.getUuid()); final var found = personRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved); assertThat(found).isNotEmpty().get().usingRecursiveComparison().isEqualTo(saved);
@ -97,7 +133,8 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
final var result = personRepo.findPersonByOptionalNameLike(null); final var result = personRepo.findPersonByOptionalNameLike(null);
// then // then
allThesePersonsAreReturned(result, allThesePersonsAreReturned(
result,
"Peter, Smith", "Peter, Smith",
"Rockshop e.K.", "Rockshop e.K.",
"Ostfriesische Stahlhandel OHG", "Ostfriesische Stahlhandel OHG",
@ -187,6 +224,31 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
return personRepo.findPersonByOptionalNameLike(givenPerson.getTradeName()); return personRepo.findPersonByOptionalNameLike(givenPerson.getTradeName());
}).assertSuccessful().returnedValue()).hasSize(0); }).assertSuccessful().returnedValue()).hasSize(0);
} }
@Test
public void deletingAPersonAlsoDeletesRelatedRolesAndGrants() {
// given
context("drew@hostsharing.org", null);
final var initialRoleCount = roleRepo.findAll().size();
final var initialGrantCount = grantRepo.findAll().size();
final var givenPerson = givenSomeTemporaryPerson("drew@hostsharing.org");
assumeThat(roleRepo.findAll().size()).as("unexpected number of roles created")
.isEqualTo(initialRoleCount + 2);
assumeThat(grantRepo.findAll().size()).as("unexpected number of grants created")
.isEqualTo(initialGrantCount + 1);
// when
final var result = jpaAttempt.transacted(() -> {
context("drew@hostsharing.org", null);
personRepo.deleteByUuid(givenPerson.getUuid());
}).assumeSuccessful();
// then
assertThat(roleRepo.findAll().size()).as("invalid number of roles deleted")
.isEqualTo(initialRoleCount);
assertThat(grantRepo.findAll().size()).as("invalid number of grants revoked")
.isEqualTo(initialGrantCount);
}
} }
@AfterEach @AfterEach

View File

@ -0,0 +1,14 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
public class RbacGrantDisplayExtractor {
@NotNull
public static List<String> grantDisplaysOf(final List<RbacGrantEntity> roles) {
return roles.stream().map(RbacGrantEntity::toDisplay).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,15 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
public class RbacRoleNameExtractor {
@NotNull
public static List<String> roleNamesOf(@NotNull final List<RbacRoleEntity> roles) {
return roles.stream().map(RbacRoleEntity::getRoleName).collect(Collectors.toList());
}
}