diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntityUnitTest.java index acd6c8f3..6367c56e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntityUnitTest.java @@ -1,5 +1,6 @@ package net.hostsharing.hsadminng.hs.office.bankaccount; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -32,4 +33,48 @@ class HsOfficeBankAccountEntityUnitTest { assertThat(givenBankAccount.toShortString()).isEqualTo("given holder"); } + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeBankAccountEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph bankAccount["`**bankAccount**`"] + direction TB + style bankAccount fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph bankAccount:roles[ ] + style bankAccount:roles fill:#dd4901,stroke:white + + role:bankAccount:OWNER[[bankAccount:OWNER]] + role:bankAccount:ADMIN[[bankAccount:ADMIN]] + role:bankAccount:REFERRER[[bankAccount:REFERRER]] + end + + subgraph bankAccount:permissions[ ] + style bankAccount:permissions fill:#dd4901,stroke:white + + perm:bankAccount:INSERT{{bankAccount:INSERT}} + perm:bankAccount:DELETE{{bankAccount:DELETE}} + perm:bankAccount:UPDATE{{bankAccount:UPDATE}} + perm:bankAccount:SELECT{{bankAccount:SELECT}} + end + end + + %% granting roles to users + user:creator ==> role:bankAccount:OWNER + + %% granting roles to roles + role:rbac.global:ADMIN ==> role:bankAccount:OWNER + role:bankAccount:OWNER ==> role:bankAccount:ADMIN + role:bankAccount:ADMIN ==> role:bankAccount:REFERRER + + %% granting permissions to roles + role:rbac.global:GUEST ==> perm:bankAccount:INSERT + role:bankAccount:OWNER ==> perm:bankAccount:DELETE + role:bankAccount:ADMIN ==> perm:bankAccount:UPDATE + role:bankAccount:REFERRER ==> perm:bankAccount:SELECT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactUnitTest.java index 94f8e0b8..de61688a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactUnitTest.java @@ -1,5 +1,6 @@ package net.hostsharing.hsadminng.hs.office.contact; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -18,4 +19,48 @@ class HsOfficeContactUnitTest { assertThat("" + givenContact).isEqualTo("contact(caption='given caption')"); } + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeContactRbacEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph contact["`**contact**`"] + direction TB + style contact fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph contact:roles[ ] + style contact:roles fill:#dd4901,stroke:white + + role:contact:OWNER[[contact:OWNER]] + role:contact:ADMIN[[contact:ADMIN]] + role:contact:REFERRER[[contact:REFERRER]] + end + + subgraph contact:permissions[ ] + style contact:permissions fill:#dd4901,stroke:white + + perm:contact:DELETE{{contact:DELETE}} + perm:contact:UPDATE{{contact:UPDATE}} + perm:contact:SELECT{{contact:SELECT}} + perm:contact:INSERT{{contact:INSERT}} + end + end + + %% granting roles to users + user:creator ==> role:contact:OWNER + + %% granting roles to roles + role:rbac.global:ADMIN ==> role:contact:OWNER + role:contact:OWNER ==> role:contact:ADMIN + role:contact:ADMIN ==> role:contact:REFERRER + + %% granting permissions to roles + role:contact:OWNER ==> perm:contact:DELETE + role:contact:ADMIN ==> perm:contact:UPDATE + role:contact:REFERRER ==> perm:contact:SELECT + role:rbac.global:GUEST ==> perm:contact:INSERT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java index aada2552..09f704d6 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopassets/HsOfficeCoopAssetsTransactionEntityUnitTest.java @@ -1,5 +1,6 @@ package net.hostsharing.hsadminng.hs.office.coopassets; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import java.math.BigDecimal; @@ -68,4 +69,123 @@ class HsOfficeCoopAssetsTransactionEntityUnitTest { assertThat(result).isEqualTo("M-???????:nul:+0.00"); } + + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeCoopAssetsTransactionEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph coopAssetsTransaction["`**coopAssetsTransaction**`"] + direction TB + style coopAssetsTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph coopAssetsTransaction:permissions[ ] + style coopAssetsTransaction:permissions fill:#dd4901,stroke:white + + perm:coopAssetsTransaction:INSERT{{coopAssetsTransaction:INSERT}} + perm:coopAssetsTransaction:UPDATE{{coopAssetsTransaction:UPDATE}} + perm:coopAssetsTransaction:SELECT{{coopAssetsTransaction:SELECT}} + end + end + + subgraph membership["`**membership**`"] + direction TB + style membership fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership:roles[ ] + style membership:roles fill:#99bcdb,stroke:white + + role:membership:OWNER[[membership:OWNER]] + role:membership:ADMIN[[membership:ADMIN]] + role:membership:AGENT[[membership:AGENT]] + end + end + + subgraph membership.partnerRel["`**membership.partnerRel**`"] + direction TB + style membership.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel:roles[ ] + style membership.partnerRel:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel:OWNER[[membership.partnerRel:OWNER]] + role:membership.partnerRel:ADMIN[[membership.partnerRel:ADMIN]] + role:membership.partnerRel:AGENT[[membership.partnerRel:AGENT]] + role:membership.partnerRel:TENANT[[membership.partnerRel:TENANT]] + end + end + + subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"] + direction TB + style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel.anchorPerson:roles[ ] + style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]] + role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]] + role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]] + end + end + + subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"] + direction TB + style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel.contact:roles[ ] + style membership.partnerRel.contact:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel.contact:OWNER[[membership.partnerRel.contact:OWNER]] + role:membership.partnerRel.contact:ADMIN[[membership.partnerRel.contact:ADMIN]] + role:membership.partnerRel.contact:REFERRER[[membership.partnerRel.contact:REFERRER]] + end + end + + subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"] + direction TB + style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel.holderPerson:roles[ ] + style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]] + role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]] + role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]] + end + end + + %% granting roles to roles + role:rbac.global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER + role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN + role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel.anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:membership.partnerRel.holderPerson:OWNER + role:membership.partnerRel.holderPerson:OWNER -.-> role:membership.partnerRel.holderPerson:ADMIN + role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel.holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:membership.partnerRel.contact:OWNER + role:membership.partnerRel.contact:OWNER -.-> role:membership.partnerRel.contact:ADMIN + role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel.contact:REFERRER + role:rbac.global:ADMIN -.-> role:membership.partnerRel:OWNER + role:membership.partnerRel:OWNER -.-> role:membership.partnerRel:ADMIN + role:membership.partnerRel:ADMIN -.-> role:membership.partnerRel:AGENT + role:membership.partnerRel:AGENT -.-> role:membership.partnerRel:TENANT + role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel:TENANT + role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.anchorPerson:REFERRER + role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER + role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER + role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:OWNER + role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT + role:membership:OWNER -.-> role:membership:ADMIN + role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN + role:membership:ADMIN -.-> role:membership:AGENT + role:membership.partnerRel:AGENT -.-> role:membership:AGENT + role:membership:AGENT -.-> role:membership.partnerRel:TENANT + + %% granting permissions to roles + role:membership:ADMIN ==> perm:coopAssetsTransaction:INSERT + role:membership:ADMIN ==> perm:coopAssetsTransaction:UPDATE + role:membership:AGENT ==> perm:coopAssetsTransaction:SELECT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java index 08a2718d..6d15cb78 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/coopshares/HsOfficeCoopSharesTransactionEntityUnitTest.java @@ -1,5 +1,6 @@ package net.hostsharing.hsadminng.hs.office.coopshares; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import java.time.LocalDate; @@ -67,4 +68,123 @@ class HsOfficeCoopSharesTransactionEntityUnitTest { assertThat(result).isEqualTo("null:nul:+0"); } + + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeCoopSharesTransactionEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph coopSharesTransaction["`**coopSharesTransaction**`"] + direction TB + style coopSharesTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph coopSharesTransaction:permissions[ ] + style coopSharesTransaction:permissions fill:#dd4901,stroke:white + + perm:coopSharesTransaction:INSERT{{coopSharesTransaction:INSERT}} + perm:coopSharesTransaction:UPDATE{{coopSharesTransaction:UPDATE}} + perm:coopSharesTransaction:SELECT{{coopSharesTransaction:SELECT}} + end + end + + subgraph membership["`**membership**`"] + direction TB + style membership fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership:roles[ ] + style membership:roles fill:#99bcdb,stroke:white + + role:membership:OWNER[[membership:OWNER]] + role:membership:ADMIN[[membership:ADMIN]] + role:membership:AGENT[[membership:AGENT]] + end + end + + subgraph membership.partnerRel["`**membership.partnerRel**`"] + direction TB + style membership.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel:roles[ ] + style membership.partnerRel:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel:OWNER[[membership.partnerRel:OWNER]] + role:membership.partnerRel:ADMIN[[membership.partnerRel:ADMIN]] + role:membership.partnerRel:AGENT[[membership.partnerRel:AGENT]] + role:membership.partnerRel:TENANT[[membership.partnerRel:TENANT]] + end + end + + subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"] + direction TB + style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel.anchorPerson:roles[ ] + style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]] + role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]] + role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]] + end + end + + subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"] + direction TB + style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel.contact:roles[ ] + style membership.partnerRel.contact:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel.contact:OWNER[[membership.partnerRel.contact:OWNER]] + role:membership.partnerRel.contact:ADMIN[[membership.partnerRel.contact:ADMIN]] + role:membership.partnerRel.contact:REFERRER[[membership.partnerRel.contact:REFERRER]] + end + end + + subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"] + direction TB + style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph membership.partnerRel.holderPerson:roles[ ] + style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white + + role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]] + role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]] + role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]] + end + end + + %% granting roles to roles + role:rbac.global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER + role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN + role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel.anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:membership.partnerRel.holderPerson:OWNER + role:membership.partnerRel.holderPerson:OWNER -.-> role:membership.partnerRel.holderPerson:ADMIN + role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel.holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:membership.partnerRel.contact:OWNER + role:membership.partnerRel.contact:OWNER -.-> role:membership.partnerRel.contact:ADMIN + role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel.contact:REFERRER + role:rbac.global:ADMIN -.-> role:membership.partnerRel:OWNER + role:membership.partnerRel:OWNER -.-> role:membership.partnerRel:ADMIN + role:membership.partnerRel:ADMIN -.-> role:membership.partnerRel:AGENT + role:membership.partnerRel:AGENT -.-> role:membership.partnerRel:TENANT + role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel:TENANT + role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.anchorPerson:REFERRER + role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER + role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER + role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:OWNER + role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT + role:membership:OWNER -.-> role:membership:ADMIN + role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN + role:membership:ADMIN -.-> role:membership:AGENT + role:membership.partnerRel:AGENT -.-> role:membership:AGENT + role:membership:AGENT -.-> role:membership.partnerRel:TENANT + + %% granting permissions to roles + role:membership:ADMIN ==> perm:coopSharesTransaction:INSERT + role:membership:ADMIN ==> perm:coopSharesTransaction:UPDATE + role:membership:AGENT ==> perm:coopSharesTransaction:SELECT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java index 5dc61235..f11856d4 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorEntityUnitTest.java @@ -5,6 +5,8 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; +import net.hostsharing.hsadminng.rbac.test.cust.TestCustomerEntity; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -109,4 +111,200 @@ class HsOfficeDebitorEntityUnitTest { assertThat(result).isNull(); } + + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeDebitorEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph debitor["`**debitor**`"] + direction TB + style debitor fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph debitor:permissions[ ] + style debitor:permissions fill:#dd4901,stroke:white + + perm:debitor:INSERT{{debitor:INSERT}} + perm:debitor:DELETE{{debitor:DELETE}} + perm:debitor:UPDATE{{debitor:UPDATE}} + perm:debitor:SELECT{{debitor:SELECT}} + end + + subgraph debitorRel["`**debitorRel**`"] + direction TB + style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel:roles[ ] + style debitorRel:roles fill:#99bcdb,stroke:white + + role:debitorRel:OWNER[[debitorRel:OWNER]] + role:debitorRel:ADMIN[[debitorRel:ADMIN]] + role:debitorRel:AGENT[[debitorRel:AGENT]] + role:debitorRel:TENANT[[debitorRel:TENANT]] + end + end + end + + subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"] + direction TB + style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel.anchorPerson:roles[ ] + style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white + + role:debitorRel.anchorPerson:OWNER[[debitorRel.anchorPerson:OWNER]] + role:debitorRel.anchorPerson:ADMIN[[debitorRel.anchorPerson:ADMIN]] + role:debitorRel.anchorPerson:REFERRER[[debitorRel.anchorPerson:REFERRER]] + end + end + + subgraph debitorRel.contact["`**debitorRel.contact**`"] + direction TB + style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel.contact:roles[ ] + style debitorRel.contact:roles fill:#99bcdb,stroke:white + + role:debitorRel.contact:OWNER[[debitorRel.contact:OWNER]] + role:debitorRel.contact:ADMIN[[debitorRel.contact:ADMIN]] + role:debitorRel.contact:REFERRER[[debitorRel.contact:REFERRER]] + end + end + + subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"] + direction TB + style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel.holderPerson:roles[ ] + style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white + + role:debitorRel.holderPerson:OWNER[[debitorRel.holderPerson:OWNER]] + role:debitorRel.holderPerson:ADMIN[[debitorRel.holderPerson:ADMIN]] + role:debitorRel.holderPerson:REFERRER[[debitorRel.holderPerson:REFERRER]] + end + end + + subgraph partnerRel["`**partnerRel**`"] + direction TB + style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel:roles[ ] + style partnerRel:roles fill:#99bcdb,stroke:white + + role:partnerRel:OWNER[[partnerRel:OWNER]] + role:partnerRel:ADMIN[[partnerRel:ADMIN]] + role:partnerRel:AGENT[[partnerRel:AGENT]] + role:partnerRel:TENANT[[partnerRel:TENANT]] + end + end + + subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"] + direction TB + style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.anchorPerson:roles[ ] + style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white + + role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]] + role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]] + role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]] + end + end + + subgraph partnerRel.contact["`**partnerRel.contact**`"] + direction TB + style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.contact:roles[ ] + style partnerRel.contact:roles fill:#99bcdb,stroke:white + + role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]] + role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]] + role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]] + end + end + + subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"] + direction TB + style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.holderPerson:roles[ ] + style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white + + role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]] + role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]] + role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]] + end + end + + subgraph refundBankAccount["`**refundBankAccount**`"] + direction TB + style refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph refundBankAccount:roles[ ] + style refundBankAccount:roles fill:#99bcdb,stroke:white + + role:refundBankAccount:OWNER[[refundBankAccount:OWNER]] + role:refundBankAccount:ADMIN[[refundBankAccount:ADMIN]] + role:refundBankAccount:REFERRER[[refundBankAccount:REFERRER]] + end + end + + %% granting roles to roles + role:rbac.global:ADMIN -.-> role:debitorRel.anchorPerson:OWNER + role:debitorRel.anchorPerson:OWNER -.-> role:debitorRel.anchorPerson:ADMIN + role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel.anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:debitorRel.holderPerson:OWNER + role:debitorRel.holderPerson:OWNER -.-> role:debitorRel.holderPerson:ADMIN + role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel.holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:debitorRel.contact:OWNER + role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN + role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER + role:rbac.global:ADMIN -.-> role:debitorRel:OWNER + role:debitorRel:OWNER -.-> role:debitorRel:ADMIN + role:debitorRel:ADMIN -.-> role:debitorRel:AGENT + role:debitorRel:AGENT -.-> role:debitorRel:TENANT + role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT + role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER + role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER + role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER + role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:OWNER + role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT + role:rbac.global:ADMIN -.-> role:refundBankAccount:OWNER + role:refundBankAccount:OWNER -.-> role:refundBankAccount:ADMIN + role:refundBankAccount:ADMIN -.-> role:refundBankAccount:REFERRER + role:refundBankAccount:ADMIN ==> role:debitorRel:AGENT + role:debitorRel:AGENT ==> role:refundBankAccount:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER + role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN + role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel.holderPerson:OWNER + role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN + role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel.contact:OWNER + role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN + role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel:OWNER + role:partnerRel:OWNER -.-> role:partnerRel:ADMIN + role:partnerRel:ADMIN -.-> role:partnerRel:AGENT + role:partnerRel:AGENT -.-> role:partnerRel:TENANT + role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT + role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER + role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER + role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER + role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:OWNER + role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT + role:partnerRel:ADMIN ==> role:debitorRel:ADMIN + role:partnerRel:AGENT ==> role:debitorRel:AGENT + role:debitorRel:AGENT ==> role:partnerRel:TENANT + + %% granting permissions to roles + role:rbac.global:ADMIN ==> perm:debitor:INSERT + role:debitorRel:OWNER ==> perm:debitor:DELETE + role:debitorRel:ADMIN ==> perm:debitor:UPDATE + role:debitorRel:TENANT ==> perm:debitor:SELECT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java index b2e5bb68..bd65db75 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntityUnitTest.java @@ -1,7 +1,9 @@ package net.hostsharing.hsadminng.hs.office.membership; import io.hypersistence.utils.hibernate.type.range.Range; +import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import jakarta.persistence.PrePersist; @@ -98,7 +100,126 @@ class HsOfficeMembershipEntityUnitTest { givenMembership.setValidTo(LocalDate.parse("2024-12-31")); assertThat(givenMembership.getValidFrom()).isEqualTo(GIVEN_VALID_FROM); assertThat(givenMembership.getValidTo()).isEqualTo(LocalDate.parse("2024-12-31")); + } + + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeMembershipEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph membership["`**membership**`"] + direction TB + style membership fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph membership:roles[ ] + style membership:roles fill:#dd4901,stroke:white + + role:membership:OWNER[[membership:OWNER]] + role:membership:ADMIN[[membership:ADMIN]] + role:membership:AGENT[[membership:AGENT]] + end + + subgraph membership:permissions[ ] + style membership:permissions fill:#dd4901,stroke:white + + perm:membership:INSERT{{membership:INSERT}} + perm:membership:DELETE{{membership:DELETE}} + perm:membership:UPDATE{{membership:UPDATE}} + perm:membership:SELECT{{membership:SELECT}} + end + end + + subgraph partnerRel["`**partnerRel**`"] + direction TB + style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel:roles[ ] + style partnerRel:roles fill:#99bcdb,stroke:white + + role:partnerRel:OWNER[[partnerRel:OWNER]] + role:partnerRel:ADMIN[[partnerRel:ADMIN]] + role:partnerRel:AGENT[[partnerRel:AGENT]] + role:partnerRel:TENANT[[partnerRel:TENANT]] + end + end + + subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"] + direction TB + style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.anchorPerson:roles[ ] + style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white + + role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]] + role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]] + role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]] + end + end + + subgraph partnerRel.contact["`**partnerRel.contact**`"] + direction TB + style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.contact:roles[ ] + style partnerRel.contact:roles fill:#99bcdb,stroke:white + + role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]] + role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]] + role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]] + end + end + + subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"] + direction TB + style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.holderPerson:roles[ ] + style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white + + role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]] + role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]] + role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]] + end + end + + %% granting roles to users + user:creator ==> role:membership:OWNER + + %% granting roles to roles + role:rbac.global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER + role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN + role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel.holderPerson:OWNER + role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN + role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel.contact:OWNER + role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN + role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel:OWNER + role:partnerRel:OWNER -.-> role:partnerRel:ADMIN + role:partnerRel:ADMIN -.-> role:partnerRel:AGENT + role:partnerRel:AGENT -.-> role:partnerRel:TENANT + role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT + role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER + role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER + role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER + role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:OWNER + role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT + role:membership:OWNER ==> role:membership:ADMIN + role:partnerRel:ADMIN ==> role:membership:ADMIN + role:membership:ADMIN ==> role:membership:AGENT + role:partnerRel:AGENT ==> role:membership:AGENT + role:membership:AGENT ==> role:partnerRel:TENANT + + %% granting permissions to roles + role:rbac.global:ADMIN ==> perm:membership:INSERT + role:membership:ADMIN ==> perm:membership:DELETE + role:membership:ADMIN ==> perm:membership:UPDATE + role:membership:AGENT ==> perm:membership:SELECT + """); } private static void invokePrePersist(final HsOfficeMembershipEntity membershipEntity) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java index 3cf07cab..33c83df7 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerEntityUnitTest.java @@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -38,4 +39,123 @@ class HsOfficePartnerEntityUnitTest { final var result = givenPartner.toShortString(); assertThat(result).isEqualTo("P-12345"); } + + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePartnerEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph partner["`**partner**`"] + direction TB + style partner fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph partner:permissions[ ] + style partner:permissions fill:#dd4901,stroke:white + + perm:partner:INSERT{{partner:INSERT}} + perm:partner:DELETE{{partner:DELETE}} + perm:partner:UPDATE{{partner:UPDATE}} + perm:partner:SELECT{{partner:SELECT}} + end + + subgraph partnerRel["`**partnerRel**`"] + direction TB + style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel:roles[ ] + style partnerRel:roles fill:#99bcdb,stroke:white + + role:partnerRel:OWNER[[partnerRel:OWNER]] + role:partnerRel:ADMIN[[partnerRel:ADMIN]] + role:partnerRel:AGENT[[partnerRel:AGENT]] + role:partnerRel:TENANT[[partnerRel:TENANT]] + end + end + end + + subgraph partnerDetails["`**partnerDetails**`"] + direction TB + style partnerDetails fill:#feb28c,stroke:#274d6e,stroke-width:8px + + subgraph partnerDetails:permissions[ ] + style partnerDetails:permissions fill:#feb28c,stroke:white + + perm:partnerDetails:DELETE{{partnerDetails:DELETE}} + perm:partnerDetails:UPDATE{{partnerDetails:UPDATE}} + perm:partnerDetails:SELECT{{partnerDetails:SELECT}} + end + end + + subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"] + direction TB + style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.anchorPerson:roles[ ] + style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white + + role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]] + role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]] + role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]] + end + end + + subgraph partnerRel.contact["`**partnerRel.contact**`"] + direction TB + style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.contact:roles[ ] + style partnerRel.contact:roles fill:#99bcdb,stroke:white + + role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]] + role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]] + role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]] + end + end + + subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"] + direction TB + style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph partnerRel.holderPerson:roles[ ] + style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white + + role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]] + role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]] + role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]] + end + end + + %% granting roles to roles + role:rbac.global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER + role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN + role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel.holderPerson:OWNER + role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN + role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel.contact:OWNER + role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN + role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER + role:rbac.global:ADMIN -.-> role:partnerRel:OWNER + role:partnerRel:OWNER -.-> role:partnerRel:ADMIN + role:partnerRel:ADMIN -.-> role:partnerRel:AGENT + role:partnerRel:AGENT -.-> role:partnerRel:TENANT + role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT + role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER + role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER + role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER + role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:OWNER + role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT + + %% granting permissions to roles + role:rbac.global:ADMIN ==> perm:partner:INSERT + role:partnerRel:OWNER ==> perm:partner:DELETE + role:partnerRel:ADMIN ==> perm:partner:UPDATE + role:partnerRel:TENANT ==> perm:partner:SELECT + role:partnerRel:OWNER ==> perm:partnerDetails:DELETE + role:partnerRel:AGENT ==> perm:partnerDetails:UPDATE + role:partnerRel:AGENT ==> perm:partnerDetails:SELECT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntityUnitTest.java index 199e7f23..f015b10e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntityUnitTest.java @@ -1,5 +1,7 @@ package net.hostsharing.hsadminng.hs.office.person; +import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import java.util.UUID; @@ -155,6 +157,7 @@ class HsOfficePersonEntityUnitTest { assertThat(actualDisplay).isEqualTo("person(salutation='Herr', familyName='some family name', givenName='some given name')"); } + @Test void toStringWithoutSalutationAndWithTitleSkipsSalutation() { final var givenPersonEntity = HsOfficePersonEntity.builder() @@ -168,4 +171,48 @@ class HsOfficePersonEntityUnitTest { assertThat(actualDisplay).isEqualTo("person(title='some title', familyName='some family name', givenName='some given name')"); } + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficePersonEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph person["`**person**`"] + direction TB + style person fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph person:roles[ ] + style person:roles fill:#dd4901,stroke:white + + role:person:OWNER[[person:OWNER]] + role:person:ADMIN[[person:ADMIN]] + role:person:REFERRER[[person:REFERRER]] + end + + subgraph person:permissions[ ] + style person:permissions fill:#dd4901,stroke:white + + perm:person:INSERT{{person:INSERT}} + perm:person:DELETE{{person:DELETE}} + perm:person:UPDATE{{person:UPDATE}} + perm:person:SELECT{{person:SELECT}} + end + end + + %% granting roles to users + user:creator ==> role:person:OWNER + + %% granting roles to roles + role:rbac.global:ADMIN ==> role:person:OWNER + role:person:OWNER ==> role:person:ADMIN + role:person:ADMIN ==> role:person:REFERRER + + %% granting permissions to roles + role:rbac.global:GUEST ==> perm:person:INSERT + role:person:OWNER ==> perm:person:DELETE + role:person:ADMIN ==> perm:person:UPDATE + role:person:REFERRER ==> perm:person:SELECT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationUnitTest.java index a422a8b6..96ebc37c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationUnitTest.java @@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.office.relation; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -40,4 +41,103 @@ class HsOfficeRelationUnitTest { assertThat(given.toShortString()).isEqualTo("rel(anchor='LP some trade name', type='REPRESENTATIVE', holder='NP Meier, Mellie')"); } + + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeRelationRbacEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph anchorPerson["`**anchorPerson**`"] + direction TB + style anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph anchorPerson:roles[ ] + style anchorPerson:roles fill:#99bcdb,stroke:white + + role:anchorPerson:OWNER[[anchorPerson:OWNER]] + role:anchorPerson:ADMIN[[anchorPerson:ADMIN]] + role:anchorPerson:REFERRER[[anchorPerson:REFERRER]] + end + end + + subgraph contact["`**contact**`"] + direction TB + style contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph contact:roles[ ] + style contact:roles fill:#99bcdb,stroke:white + + role:contact:OWNER[[contact:OWNER]] + role:contact:ADMIN[[contact:ADMIN]] + role:contact:REFERRER[[contact:REFERRER]] + end + end + + subgraph holderPerson["`**holderPerson**`"] + direction TB + style holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph holderPerson:roles[ ] + style holderPerson:roles fill:#99bcdb,stroke:white + + role:holderPerson:OWNER[[holderPerson:OWNER]] + role:holderPerson:ADMIN[[holderPerson:ADMIN]] + role:holderPerson:REFERRER[[holderPerson:REFERRER]] + end + end + + subgraph relation["`**relation**`"] + direction TB + style relation fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph relation:roles[ ] + style relation:roles fill:#dd4901,stroke:white + + role:relation:OWNER[[relation:OWNER]] + role:relation:ADMIN[[relation:ADMIN]] + role:relation:AGENT[[relation:AGENT]] + role:relation:TENANT[[relation:TENANT]] + end + + subgraph relation:permissions[ ] + style relation:permissions fill:#dd4901,stroke:white + + perm:relation:DELETE{{relation:DELETE}} + perm:relation:UPDATE{{relation:UPDATE}} + perm:relation:SELECT{{relation:SELECT}} + perm:relation:INSERT{{relation:INSERT}} + end + end + + %% granting roles to users + user:creator ==> role:relation:OWNER + + %% granting roles to roles + role:rbac.global:ADMIN -.-> role:anchorPerson:OWNER + role:anchorPerson:OWNER -.-> role:anchorPerson:ADMIN + role:anchorPerson:ADMIN -.-> role:anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:holderPerson:OWNER + role:holderPerson:OWNER -.-> role:holderPerson:ADMIN + role:holderPerson:ADMIN -.-> role:holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:contact:OWNER + role:contact:OWNER -.-> role:contact:ADMIN + role:contact:ADMIN -.-> role:contact:REFERRER + role:rbac.global:ADMIN ==> role:relation:OWNER + role:relation:OWNER ==> role:relation:ADMIN + role:relation:ADMIN ==> role:relation:AGENT + role:relation:AGENT ==> role:relation:TENANT + role:contact:ADMIN ==> role:relation:TENANT + role:relation:TENANT ==> role:anchorPerson:REFERRER + role:relation:TENANT ==> role:holderPerson:REFERRER + role:relation:TENANT ==> role:contact:REFERRER + + %% granting permissions to roles + role:relation:OWNER ==> perm:relation:DELETE + role:relation:ADMIN ==> perm:relation:UPDATE + role:relation:TENANT ==> perm:relation:SELECT + role:anchorPerson:ADMIN ==> perm:relation:INSERT + """); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityUnitTest.java index aaa40e7c..e3ca9feb 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntityUnitTest.java @@ -1,6 +1,8 @@ package net.hostsharing.hsadminng.hs.office.sepamandate; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; +import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; +import net.hostsharing.hsadminng.rbac.generator.RbacViewMermaidFlowchartGenerator; import org.junit.jupiter.api.Test; import java.time.LocalDate; @@ -49,4 +51,143 @@ class HsOfficeSepaMandateEntityUnitTest { assertThat(givenSepaMandate.getValidTo()).isEqualTo(LocalDate.parse("2024-12-31")); } + @Test + void definesRbac() { + final var rbacFlowchart = new RbacViewMermaidFlowchartGenerator(HsOfficeSepaMandateEntity.rbac()).toString(); + assertThat(rbacFlowchart).isEqualTo(""" + %%{init:{'flowchart':{'htmlLabels':false}}}%% + flowchart TB + + subgraph bankAccount["`**bankAccount**`"] + direction TB + style bankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph bankAccount:roles[ ] + style bankAccount:roles fill:#99bcdb,stroke:white + + role:bankAccount:OWNER[[bankAccount:OWNER]] + role:bankAccount:ADMIN[[bankAccount:ADMIN]] + role:bankAccount:REFERRER[[bankAccount:REFERRER]] + end + end + + subgraph debitorRel["`**debitorRel**`"] + direction TB + style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel:roles[ ] + style debitorRel:roles fill:#99bcdb,stroke:white + + role:debitorRel:OWNER[[debitorRel:OWNER]] + role:debitorRel:ADMIN[[debitorRel:ADMIN]] + role:debitorRel:AGENT[[debitorRel:AGENT]] + role:debitorRel:TENANT[[debitorRel:TENANT]] + end + end + + subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"] + direction TB + style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel.anchorPerson:roles[ ] + style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white + + role:debitorRel.anchorPerson:OWNER[[debitorRel.anchorPerson:OWNER]] + role:debitorRel.anchorPerson:ADMIN[[debitorRel.anchorPerson:ADMIN]] + role:debitorRel.anchorPerson:REFERRER[[debitorRel.anchorPerson:REFERRER]] + end + end + + subgraph debitorRel.contact["`**debitorRel.contact**`"] + direction TB + style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel.contact:roles[ ] + style debitorRel.contact:roles fill:#99bcdb,stroke:white + + role:debitorRel.contact:OWNER[[debitorRel.contact:OWNER]] + role:debitorRel.contact:ADMIN[[debitorRel.contact:ADMIN]] + role:debitorRel.contact:REFERRER[[debitorRel.contact:REFERRER]] + end + end + + subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"] + direction TB + style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px + + subgraph debitorRel.holderPerson:roles[ ] + style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white + + role:debitorRel.holderPerson:OWNER[[debitorRel.holderPerson:OWNER]] + role:debitorRel.holderPerson:ADMIN[[debitorRel.holderPerson:ADMIN]] + role:debitorRel.holderPerson:REFERRER[[debitorRel.holderPerson:REFERRER]] + end + end + + subgraph sepaMandate["`**sepaMandate**`"] + direction TB + style sepaMandate fill:#dd4901,stroke:#274d6e,stroke-width:8px + + subgraph sepaMandate:roles[ ] + style sepaMandate:roles fill:#dd4901,stroke:white + + role:sepaMandate:OWNER[[sepaMandate:OWNER]] + role:sepaMandate:ADMIN[[sepaMandate:ADMIN]] + role:sepaMandate:AGENT[[sepaMandate:AGENT]] + role:sepaMandate:REFERRER[[sepaMandate:REFERRER]] + end + + subgraph sepaMandate:permissions[ ] + style sepaMandate:permissions fill:#dd4901,stroke:white + + perm:sepaMandate:DELETE{{sepaMandate:DELETE}} + perm:sepaMandate:UPDATE{{sepaMandate:UPDATE}} + perm:sepaMandate:SELECT{{sepaMandate:SELECT}} + perm:sepaMandate:INSERT{{sepaMandate:INSERT}} + end + end + + %% granting roles to users + user:creator ==> role:sepaMandate:OWNER + + %% granting roles to roles + role:rbac.global:ADMIN -.-> role:debitorRel.anchorPerson:OWNER + role:debitorRel.anchorPerson:OWNER -.-> role:debitorRel.anchorPerson:ADMIN + role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel.anchorPerson:REFERRER + role:rbac.global:ADMIN -.-> role:debitorRel.holderPerson:OWNER + role:debitorRel.holderPerson:OWNER -.-> role:debitorRel.holderPerson:ADMIN + role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel.holderPerson:REFERRER + role:rbac.global:ADMIN -.-> role:debitorRel.contact:OWNER + role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN + role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER + role:rbac.global:ADMIN -.-> role:debitorRel:OWNER + role:debitorRel:OWNER -.-> role:debitorRel:ADMIN + role:debitorRel:ADMIN -.-> role:debitorRel:AGENT + role:debitorRel:AGENT -.-> role:debitorRel:TENANT + role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT + role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER + role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER + role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER + role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:OWNER + role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT + role:rbac.global:ADMIN -.-> role:bankAccount:OWNER + role:bankAccount:OWNER -.-> role:bankAccount:ADMIN + role:bankAccount:ADMIN -.-> role:bankAccount:REFERRER + role:rbac.global:ADMIN ==> role:sepaMandate:OWNER + role:sepaMandate:OWNER ==> role:sepaMandate:ADMIN + role:sepaMandate:ADMIN ==> role:sepaMandate:AGENT + role:sepaMandate:AGENT ==> role:bankAccount:REFERRER + role:sepaMandate:AGENT ==> role:debitorRel:AGENT + role:sepaMandate:AGENT ==> role:sepaMandate:REFERRER + role:bankAccount:ADMIN ==> role:sepaMandate:REFERRER + role:debitorRel:AGENT ==> role:sepaMandate:REFERRER + role:sepaMandate:REFERRER ==> role:debitorRel:TENANT + + %% granting permissions to roles + role:sepaMandate:OWNER ==> perm:sepaMandate:DELETE + role:sepaMandate:ADMIN ==> perm:sepaMandate:UPDATE + role:sepaMandate:REFERRER ==> perm:sepaMandate:SELECT + role:debitorRel:ADMIN ==> perm:sepaMandate:INSERT + """); + } }