real rbac-entities in booking+hosting #89

Merged
hsh-michaelhoennig merged 15 commits from real-and-rbac-entities-everywhere into master 2024-08-21 06:18:38 +02:00
4 changed files with 104 additions and 29 deletions
Showing only changes of commit f7c55ea3c8 - Show all commits

View File

@ -6,7 +6,8 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRbacRepository extends Repository<HsBookingProjectRbacEntity, UUID> {
public interface HsBookingProjectRbacRepository extends HsBookingProjectRepository<HsBookingProjectRbacEntity>,
Repository<HsBookingProjectRbacEntity, UUID> {
Optional<HsBookingProjectRbacEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectRbacEntity> findByCaption(final String projectCaption);

View File

@ -6,7 +6,8 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRealRepository extends Repository<HsBookingProjectRealEntity, UUID> {
public interface HsBookingProjectRealRepository extends HsBookingProjectRepository<HsBookingProjectRealEntity>,
Repository<HsBookingProjectRealEntity, UUID> {
Optional<HsBookingProjectRealEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectRealEntity> findByCaption(final String projectCaption);

View File

@ -0,0 +1,19 @@
package net.hostsharing.hsadminng.hs.booking.project;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRepository<E extends HsBookingProject> {
Optional<E> findByUuid(final UUID bookingProjectUuid);
List<E> findByCaption(final String projectCaption);
List<E> findAllByDebitorUuid(final UUID bookingProjectUuid);
E save(E current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -9,6 +9,8 @@ import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
@ -29,7 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest
@Import({ Context.class, JpaAttempt.class })
class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired
HsBookingProjectRealRepository realProjectRepo;
@ -58,8 +60,9 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
@Nested
class CreateBookingProject {
@Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net"); // TODO.test: remove once we have a realDebitorRepo
final var count = realProjectRepo.count();
@ -71,7 +74,7 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(rbacProjectRepo.save(newBookingProject));
return toCleanup(repoUnderTest(testCase).save(newBookingProject));
});
// then
@ -81,8 +84,9 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
assertThat(realProjectRepo.count()).isEqualTo(count + 1);
}
@Test
public void createsAndGrantsRoles() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void createsAndGrantsRoles(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
@ -97,7 +101,7 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(rbacProjectRepo.save(newBookingProject));
return toCleanup(repoUnderTest(testCase).save(newBookingProject));
});
// then
@ -144,15 +148,16 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
@Nested
class FindByDebitorUuid {
@Test
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net");
final var debitorUuid = debitorRepo.findByDebitorNumber(1000212).stream()
.findAny().orElseThrow().getUuid();
// when
final var result = rbacProjectRepo.findAllByDebitorUuid(debitorUuid);
final var result = repoUnderTest(testCase).findAllByDebitorUuid(debitorUuid);
// then
allTheseBookingProjectsAreReturned(
@ -160,8 +165,9 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
"HsBookingProject(D-1000212, D-1000212 default project)");
}
@Test
public void packetAgent_canViewOnlyRelatedBookingProjects() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void packetAgent_canViewOnlyRelatedBookingProjects(final TestCase testCase) {
// given:
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
@ -169,11 +175,10 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
.findAny().orElseThrow().getUuid();
// when:
final var result = rbacProjectRepo.findAllByDebitorUuid(debitorUuid);
final var result = repoUnderTest(testCase).findAllByDebitorUuid(debitorUuid);
// then:
exactlyTheseBookingProjectsAreReturned(
result,
assertResult(testCase, result,
"HsBookingProject(D-1000111, D-1000111 default project)");
}
}
@ -181,8 +186,9 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
@Nested
class UpdateBookingProject {
@Test
public void bookingProjectAdmin_canUpdateArbitraryBookingProject() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void bookingProjectAdmin_canUpdateArbitraryBookingProject(final TestCase testCase) {
// given
final var givenBookingProjectUuid = givenSomeTemporaryBookingProject(1000111).getUuid();
@ -191,7 +197,7 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-sometempproject:ADMIN");
final var foundBookingProject = em.find(HsBookingProjectRbacEntity.class, givenBookingProjectUuid);
foundBookingProject.setCaption("updated caption");
return toCleanup(rbacProjectRepo.save(foundBookingProject));
return toCleanup(repoUnderTest(testCase).save(foundBookingProject));
});
// then
@ -212,8 +218,9 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
@Nested
class DeleteByUuid {
@Test
public void globalAdmin_withoutAssumedRole_canDeleteAnyBookingProject() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canDeleteAnyBookingProject(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net", null);
final var givenBookingProject = givenSomeTemporaryBookingProject(1000111);
@ -221,7 +228,7 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
rbacProjectRepo.deleteByUuid(givenBookingProject.getUuid());
repoUnderTest(testCase).deleteByUuid(givenBookingProject.getUuid());
});
// then
@ -242,7 +249,7 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-sometempproject:AGENT");
assertThat(rbacProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent();
rbacProjectRepo.deleteByUuid(givenBookingProject.getUuid());
repoUnderTest(TestCase.RBAC).deleteByUuid(givenBookingProject.getUuid());
});
// then
@ -255,8 +262,9 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
}).assertSuccessful().returnedValue()).isPresent(); // still there
}
@Test
public void deletingABookingProjectAlsoDeletesRelatedRolesAndGrants() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void deletingABookingProjectAlsoDeletesRelatedRolesAndGrants(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
@ -266,7 +274,7 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return rbacProjectRepo.deleteByUuid(givenBookingProject.getUuid());
return repoUnderTest(testCase).deleteByUuid(givenBookingProject.getUuid());
});
// then
@ -310,7 +318,7 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
}
void exactlyTheseBookingProjectsAreReturned(
final List<HsBookingProjectRbacEntity> actualResult,
final List<? extends HsBookingProject> actualResult,
final String... bookingProjectNames) {
assertThat(actualResult)
.extracting(HsBookingProject::toString)
@ -318,10 +326,56 @@ class HsBookingProjectRbacRepositoryIntegrationTest extends ContextBasedTestWith
}
void allTheseBookingProjectsAreReturned(
final List<HsBookingProjectRbacEntity> actualResult,
final List<? extends HsBookingProject> actualResult,
final String... bookingProjectNames) {
assertThat(actualResult)
.extracting(HsBookingProject::toString)
.contains(bookingProjectNames);
}
private HsBookingProjectRepository repoUnderTest(final TestCase testCase) {
return testCase.repo(HsBookingProjectRepositoryIntegrationTest.this);
}
private void assertResult(
final TestCase testCase,
final List<? extends HsBookingProject> actualResult,
final String... expectedProjects) {
testCase.assertResult(HsBookingProjectRepositoryIntegrationTest.this, actualResult, expectedProjects);
}
enum TestCase {
REAL {
@Override
HsBookingProjectRepository repo(final HsBookingProjectRepositoryIntegrationTest test) {
return test.realProjectRepo;
}
@Override
void assertResult(
final HsBookingProjectRepositoryIntegrationTest test,
final List<? extends HsBookingProject> result,
final String... expectedProjects) {
test.allTheseBookingProjectsAreReturned(result, expectedProjects);
}
},
RBAC {
@Override
HsBookingProjectRepository repo(final HsBookingProjectRepositoryIntegrationTest test) {
return test.rbacProjectRepo;
}
@Override
void assertResult(
final HsBookingProjectRepositoryIntegrationTest test,
final List<? extends HsBookingProject> result,
final String... expectedProjects) {
test.exactlyTheseBookingProjectsAreReturned(result, expectedProjects);
}
};
abstract HsBookingProjectRepository repo(final HsBookingProjectRepositoryIntegrationTest test);
abstract void assertResult(final HsBookingProjectRepositoryIntegrationTest test, final List<? extends HsBookingProject> result, final String... expectedProjects);
}
}