Compare commits
No commits in common. "f1fbb4937049d34268386c5ae1e3f3c50db4263e" and "4c0b4a2c1e35b8f33e3b853601a239253f8274f1" have entirely different histories.
f1fbb49370
...
4c0b4a2c1e
@ -21,7 +21,6 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
|||||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
|
|
||||||
// TODO.refa: split HsOfficePersonEntity into Real+Rbac-Entity
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(schema = "hs_office", name = "person_rv")
|
@Table(schema = "hs_office", name = "person_rv")
|
||||||
@Getter
|
@Getter
|
||||||
|
@ -52,7 +52,7 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
|||||||
context.define(currentSubject, assumedRoles);
|
context.define(currentSubject, assumedRoles);
|
||||||
|
|
||||||
final var entities = relationRbacRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid,
|
final var entities = relationRbacRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid,
|
||||||
relationType == null ? null : HsOfficeRelationType.valueOf(relationType.name()));
|
mapper.map(relationType, HsOfficeRelationType.class));
|
||||||
|
|
||||||
final var resources = mapper.mapList(entities, HsOfficeRelationResource.class,
|
final var resources = mapper.mapList(entities, HsOfficeRelationResource.class,
|
||||||
RELATION_ENTITY_TO_RESOURCE_POSTMAPPER);
|
RELATION_ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||||
|
@ -13,20 +13,20 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
|
|||||||
Optional<HsOfficeRelationRbacEntity> findByUuid(UUID id);
|
Optional<HsOfficeRelationRbacEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
default List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) {
|
default List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) {
|
||||||
return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType == null ? null : relationType.toString());
|
return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT p.* FROM hs_office.relation_rv AS p
|
SELECT p.* FROM hs_office.relation_rv AS p
|
||||||
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
||||||
|
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT p.* FROM hs_office.relation_rv AS p
|
SELECT p.* FROM hs_office.relation_rv AS p
|
||||||
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS hs_office.RelationType))
|
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS hs_office.RelationType))
|
||||||
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
|
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
|
||||||
|
|
||||||
HsOfficeRelationRbacEntity save(final HsOfficeRelationRbacEntity entity);
|
HsOfficeRelationRbacEntity save(final HsOfficeRelationRbacEntity entity);
|
||||||
|
@ -13,7 +13,7 @@ public interface HsOfficeRelationRealRepository extends Repository<HsOfficeRelat
|
|||||||
Optional<HsOfficeRelationRealEntity> findByUuid(UUID id);
|
Optional<HsOfficeRelationRealEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
default List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) {
|
default List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) {
|
||||||
return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType == null ? null : relationType.toString());
|
return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
|
@ -182,7 +182,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
// finally, the new bookingItem can be accessed under the generated UUID
|
// finally, the new bookingItem can be accessed under the generated UUID
|
||||||
assertThat(fetchRealBookingItemFromURI(location)).isNotNull();
|
final var newSubjectUuid = UUID.fromString(
|
||||||
|
location.substring(location.lastIndexOf('/') + 1));
|
||||||
|
assertThat(newSubjectUuid).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -218,24 +220,24 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
)
|
)
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/booking/items")
|
.post("http://localhost/api/hs/booking/items")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"type": "DOMAIN_SETUP",
|
"type": "DOMAIN_SETUP",
|
||||||
"caption": "some new domain-setup booking",
|
"caption": "some new domain-setup booking",
|
||||||
"validFrom": "{today}",
|
"validFrom": "{today}",
|
||||||
"validTo": null,
|
"validTo": null,
|
||||||
"resources": { "domainName": "example.org", "targetUnixUser": "fir01-web" }
|
"resources": { "domainName": "example.org", "targetUnixUser": "fir01-web" }
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
.replace("{today}", LocalDate.now().toString())
|
.replace("{today}", LocalDate.now().toString())
|
||||||
.replace("{todayPlus1Month}", LocalDate.now().plusMonths(1).toString()))
|
.replace("{todayPlus1Month}", LocalDate.now().plusMonths(1).toString()))
|
||||||
)
|
)
|
||||||
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/booking/items/[^/]*"))
|
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/booking/items/[^/]*"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
// then, the new BookingItem can be accessed under the generated UUID
|
// then, the new BookingItem can be accessed under the generated UUID
|
||||||
final var newBookingItem = fetchRealBookingItemFromURI(location);
|
final var newBookingItem = fetchRealBookingItemFromURI(location);
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relation;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType;
|
|
||||||
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.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import jakarta.persistence.PersistenceContext;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.NATURAL_PERSON;
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.REPRESENTATIVE;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
@DataJpaTest
|
|
||||||
@Import( { Context.class, JpaAttempt.class })
|
|
||||||
class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
HsOfficeRelationRealRepository relationRealRepo;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
HsOfficePersonRepository personRepo;
|
|
||||||
|
|
||||||
@PersistenceContext
|
|
||||||
EntityManager em;
|
|
||||||
|
|
||||||
@MockBean
|
|
||||||
HttpServletRequest request;
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
class FindRelations {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canFindAllRelationsOfGivenPerson() {
|
|
||||||
// given
|
|
||||||
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var result = relationRealRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid, null);
|
|
||||||
|
|
||||||
// then
|
|
||||||
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
|
|
||||||
exactlyTheseRelationsAreReturned(
|
|
||||||
result,
|
|
||||||
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
|
|
||||||
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
|
|
||||||
"rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')",
|
|
||||||
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canFindAllRelationsOfGivenPersonAndType() {
|
|
||||||
// given:
|
|
||||||
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
|
|
||||||
|
|
||||||
// when:
|
|
||||||
final var result = relationRealRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid, REPRESENTATIVE);
|
|
||||||
|
|
||||||
// then:
|
|
||||||
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
|
|
||||||
exactlyTheseRelationsAreReturned(
|
|
||||||
result,
|
|
||||||
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private UUID determinePersonUuid(final HsOfficePersonType type, final String familyName) {
|
|
||||||
return (UUID) em.createNativeQuery("""
|
|
||||||
SELECT uuid FROM hs_office.person p
|
|
||||||
WHERE p.personType = cast(:type as hs_office.PersonType) AND p.familyName = :familyName
|
|
||||||
""", UUID.class)
|
|
||||||
.setParameter("familyName", familyName)
|
|
||||||
.setParameter("type", type.toString())
|
|
||||||
.getSingleResult();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void exactlyTheseRelationsAreReturned(
|
|
||||||
final List<HsOfficeRelationRealEntity> actualResult,
|
|
||||||
final String... relationNames) {
|
|
||||||
assertThat(actualResult)
|
|
||||||
.extracting(HsOfficeRelation::toString)
|
|
||||||
.containsExactlyInAnyOrder(relationNames);
|
|
||||||
}
|
|
||||||
}
|
|
@ -55,7 +55,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
class ListRelations {
|
class ListRelations {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRoles_canViewAllRelationsOfGivenPersonAndType() throws JSONException {
|
void globalAdmin_withoutAssumedRoles_canViewAllRelationsOfGivenPersonAndType_ifNoCriteriaGiven() throws JSONException {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
@ -111,64 +111,6 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
"""));
|
"""));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void personAdmin_canViewAllRelationsOfGivenRelatedPersonAndAnyType() throws JSONException {
|
|
||||||
|
|
||||||
// given
|
|
||||||
context.define("contact-admin@firstcontact.example.com");
|
|
||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("First GmbH").get(0);
|
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
|
||||||
.given()
|
|
||||||
.header("current-subject", "superuser-alex@hostsharing.net")
|
|
||||||
.port(port)
|
|
||||||
.when()
|
|
||||||
.get("http://localhost/api/hs/office/relations?personUuid=%s"
|
|
||||||
.formatted(givenPerson.getUuid(), HsOfficeRelationTypeResource.PARTNER))
|
|
||||||
.then().log().all().assertThat()
|
|
||||||
.statusCode(200)
|
|
||||||
.contentType("application/json")
|
|
||||||
.body("", lenientlyEquals("""
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"anchor": {
|
|
||||||
"tradeName": "First GmbH"
|
|
||||||
},
|
|
||||||
"holder": {
|
|
||||||
"givenName": "Susan",
|
|
||||||
"familyName": "Firby"
|
|
||||||
},
|
|
||||||
"type": "REPRESENTATIVE",
|
|
||||||
"mark": null,
|
|
||||||
"contact": { "caption": "first contact" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anchor": {
|
|
||||||
"tradeName": "Hostsharing eG"
|
|
||||||
},
|
|
||||||
"holder": {
|
|
||||||
"tradeName": "First GmbH"
|
|
||||||
},
|
|
||||||
"type": "PARTNER",
|
|
||||||
"mark": null,
|
|
||||||
"contact": { "caption": "first contact" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"anchor": {
|
|
||||||
"tradeName": "First GmbH"
|
|
||||||
},
|
|
||||||
"holder": {
|
|
||||||
"tradeName": "First GmbH"
|
|
||||||
},
|
|
||||||
"type": "DEBITOR",
|
|
||||||
"mark": null,
|
|
||||||
"contact": { "caption": "first contact" }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"""));
|
|
||||||
// @formatter:on
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -163,7 +163,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class FindRelations {
|
class FindAllRelations {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void globalAdmin_withoutAssumedRole_canViewAllRelationsOfArbitraryPerson() {
|
public void globalAdmin_withoutAssumedRole_canViewAllRelationsOfArbitraryPerson() {
|
||||||
@ -193,7 +193,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
.findFirst().orElseThrow();
|
.findFirst().orElseThrow();
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = relationRbacRepo.findRelationRelatedToPersonUuidAndRelationType(person.getUuid(), null);
|
final var result = relationRbacRepo.findRelationRelatedToPersonUuid(person.getUuid());
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseRelationsAreReturned(
|
exactlyTheseRelationsAreReturned(
|
||||||
|
Loading…
Reference in New Issue
Block a user