Compare commits
9 Commits
4f25bf1496
...
92086d8634
Author | SHA1 | Date | |
---|---|---|---|
|
92086d8634 | ||
|
b5ef54e83c | ||
|
630a9fe3d0 | ||
73c378b456 | |||
ad04faa21d | |||
277369a960 | |||
87af20a3a1 | |||
7f418c12a1 | |||
f8fb273918 |
@ -82,7 +82,7 @@ If you have at least Docker and the Java JDK installed in appropriate versions a
|
|||||||
|
|
||||||
# the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
|
# the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
|
||||||
curl \
|
curl \
|
||||||
-H 'current-user: superuser-alex@hostsharing.net' -H 'assumed-roles: test_customer#yyy:admin' \
|
-H 'current-user: superuser-alex@hostsharing.net' -H 'assumed-roles: test_customer#yyy:ADMIN' \
|
||||||
http://localhost:8080/api/test/packages
|
http://localhost:8080/api/test/packages
|
||||||
|
|
||||||
# add a new customer
|
# add a new customer
|
||||||
|
@ -62,7 +62,6 @@ dependencies {
|
|||||||
implementation 'org.springdoc:springdoc-openapi:2.4.0'
|
implementation 'org.springdoc:springdoc-openapi:2.4.0'
|
||||||
implementation 'org.postgresql:postgresql:42.7.3'
|
implementation 'org.postgresql:postgresql:42.7.3'
|
||||||
implementation 'org.liquibase:liquibase-core:4.27.0'
|
implementation 'org.liquibase:liquibase-core:4.27.0'
|
||||||
//implementation 'com.vladmihalcea:hibernate-types-60:2.21.1'
|
|
||||||
implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.7.3'
|
implementation 'io.hypersistence:hypersistence-utils-hibernate-63:3.7.3'
|
||||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.0'
|
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.0'
|
||||||
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
|
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
|
||||||
|
22
doc/rbac.md
22
doc/rbac.md
@ -206,7 +206,7 @@ and the *role-stereotype* describes a role relative to a referenced business-obj
|
|||||||
#### owner
|
#### owner
|
||||||
|
|
||||||
The owner-role is granted to the subject which created the business object.
|
The owner-role is granted to the subject which created the business object.
|
||||||
E.g. for a new *customer* it would be granted to 'administrators' and for a new *package* to the 'customer#...:admin'.
|
E.g. for a new *customer* it would be granted to 'administrators' and for a new *package* to the 'customer#...:ADMIN'.
|
||||||
|
|
||||||
Whoever has the owner-role assigned can do everything with the related business-object, including deleting (or deactivating) it.
|
Whoever has the owner-role assigned can do everything with the related business-object, including deleting (or deactivating) it.
|
||||||
|
|
||||||
@ -470,14 +470,14 @@ together {
|
|||||||
permCustomerXyzSELECT--> boCustXyz
|
permCustomerXyzSELECT--> boCustXyz
|
||||||
}
|
}
|
||||||
|
|
||||||
entity "Role customer#xyz:tenant" as roleCustXyzTenant
|
entity "Role customer#xyz:TENANT" as roleCustXyzTenant
|
||||||
roleCustXyzTenant --> permCustomerXyzSELECT
|
roleCustXyzTenant --> permCustomerXyzSELECT
|
||||||
|
|
||||||
entity "Role customer#xyz:admin" as roleCustXyzAdmin
|
entity "Role customer#xyz:ADMIN" as roleCustXyzAdmin
|
||||||
roleCustXyzAdmin --> roleCustXyzTenant
|
roleCustXyzAdmin --> roleCustXyzTenant
|
||||||
roleCustXyzAdmin --> permCustomerXyzINSERT:package
|
roleCustXyzAdmin --> permCustomerXyzINSERT:package
|
||||||
|
|
||||||
entity "Role customer#xyz:owner" as roleCustXyzOwner
|
entity "Role customer#xyz:OWNER" as roleCustXyzOwner
|
||||||
roleCustXyzOwner ..> roleCustXyzAdmin
|
roleCustXyzOwner ..> roleCustXyzAdmin
|
||||||
roleCustXyzOwner --> permCustomerXyzDELETE
|
roleCustXyzOwner --> permCustomerXyzDELETE
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ actorHostmaster --> roleAdmins
|
|||||||
```
|
```
|
||||||
|
|
||||||
As you can see, there something special:
|
As you can see, there something special:
|
||||||
From the 'Role customer#xyz:owner' to the 'Role customer#xyz:admin' there is a dashed line, whereas all other lines are solid lines.
|
From the 'Role customer#xyz:OWNER' to the 'Role customer#xyz:admin' there is a dashed line, whereas all other lines are solid lines.
|
||||||
Solid lines means, that one role is granted to another and automatically assumed in all queries to the restricted views.
|
Solid lines means, that one role is granted to another and automatically assumed in all queries to the restricted views.
|
||||||
The dashed line means that one role is granted to another but not automatically assumed in queries to the restricted views.
|
The dashed line means that one role is granted to another but not automatically assumed in queries to the restricted views.
|
||||||
|
|
||||||
@ -541,15 +541,15 @@ together {
|
|||||||
}
|
}
|
||||||
|
|
||||||
package {
|
package {
|
||||||
entity "Role customer#xyz:tenant" as roleCustXyzTenant
|
entity "Role customer#xyz:TENANT" as roleCustXyzTenant
|
||||||
entity "Role customer#xyz:admin" as roleCustXyzAdmin
|
entity "Role customer#xyz:ADMIN" as roleCustXyzAdmin
|
||||||
entity "Role customer#xyz:owner" as roleCustXyzOwner
|
entity "Role customer#xyz:OWNER" as roleCustXyzOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
package {
|
package {
|
||||||
entity "Role package#xyz00:owner" as rolePacXyz00Owner
|
entity "Role package#xyz00:OWNER" as rolePacXyz00Owner
|
||||||
entity "Role package#xyz00:admin" as rolePacXyz00Admin
|
entity "Role package#xyz00:ADMIN" as rolePacXyz00Admin
|
||||||
entity "Role package#xyz00:tenant" as rolePacXyz00Tenant
|
entity "Role package#xyz00:TENANT" as rolePacXyz00Tenant
|
||||||
}
|
}
|
||||||
|
|
||||||
rolePacXyz00Tenant --> permPacXyz00SELECT
|
rolePacXyz00Tenant --> permPacXyz00SELECT
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
|
|
||||||
package net.hostsharing.hsadminng.hs.office.coopassets;
|
package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
@ -10,7 +14,15 @@ import net.hostsharing.hsadminng.stringify.Stringify;
|
|||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@ -20,8 +32,11 @@ import java.util.UUID;
|
|||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
@ -109,7 +124,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacO
|
|||||||
|
|
||||||
.toRole("membership", ADMIN).grantPermission(INSERT)
|
.toRole("membership", ADMIN).grantPermission(INSERT)
|
||||||
.toRole("membership", ADMIN).grantPermission(UPDATE)
|
.toRole("membership", ADMIN).grantPermission(UPDATE)
|
||||||
.toRole("membership", ADMIN).grantPermission(SELECT);
|
.toRole("membership", AGENT).grantPermission(SELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -17,9 +29,11 @@ import java.util.UUID;
|
|||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
@ -105,7 +119,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacO
|
|||||||
|
|
||||||
.toRole("membership", ADMIN).grantPermission(INSERT)
|
.toRole("membership", ADMIN).grantPermission(INSERT)
|
||||||
.toRole("membership", ADMIN).grantPermission(UPDATE)
|
.toRole("membership", ADMIN).grantPermission(UPDATE)
|
||||||
.toRole("membership", ADMIN).grantPermission(SELECT);
|
.toRole("membership", AGENT).grantPermission(SELECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
@ -26,6 +26,7 @@ import static jakarta.persistence.CascadeType.PERSIST;
|
|||||||
import static jakarta.persistence.CascadeType.REFRESH;
|
import static jakarta.persistence.CascadeType.REFRESH;
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||||
@ -157,6 +158,7 @@ public class HsOfficeDebitorEntity implements RbacObject, Stringifyable {
|
|||||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
|
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
|
||||||
|
usingCase("DEBITOR"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
directlyFetchedByDependsOnColumn(),
|
||||||
dependsOnColumn("debitorRelUuid"))
|
dependsOnColumn("debitorRelUuid"))
|
||||||
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
||||||
|
@ -28,7 +28,6 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.
|
|||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||||
@ -148,14 +147,14 @@ public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
|
|||||||
|
|
||||||
.createRole(OWNER, (with) -> {
|
.createRole(OWNER, (with) -> {
|
||||||
with.owningUser(CREATOR);
|
with.owningUser(CREATOR);
|
||||||
with.incomingSuperRole("partnerRel", ADMIN);
|
|
||||||
with.permission(DELETE);
|
|
||||||
})
|
})
|
||||||
.createSubRole(ADMIN, (with) -> {
|
.createSubRole(ADMIN, (with) -> {
|
||||||
with.incomingSuperRole("partnerRel", AGENT);
|
with.incomingSuperRole("partnerRel", ADMIN);
|
||||||
|
with.permission(DELETE);
|
||||||
with.permission(UPDATE);
|
with.permission(UPDATE);
|
||||||
})
|
})
|
||||||
.createSubRole(REFERRER, (with) -> {
|
.createSubRole(AGENT, (with) -> {
|
||||||
|
with.incomingSuperRole("partnerRel", AGENT);
|
||||||
with.outgoingSubRole("partnerRel", TENANT);
|
with.outgoingSubRole("partnerRel", TENANT);
|
||||||
with.permission(SELECT);
|
with.permission(SELECT);
|
||||||
});
|
});
|
||||||
|
@ -29,6 +29,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import static jakarta.persistence.CascadeType.*;
|
import static jakarta.persistence.CascadeType.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||||
@ -98,6 +99,7 @@ public class HsOfficePartnerEntity implements Stringifyable, RbacObject {
|
|||||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationEntity.class,
|
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationEntity.class,
|
||||||
|
usingDefaultCase(),
|
||||||
directlyFetchedByDependsOnColumn(),
|
directlyFetchedByDependsOnColumn(),
|
||||||
dependsOnColumn("partnerRelUuid"))
|
dependsOnColumn("partnerRelUuid"))
|
||||||
.createPermission(DELETE).grantedTo("partnerRel", ADMIN)
|
.createPermission(DELETE).grantedTo("partnerRel", ADMIN)
|
||||||
|
@ -11,17 +11,17 @@ import net.hostsharing.hsadminng.stringify.Stringify;
|
|||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
|
||||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -101,28 +101,53 @@ public class HsOfficeRelationEntity implements RbacObject, Stringifyable {
|
|||||||
dependsOnColumn("contactUuid"),
|
dependsOnColumn("contactUuid"),
|
||||||
directlyFetchedByDependsOnColumn(),
|
directlyFetchedByDependsOnColumn(),
|
||||||
NOT_NULL)
|
NOT_NULL)
|
||||||
.createRole(OWNER, (with) -> {
|
.switchOnColumn("type",
|
||||||
with.owningUser(CREATOR);
|
inCaseOf("REPRESENTATIVE", then -> {
|
||||||
with.incomingSuperRole(GLOBAL, ADMIN);
|
then.createRole(OWNER, (with) -> {
|
||||||
with.incomingSuperRole("holderPerson", ADMIN).where("${REF}.type = 'REPRESENTATIVE'");
|
with.owningUser(CREATOR);
|
||||||
with.permission(DELETE);
|
with.incomingSuperRole(GLOBAL, ADMIN);
|
||||||
})
|
with.incomingSuperRole("holderPerson", ADMIN);
|
||||||
.createSubRole(ADMIN, (with) -> {
|
with.permission(DELETE);
|
||||||
with.incomingSuperRole("anchorPerson", ADMIN).where("${REF}.type <> 'REPRESENTATIVE'");
|
})
|
||||||
with.outgoingSubRole("anchorPerson", OWNER).where("${REF}.type = 'REPRESENTATIVE'");
|
.createSubRole(ADMIN, (with) -> {
|
||||||
with.permission(UPDATE);
|
with.incomingSuperRole("anchorPerson", ADMIN);
|
||||||
})
|
with.outgoingSubRole("anchorPerson", OWNER);
|
||||||
.createSubRole(AGENT, (with) -> {
|
with.permission(UPDATE);
|
||||||
with.incomingSuperRole("holderPerson", ADMIN).where("${REF}.type <> 'REPRESENTATIVE'");
|
})
|
||||||
})
|
.createSubRole(AGENT, (with) -> {
|
||||||
.createSubRole(TENANT, (with) -> {
|
})
|
||||||
with.incomingSuperRole("contact", ADMIN);
|
.createSubRole(TENANT, (with) -> {
|
||||||
with.outgoingSubRole("anchorPerson", REFERRER);
|
with.incomingSuperRole("holderPerson", ADMIN);
|
||||||
with.outgoingSubRole("holderPerson", REFERRER);
|
with.incomingSuperRole("contact", ADMIN);
|
||||||
with.outgoingSubRole("contact", REFERRER);
|
with.outgoingSubRole("anchorPerson", REFERRER);
|
||||||
with.permission(SELECT);
|
with.outgoingSubRole("holderPerson", REFERRER);
|
||||||
})
|
with.outgoingSubRole("contact", REFERRER);
|
||||||
|
with.permission(SELECT);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
//FIXME: .inCaseOf("DEBITOR")
|
||||||
|
inOtherCases(then -> {
|
||||||
|
then.createRole(OWNER, (with) -> {
|
||||||
|
with.owningUser(CREATOR);
|
||||||
|
with.incomingSuperRole(GLOBAL, ADMIN);
|
||||||
|
with.permission(DELETE);
|
||||||
|
})
|
||||||
|
.createSubRole(ADMIN, (with) -> {
|
||||||
|
with.incomingSuperRole("anchorPerson", ADMIN);
|
||||||
|
with.permission(UPDATE);
|
||||||
|
})
|
||||||
|
.createSubRole(AGENT, (with) -> {
|
||||||
|
with.incomingSuperRole("holderPerson", ADMIN);
|
||||||
|
})
|
||||||
|
.createSubRole(TENANT, (with) -> {
|
||||||
|
with.incomingSuperRole("holderPerson", ADMIN);
|
||||||
|
with.incomingSuperRole("contact", ADMIN);
|
||||||
|
with.outgoingSubRole("anchorPerson", REFERRER);
|
||||||
|
with.outgoingSubRole("holderPerson", REFERRER);
|
||||||
|
with.outgoingSubRole("contact", REFERRER);
|
||||||
|
with.permission(SELECT);
|
||||||
|
});
|
||||||
|
}))
|
||||||
.toRole("anchorPerson", ADMIN).grantPermission(INSERT);
|
.toRole("anchorPerson", ADMIN).grantPermission(INSERT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.mapper;
|
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.postgresql.util.PGtokenizer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class PostgresArray {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a byte[], as returned for a Postgres-array by native queries, to a Java array.
|
|
||||||
*
|
|
||||||
* <p>This example code worked with Hibernate 5 (Spring Boot 3.0.x):
|
|
||||||
* <pre><code>
|
|
||||||
* return (UUID[]) em.createNativeQuery("select currentSubjectsUuids() as uuids", UUID[].class).getSingleResult();
|
|
||||||
* </code></pre>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>With Hibernate 6 (Spring Boot 3.1.x), this utility method can be used like such:
|
|
||||||
* <pre><code>
|
|
||||||
* final byte[] result = (byte[]) em.createNativeQuery("select * from currentSubjectsUuids() as uuids", UUID[].class)
|
|
||||||
* .getSingleResult();
|
|
||||||
* return fromPostgresArray(result, UUID.class, UUID::fromString);
|
|
||||||
* </code></pre>
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param pgArray the byte[] returned by a native query containing as rendered for a Postgres array
|
|
||||||
* @param elementClass the class of a single element of the Java array to be returned
|
|
||||||
* @param itemParser converts a string element to the specified elementClass
|
|
||||||
* @return a Java array containing the data from pgArray
|
|
||||||
* @param <T> type of a single element of the Java array
|
|
||||||
*/
|
|
||||||
public static <T> T[] fromPostgresArray(final byte[] pgArray, final Class<T> elementClass, final Function<String, T> itemParser) {
|
|
||||||
final var pgArrayLiteral = new String(pgArray, StandardCharsets.UTF_8);
|
|
||||||
if (pgArrayLiteral.length() == 2) {
|
|
||||||
return newGenericArray(elementClass, 0);
|
|
||||||
}
|
|
||||||
final PGtokenizer tokenizer = new PGtokenizer(pgArrayLiteral.substring(1, pgArrayLiteral.length()-1), ',');
|
|
||||||
tokenizer.remove("\"", "\"");
|
|
||||||
final T[] array = newGenericArray(elementClass, tokenizer.getSize()); // Create a new array of the specified type and length
|
|
||||||
for ( int n = 0; n < tokenizer.getSize(); ++n ) {
|
|
||||||
final String token = tokenizer.getToken(n);
|
|
||||||
if ( !"NULL".equals(token) ) {
|
|
||||||
array[n] = itemParser.apply(token.trim().replace("\\\"", "\""));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private static <T> T[] newGenericArray(final Class<T> elementClass, final int length) {
|
|
||||||
return (T[]) Array.newInstance(elementClass, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -14,7 +14,6 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
|
||||||
import net.hostsharing.hsadminng.test.cust.TestCustomerEntity;
|
import net.hostsharing.hsadminng.test.cust.TestCustomerEntity;
|
||||||
import net.hostsharing.hsadminng.test.dom.TestDomainEntity;
|
import net.hostsharing.hsadminng.test.dom.TestDomainEntity;
|
||||||
import net.hostsharing.hsadminng.test.pac.TestPackageEntity;
|
import net.hostsharing.hsadminng.test.pac.TestPackageEntity;
|
||||||
@ -35,10 +34,10 @@ import static java.util.Optional.ofNullable;
|
|||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.Part.AUTO_FETCH;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.Part.AUTO_FETCH;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
// TODO.refa: rename to RbacDSL
|
||||||
public class RbacView {
|
public class RbacView {
|
||||||
|
|
||||||
public static final String GLOBAL = "global";
|
public static final String GLOBAL = "global";
|
||||||
@ -66,6 +65,15 @@ public class RbacView {
|
|||||||
private SQL orderBySqlExpression;
|
private SQL orderBySqlExpression;
|
||||||
private EntityAlias rootEntityAliasProxy;
|
private EntityAlias rootEntityAliasProxy;
|
||||||
private RbacRoleDefinition previousRoleDef;
|
private RbacRoleDefinition previousRoleDef;
|
||||||
|
private final Map<String, String> cases = new HashMap<>() {
|
||||||
|
@Override
|
||||||
|
public String put(final String key, final String value) {
|
||||||
|
if (containsKey(key)) {
|
||||||
|
throw new IllegalArgumentException("duplicate case: " + key);
|
||||||
|
}
|
||||||
|
return super.put(key, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** Crates an RBAC definition template for the given entity class and defining the given alias.
|
/** Crates an RBAC definition template for the given entity class and defining the given alias.
|
||||||
*
|
*
|
||||||
@ -278,6 +286,7 @@ public class RbacView {
|
|||||||
public <EC extends RbacObject> RbacView importRootEntityAliasProxy(
|
public <EC extends RbacObject> RbacView importRootEntityAliasProxy(
|
||||||
final String aliasName,
|
final String aliasName,
|
||||||
final Class<? extends RbacObject> entityClass,
|
final Class<? extends RbacObject> entityClass,
|
||||||
|
final ColumnValue forCase,
|
||||||
final SQL fetchSql,
|
final SQL fetchSql,
|
||||||
final Column dependsOnColum) {
|
final Column dependsOnColum) {
|
||||||
if (rootEntityAliasProxy != null) {
|
if (rootEntityAliasProxy != null) {
|
||||||
@ -340,14 +349,6 @@ public class RbacView {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove once it's not used in HsOffice...Entity anymore
|
|
||||||
public RbacView importEntityAlias(
|
|
||||||
final String aliasName, final Class<? extends RbacObject> entityClass,
|
|
||||||
final Column dependsOnColum) {
|
|
||||||
importEntityAliasImpl(aliasName, entityClass, directlyFetchedByDependsOnColumn(), dependsOnColum, false, null);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private EntityAlias importEntityAliasImpl(
|
private EntityAlias importEntityAliasImpl(
|
||||||
final String aliasName, final Class<? extends RbacObject> entityClass,
|
final String aliasName, final Class<? extends RbacObject> entityClass,
|
||||||
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
||||||
@ -398,6 +399,12 @@ public class RbacView {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RbacView switchOnColumn(final String discriminatorColumName, final CaseDef... caseDefs) {
|
||||||
|
// FIXME: currently only the default case is executed
|
||||||
|
stream(caseDefs).filter(caseDef -> caseDef.val == null).findAny().orElseThrow().def.accept(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyVersionColumnExists() {
|
private void verifyVersionColumnExists() {
|
||||||
if (stream(rootEntityAlias.entityClass.getDeclaredFields())
|
if (stream(rootEntityAlias.entityClass.getDeclaredFields())
|
||||||
.noneMatch(f -> f.getAnnotation(Version.class) != null)) {
|
.noneMatch(f -> f.getAnnotation(Version.class) != null)) {
|
||||||
@ -481,6 +488,25 @@ public class RbacView {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class CaseDef {
|
||||||
|
|
||||||
|
private final String val;
|
||||||
|
private final Consumer<RbacView> def;
|
||||||
|
|
||||||
|
public CaseDef(final String discriminatorColumnValue, final Consumer<RbacView> def) {
|
||||||
|
this.val = discriminatorColumnValue;
|
||||||
|
this.def = def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CaseDef inCaseOf(final String discriminatorColumnValue, final Consumer<RbacView> def) {
|
||||||
|
return new CaseDef(discriminatorColumnValue, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CaseDef inOtherCases(final Consumer<RbacView> def) {
|
||||||
|
return new CaseDef(null, def);
|
||||||
|
}
|
||||||
|
|
||||||
public enum Nullable {
|
public enum Nullable {
|
||||||
NOT_NULL, // DEFAULT
|
NOT_NULL, // DEFAULT
|
||||||
NULLABLE
|
NULLABLE
|
||||||
@ -496,7 +522,8 @@ public class RbacView {
|
|||||||
private final RbacPermissionDefinition permDef;
|
private final RbacPermissionDefinition permDef;
|
||||||
private boolean assumed = true;
|
private boolean assumed = true;
|
||||||
private boolean toCreate = false;
|
private boolean toCreate = false;
|
||||||
private String sqlWhere;
|
private String onlyInCaseOf;
|
||||||
|
private String exceptInCaseOf;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -550,7 +577,7 @@ public class RbacView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isConditional() {
|
boolean isConditional() {
|
||||||
return sqlWhere != null;
|
return onlyInCaseOf != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isToCreate() {
|
boolean isToCreate() {
|
||||||
@ -579,8 +606,14 @@ public class RbacView {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RbacGrantDefinition where(final String sqlWhere) {
|
public RbacGrantDefinition onlyInCaseOf(final String caseName) {
|
||||||
this.sqlWhere = sqlWhere;
|
this.onlyInCaseOf = caseName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public RbacGrantDefinition exceptInCaseOf(final String caseName) {
|
||||||
|
this.exceptInCaseOf = caseName;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1035,6 +1068,23 @@ public class RbacView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ColumnValue {
|
||||||
|
|
||||||
|
public static ColumnValue usingDefaultCase() {
|
||||||
|
return new ColumnValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColumnValue usingCase(final String value) {
|
||||||
|
return new ColumnValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String value;
|
||||||
|
|
||||||
|
private ColumnValue(final String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class AliasNameMapper {
|
private static class AliasNameMapper {
|
||||||
|
|
||||||
private final RbacView importedRbacView;
|
private final RbacView importedRbacView;
|
||||||
|
@ -301,11 +301,11 @@ class RolesGrantsAndPermissionsGenerator {
|
|||||||
.replace("${permRef}", createPerm(NEW, grantDef.getPermDef()))
|
.replace("${permRef}", createPerm(NEW, grantDef.getPermDef()))
|
||||||
.replace("${superRoleRef}", roleRef(NEW, grantDef.getSuperRoleDef()));
|
.replace("${superRoleRef}", roleRef(NEW, grantDef.getSuperRoleDef()));
|
||||||
};
|
};
|
||||||
if (grantDef.isConditional()) {
|
// if (grantDef.isConditional()) {
|
||||||
return "if " + grantDef.getSqlWhere() + " then\n"
|
// return "if " + grantDef.getOnlyInCaseOf() + " then\n"
|
||||||
+ " " + grantSql + "\n"
|
// + " " + grantSql + "\n"
|
||||||
+ "end if;";
|
// + "end if;";
|
||||||
}
|
// }
|
||||||
return grantSql;
|
return grantSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ public class RbacGrantsDiagramService {
|
|||||||
return "users";
|
return "users";
|
||||||
}
|
}
|
||||||
if (refType.equals("perm")) {
|
if (refType.equals("perm")) {
|
||||||
return node.idName().split(" ", 4)[3];
|
return node.idName().split(":", 3)[1];
|
||||||
}
|
}
|
||||||
if (refType.equals("role")) {
|
if (refType.equals("role")) {
|
||||||
final var withoutRolePrefix = node.idName().substring("role:".length());
|
final var withoutRolePrefix = node.idName().substring("role:".length());
|
||||||
|
@ -31,7 +31,7 @@ public class RbacRoleController implements RbacRolesApi {
|
|||||||
|
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final List<RbacRoleRvEntity> result = rbacRoleRepository.findAll();
|
final List<RbacRoleEntity> result = rbacRoleRepository.findAll();
|
||||||
|
|
||||||
return ResponseEntity.ok(mapper.mapList(result, RbacRoleResource.class));
|
return ResponseEntity.ok(mapper.mapList(result, RbacRoleResource.class));
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import java.util.UUID;
|
|||||||
@Immutable
|
@Immutable
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class RbacRoleRvEntity {
|
public class RbacRoleEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
@ -5,7 +5,7 @@ import org.springframework.data.repository.Repository;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface RbacRoleRepository extends Repository<RbacRoleRvEntity, UUID> {
|
public interface RbacRoleRepository extends Repository<RbacRoleEntity, UUID> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of persistent RbacRoleEntity instances, mostly for testing purposes.
|
* @return the number of persistent RbacRoleEntity instances, mostly for testing purposes.
|
||||||
@ -15,7 +15,7 @@ public interface RbacRoleRepository extends Repository<RbacRoleRvEntity, UUID> {
|
|||||||
/**
|
/**
|
||||||
* @return all persistent RbacRoleEntity instances, assigned to the current subject (user or assumed roles)
|
* @return all persistent RbacRoleEntity instances, assigned to the current subject (user or assumed roles)
|
||||||
*/
|
*/
|
||||||
List<RbacRoleRvEntity> findAll();
|
List<RbacRoleEntity> findAll();
|
||||||
|
|
||||||
RbacRoleRvEntity findByRoleName(String roleName);
|
RbacRoleEntity findByRoleName(String roleName);
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,15 @@ begin
|
|||||||
return roleDescriptor('%2$s', entity.uuid, 'TENANT', assumed);
|
return roleDescriptor('%2$s', entity.uuid, 'TENANT', assumed);
|
||||||
end; $f$;
|
end; $f$;
|
||||||
|
|
||||||
|
-- TODO: remove guest role
|
||||||
|
create or replace function %1$sGuest(entity %2$s, assumed boolean = true)
|
||||||
|
returns RbacRoleDescriptor
|
||||||
|
language plpgsql
|
||||||
|
strict as $f$
|
||||||
|
begin
|
||||||
|
return roleDescriptor('%2$s', entity.uuid, 'GUEST', assumed);
|
||||||
|
end; $f$;
|
||||||
|
|
||||||
create or replace function %1$sReferrer(entity %2$s)
|
create or replace function %1$sReferrer(entity %2$s)
|
||||||
returns RbacRoleDescriptor
|
returns RbacRoleDescriptor
|
||||||
language plpgsql
|
language plpgsql
|
||||||
|
@ -139,7 +139,7 @@ select 'global', (select uuid from RbacObject where objectTable = 'global'), 'GU
|
|||||||
$$;
|
$$;
|
||||||
|
|
||||||
begin transaction;
|
begin transaction;
|
||||||
call defineContext('creating role:global#loba:guest', null, null, null);
|
call defineContext('creating role:global#global:guest', null, null, null);
|
||||||
select createRole(globalGuest());
|
select createRole(globalGuest());
|
||||||
commit;
|
commit;
|
||||||
--//
|
--//
|
||||||
|
@ -82,13 +82,12 @@ role:global:ADMIN -.-> role:contact:OWNER
|
|||||||
role:contact:OWNER -.-> role:contact:ADMIN
|
role:contact:OWNER -.-> role:contact:ADMIN
|
||||||
role:contact:ADMIN -.-> role:contact:REFERRER
|
role:contact:ADMIN -.-> role:contact:REFERRER
|
||||||
role:global:ADMIN ==> role:relation:OWNER
|
role:global:ADMIN ==> role:relation:OWNER
|
||||||
role:holderPerson:ADMIN ==> |??| role:relation:OWNER
|
|
||||||
role:relation:OWNER ==> role:relation:ADMIN
|
role:relation:OWNER ==> role:relation:ADMIN
|
||||||
role:anchorPerson:ADMIN ==> |??| role:relation:ADMIN
|
role:anchorPerson:ADMIN ==> role:relation:ADMIN
|
||||||
role:relation:ADMIN ==> |??| role:anchorPerson:OWNER
|
|
||||||
role:relation:ADMIN ==> role:relation:AGENT
|
role:relation:ADMIN ==> role:relation:AGENT
|
||||||
role:holderPerson:ADMIN ==> |??| role:relation:AGENT
|
role:holderPerson:ADMIN ==> role:relation:AGENT
|
||||||
role:relation:AGENT ==> role:relation:TENANT
|
role:relation:AGENT ==> role:relation:TENANT
|
||||||
|
role:holderPerson:ADMIN ==> role:relation:TENANT
|
||||||
role:contact:ADMIN ==> role:relation:TENANT
|
role:contact:ADMIN ==> role:relation:TENANT
|
||||||
role:relation:TENANT ==> role:anchorPerson:REFERRER
|
role:relation:TENANT ==> role:anchorPerson:REFERRER
|
||||||
role:relation:TENANT ==> role:holderPerson:REFERRER
|
role:relation:TENANT ==> role:holderPerson:REFERRER
|
||||||
|
@ -57,12 +57,16 @@ begin
|
|||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeRelationADMIN(NEW),
|
hsOfficeRelationADMIN(NEW),
|
||||||
permissions => array['UPDATE'],
|
permissions => array['UPDATE'],
|
||||||
incomingSuperRoles => array[hsOfficeRelationOWNER(NEW)]
|
incomingSuperRoles => array[
|
||||||
|
hsOfficePersonADMIN(newAnchorPerson),
|
||||||
|
hsOfficeRelationOWNER(NEW)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeRelationAGENT(NEW),
|
hsOfficeRelationAGENT(NEW),
|
||||||
incomingSuperRoles => array[hsOfficeRelationADMIN(NEW)]
|
incomingSuperRoles => array[
|
||||||
|
hsOfficePersonADMIN(newHolderPerson),
|
||||||
|
hsOfficeRelationADMIN(NEW)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
@ -70,6 +74,7 @@ begin
|
|||||||
permissions => array['SELECT'],
|
permissions => array['SELECT'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeContactADMIN(newContact),
|
hsOfficeContactADMIN(newContact),
|
||||||
|
hsOfficePersonADMIN(newHolderPerson),
|
||||||
hsOfficeRelationAGENT(NEW)],
|
hsOfficeRelationAGENT(NEW)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsOfficeContactREFERRER(newContact),
|
hsOfficeContactREFERRER(newContact),
|
||||||
@ -77,19 +82,6 @@ begin
|
|||||||
hsOfficePersonREFERRER(newHolderPerson)]
|
hsOfficePersonREFERRER(newHolderPerson)]
|
||||||
);
|
);
|
||||||
|
|
||||||
if NEW.type <> 'REPRESENTATIVE' then
|
|
||||||
call grantRoleToRole(hsOfficeRelationADMIN(NEW), hsOfficePersonADMIN(newAnchorPerson));
|
|
||||||
end if;
|
|
||||||
if NEW.type <> 'REPRESENTATIVE' then
|
|
||||||
call grantRoleToRole(hsOfficeRelationAGENT(NEW), hsOfficePersonADMIN(newHolderPerson));
|
|
||||||
end if;
|
|
||||||
if NEW.type = 'REPRESENTATIVE' then
|
|
||||||
call grantRoleToRole(hsOfficePersonOWNER(newAnchorPerson), hsOfficeRelationADMIN(NEW));
|
|
||||||
end if;
|
|
||||||
if NEW.type = 'REPRESENTATIVE' then
|
|
||||||
call grantRoleToRole(hsOfficeRelationOWNER(NEW), hsOfficePersonADMIN(newHolderPerson));
|
|
||||||
end if;
|
|
||||||
|
|
||||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
@ -126,12 +118,48 @@ create or replace procedure updateRbacRulesForHsOfficeRelation(
|
|||||||
NEW hs_office_relation
|
NEW hs_office_relation
|
||||||
)
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
|
||||||
|
|
||||||
if NEW.contactUuid is distinct from OLD.contactUuid then
|
declare
|
||||||
delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid;
|
oldHolderPerson hs_office_person;
|
||||||
call buildRbacSystemForHsOfficeRelation(NEW);
|
newHolderPerson hs_office_person;
|
||||||
|
oldAnchorPerson hs_office_person;
|
||||||
|
newAnchorPerson hs_office_person;
|
||||||
|
oldContact hs_office_contact;
|
||||||
|
newContact hs_office_contact;
|
||||||
|
|
||||||
|
begin
|
||||||
|
call enterTriggerForObjectUuid(NEW.uuid);
|
||||||
|
|
||||||
|
SELECT * FROM hs_office_person WHERE uuid = OLD.holderUuid INTO oldHolderPerson;
|
||||||
|
assert oldHolderPerson.uuid is not null, format('oldHolderPerson must not be null for OLD.holderUuid = %s', OLD.holderUuid);
|
||||||
|
|
||||||
|
SELECT * FROM hs_office_person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
||||||
|
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s', NEW.holderUuid);
|
||||||
|
|
||||||
|
SELECT * FROM hs_office_person WHERE uuid = OLD.anchorUuid INTO oldAnchorPerson;
|
||||||
|
assert oldAnchorPerson.uuid is not null, format('oldAnchorPerson must not be null for OLD.anchorUuid = %s', OLD.anchorUuid);
|
||||||
|
|
||||||
|
SELECT * FROM hs_office_person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
||||||
|
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s', NEW.anchorUuid);
|
||||||
|
|
||||||
|
SELECT * FROM hs_office_contact WHERE uuid = OLD.contactUuid INTO oldContact;
|
||||||
|
assert oldContact.uuid is not null, format('oldContact must not be null for OLD.contactUuid = %s', OLD.contactUuid);
|
||||||
|
|
||||||
|
SELECT * FROM hs_office_contact WHERE uuid = NEW.contactUuid INTO newContact;
|
||||||
|
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
|
||||||
|
|
||||||
|
|
||||||
|
if NEW.contactUuid <> OLD.contactUuid then
|
||||||
|
|
||||||
|
call revokeRoleFromRole(hsOfficeRelationTENANT(OLD), hsOfficeContactADMIN(oldContact));
|
||||||
|
call grantRoleToRole(hsOfficeRelationTENANT(NEW), hsOfficeContactADMIN(newContact));
|
||||||
|
|
||||||
|
call revokeRoleFromRole(hsOfficeContactREFERRER(oldContact), hsOfficeRelationTENANT(OLD));
|
||||||
|
call grantRoleToRole(hsOfficeContactREFERRER(newContact), hsOfficeRelationTENANT(NEW));
|
||||||
|
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -42,7 +42,7 @@ subgraph membership["`**membership**`"]
|
|||||||
|
|
||||||
role:membership:OWNER[[membership:OWNER]]
|
role:membership:OWNER[[membership:OWNER]]
|
||||||
role:membership:ADMIN[[membership:ADMIN]]
|
role:membership:ADMIN[[membership:ADMIN]]
|
||||||
role:membership:REFERRER[[membership:REFERRER]]
|
role:membership:AGENT[[membership:AGENT]]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph membership:permissions[ ]
|
subgraph membership:permissions[ ]
|
||||||
@ -105,16 +105,16 @@ role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
|
|||||||
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
|
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
|
||||||
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
|
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
|
||||||
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
|
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
|
||||||
role:partnerRel:ADMIN ==> role:membership:OWNER
|
|
||||||
role:membership:OWNER ==> role:membership:ADMIN
|
role:membership:OWNER ==> role:membership:ADMIN
|
||||||
role:partnerRel:AGENT ==> role:membership:ADMIN
|
role:partnerRel:ADMIN ==> role:membership:ADMIN
|
||||||
role:membership:ADMIN ==> role:membership:REFERRER
|
role:membership:ADMIN ==> role:membership:AGENT
|
||||||
role:membership:REFERRER ==> role:partnerRel:TENANT
|
role:partnerRel:AGENT ==> role:membership:AGENT
|
||||||
|
role:membership:AGENT ==> role:partnerRel:TENANT
|
||||||
|
|
||||||
%% granting permissions to roles
|
%% granting permissions to roles
|
||||||
role:global:ADMIN ==> perm:membership:INSERT
|
role:global:ADMIN ==> perm:membership:INSERT
|
||||||
role:membership:OWNER ==> perm:membership:DELETE
|
role:membership:ADMIN ==> perm:membership:DELETE
|
||||||
role:membership:ADMIN ==> perm:membership:UPDATE
|
role:membership:ADMIN ==> perm:membership:UPDATE
|
||||||
role:membership:REFERRER ==> perm:membership:SELECT
|
role:membership:AGENT ==> perm:membership:SELECT
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -45,23 +45,23 @@ begin
|
|||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeMembershipOWNER(NEW),
|
hsOfficeMembershipOWNER(NEW),
|
||||||
permissions => array['DELETE'],
|
|
||||||
incomingSuperRoles => array[hsOfficeRelationADMIN(newPartnerRel)],
|
|
||||||
userUuids => array[currentUserUuid()]
|
userUuids => array[currentUserUuid()]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeMembershipADMIN(NEW),
|
hsOfficeMembershipADMIN(NEW),
|
||||||
permissions => array['UPDATE'],
|
permissions => array['DELETE', 'UPDATE'],
|
||||||
incomingSuperRoles => array[
|
incomingSuperRoles => array[
|
||||||
hsOfficeMembershipOWNER(NEW),
|
hsOfficeMembershipOWNER(NEW),
|
||||||
hsOfficeRelationAGENT(newPartnerRel)]
|
hsOfficeRelationADMIN(newPartnerRel)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsOfficeMembershipREFERRER(NEW),
|
hsOfficeMembershipAGENT(NEW),
|
||||||
permissions => array['SELECT'],
|
permissions => array['SELECT'],
|
||||||
incomingSuperRoles => array[hsOfficeMembershipADMIN(NEW)],
|
incomingSuperRoles => array[
|
||||||
|
hsOfficeMembershipADMIN(NEW),
|
||||||
|
hsOfficeRelationAGENT(newPartnerRel)],
|
||||||
outgoingSubRoles => array[hsOfficeRelationTENANT(newPartnerRel)]
|
outgoingSubRoles => array[hsOfficeRelationTENANT(newPartnerRel)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ subgraph membership["`**membership**`"]
|
|||||||
|
|
||||||
role:membership:OWNER[[membership:OWNER]]
|
role:membership:OWNER[[membership:OWNER]]
|
||||||
role:membership:ADMIN[[membership:ADMIN]]
|
role:membership:ADMIN[[membership:ADMIN]]
|
||||||
role:membership:REFERRER[[membership:REFERRER]]
|
role:membership:AGENT[[membership:AGENT]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -106,15 +106,15 @@ 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.anchorPerson:REFERRER
|
||||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
|
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
|
||||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
|
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
|
||||||
role:membership.partnerRel:ADMIN -.-> role:membership:OWNER
|
|
||||||
role:membership:OWNER -.-> role:membership:ADMIN
|
role:membership:OWNER -.-> role:membership:ADMIN
|
||||||
role:membership.partnerRel:AGENT -.-> role:membership:ADMIN
|
role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN
|
||||||
role:membership:ADMIN -.-> role:membership:REFERRER
|
role:membership:ADMIN -.-> role:membership:AGENT
|
||||||
role:membership:REFERRER -.-> role:membership.partnerRel:TENANT
|
role:membership.partnerRel:AGENT -.-> role:membership:AGENT
|
||||||
|
role:membership:AGENT -.-> role:membership.partnerRel:TENANT
|
||||||
|
|
||||||
%% granting permissions to roles
|
%% granting permissions to roles
|
||||||
role:membership:ADMIN ==> perm:coopSharesTransaction:INSERT
|
role:membership:ADMIN ==> perm:coopSharesTransaction:INSERT
|
||||||
role:membership:ADMIN ==> perm:coopSharesTransaction:UPDATE
|
role:membership:ADMIN ==> perm:coopSharesTransaction:UPDATE
|
||||||
role:membership:ADMIN ==> perm:coopSharesTransaction:SELECT
|
role:membership:AGENT ==> perm:coopSharesTransaction:SELECT
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -38,7 +38,7 @@ begin
|
|||||||
SELECT * FROM hs_office_membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
SELECT * FROM hs_office_membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
||||||
|
|
||||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeMembershipADMIN(newMembership));
|
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeMembershipAGENT(newMembership));
|
||||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeMembershipADMIN(newMembership));
|
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeMembershipADMIN(newMembership));
|
||||||
|
|
||||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||||
|
@ -54,7 +54,7 @@ subgraph membership["`**membership**`"]
|
|||||||
|
|
||||||
role:membership:OWNER[[membership:OWNER]]
|
role:membership:OWNER[[membership:OWNER]]
|
||||||
role:membership:ADMIN[[membership:ADMIN]]
|
role:membership:ADMIN[[membership:ADMIN]]
|
||||||
role:membership:REFERRER[[membership:REFERRER]]
|
role:membership:AGENT[[membership:AGENT]]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -106,15 +106,15 @@ 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.anchorPerson:REFERRER
|
||||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
|
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
|
||||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
|
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
|
||||||
role:membership.partnerRel:ADMIN -.-> role:membership:OWNER
|
|
||||||
role:membership:OWNER -.-> role:membership:ADMIN
|
role:membership:OWNER -.-> role:membership:ADMIN
|
||||||
role:membership.partnerRel:AGENT -.-> role:membership:ADMIN
|
role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN
|
||||||
role:membership:ADMIN -.-> role:membership:REFERRER
|
role:membership:ADMIN -.-> role:membership:AGENT
|
||||||
role:membership:REFERRER -.-> role:membership.partnerRel:TENANT
|
role:membership.partnerRel:AGENT -.-> role:membership:AGENT
|
||||||
|
role:membership:AGENT -.-> role:membership.partnerRel:TENANT
|
||||||
|
|
||||||
%% granting permissions to roles
|
%% granting permissions to roles
|
||||||
role:membership:ADMIN ==> perm:coopAssetsTransaction:INSERT
|
role:membership:ADMIN ==> perm:coopAssetsTransaction:INSERT
|
||||||
role:membership:ADMIN ==> perm:coopAssetsTransaction:UPDATE
|
role:membership:ADMIN ==> perm:coopAssetsTransaction:UPDATE
|
||||||
role:membership:ADMIN ==> perm:coopAssetsTransaction:SELECT
|
role:membership:AGENT ==> perm:coopAssetsTransaction:SELECT
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -38,7 +38,7 @@ begin
|
|||||||
SELECT * FROM hs_office_membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
SELECT * FROM hs_office_membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
||||||
|
|
||||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeMembershipADMIN(newMembership));
|
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeMembershipAGENT(newMembership));
|
||||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeMembershipADMIN(newMembership));
|
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeMembershipADMIN(newMembership));
|
||||||
|
|
||||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||||
|
@ -112,7 +112,7 @@ class HsOfficeCoopAssetsTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
"{ grant perm:coopassetstransaction#temprefB:SELECT to role:membership#M-1000101:ADMIN by system and assume }",
|
"{ grant perm:coopassetstransaction#temprefB:SELECT to role:membership#M-1000101:AGENT by system and assume }",
|
||||||
"{ grant perm:coopassetstransaction#temprefB:UPDATE to role:membership#M-1000101:ADMIN by system and assume }",
|
"{ grant perm:coopassetstransaction#temprefB:UPDATE to role:membership#M-1000101:ADMIN by system and assume }",
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ class HsOfficeCoopSharesTransactionRepositoryIntegrationTest extends ContextBase
|
|||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
initialGrantNames,
|
initialGrantNames,
|
||||||
"{ grant perm:coopsharestransaction#temprefB:SELECT to role:membership#M-1000101:ADMIN by system and assume }",
|
"{ grant perm:coopsharestransaction#temprefB:SELECT to role:membership#M-1000101:AGENT by system and assume }",
|
||||||
"{ grant perm:coopsharestransaction#temprefB:UPDATE to role:membership#M-1000101:ADMIN by system and assume }",
|
"{ grant perm:coopsharestransaction#temprefB:UPDATE to role:membership#M-1000101:ADMIN by system and assume }",
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
@ -335,18 +335,18 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void partnerRelAgent_canPatchValidityOfRelatedMembership() {
|
void partnerRelAdmin_canPatchValidityOfRelatedMembership() {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
final var givenPartnerAgent = "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT";
|
final var givenPartnerAdmin = "hs_office_relation#HostsharingeG-with-PARTNER-FirstGmbH:ADMIN";
|
||||||
context.define("superuser-alex@hostsharing.net", givenPartnerAgent);
|
context.define("superuser-alex@hostsharing.net", givenPartnerAdmin);
|
||||||
final var givenMembership = givenSomeTemporaryMembershipBessler("First");
|
final var givenMembership = givenSomeTemporaryMembershipBessler("First");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.header("assumed-roles", givenPartnerAgent)
|
.header("assumed-roles", givenPartnerAdmin)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
|
@ -110,9 +110,9 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
final var all = rawRoleRepo.findAll();
|
final var all = rawRoleRepo.findAll();
|
||||||
assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
||||||
initialRoleNames,
|
initialRoleNames,
|
||||||
"hs_office_membership#M-1000117:ADMIN",
|
|
||||||
"hs_office_membership#M-1000117:OWNER",
|
"hs_office_membership#M-1000117:OWNER",
|
||||||
"hs_office_membership#M-1000117:REFERRER"));
|
"hs_office_membership#M-1000117:ADMIN",
|
||||||
|
"hs_office_membership#M-1000117:AGENT"));
|
||||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
|
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
|
||||||
.map(s -> s.replace("hs_office_", ""))
|
.map(s -> s.replace("hs_office_", ""))
|
||||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||||
@ -122,21 +122,21 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
"{ grant perm:membership#M-1000117:INSERT>coopsharestransaction to role:membership#M-1000117:ADMIN by system and assume }",
|
"{ grant perm:membership#M-1000117:INSERT>coopsharestransaction to role:membership#M-1000117:ADMIN by system and assume }",
|
||||||
|
|
||||||
// owner
|
// owner
|
||||||
"{ grant perm:membership#M-1000117:DELETE to role:membership#M-1000117:OWNER by system and assume }",
|
"{ grant perm:membership#M-1000117:DELETE to role:membership#M-1000117:ADMIN by system and assume }",
|
||||||
|
"{ grant role:membership#M-1000117:OWNER to user:superuser-alex@hostsharing.net by membership#M-1000117:OWNER and assume }",
|
||||||
|
|
||||||
// admin
|
// admin
|
||||||
"{ grant perm:membership#M-1000117:UPDATE to role:membership#M-1000117:ADMIN by system and assume }",
|
"{ grant perm:membership#M-1000117:UPDATE to role:membership#M-1000117:ADMIN by system and assume }",
|
||||||
"{ grant role:membership#M-1000117:ADMIN to role:membership#M-1000117:OWNER by system and assume }",
|
"{ grant role:membership#M-1000117:ADMIN to role:membership#M-1000117:OWNER by system and assume }",
|
||||||
"{ grant role:membership#M-1000117:OWNER to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:ADMIN by system and assume }",
|
"{ grant role:membership#M-1000117:ADMIN to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:ADMIN by system and assume }",
|
||||||
"{ grant role:membership#M-1000117:OWNER to user:superuser-alex@hostsharing.net by membership#M-1000117:OWNER and assume }",
|
|
||||||
|
|
||||||
// agent
|
// agent
|
||||||
"{ grant role:membership#M-1000117:ADMIN to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT by system and assume }",
|
"{ grant perm:membership#M-1000117:SELECT to role:membership#M-1000117:AGENT by system and assume }",
|
||||||
|
"{ grant role:membership#M-1000117:AGENT to role:membership#M-1000117:ADMIN by system and assume }",
|
||||||
|
|
||||||
// referrer
|
// referrer
|
||||||
"{ grant perm:membership#M-1000117:SELECT to role:membership#M-1000117:REFERRER by system and assume }",
|
"{ grant role:membership#M-1000117:AGENT to role:relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT by system and assume }",
|
||||||
"{ grant role:membership#M-1000117:REFERRER to role:membership#M-1000117:ADMIN by system and assume }",
|
"{ grant role:relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT to role:membership#M-1000117:AGENT by system and assume }",
|
||||||
"{ grant role:relation#HostsharingeG-with-PARTNER-FirstGmbH:TENANT to role:membership#M-1000117:REFERRER by system and assume }",
|
|
||||||
|
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
@ -224,20 +224,20 @@ class HsOfficeMembershipRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void membershipReferrer_canViewButNotUpdateRelatedMembership() {
|
public void membershipAgent_canViewButNotUpdateRelatedMembership() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenMembership = givenSomeTemporaryMembership("First", "13");
|
final var givenMembership = givenSomeTemporaryMembership("First", "13");
|
||||||
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
assertThatMembershipExistsAndIsAccessibleToCurrentContext(givenMembership);
|
||||||
assertThatMembershipIsVisibleForRole(
|
assertThatMembershipIsVisibleForRole(
|
||||||
givenMembership,
|
givenMembership,
|
||||||
"hs_office_membership#M-1000113:REFERRER");
|
"hs_office_membership#M-1000113:AGENT");
|
||||||
final var newValidityEnd = LocalDate.now();
|
final var newValidityEnd = LocalDate.now();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
// TODO: we should test with debitor- and partner-admin as well
|
// TODO: we should test with debitor- and partner-admin as well
|
||||||
context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000113:REFERRER");
|
context("superuser-alex@hostsharing.net", "hs_office_membership#M-1000113:AGENT");
|
||||||
givenMembership.setValidity(
|
givenMembership.setValidity(
|
||||||
Range.closedOpen(givenMembership.getValidity().lower(), newValidityEnd));
|
Range.closedOpen(givenMembership.getValidity().lower(), newValidityEnd));
|
||||||
return membershipRepo.save(givenMembership);
|
return membershipRepo.save(givenMembership);
|
||||||
|
@ -362,7 +362,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
assertThat(givenRelation.getContact().getLabel()).isEqualTo("seventh contact");
|
assertThat(givenRelation.getContact().getLabel()).isEqualTo("seventh contact");
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth").get(0);
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
|
@ -103,69 +103,6 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
|
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
|
||||||
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
|
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
|
||||||
|
|
||||||
// when
|
|
||||||
attempt(em, () -> {
|
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
|
|
||||||
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
|
|
||||||
.findFirst().orElseThrow();
|
|
||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Bert").stream()
|
|
||||||
.filter(p -> p.getPersonType() == NATURAL_PERSON)
|
|
||||||
.findFirst().orElseThrow();
|
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("fourth contact").stream()
|
|
||||||
.findFirst().orElseThrow();
|
|
||||||
final var newRelation = HsOfficeRelationEntity.builder()
|
|
||||||
.anchor(givenAnchorPerson)
|
|
||||||
.holder(givenHolderPerson)
|
|
||||||
.type(HsOfficeRelationType.SUBSCRIBER)
|
|
||||||
.mark("dummy")
|
|
||||||
.contact(givenContact)
|
|
||||||
.build();
|
|
||||||
return toCleanup(relationRepo.save(newRelation));
|
|
||||||
});
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
|
||||||
initialRoleNames,
|
|
||||||
"hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:OWNER",
|
|
||||||
"hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:ADMIN",
|
|
||||||
"hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:AGENT",
|
|
||||||
"hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:TENANT"));
|
|
||||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
|
|
||||||
initialGrantNames,
|
|
||||||
// TODO: this grant should only be created for DEBITOR-Relationships, thus the RBAC DSL needs to support conditional grants
|
|
||||||
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:INSERT>hs_office_sepamandate to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:ADMIN by system and assume }",
|
|
||||||
|
|
||||||
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:DELETE to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:OWNER by system and assume }",
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:OWNER to role:global#global:ADMIN by system and assume }",
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:OWNER to user:superuser-alex@hostsharing.net by hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:OWNER and assume }",
|
|
||||||
|
|
||||||
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:UPDATE to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:ADMIN by system and assume }",
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:ADMIN to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:OWNER by system and assume }",
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:ADMIN to role:hs_office_person#ErbenBesslerMelBessler:ADMIN by system and assume }",
|
|
||||||
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:AGENT to role:hs_office_person#BesslerBert:ADMIN by system and assume }",
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:AGENT to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:ADMIN by system and assume }",
|
|
||||||
|
|
||||||
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:SELECT to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:TENANT by system and assume }",
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:TENANT to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:AGENT by system and assume }",
|
|
||||||
"{ grant role:hs_office_person#BesslerBert:REFERRER to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:TENANT by system and assume }",
|
|
||||||
"{ grant role:hs_office_person#ErbenBesslerMelBessler:REFERRER to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:TENANT by system and assume }",
|
|
||||||
"{ grant role:hs_office_contact#fourthcontact:REFERRER to role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:TENANT by system and assume }",
|
|
||||||
|
|
||||||
// SUBSCRIBER holder person -> (represented) anchor person
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-SUBSCRIBER-BesslerBert:TENANT to role:hs_office_contact#fourthcontact:ADMIN by system and assume }",
|
|
||||||
|
|
||||||
null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void createsAndGrantsRolesForTypeRepresentative() {
|
|
||||||
// given
|
|
||||||
context("superuser-alex@hostsharing.net");
|
|
||||||
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
|
|
||||||
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
attempt(em, () -> {
|
attempt(em, () -> {
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
|
||||||
@ -203,9 +140,9 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
|
|
||||||
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:UPDATE to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
|
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:UPDATE to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER by system and assume }",
|
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER by system and assume }",
|
||||||
"{ grant role:hs_office_person#ErbenBesslerMelBessler:OWNER to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
|
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN to role:hs_office_person#ErbenBesslerMelBessler:ADMIN by system and assume }",
|
||||||
|
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:OWNER to role:hs_office_person#BesslerBert:ADMIN by system and assume }",
|
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:AGENT to role:hs_office_person#BesslerBert:ADMIN by system and assume }",
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:AGENT to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
|
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:AGENT to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:ADMIN by system and assume }",
|
||||||
|
|
||||||
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:SELECT to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT by system and assume }",
|
"{ grant perm:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:SELECT to role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT by system and assume }",
|
||||||
@ -216,6 +153,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
|
|
||||||
// REPRESENTATIVE holder person -> (represented) anchor person
|
// REPRESENTATIVE holder person -> (represented) anchor person
|
||||||
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT to role:hs_office_contact#fourthcontact:ADMIN by system and assume }",
|
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT to role:hs_office_contact#fourthcontact:ADMIN by system and assume }",
|
||||||
|
"{ grant role:hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert:TENANT to role:hs_office_person#BesslerBert:ADMIN by system and assume }",
|
||||||
|
|
||||||
null)
|
null)
|
||||||
);
|
);
|
||||||
@ -279,10 +217,10 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenRelation = givenSomeTemporaryRelationBessler(
|
final var givenRelation = givenSomeTemporaryRelationBessler(
|
||||||
"Bert", "fifth contact");
|
"Bert", "fifth contact");
|
||||||
|
assertThatRelationActuallyInDatabase(givenRelation);
|
||||||
assertThatRelationIsVisibleForUserWithRole(
|
assertThatRelationIsVisibleForUserWithRole(
|
||||||
givenRelation,
|
givenRelation,
|
||||||
"hs_office_person#ErbenBesslerMelBessler:ADMIN");
|
"hs_office_person#ErbenBesslerMelBessler:ADMIN");
|
||||||
assertThatRelationActuallyInDatabase(givenRelation);
|
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").stream().findFirst().orElseThrow();
|
final var givenContact = contactRepo.findContactByOptionalLabelLike("sixth contact").stream().findFirst().orElseThrow();
|
||||||
|
|
||||||
|
@ -5,8 +5,7 @@ import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
|||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRvEntity;
|
|
||||||
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
|
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
|
||||||
import net.hostsharing.test.JpaAttempt;
|
import net.hostsharing.test.JpaAttempt;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -255,7 +254,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
|
|||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net", null);
|
context.define("superuser-alex@hostsharing.net", null);
|
||||||
return rbacRoleRepo.findAll().stream()
|
return rbacRoleRepo.findAll().stream()
|
||||||
.map(RbacRoleRvEntity::getRoleName)
|
.map(RbacRoleEntity::getRoleName)
|
||||||
.collect(toSet());
|
.collect(toSet());
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import io.restassured.http.ContentType;
|
|||||||
import io.restassured.response.ValidatableResponse;
|
import io.restassured.response.ValidatableResponse;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRvEntity;
|
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
|
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity;
|
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
|
import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository;
|
||||||
@ -361,11 +361,11 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
this(currentUser, "");
|
this(currentUser, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
GrantFixture grantsRole(final RbacRoleRvEntity givenOwnPackageAdminRole) {
|
GrantFixture grantsRole(final RbacRoleEntity givenOwnPackageAdminRole) {
|
||||||
return new GrantFixture(givenOwnPackageAdminRole);
|
return new GrantFixture(givenOwnPackageAdminRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
RevokeFixture revokesRole(final RbacRoleRvEntity givenOwnPackageAdminRole) {
|
RevokeFixture revokesRole(final RbacRoleEntity givenOwnPackageAdminRole) {
|
||||||
return new RevokeFixture(givenOwnPackageAdminRole);
|
return new RevokeFixture(givenOwnPackageAdminRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,11 +376,11 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
class GrantFixture {
|
class GrantFixture {
|
||||||
|
|
||||||
private Subject grantingSubject = Subject.this;
|
private Subject grantingSubject = Subject.this;
|
||||||
private final RbacRoleRvEntity grantedRole;
|
private final RbacRoleEntity grantedRole;
|
||||||
private boolean assumed;
|
private boolean assumed;
|
||||||
private RbacUserEntity granteeUser;
|
private RbacUserEntity granteeUser;
|
||||||
|
|
||||||
public GrantFixture(final RbacRoleRvEntity roleToGrant) {
|
public GrantFixture(final RbacRoleEntity roleToGrant) {
|
||||||
this.grantedRole = roleToGrant;
|
this.grantedRole = roleToGrant;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,11 +417,11 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
class RevokeFixture {
|
class RevokeFixture {
|
||||||
|
|
||||||
private Subject currentSubject = Subject.this;
|
private Subject currentSubject = Subject.this;
|
||||||
private final RbacRoleRvEntity grantedRole;
|
private final RbacRoleEntity grantedRole;
|
||||||
private boolean assumed;
|
private boolean assumed;
|
||||||
private RbacUserEntity granteeUser;
|
private RbacUserEntity granteeUser;
|
||||||
|
|
||||||
public RevokeFixture(final RbacRoleRvEntity roleToGrant) {
|
public RevokeFixture(final RbacRoleEntity roleToGrant) {
|
||||||
this.grantedRole = roleToGrant;
|
this.grantedRole = roleToGrant;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,9 +455,9 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
private class GetGrantByIdFixture {
|
private class GetGrantByIdFixture {
|
||||||
|
|
||||||
private Subject currentSubject = Subject.this;
|
private Subject currentSubject = Subject.this;
|
||||||
private RbacRoleRvEntity grantedRole;
|
private RbacRoleEntity grantedRole;
|
||||||
|
|
||||||
GetGrantByIdFixture forGrantedRole(final RbacRoleRvEntity grantedRole) {
|
GetGrantByIdFixture forGrantedRole(final RbacRoleEntity grantedRole) {
|
||||||
this.grantedRole = grantedRole;
|
this.grantedRole = grantedRole;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -507,7 +507,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
|||||||
}).assertNotNull().returnedValue();
|
}).assertNotNull().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
RbacRoleRvEntity getRbacRoleByName(final String roleName) {
|
RbacRoleEntity getRbacRoleByName(final String roleName) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
return rbacRoleRepository.findByRoleName(roleName);
|
return rbacRoleRepository.findByRoleName(roleName);
|
||||||
|
@ -175,21 +175,21 @@ class RbacRoleRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void exactlyTheseRbacRolesAreReturned(final List<RbacRoleRvEntity> actualResult, final String... expectedRoleNames) {
|
void exactlyTheseRbacRolesAreReturned(final List<RbacRoleEntity> actualResult, final String... expectedRoleNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(RbacRoleRvEntity::getRoleName)
|
.extracting(RbacRoleEntity::getRoleName)
|
||||||
.containsExactlyInAnyOrder(expectedRoleNames);
|
.containsExactlyInAnyOrder(expectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void allTheseRbacRolesAreReturned(final List<RbacRoleRvEntity> actualResult, final String... expectedRoleNames) {
|
void allTheseRbacRolesAreReturned(final List<RbacRoleEntity> actualResult, final String... expectedRoleNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(RbacRoleRvEntity::getRoleName)
|
.extracting(RbacRoleEntity::getRoleName)
|
||||||
.contains(expectedRoleNames);
|
.contains(expectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
void noneOfTheseRbacRolesIsReturned(final List<RbacRoleRvEntity> actualResult, final String... unexpectedRoleNames) {
|
void noneOfTheseRbacRolesIsReturned(final List<RbacRoleEntity> actualResult, final String... unexpectedRoleNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(RbacRoleRvEntity::getRoleName)
|
.extracting(RbacRoleEntity::getRoleName)
|
||||||
.doesNotContain(unexpectedRoleNames);
|
.doesNotContain(unexpectedRoleNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@ import static java.util.UUID.randomUUID;
|
|||||||
|
|
||||||
public class TestRbacRole {
|
public class TestRbacRole {
|
||||||
|
|
||||||
public static final RbacRoleRvEntity hostmasterRole = rbacRole("global", "global", RbacRoleType.ADMIN);
|
public static final RbacRoleEntity hostmasterRole = rbacRole("global", "global", RbacRoleType.ADMIN);
|
||||||
static final RbacRoleRvEntity customerXxxOwner = rbacRole("test_customer", "xxx", RbacRoleType.OWNER);
|
static final RbacRoleEntity customerXxxOwner = rbacRole("test_customer", "xxx", RbacRoleType.OWNER);
|
||||||
static final RbacRoleRvEntity customerXxxAdmin = rbacRole("test_customer", "xxx", RbacRoleType.ADMIN);
|
static final RbacRoleEntity customerXxxAdmin = rbacRole("test_customer", "xxx", RbacRoleType.ADMIN);
|
||||||
|
|
||||||
static public RbacRoleRvEntity rbacRole(final String objectTable, final String objectIdName, final RbacRoleType roleType) {
|
static public RbacRoleEntity rbacRole(final String objectTable, final String objectIdName, final RbacRoleType roleType) {
|
||||||
return new RbacRoleRvEntity(randomUUID(), randomUUID(), objectTable, objectIdName, roleType, objectTable+'#'+objectIdName+':'+roleType);
|
return new RbacRoleEntity(randomUUID(), randomUUID(), objectTable, objectIdName, roleType, objectTable+'#'+objectIdName+':'+roleType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user