improve Contact/Partner/Contact Repository integration tests with Raw...Repos

This commit is contained in:
Michael Hoennig 2022-09-12 16:27:17 +02:00
parent 3eec8a4138
commit ac5f19e399
16 changed files with 210 additions and 109 deletions

View File

@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.admin.partner;
import lombok.*;
import net.hostsharing.hsadminng.hs.admin.contact.HsAdminContactEntity;
import net.hostsharing.hsadminng.hs.admin.person.HsAdminPersonEntity;
import org.hibernate.annotations.Cascade;
import javax.persistence.*;
import java.time.LocalDate;
@ -33,4 +32,8 @@ public class HsAdminPartnerEntity {
private @Column(name = "birthname") String birthName;
private @Column(name = "birthday") LocalDate birthday;
private @Column(name = "dateofdeath") LocalDate dateOfDeath;
public String getDisplayName() {
return "partner(%s, %s)".formatted(person.getDisplayName(), contact.getLabel());
}
}

View File

@ -27,5 +27,6 @@ public interface HsAdminPartnerRepository extends Repository<HsAdminPartnerEntit
HsAdminPartnerEntity save(final HsAdminPartnerEntity entity);
long count();
void deleteByUuid(UUID uuid);
int deleteByUuid(UUID uuid);
}

View File

@ -22,7 +22,7 @@ public interface HsAdminPersonRepository extends Repository<HsAdminPersonEntity,
HsAdminPersonEntity save(final HsAdminPersonEntity entity);
void deleteByUuid(final UUID personUuid);
int deleteByUuid(final UUID personUuid);
long count();
}

View File

@ -205,6 +205,7 @@ $$;
create or replace procedure deleteRole(roleUUid uuid)
language plpgsql as $$
begin
--raise exception '% deleting role uuid %', currentsubjectsuuids(), roleUUid;
delete from RbacRole where uuid = roleUUid;
end;
$$;
@ -266,6 +267,38 @@ begin
end;
$$;
-- ============================================================================
--changeset hs-admin-person-rbac-ROLES-REMOVAL:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
RbacRole BEFORE DELETE TRIGGER function which deletes all related roles.
*/
create or replace function deleteRbacGrantsForRbacRole()
returns trigger
language plpgsql
strict as $$
begin
if TG_OP = 'DELETE' then
delete from RbacGrants g where old.uuid in (g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid);
else
raise exception 'invalid usage of TRIGGER BEFORE DELETE';
end if;
return old;
end; $$;
/*
Installs the RbacRole BEFORE DELETE TRIGGER.
*/
create trigger deleteRbacGrantsForRbacRole_Trigger
before delete
on RbacRole
for each row
execute procedure deleteRbacGrantsForRbacRole();
--//
-- ============================================================================
--changeset rbac-base-PERMISSION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
@ -363,9 +396,9 @@ $$;
create table RbacGrants
(
uuid uuid primary key default uuid_generate_v4(),
grantedByRoleUuid uuid references RbacRole (uuid) on delete cascade,
ascendantUuid uuid references RbacReference (uuid) on delete cascade not null,
descendantUuid uuid references RbacReference (uuid) on delete cascade not null,
grantedByRoleUuid uuid references RbacRole (uuid),
ascendantUuid uuid references RbacReference (uuid),
descendantUuid uuid references RbacReference (uuid),
assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false)
unique (ascendantUuid, descendantUuid)
);

View File

@ -168,6 +168,8 @@ execute function insertRbacGrant();
/**
Instead of delete trigger function for RbacGrants_RV.
Checks if the current subject (user / assumed role) has the permission to revoke the grant.
*/
create or replace function deleteRbacGrant()
returns trigger
@ -283,6 +285,8 @@ execute function insertRbacUser();
/**
Instead of delete trigger function for RbacUser_RV.
Checks if the current subject (user / assumed role) has the permission to delete the user.
*/
create or replace function deleteRbacUser()
returns trigger

View File

@ -6,7 +6,7 @@
create table if not exists hs_admin_contact
(
uuid uuid unique references RbacObject (uuid),
uuid uuid unique references RbacObject (uuid) on delete cascade,
label varchar(96) not null,
postalAddress text,
emailAddresses text, -- TODO.feat: change to json

View File

@ -224,6 +224,8 @@ execute function insertHsAdminContact();
/**
Instead of delete trigger function for hs_admin_contact_rv.
Checks if the current subject (user / assumed role) has the permission to delete the row.
*/
create or replace function deleteHsAdminContact()
returns trigger

View File

@ -10,7 +10,7 @@ CREATE CAST (character varying as HsAdminPersonType) WITH INOUT AS IMPLICIT;
create table if not exists hs_admin_person
(
uuid uuid unique references RbacObject (uuid),
uuid uuid unique references RbacObject (uuid) on delete cascade,
personType HsAdminPersonType not null,
tradeName varchar(96),
givenName varchar(48),

View File

@ -66,12 +66,12 @@ begin
-- the owner role with full access for the creator assigned to the current user
ownerRole := createRole(
hsAdminPersonOwner(NEW),
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']),
beneathRole(globalAdmin()),
withoutSubRoles(),
withUser(currentUser()), -- TODO.spec: Who is owner of a new person?
grantedByRole(globalAdmin())
hsAdminPersonOwner(NEW),
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['*']),
beneathRole(globalAdmin()),
withoutSubRoles(),
withUser(currentUser()), -- TODO.spec: Who is owner of a new person?
grantedByRole(globalAdmin())
);
-- the tenant role for those related users who can view the data
@ -83,9 +83,9 @@ begin
-- the tenant role for those related users who can view the data
perform createRole(
hsAdminPersonTenant(NEW),
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['view']),
beneathRole(adminRole)
hsAdminPersonTenant(NEW),
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['view']),
beneathRole(adminRole)
);
return NEW;
@ -107,6 +107,8 @@ execute procedure createRbacRolesForHsAdminPerson();
--changeset hs-admin-person-rbac-ROLES-REMOVAL:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
-- TODO: can we replace all these delete triggers by a delete trigger on RbacObject?
/*
Deletes the roles and their assignments of a deleted person for the BEFORE DELETE TRIGGER.
*/
@ -117,6 +119,7 @@ create or replace function deleteRbacRulesForHsAdminPerson()
begin
if TG_OP = 'DELETE' then
call deleteRole(findRoleId(hsAdminPersonOwner(OLD)));
call deleteRole(findRoleId(hsAdminPersonAdmin(OLD)));
call deleteRole(findRoleId(hsAdminPersonTenant(OLD)));
else
raise exception 'invalid usage of TRIGGER BEFORE DELETE';
@ -224,6 +227,8 @@ execute function insertHsAdminPerson();
/**
Instead of delete trigger function for hs_admin_person_rv.
Checks if the current subject (user / assumed role) has the permission to delete the row.
*/
create or replace function deleteHsAdminPerson()
returns trigger
@ -255,9 +260,9 @@ execute function deleteHsAdminPerson();
*/
do language plpgsql $$
declare
addCustomerPermissions uuid[];
globalObjectUuid uuid;
globalAdminRoleUuid uuid ;
addCustomerPermissions uuid[];
globalObjectUuid uuid;
globalAdminRoleUuid uuid ;
begin
call defineContext('granting global new-person permission to global admin role', null, null, null);

View File

@ -63,7 +63,7 @@ do language plpgsql $$
call createHsAdminPersonTestData('NATURAL', null, 'Peter', 'Smith');
call createHsAdminPersonTestData('LEGAL', 'Rockshop e.K.', 'Sandra', 'Miller');
call createHsAdminPersonTestData('SOLE_REPRESENTATION', 'Ostfriesische Kuhhandel OHG');
call createHsAdminPersonTestData('JOINT_REPRESENTATION', 'Erbengemeinschaft Bessler', 'Mel', 'Bessler');
call createHsAdminPersonTestData('JOINT_REPRESENTATION', 'Erben Bessler', 'Mel', 'Bessler');
end;
$$;
--//

View File

@ -6,7 +6,7 @@
create table if not exists hs_admin_partner
(
uuid uuid unique references RbacObject (uuid),
uuid uuid unique references RbacObject (uuid) on delete cascade,
personUuid uuid not null references hs_admin_person(uuid),
contactUuid uuid not null references hs_admin_contact(uuid),
registrationOffice varchar(96),

View File

@ -234,6 +234,8 @@ execute function insertHsAdminPartner();
/**
Instead of delete trigger function for hs_admin_partner_rv.
Checks if the current subject (user / assumed role) has the permission to delete the row.
*/
create or replace function deleteHsAdminPartner()
returns trigger

View File

@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested;
@ -97,7 +98,7 @@ class HsAdminContactRepositoryIntegrationTest extends ContextBasedTest {
// given
context("drew@hostsharing.org");
final var count = contactRepo.count();
final var initialRoleCount = roleRepo.findAll().size();
final var initialRoleNames = roleNamesOf(roleRepo.findAll());
final var initialGrantCount = grantRepo.findAll().size();
// when
@ -107,11 +108,12 @@ class HsAdminContactRepositoryIntegrationTest extends ContextBasedTest {
// then
final var roles = roleRepo.findAll();
assertThat(roleNamesOf(roles)).containsAll(List.of(
"hs_admin_contact#anothernewcontact.owner",
"hs_admin_contact#anothernewcontact.tenant"));
assertThat(roles.size()).as("invalid number of roles created")
.isEqualTo(initialRoleCount + 2);
assertThat(roleNamesOf(roles)).containsExactlyInAnyOrder(
Array.from(
initialRoleNames,
"hs_admin_contact#anothernewcontact.owner",
"hs_admin_contact#anothernewcontact.admin",
"hs_admin_contact#anothernewcontact.tenant"));
final var grants = grantRepo.findAll();
assertThat(grantDisplaysOf(grants)).containsAll(List.of(
"{ grant assumed role hs_admin_contact#anothernewcontact.owner to user drew@hostsharing.org by role global#global.admin }"));
@ -265,7 +267,7 @@ class HsAdminContactRepositoryIntegrationTest extends ContextBasedTest {
context("alex@hostsharing.net", null);
final var result = contactRepo.findContactByOptionalLabelLike("some temporary contact");
result.forEach(tempPerson -> {
System.out.println("DELETING contact: " + tempPerson.getLabel());
System.out.println("DELETING temporary contact: " + tempPerson.getLabel());
contactRepo.deleteByUuid(tempPerson.getUuid());
});
}

View File

@ -5,9 +5,11 @@ import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.hs.admin.contact.HsAdminContactRepository;
import net.hostsharing.hsadminng.hs.admin.person.HsAdminPersonEntity;
import net.hostsharing.hsadminng.hs.admin.person.HsAdminPersonRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,11 +21,13 @@ import org.springframework.test.annotation.DirtiesContext;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantDisplayExtractor.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleNameExtractor.roleNamesOf;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantDisplayExtractor.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleNameExtractor.roleNamesOf;
import static net.hostsharing.test.JpaAttempt.attempt;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
@ -43,10 +47,10 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
HsAdminContactRepository contactRepo;
@Autowired
RbacRoleRepository roleRepo;
RawRbacRoleRepository rawRoleRepo;
@Autowired
RbacGrantRepository grantRepo;
RawRbacGrantRepository rawGrantRepo;
@Autowired
EntityManager em;
@ -57,6 +61,8 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
@MockBean
HttpServletRequest request;
Set<HsAdminPartnerEntity> tempPartners = new HashSet<>();
@Nested
class CreatePartner {
@ -89,12 +95,13 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
public void createsAndGrantsRoles() {
// given
context("alex@hostsharing.net");
final var initialRoleCount = roleRepo.findAll().size();
final var initialGrantCount = grantRepo.findAll().size();
final var initialRoleCount = rawRoleRepo.findAll().size();
final var initialGrantCount = rawGrantRepo.findAll().size();
final var initialGrantsDisplayNames = grantDisplaysOf(rawGrantRepo.findAll());
// when
attempt(em, () -> {
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erbengemeinschaft Bessler").get(0);
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
final var newPartner = HsAdminPartnerEntity.builder()
.uuid(UUID.randomUUID())
@ -105,21 +112,24 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
});
// then
final var roles = roleRepo.findAll();
assertThat(roleNamesOf(roles)).containsAll(List.of(
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.admin",
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.owner",
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.tenant"));
assertThat(roles.size()).as("invalid number of roles created")
.isEqualTo(initialRoleCount + 3);
context("customer-admin@forthcontact.example.com");
assertThat(grantDisplaysOf(grantRepo.findAll())).containsAll(List.of(
"{ grant assumed role hs_admin_contact#forthcontact.owner to user customer-admin@forthcontact.example.com by role global#global.admin }"));
context("person-ErbengemeinschaftBesslerMelBessl@example.com");
assertThat(grantDisplaysOf(grantRepo.findAll())).containsAll(List.of(
"{ grant assumed role hs_admin_person#ErbengemeinschaftBesslerMelBessler.owner to user person-ErbengemeinschaftBesslerMelBessl@example.com by role global#global.admin }"));
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsAll(List.of(
"hs_admin_partner#ErbenBesslerMelBessler-forthcontact.admin",
"hs_admin_partner#ErbenBesslerMelBessler-forthcontact.owner",
"hs_admin_partner#ErbenBesslerMelBessler-forthcontact.tenant"))
.as("invalid number of roles created")
.hasSize(initialRoleCount + 3);
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsAll(List.of(
"{ grant role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.owner to role global#global.admin by system and assume }",
"{ grant role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.tenant to role hs_admin_contact#forthcontact.admin by system and assume }",
"{ grant perm edit on hs_admin_partner#ErbenBesslerMelBessler-forthcontact to role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.admin by system and assume }",
"{ grant role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.tenant to role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.admin by system and assume }",
"{ grant perm * on hs_admin_partner#ErbenBesslerMelBessler-forthcontact to role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.owner by system and assume }",
"{ grant role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.admin to role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.owner by system and assume }",
"{ grant perm view on hs_admin_partner#ErbenBesslerMelBessler-forthcontact to role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.tenant by system and assume }",
"{ grant role hs_admin_contact#forthcontact.tenant to role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.tenant by system and assume }",
"{ grant role hs_admin_person#ErbenBesslerMelBessler.tenant to role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.tenant by system and assume }",
"{ grant role hs_admin_partner#ErbenBesslerMelBessler-forthcontact.tenant to role hs_admin_person#ErbenBesslerMelBessler.admin by system and assume }"))
.as("invalid number of grants created").hasSize(initialGrantCount + 10);
}
private void assertThatPartnerIsPersisted(final HsAdminPartnerEntity saved) {
@ -199,19 +209,20 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
public void nonGlobalAdmin_canNotDeleteTheirRelatedPartner() {
// given
context("alex@hostsharing.net", null);
final var givenPartner = givenSomeTemporaryPartnerBessler();
final var givenPartner = toCleanup(givenSomeTemporaryPartnerBessler());
// when
final var result = jpaAttempt.transacted(() -> {
context("person-ErbengemeinschaftBesslerMelBessl@example.com");
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent();
context("person-ErbenBesslerMelBessler@example.com");
assumeThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent();
partnerRepo.deleteByUuid(givenPartner.getUuid());
});
// then
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
"[403] User person-ErbengemeinschaftBesslerMelBessl@example.com not allowed to delete partner");
result.assertExceptionWithRootCauseMessage(
JpaSystemException.class,
"[403] User person-ErbenBesslerMelBessler@example.com not allowed to delete partner");
assertThat(jpaAttempt.transacted(() -> {
context("alex@hostsharing.net");
return partnerRepo.findByUuid(givenPartner.getUuid());
@ -222,10 +233,13 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
public void deletingAPartnerAlsoDeletesRelatedRolesAndGrants() {
// given
context("alex@hostsharing.net");
final var initialRoleCount = roleRepo.findAll().size();
final var initialRoleNames = Array.from(roleNamesOf(rawRoleRepo.findAll()));
final var initialGrantNames = Array.from(grantDisplaysOf(rawGrantRepo.findAll()));
final var givenPartner = givenSomeTemporaryPartnerBessler();
assumeThat(roleRepo.findAll().size()).as("unexpected number of roles created")
.isEqualTo(initialRoleCount + 3);;
assumeThat(rawRoleRepo.findAll().size()).as("unexpected number of roles created")
.isEqualTo(initialRoleNames.length + 3);
assumeThat(rawGrantRepo.findAll().size()).as("unexpected number of grants created")
.isEqualTo(initialGrantNames.length + 10);
// when
final var result = jpaAttempt.transacted(() -> {
@ -234,28 +248,23 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
}).assertSuccessful();
// then
final var roles = roleRepo.findAll();
assertThat(roleNamesOf(roles)).doesNotContainAnyElementsOf(List.of(
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.admin",
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.owner",
"hs_admin_partner#ErbengemeinschaftBesslerMelBessler-forthcontact.tenant"));
assertThat(roles.size()).as("invalid number of roles created")
.isEqualTo(initialRoleCount);
final var roles = rawRoleRepo.findAll();
assertThat(roleNamesOf(roles)).containsExactlyInAnyOrder(initialRoleNames);
context("customer-admin@forthcontact.example.com");
assertThat(grantDisplaysOf(grantRepo.findAll())).doesNotContain(
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).doesNotContain(
"{ grant assumed role hs_admin_contact#forthcontact.owner to user customer-admin@forthcontact.example.com by role global#global.admin }");
context("person-ErbengemeinschaftBesslerMelBessl@example.com");
assertThat(grantDisplaysOf(grantRepo.findAll())).doesNotContain(
"{ grant assumed role hs_admin_person#ErbengemeinschaftBesslerMelBessler.owner to user person-ErbengemeinschaftBesslerMelBessl@example.com by role global#global.admin }");
context("person-ErbenBesslerMelBessler@example.com");
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).doesNotContain(
"{ grant assumed role hs_admin_person#ErbenBesslerMelBessler.owner to user person-ErbenBesslerMelBessl@example.com by role global#global.admin }");
}
}
private HsAdminPartnerEntity givenSomeTemporaryPartnerBessler() {
return jpaAttempt.transacted(() -> {
context("alex@hostsharing.net");
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erbengemeinschaft Bessler").get(0);
final var givenPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
final var givenContact = contactRepo.findContactByOptionalLabelLike("forth contact").get(0);
final var newPartner = HsAdminPartnerEntity.builder()
.uuid(UUID.randomUUID())
@ -267,6 +276,21 @@ class HsAdminPartnerRepositoryIntegrationTest extends ContextBasedTest {
}).assertSuccessful().returnedValue();
}
private HsAdminPartnerEntity toCleanup(final HsAdminPartnerEntity tempPartner) {
tempPartners.add(tempPartner);
return tempPartner;
}
@AfterEach
void cleanup() {
context("alex@hostsharing.net", null);
tempPartners.forEach(tempPartner -> {
System.out.println("DELETING temporary partner: " + tempPartner.getDisplayName());
final var count = partnerRepo.deleteByUuid(tempPartner.getUuid());
assertThat(count).isGreaterThan(0);
});
}
void exactlyThesePartnersAreReturned(final List<HsAdminPartnerEntity> actualResult, final String... partnerTradeNames) {
assertThat(actualResult)
.hasSize(partnerTradeNames.length)

View File

@ -2,8 +2,9 @@ package net.hostsharing.hsadminng.hs.admin.person;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.test.Array;
import net.hostsharing.test.JpaAttempt;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Nested;
@ -21,8 +22,8 @@ import java.util.List;
import java.util.function.Supplier;
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.hsadminng.rbac.rbacgrant.RawRbacGrantDisplayExtractor.grantDisplaysOf;
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleNameExtractor.roleNamesOf;
import static net.hostsharing.test.JpaAttempt.attempt;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
@ -36,10 +37,10 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
HsAdminPersonRepository personRepo;
@Autowired
RbacRoleRepository roleRepo;
RawRbacRoleRepository rawRoleRepo;
@Autowired
RbacGrantRepository grantRepo;
RawRbacGrantRepository rawGrantRepo;
@Autowired
EntityManager em;
@ -93,8 +94,8 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
// given
context("drew@hostsharing.org");
final var count = personRepo.count();
final var initialRoleCount = roleRepo.findAll().size();
final var initialGrantCount = grantRepo.findAll().size();
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll());
// when
attempt(em, () -> personRepo.save(
@ -102,17 +103,24 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
).assumeSuccessful();
// then
final var roles = roleRepo.findAll();
assertThat(roleNamesOf(roles)).containsAll(List.of(
"hs_admin_person#anothernewperson.owner",
"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.owner to user drew@hostsharing.org by role global#global.admin }"));
assertThat(grants.size()).as("invalid number of grants created")
.isEqualTo(initialGrantCount + 1);
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(
Array.from(
initialRoleNames,
"hs_admin_person#anothernewperson.owner",
"hs_admin_person#anothernewperson.admin",
"hs_admin_person#anothernewperson.tenant"
));
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(
Array.from(
initialGrantNames,
"{ grant role hs_admin_person#anothernewperson.owner to role global#global.admin by system and assume }",
"{ grant perm edit on hs_admin_person#anothernewperson to role hs_admin_person#anothernewperson.admin by system and assume }",
"{ grant role hs_admin_person#anothernewperson.tenant to role hs_admin_person#anothernewperson.admin by system and assume }",
"{ grant perm * on hs_admin_person#anothernewperson to role hs_admin_person#anothernewperson.owner by system and assume }",
"{ grant role hs_admin_person#anothernewperson.admin to role hs_admin_person#anothernewperson.owner by system and assume }",
"{ grant perm view on hs_admin_person#anothernewperson to role hs_admin_person#anothernewperson.tenant by system and assume }",
"{ grant role hs_admin_person#anothernewperson.owner to user drew@hostsharing.org by global#global.admin and assume }"
));
}
private void assertThatPersonIsPersisted(final HsAdminPersonEntity saved) {
@ -137,8 +145,8 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
result,
"Peter, Smith",
"Rockshop e.K.",
"Ostfriesische Stahlhandel OHG",
"Erbengemeinschaft Bessler");
"Ostfriesische Kuhhandel OHG",
"Erben Bessler");
}
@Test
@ -231,25 +239,25 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
public void deletingAPersonAlsoDeletesRelatedRolesAndGrants() {
// given
context("drew@hostsharing.org", null);
final var initialRoleCount = roleRepo.findAll().size();
final var initialGrantCount = grantRepo.findAll().size();
final var initialRoleNames = roleNamesOf(rawRoleRepo.findAll());
final var initialGrantNames = grantDisplaysOf(rawGrantRepo.findAll());
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);
assumeThat(rawRoleRepo.findAll().size()).as("unexpected number of roles created")
.isEqualTo(initialRoleNames.size() + 3);
assumeThat(rawGrantRepo.findAll().size()).as("unexpected number of grants created")
.isEqualTo(initialGrantNames.size() + 7);
// when
final var result = jpaAttempt.transacted(() -> {
context("drew@hostsharing.org", null);
personRepo.deleteByUuid(givenPerson.getUuid());
}).assumeSuccessful();
return personRepo.deleteByUuid(givenPerson.getUuid());
});
// 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);
result.assertSuccessful();
assertThat(result.returnedValue()).isEqualTo(1);
assertThat(roleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(initialRoleNames));
assertThat(grantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.from(initialGrantNames));
}
}
@ -258,7 +266,7 @@ class HsAdminPersonRepositoryIntegrationTest extends ContextBasedTest {
context("alex@hostsharing.net", null);
final var result = personRepo.findPersonByOptionalNameLike("some temporary person");
result.forEach(tempPerson -> {
System.out.println("DELETING person: " + tempPerson.getDisplayName());
System.out.println("DELETING temporary person: " + tempPerson.getDisplayName());
personRepo.deleteByUuid(tempPerson.getUuid());
});
}

View File

@ -1,8 +1,12 @@
package net.hostsharing.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Java has List.of(...), Set.of(...) and Map.of(...) all with varargs parameter,
* but no Array.of(...). Here it is.
* Java has List.of(...), Set.of(...) and Map.of(...) all with varargs parameter,
* but no Array.of(...). Here it is.
*/
public class Array {
@ -10,4 +14,17 @@ public class Array {
public static <E> E[] of(E... elements) {
return elements;
}
public static String[] from(final List<String> initialList, final String... additionalStrings) {
final var resultList = new ArrayList<>(initialList);
resultList.addAll(Arrays.asList(additionalStrings));
return resultList.toArray(String[]::new);
}
public static String[] from(final String[] initialStrings, final String... additionalStrings) {
final var resultList = Arrays.asList(initialStrings);
resultList.addAll(Arrays.asList(additionalStrings));
return resultList.toArray(String[]::new);
}
}