all direct partner tests green
This commit is contained in:
parent
717bdca948
commit
6a01002a05
@ -1,6 +1,6 @@
|
|||||||
## *hsadmin-ng*'s Role-Based-Access-Management (RBAC)
|
## *hsadmin-ng*'s Role-Based-Access-Management (RBAC)
|
||||||
|
|
||||||
The requirements of *hsadmin-ng* include table-m row- and column-level-security for read and write access to business-objects.
|
The requirements of *hsadmin-ng* option table-m row- and column-level-security for read and write access to business-objects.
|
||||||
More precisely, any access has to be controlled according to given rules depending on the accessing users, their roles and the accessed business-object.
|
More precisely, any access has to be controlled according to given rules depending on the accessing users, their roles and the accessed business-object.
|
||||||
Further, roles and business-objects are hierarchical.
|
Further, roles and business-objects are hierarchical.
|
||||||
|
|
||||||
|
@ -110,9 +110,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
|||||||
return ResponseEntity.notFound().build();
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (partnerRepo.deleteByUuid(partnerUuid) != 1 ||
|
if (partnerRepo.deleteByUuid(partnerUuid) != 1) {
|
||||||
// TODO: move to after delete trigger in partner
|
|
||||||
relationshipRepo.deleteByUuid(partnerToDelete.get().getPartnerRole().getUuid()) != 1 ) {
|
|
||||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class HsOfficePartnerEntityPatcher implements EntityPatcher<HsOfficePartnerPatch
|
|||||||
@Override
|
@Override
|
||||||
public void apply(final HsOfficePartnerPatchResource resource) {
|
public void apply(final HsOfficePartnerPatchResource resource) {
|
||||||
OptionalFromJson.of(resource.getPartnerRoleUuid()).ifPresent(newValue -> {
|
OptionalFromJson.of(resource.getPartnerRoleUuid()).ifPresent(newValue -> {
|
||||||
verifyNotNull(newValue, "contact");
|
verifyNotNull(newValue, "partnerRole");
|
||||||
entity.setPartnerRole(em.getReference(HsOfficeRelationshipEntity.class, newValue));
|
entity.setPartnerRole(em.getReference(HsOfficeRelationshipEntity.class, newValue));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11,11 +11,13 @@ public interface HsOfficePartnerRepository extends Repository<HsOfficePartnerEnt
|
|||||||
|
|
||||||
Optional<HsOfficePartnerEntity> findByUuid(UUID id);
|
Optional<HsOfficePartnerEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
|
List<HsOfficePartnerEntity> findAll(); // TODO: move to a repo in test sources
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT partner FROM HsOfficePartnerEntity partner
|
SELECT partner FROM HsOfficePartnerEntity partner
|
||||||
JOIN HsOfficeRelationshipEntity rel ON rel.uuid = partner.partnerRole.uuid
|
JOIN HsOfficeRelationshipEntity rel ON rel.uuid = partner.partnerRole.uuid
|
||||||
JOIN HsOfficeContactEntity contact ON contact.uuid = rel.contact.uuid
|
JOIN HsOfficeContactEntity contact ON contact.uuid = rel.contact.uuid
|
||||||
JOIN HsOfficePersonEntity person ON person.uuid = rel.relAnchor.uuid
|
JOIN HsOfficePersonEntity person ON person.uuid = rel.relHolder.uuid
|
||||||
WHERE :name is null
|
WHERE :name is null
|
||||||
OR partner.details.birthName like concat(cast(:name as text), '%')
|
OR partner.details.birthName like concat(cast(:name as text), '%')
|
||||||
OR contact.label like concat(cast(:name as text), '%')
|
OR contact.label like concat(cast(:name as text), '%')
|
||||||
|
@ -37,6 +37,7 @@ public class RbacGrantsMermaidService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum Include {
|
public enum Include {
|
||||||
|
DETAILS,
|
||||||
USERS,
|
USERS,
|
||||||
PERMISSIONS,
|
PERMISSIONS,
|
||||||
NOT_ASSUMED,
|
NOT_ASSUMED,
|
||||||
@ -53,84 +54,91 @@ public class RbacGrantsMermaidService {
|
|||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
private EntityManager em;
|
private EntityManager em;
|
||||||
|
|
||||||
public String allGrantsToCurrentUser(final EnumSet<Include> include) {
|
public String allGrantsToCurrentUser(final EnumSet<Include> includes) {
|
||||||
final var graph = new HashSet<RawRbacGrantEntity>();
|
final var graph = new HashSet<RawRbacGrantEntity>();
|
||||||
for ( UUID subjectUuid: context.currentSubjectsUuids() ) {
|
for ( UUID subjectUuid: context.currentSubjectsUuids() ) {
|
||||||
traverseGrantsTo(graph, subjectUuid, include);
|
traverseGrantsTo(graph, subjectUuid, includes);
|
||||||
}
|
}
|
||||||
return toMermaidFlowchart(graph);
|
return toMermaidFlowchart(graph, includes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void traverseGrantsTo(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> include) {
|
private void traverseGrantsTo(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> includes) {
|
||||||
final var grants = rawGrantRepo.findByAscendingUuid(refUuid);
|
final var grants = rawGrantRepo.findByAscendingUuid(refUuid);
|
||||||
grants.forEach(g -> {
|
grants.forEach(g -> {
|
||||||
if (!include.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm ")) {
|
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm ")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!include.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(" test_")) {
|
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(" test_")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!include.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(" test_")) {
|
if (!includes.contains(NON_TEST_ENTITIES) && !g.getDescendantIdName().contains(" test_")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
graph.add(g);
|
graph.add(g);
|
||||||
if (include.contains(NOT_ASSUMED) || g.isAssumed()) {
|
if (includes.contains(NOT_ASSUMED) || g.isAssumed()) {
|
||||||
traverseGrantsTo(graph, g.getDescendantUuid(), include);
|
traverseGrantsTo(graph, g.getDescendantUuid(), includes);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> include) {
|
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
|
||||||
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbacpermission WHERE objectuuid=:targetObject AND op=:op")
|
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbacpermission WHERE objectuuid=:targetObject AND op=:op")
|
||||||
.setParameter("targetObject", targetObject)
|
.setParameter("targetObject", targetObject)
|
||||||
.setParameter("op", op)
|
.setParameter("op", op)
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
final var graph = new HashSet<RawRbacGrantEntity>();
|
final var graph = new HashSet<RawRbacGrantEntity>();
|
||||||
traverseGrantsFrom(graph, refUuid, include);
|
traverseGrantsFrom(graph, refUuid, includes);
|
||||||
return toMermaidFlowchart(graph);
|
return toMermaidFlowchart(graph, includes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void traverseGrantsFrom(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> include) {
|
private void traverseGrantsFrom(final Set<RawRbacGrantEntity> graph, final UUID refUuid, final EnumSet<Include> option) {
|
||||||
final var grants = rawGrantRepo.findByDescendantUuid(refUuid);
|
final var grants = rawGrantRepo.findByDescendantUuid(refUuid);
|
||||||
grants.forEach(g -> {
|
grants.forEach(g -> {
|
||||||
if (!include.contains(USERS) && g.getAscendantIdName().startsWith("user ")) {
|
if (!option.contains(USERS) && g.getAscendantIdName().startsWith("user ")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
graph.add(g);
|
graph.add(g);
|
||||||
if (include.contains(NOT_ASSUMED) || g.isAssumed()) {
|
if (option.contains(NOT_ASSUMED) || g.isAssumed()) {
|
||||||
traverseGrantsFrom(graph, g.getAscendingUuid(), include);
|
traverseGrantsFrom(graph, g.getAscendingUuid(), option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toMermaidFlowchart(final HashSet<RawRbacGrantEntity> graph) {
|
private String toMermaidFlowchart(final HashSet<RawRbacGrantEntity> graph, final EnumSet<Include> includes) {
|
||||||
final var entities = graph.stream()
|
final var entities =
|
||||||
|
includes.contains(DETAILS)
|
||||||
|
? graph.stream()
|
||||||
.flatMap(g -> Stream.of(
|
.flatMap(g -> Stream.of(
|
||||||
new Node(g.getAscendantIdName(), g.getAscendingUuid()),
|
new Node(g.getAscendantIdName(), g.getAscendingUuid()),
|
||||||
new Node(g.getDescendantIdName(), g.getDescendantUuid()))
|
new Node(g.getDescendantIdName(), g.getDescendantUuid()))
|
||||||
)
|
)
|
||||||
.collect(groupingBy(RbacGrantsMermaidService::entityIdName));
|
.collect(groupingBy(RbacGrantsMermaidService::renderEntityIdName))
|
||||||
|
.entrySet().stream()
|
||||||
return "%%{init:{'flowchart':{'htmlLabels':false}}}%%\n\n" +
|
.map(entity -> "subgraph " + quoted(entity.getKey()) + renderSubgraph(entity.getKey()) + "\n\n "
|
||||||
"flowchart TB\n\n"
|
|
||||||
+ entities.entrySet().stream()
|
|
||||||
.map(entity -> "subgraph " + quoted(entity.getKey()) + subgraphDisplay(entity.getKey()) + "\n\n "
|
|
||||||
+ entity.getValue().stream()
|
+ entity.getValue().stream()
|
||||||
.map(n -> node(n.idName(), n.uuid()).replace("\n", "\n "))
|
.map(n -> renderNode(n.idName(), n.uuid()).replace("\n", "\n "))
|
||||||
.sorted()
|
.sorted()
|
||||||
.distinct()
|
.distinct()
|
||||||
.collect(joining("\n\n ")))
|
.collect(joining("\n\n ")))
|
||||||
.collect(joining("\n\nend\n\n"))
|
.collect(joining("\n\nend\n\n"))
|
||||||
+ "\n\nend\n\n"
|
+ "\n\nend\n\n"
|
||||||
+ graph.stream()
|
: "";
|
||||||
|
|
||||||
|
final var grants = graph.stream()
|
||||||
.map(g -> quoted(g.getAscendantIdName()) +
|
.map(g -> quoted(g.getAscendantIdName()) +
|
||||||
(g.isAssumed() ? " --> " : " -.-> ") +
|
(g.isAssumed() ? " --> " : " -.-> ") +
|
||||||
quoted(g.getDescendantIdName()))
|
quoted(g.getDescendantIdName()))
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect(joining("\n"));
|
.collect(joining("\n"));
|
||||||
|
|
||||||
|
final var avoidCroppedNodeLabels = "%%{init:{'flowchart':{'htmlLabels':false}}}%%\n\n";
|
||||||
|
return (includes.contains(DETAILS) ? avoidCroppedNodeLabels : "")
|
||||||
|
+ "flowchart TB\n\n"
|
||||||
|
+ entities
|
||||||
|
+ grants;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String subgraphDisplay(final String entityId) {
|
private String renderSubgraph(final String entityId) {
|
||||||
// this does not work according to Mermaid bug https://github.com/mermaid-js/mermaid/issues/3806
|
// this does not work according to Mermaid bug https://github.com/mermaid-js/mermaid/issues/3806
|
||||||
// if (entityId.contains("#")) {
|
// if (entityId.contains("#")) {
|
||||||
// final var parts = entityId.split("#");
|
// final var parts = entityId.split("#");
|
||||||
@ -144,7 +152,7 @@ public class RbacGrantsMermaidService {
|
|||||||
return "[" + entityId + "]";
|
return "[" + entityId + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String entityIdName(final Node node) {
|
private static String renderEntityIdName(final Node node) {
|
||||||
final var refType = refType(node.idName());
|
final var refType = refType(node.idName());
|
||||||
if (refType.equals("user")) {
|
if (refType.equals("user")) {
|
||||||
return "users";
|
return "users";
|
||||||
@ -159,11 +167,11 @@ public class RbacGrantsMermaidService {
|
|||||||
throw new IllegalArgumentException("unknown refType '" + refType + "' in '" + node.idName() + "'");
|
throw new IllegalArgumentException("unknown refType '" + refType + "' in '" + node.idName() + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String node(final String idName, final UUID uuid) {
|
private String renderNode(final String idName, final UUID uuid) {
|
||||||
return quoted(idName) + nodeContent(idName, uuid);
|
return quoted(idName) + renderNodeContent(idName, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String nodeContent(final String idName, final UUID uuid) {
|
private String renderNodeContent(final String idName, final UUID uuid) {
|
||||||
final var refType = refType(idName);
|
final var refType = refType(idName);
|
||||||
|
|
||||||
if (refType.equals("user")) {
|
if (refType.equals("user")) {
|
||||||
|
@ -50,7 +50,7 @@ components:
|
|||||||
HsOfficePartnerPatch:
|
HsOfficePartnerPatch:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
partnerRoleUUid:
|
partnerRoleUuid:
|
||||||
type: string
|
type: string
|
||||||
format: uuid
|
format: uuid
|
||||||
nullable: true
|
nullable: true
|
||||||
|
@ -19,6 +19,7 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.test.IsValidUuidMatcher.isUuidValid;
|
||||||
@ -91,9 +92,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
void globalAdmin_withoutAssumedRole_canAddPartner() {
|
void globalAdmin_withoutAssumedRole_canAddPartner() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").stream().findFirst().orElseThrow();
|
||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
final var givenPerson = personRepo.findPersonByOptionalNameLike("Third").stream().findFirst().orElseThrow();
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").stream().findFirst().orElseThrow();
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -107,8 +108,6 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
"relHolderUuid": "%s",
|
"relHolderUuid": "%s",
|
||||||
"contactUuid": "%s"
|
"contactUuid": "%s"
|
||||||
},
|
},
|
||||||
"personUuid": "%s",
|
|
||||||
"contactUuid": "%s",
|
|
||||||
"details": {
|
"details": {
|
||||||
"registrationOffice": "Temp Registergericht Aurich",
|
"registrationOffice": "Temp Registergericht Aurich",
|
||||||
"registrationNumber": "111111"
|
"registrationNumber": "111111"
|
||||||
@ -117,21 +116,29 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
""".formatted(
|
""".formatted(
|
||||||
givenMandantPerson.getUuid(),
|
givenMandantPerson.getUuid(),
|
||||||
givenPerson.getUuid(),
|
givenPerson.getUuid(),
|
||||||
givenContact.getUuid(),
|
|
||||||
givenPerson.getUuid(),
|
|
||||||
givenContact.getUuid()))
|
givenContact.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/office/partners")
|
.post("http://localhost/api/hs/office/partners")
|
||||||
.then().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", isUuidValid())
|
.body("", lenientlyEquals("""
|
||||||
.body("partnerNumber", is(20002))
|
{
|
||||||
.body("details.registrationOffice", is("Temp Registergericht Aurich"))
|
"partnerNumber": 20002,
|
||||||
.body("details.registrationNumber", is("111111"))
|
"partnerRole": {
|
||||||
.body("contact.label", is(givenContact.getLabel()))
|
"relAnchor": { "tradeName": "Hostsharing eG" },
|
||||||
.body("person.tradeName", is(givenPerson.getTradeName()))
|
"relHolder": { "tradeName": "Third OHG" },
|
||||||
|
"relType": "PARTNER",
|
||||||
|
"relMark": null,
|
||||||
|
"contact": { "label": "fourth contact" }
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"registrationOffice": "Temp Registergericht Aurich",
|
||||||
|
"registrationNumber": "111111"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""))
|
||||||
.header("Location", startsWith("http://localhost"))
|
.header("Location", startsWith("http://localhost"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
@ -226,6 +233,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRole_canGetArbitraryPartner() {
|
void globalAdmin_withoutAssumedRole_canGetArbitraryPartner() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
|
final var partners = partnerRepo.findAll();
|
||||||
final var givenPartnerUuid = partnerRepo.findPartnerByOptionalNameLike("First").get(0).getUuid();
|
final var givenPartnerUuid = partnerRepo.findPartnerByOptionalNameLike("First").get(0).getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
@ -239,8 +247,18 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"person": { "tradeName": "First GmbH" },
|
"partnerNumber": 10001,
|
||||||
|
"partnerRole": {
|
||||||
|
"relAnchor": { "tradeName": "Hostsharing eG" },
|
||||||
|
"relHolder": { "tradeName": "First GmbH" },
|
||||||
|
"relType": "PARTNER",
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"registrationOffice": "Hamburg",
|
||||||
|
"registrationNumber": "RegNo123456789"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
@ -278,9 +296,11 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"person": { "tradeName": "First GmbH" },
|
"partnerRole": {
|
||||||
|
"relHolder": { "tradeName": "First GmbH" },
|
||||||
"contact": { "label": "first contact" }
|
"contact": { "label": "first contact" }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,8 +315,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenPartner = givenSomeTemporaryPartnerBessler(20011);
|
final var givenPartner = givenSomeTemporaryPartnerBessler(20011);
|
||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Third").get(0);
|
final var givenPartnerRel = givenSomeTemporaryPartnerRel("Third OHG", "third contact");
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -305,8 +324,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"partnerNumber": "20011",
|
"partnerNumber": "20011",
|
||||||
"contactUuid": "%s",
|
"partnerRoleUuid": "%s",
|
||||||
"personUuid": "%s",
|
|
||||||
"details": {
|
"details": {
|
||||||
"registrationOffice": "Temp Registergericht Aurich",
|
"registrationOffice": "Temp Registergericht Aurich",
|
||||||
"registrationNumber": "222222",
|
"registrationNumber": "222222",
|
||||||
@ -315,18 +333,32 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
"dateOfDeath": "2022-01-12"
|
"dateOfDeath": "2022-01-12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""".formatted(givenContact.getUuid(), givenPerson.getUuid()))
|
""".formatted(givenPartnerRel.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
.patch("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
||||||
.then().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("uuid", is(givenPartner.getUuid().toString())) // not patched!
|
.body("", lenientlyEquals("""
|
||||||
.body("partnerNumber", is(givenPartner.getPartnerNumber())) // not patched!
|
{
|
||||||
.body("details.registrationNumber", is("222222"))
|
"partnerNumber": 20011,
|
||||||
.body("contact.label", is(givenContact.getLabel()))
|
"partnerRole": {
|
||||||
.body("person.tradeName", is(givenPerson.getTradeName()));
|
"relAnchor": { "tradeName": "Hostsharing eG" },
|
||||||
|
"relHolder": { "tradeName": "Third OHG" },
|
||||||
|
"relType": "PARTNER",
|
||||||
|
"contact": { "label": "third contact" }
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"registrationOffice": "Temp Registergericht Aurich",
|
||||||
|
"registrationNumber": "222222",
|
||||||
|
"birthName": "Maja Schmidt",
|
||||||
|
"birthPlace": null,
|
||||||
|
"birthday": "1938-04-08",
|
||||||
|
"dateOfDeath": "2022-01-12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
// finally, the partner is actually updated
|
// finally, the partner is actually updated
|
||||||
@ -334,9 +366,8 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get()
|
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get()
|
||||||
.matches(partner -> {
|
.matches(partner -> {
|
||||||
assertThat(partner.getPartnerNumber()).isEqualTo(givenPartner.getPartnerNumber());
|
assertThat(partner.getPartnerNumber()).isEqualTo(givenPartner.getPartnerNumber());
|
||||||
// TODO: assert partnerRole
|
assertThat(partner.getPartnerRole().getRelHolder().getTradeName()).isEqualTo("Third OHG");
|
||||||
// assertThat(partner.getPerson().getTradeName()).isEqualTo("Third OHG");
|
assertThat(partner.getPartnerRole().getContact().getLabel()).isEqualTo("third contact");
|
||||||
// assertThat(partner.getContact().getLabel()).isEqualTo("fourth contact");
|
|
||||||
assertThat(partner.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Aurich");
|
assertThat(partner.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Aurich");
|
||||||
assertThat(partner.getDetails().getRegistrationNumber()).isEqualTo("222222");
|
assertThat(partner.getDetails().getRegistrationNumber()).isEqualTo("222222");
|
||||||
assertThat(partner.getDetails().getBirthName()).isEqualTo("Maja Schmidt");
|
assertThat(partner.getDetails().getBirthName()).isEqualTo("Maja Schmidt");
|
||||||
@ -460,13 +491,14 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
private HsOfficeRelationshipEntity givenSomeTemporaryPartnerRel(
|
||||||
|
final String partnerHolderName,
|
||||||
|
final String contactName) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").get(0);
|
final var givenMandantPerson = personRepo.findPersonByOptionalNameLike("Hostsharing eG").stream().findFirst().orElseThrow();
|
||||||
|
final var givenPerson = personRepo.findPersonByOptionalNameLike(partnerHolderName).stream().findFirst().orElseThrow();
|
||||||
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike(contactName).stream().findFirst().orElseThrow();
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").get(0);
|
|
||||||
|
|
||||||
final var partnerRole = new HsOfficeRelationshipEntity();
|
final var partnerRole = new HsOfficeRelationshipEntity();
|
||||||
partnerRole.setRelType(HsOfficeRelationshipType.PARTNER);
|
partnerRole.setRelType(HsOfficeRelationshipType.PARTNER);
|
||||||
@ -474,6 +506,13 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
partnerRole.setRelHolder(givenPerson);
|
partnerRole.setRelHolder(givenPerson);
|
||||||
partnerRole.setContact(givenContact);
|
partnerRole.setContact(givenContact);
|
||||||
em.persist(partnerRole);
|
em.persist(partnerRole);
|
||||||
|
return partnerRole;
|
||||||
|
}).assertSuccessful().returnedValue();
|
||||||
|
}
|
||||||
|
private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
||||||
|
return jpaAttempt.transacted(() -> {
|
||||||
|
context.define("superuser-alex@hostsharing.net");
|
||||||
|
final var partnerRole = em.merge(givenSomeTemporaryPartnerRel("Erben Bessler", "fourth contact"));
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
.partnerRole(partnerRole)
|
.partnerRole(partnerRole)
|
||||||
|
@ -191,31 +191,5 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
// then
|
// then
|
||||||
.andExpect(status().isForbidden());
|
.andExpect(status().isForbidden());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void respondBadRequest_ifRelationshipCannotBeDeleted() throws Exception {
|
|
||||||
// given
|
|
||||||
final UUID givenPartnerUuid = UUID.randomUUID();
|
|
||||||
when(partnerRepo.findByUuid(givenPartnerUuid)).thenReturn(Optional.of(partnerMock));
|
|
||||||
when(partnerRepo.deleteByUuid(givenPartnerUuid)).thenReturn(1);
|
|
||||||
when(relationshipRepo.deleteByUuid(any())).thenReturn(0);
|
|
||||||
|
|
||||||
final UUID givenRelationshipUuid = UUID.randomUUID();
|
|
||||||
when(partnerMock.getPartnerRole()).thenReturn(HsOfficeRelationshipEntity.builder()
|
|
||||||
.uuid(givenRelationshipUuid)
|
|
||||||
.build());
|
|
||||||
when(relationshipRepo.deleteByUuid(givenRelationshipUuid)).thenReturn(0);
|
|
||||||
|
|
||||||
// when
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
|
||||||
.delete("/api/hs/office/partners/" + givenPartnerUuid)
|
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
|
||||||
|
|
||||||
// then
|
|
||||||
.andExpect(status().isForbidden());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,8 @@ class HsOfficePartnerEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void initMocks() {
|
void initMocks() {
|
||||||
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
|
lenient().when(em.getReference(eq(HsOfficeRelationshipEntity.class), any())).thenAnswer(invocation ->
|
||||||
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
|
HsOfficeRelationshipEntity.builder().uuid(invocation.getArgument(1)).build());
|
||||||
lenient().when(em.getReference(eq(HsOfficePersonEntity.class), any())).thenAnswer(invocation ->
|
|
||||||
HsOfficePersonEntity.builder().uuid(invocation.getArgument(1)).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -8,8 +8,7 @@ import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipRepo
|
|||||||
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
import net.hostsharing.hsadminng.hs.office.relationship.HsOfficeRelationshipType;
|
||||||
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsMermaidService;
|
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacObjectRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsMermaidService.Include;
|
|
||||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||||
import net.hostsharing.test.Array;
|
import net.hostsharing.test.Array;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
@ -26,19 +25,18 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static java.lang.String.join;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacObjectEntity.objectDisplaysOf;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||||
import static net.hostsharing.test.Array.fromFormatted;
|
import static net.hostsharing.test.Array.fromFormatted;
|
||||||
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;
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@Import( { Context.class, JpaAttempt.class, RbacGrantsMermaidService.class })
|
@Import( { Context.class, JpaAttempt.class })
|
||||||
class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -53,15 +51,15 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeContactRepository contactRepo;
|
HsOfficeContactRepository contactRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RawRbacObjectRepository rawObjectRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RawRbacRoleRepository rawRoleRepo;
|
RawRbacRoleRepository rawRoleRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RawRbacGrantRepository rawGrantRepo;
|
RawRbacGrantRepository rawGrantRepo;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
RbacGrantsMermaidService mermaidService;
|
|
||||||
|
|
||||||
@PersistenceContext
|
@PersistenceContext
|
||||||
EntityManager em;
|
EntityManager em;
|
||||||
|
|
||||||
@ -263,9 +261,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
givenPartner,
|
givenPartner,
|
||||||
"hs_office_person#ErbenBesslerMelBessler.admin");
|
"hs_office_person#ErbenBesslerMelBessler.admin");
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||||
RbacGrantsMermaidService.writeToFile("initial partner: Erben Bessler + fifth contact",
|
|
||||||
mermaidService.allGrantsFrom(givenPartner.getUuid(), "view", EnumSet.of(Include.USERS)),
|
|
||||||
"doc/all-grants-before-update.md");
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -277,9 +272,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
RbacGrantsMermaidService.writeToFile("updated partner: Third OHG + sixth contact",
|
|
||||||
mermaidService.allGrantsFrom(result.returnedValue().getUuid(), "view", EnumSet.of(Include.USERS)),
|
|
||||||
"doc/all-grants-after-update.md");
|
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
assertThatPartnerIsVisibleForUserWithRole(
|
||||||
result.returnedValue(),
|
result.returnedValue(),
|
||||||
"global#global.admin");
|
"global#global.admin");
|
||||||
@ -298,13 +290,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
|
final var givenPartner = givenSomeTemporaryHostsharingPartner(20037, "Erben Bessler", "ninth");
|
||||||
assertThatPartnerIsVisibleForUserWithRole(
|
assertThatPartnerIsVisibleForUserWithRole(
|
||||||
givenPartner,
|
givenPartner,
|
||||||
"hs_office_partner#20033:ErbenBesslerMelBessler-ninthcontact.agent");
|
"hs_office_person#ErbenBesslerMelBessler.admin");
|
||||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net",
|
context("superuser-alex@hostsharing.net",
|
||||||
"hs_office_partner#20033:ErbenBesslerMelBessler-ninthcontact.agent");
|
"hs_office_person#ErbenBesslerMelBessler.admin");
|
||||||
givenPartner.getDetails().setBirthName("new birthname");
|
givenPartner.getDetails().setBirthName("new birthname");
|
||||||
return partnerRepo.save(givenPartner);
|
return partnerRepo.save(givenPartner);
|
||||||
});
|
});
|
||||||
@ -316,8 +308,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {
|
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {
|
||||||
final var found = partnerRepo.findByUuid(saved.getUuid());
|
final var found = partnerRepo.findByUuid(saved.getUuid());
|
||||||
found.get().getPartnerRole(); // TODO: remove and uncomment the next line:
|
assertThat(found).isNotEmpty().get().isNotSameAs(saved).usingRecursiveComparison().isEqualTo(saved);
|
||||||
// assertThat(found).isNotEmpty().get().isNotSameAs(saved).usingRecursiveComparison().isEqualTo(saved);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatPartnerIsVisibleForUserWithRole(
|
private void assertThatPartnerIsVisibleForUserWithRole(
|
||||||
@ -334,10 +325,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
final String assumedRoles) {
|
final String assumedRoles) {
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", assumedRoles);
|
context("superuser-alex@hostsharing.net", assumedRoles);
|
||||||
RbacGrantsMermaidService.writeToFile("partner visible in assertThatPartnerIsNotVisibleForUserWithRole",
|
|
||||||
mermaidService.allGrantsFrom(entity.getUuid(), "view", EnumSet.of(Include.USERS)),
|
|
||||||
"doc/all-grants-within-assertThatPartnerIsNotVisibleForUserWithRole.md");
|
|
||||||
|
|
||||||
final var found = partnerRepo.findByUuid(entity.getUuid());
|
final var found = partnerRepo.findByUuid(entity.getUuid());
|
||||||
assertThat(found).isEmpty();
|
assertThat(found).isEmpty();
|
||||||
}).assertSuccessful();
|
}).assertSuccessful();
|
||||||
@ -395,6 +382,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
public void deletingAPartnerAlsoDeletesRelatedRolesAndGrants() {
|
public void deletingAPartnerAlsoDeletesRelatedRolesAndGrants() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
|
final var initialObjects = Array.from(objectDisplaysOf(rawObjectRepo.findAll()));
|
||||||
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
|
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
|
||||||
final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll()));
|
final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll()));
|
||||||
final var givenPartner = givenSomeTemporaryHostsharingPartner(20034, "Erben Bessler", "twelfth");
|
final var givenPartner = givenSomeTemporaryHostsharingPartner(20034, "Erben Bessler", "twelfth");
|
||||||
@ -402,15 +390,13 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
// TODO: should deleting a partner automatically delete the PARTNER relationship? (same for debitor)
|
return partnerRepo.deleteByUuid(givenPartner.getUuid());
|
||||||
// TODO: why did the test cleanup check does not notice this, if missing?
|
|
||||||
return partnerRepo.deleteByUuid(givenPartner.getUuid()) +
|
|
||||||
relationshipRepo.deleteByUuid(givenPartner.getPartnerRole().getUuid());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
assertThat(result.returnedValue()).isEqualTo(2); // partner+relationship
|
assertThat(result.returnedValue()).isEqualTo(1);
|
||||||
|
assertThat(objectDisplaysOf(rawObjectRepo.findAll())).containsExactlyInAnyOrder(initialObjects);
|
||||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(initialRoleNames);
|
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(initialRoleNames);
|
||||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(initialGrantNames);
|
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(initialGrantNames);
|
||||||
}
|
}
|
||||||
@ -439,7 +425,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var partnerRole = givenSomeTemporaryHostsharingPartnerRole(person, contact);
|
final var partnerRole = givenSomeTemporaryHostsharingPartnerRole(person, contact);
|
||||||
// em.flush(); // TODO: why is that necessary?
|
|
||||||
|
|
||||||
final var newPartner = HsOfficePartnerEntity.builder()
|
final var newPartner = HsOfficePartnerEntity.builder()
|
||||||
.partnerNumber(partnerNumber)
|
.partnerNumber(partnerNumber)
|
||||||
@ -480,9 +465,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
cleanupAllNew(HsOfficePartnerDetailsEntity.class); // TODO: should not be necessary
|
|
||||||
cleanupAllNew(HsOfficePartnerEntity.class);
|
cleanupAllNew(HsOfficePartnerEntity.class);
|
||||||
cleanupAllNew(HsOfficeRelationshipEntity.class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] distinct(final String[] strings) {
|
private String[] distinct(final String[] strings) {
|
||||||
|
@ -4,7 +4,6 @@ import net.hostsharing.hsadminng.context.Context;
|
|||||||
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.hs.office.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsMermaidService.Include;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsMermaidService.Include;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
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;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.springframework.data.annotation.Immutable;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "rbacobject") // TODO: create view rbacobject_ev
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@Immutable
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class RawRbacObjectEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private UUID uuid;
|
||||||
|
|
||||||
|
@Column(name="objecttable")
|
||||||
|
private String objectTable;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<String> objectDisplaysOf(@NotNull final List<RawRbacObjectEntity> roles) {
|
||||||
|
return roles.stream().map(e -> e.objectTable+ "#" + e.uuid).sorted().toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface RawRbacObjectRepository extends Repository<RawRbacObjectEntity, UUID> {
|
||||||
|
|
||||||
|
List<RawRbacObjectEntity> findAll();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user