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
7 changed files with 80 additions and 13 deletions
Showing only changes of commit 048a976a1a - Show all commits

View File

@ -45,7 +45,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
private HsHostingAssetRealRepository realAssetRepo; private HsHostingAssetRealRepository realAssetRepo;
@Autowired @Autowired
private HsBookingItemRealRepository relBookingItemRepo; private HsBookingItemRealRepository realBookingItemRepo;
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
@ -151,7 +151,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final BiConsumer<HsHostingAssetInsertResource, HsHostingAssetRbacEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { final BiConsumer<HsHostingAssetInsertResource, HsHostingAssetRbacEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
entity.putConfig(KeyValueMap.from(resource.getConfig())); entity.putConfig(KeyValueMap.from(resource.getConfig()));
if (resource.getBookingItemUuid() != null) { if (resource.getBookingItemUuid() != null) {
entity.setBookingItem(relBookingItemRepo.findByUuid(resource.getBookingItemUuid()) entity.setBookingItem(realBookingItemRepo.findByUuid(resource.getBookingItemUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] bookingItemUuid %s not found".formatted( .orElseThrow(() -> new EntityNotFoundException("ERROR: [400] bookingItemUuid %s not found".formatted(
resource.getBookingItemUuid())))); resource.getBookingItemUuid()))));
} }

View File

@ -8,7 +8,7 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public interface HsHostingAssetRbacRepository extends Repository<HsHostingAssetRbacEntity, UUID> { public interface HsHostingAssetRbacRepository extends HsHostingAssetRepository<HsHostingAssetRbacEntity>, Repository<HsHostingAssetRbacEntity, UUID> {
Optional<HsHostingAssetRbacEntity> findByUuid(final UUID serverUuid); Optional<HsHostingAssetRbacEntity> findByUuid(final UUID serverUuid);

View File

@ -7,7 +7,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public interface HsHostingAssetRealRepository extends Repository<HsHostingAssetRealEntity, UUID> { public interface HsHostingAssetRealRepository extends HsHostingAssetRepository<HsHostingAssetRealEntity>, Repository<HsHostingAssetRealEntity, UUID> {
Optional<HsHostingAssetRealEntity> findByUuid(final UUID serverUuid); Optional<HsHostingAssetRealEntity> findByUuid(final UUID serverUuid);
@ -38,7 +38,7 @@ public interface HsHostingAssetRealRepository extends Repository<HsHostingAssetR
return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type)); return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type));
} }
HsHostingAssetRealEntity save(HsHostingAsset current); HsHostingAssetRealEntity save(HsHostingAssetRealEntity current);
int deleteByUuid(final UUID uuid); int deleteByUuid(final UUID uuid);

View File

@ -0,0 +1,24 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsHostingAssetRepository<E extends HsHostingAsset> {
Optional<E> findByUuid(final UUID serverUuid);
List<E> findByIdentifier(String assetIdentifier);
List<E> findAllByCriteriaImpl(UUID projectUuid, UUID parentAssetUuid, String type);
default List<E> findAllByCriteria(final UUID projectUuid, final UUID parentAssetUuid, final HsHostingAssetType type) {
return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type));
}
E save(HsHostingAsset current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -45,9 +45,8 @@ public abstract class HsEntityValidator<E extends PropertiesProvider> {
localEntityManager.set(em); localEntityManager.set(em);
try { try {
return code.get(); return code.get();
} catch (final RuntimeException e) { } finally {
localEntityManager.remove(); localEntityManager.remove();
throw e;
} }
} }

View File

@ -12,6 +12,8 @@ import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
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.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
@ -39,7 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@DataJpaTest @DataJpaTest
@Import({ Context.class, JpaAttempt.class }) @Import({ Context.class, JpaAttempt.class })
class HsHostingAssetRbacRepositoryIntegrationTest extends ContextBasedTestWithCleanup { class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired @Autowired
HsHostingAssetRealRepository realAssetRepo; HsHostingAssetRealRepository realAssetRepo;
@ -203,13 +205,14 @@ class HsHostingAssetRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
@Nested @Nested
class FindAssets { class FindAssets {
@Test @ParameterizedTest
public void globalAdmin_withoutAssumedRole_canViewArbitraryAssetsOfAllDebitors() { @EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canViewArbitraryAssetsOfAllDebitors(final TestCase testCase) {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
// when // when
final var result = rbacAssetRepo.findAllByCriteria(null, null, MANAGED_WEBSPACE); final var result = repoUnderTest(testCase).findAllByCriteria(null, null, MANAGED_WEBSPACE);
// then // then
exactlyTheseAssetsAreReturned( exactlyTheseAssetsAreReturned(
@ -451,13 +454,45 @@ class HsHostingAssetRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
} }
void exactlyTheseAssetsAreReturned( void exactlyTheseAssetsAreReturned(
final List<HsHostingAssetRbacEntity> actualResult, final List<? extends HsHostingAsset> actualResult,
final String... serverNames) { final String... serverNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(HsHostingAssetRbacEntity::toString) .extracting(HsHostingAsset::toString)
.extracting(input -> input.replaceAll("\\s+", " ")) .extracting(input -> input.replaceAll("\\s+", " "))
.extracting(input -> input.replaceAll("\"", "")) .extracting(input -> input.replaceAll("\"", ""))
.extracting(input -> input.replaceAll("\" : ", "\": ")) .extracting(input -> input.replaceAll("\" : ", "\": "))
.containsExactlyInAnyOrder(serverNames); .containsExactlyInAnyOrder(serverNames);
} }
void allTheseBookingProjectsAreReturned(
final List<? extends HsHostingAsset> actualResult,
final String... serverNames) {
assertThat(actualResult)
.extracting(HsHostingAsset::toString)
.extracting(input -> input.replaceAll("\\s+", " "))
.extracting(input -> input.replaceAll("\"", ""))
.extracting(input -> input.replaceAll("\" : ", "\": "))
.contains(serverNames);
}
private HsHostingAssetRepository<? extends HsHostingAsset> repoUnderTest(final HsHostingAssetRepositoryIntegrationTest.TestCase testCase) {
return testCase.repo(HsHostingAssetRepositoryIntegrationTest.this);
}
enum TestCase {
REAL {
@Override
HsHostingAssetRepository<HsHostingAssetRealEntity> repo(final HsHostingAssetRepositoryIntegrationTest test) {
return test.realAssetRepo;
}
},
RBAC {
@Override
HsHostingAssetRepository<HsHostingAssetRbacEntity> repo(final HsHostingAssetRepositoryIntegrationTest test) {
return test.rbacAssetRepo;
}
};
abstract HsHostingAssetRepository<? extends HsHostingAsset> repo(final HsHostingAssetRepositoryIntegrationTest test);
}
} }

View File

@ -293,7 +293,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
/** /**
* @return an array of all RBAC roles matching the given pattern * @return an array of all RBAC roles matching the given pattern
*
* Usually unused, but for temporary debugging purposes of findind role names for new tests.
*/ */
@SuppressWarnings("unused")
protected String[] roleNames(final String sqlLikeExpression) { protected String[] roleNames(final String sqlLikeExpression) {
final var pattern = Pattern.compile(sqlLikeExpression); final var pattern = Pattern.compile(sqlLikeExpression);
//noinspection unchecked //noinspection unchecked
@ -307,7 +310,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
/** /**
* Generates a diagram of the RBAC-Grants to the current subjects (user or assumed roles). * Generates a diagram of the RBAC-Grants to the current subjects (user or assumed roles).
*
* Usually unused, but for temporary use for debugging and other analysis.
*/ */
@SuppressWarnings("unused")
protected void generateRbacDiagramForCurrentSubjects(final EnumSet<RbacGrantsDiagramService.Include> include, final String name) { protected void generateRbacDiagramForCurrentSubjects(final EnumSet<RbacGrantsDiagramService.Include> include, final String name) {
RbacGrantsDiagramService.writeToFile( RbacGrantsDiagramService.writeToFile(
name, name,
@ -318,7 +324,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
/** /**
* Generates a diagram of the RBAC-Grants for the given object and permission. * Generates a diagram of the RBAC-Grants for the given object and permission.
*
* Usually unused, but for temporary use for debugging and other analysis.
*/ */
@SuppressWarnings("unused")
protected void generateRbacDiagramForObjectPermission(final UUID targetObject, final String rbacOp, final String name) { protected void generateRbacDiagramForObjectPermission(final UUID targetObject, final String rbacOp, final String name) {
RbacGrantsDiagramService.writeToFile( RbacGrantsDiagramService.writeToFile(
name, name,