1
0

introduce separate database-schemas base+rbac (#103)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Co-authored-by: Michael Hönnig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/103
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-09-16 15:36:37 +02:00
parent 80d79de5f4
commit 1eed0e9b21
287 changed files with 3194 additions and 3454 deletions

View File

@@ -38,53 +38,53 @@ public class Context {
private HttpServletRequest request;
@Transactional(propagation = MANDATORY)
public void define(final String currentUser) {
define(currentUser, null);
public void define(final String currentSubject) {
define(currentSubject, null);
}
@Transactional(propagation = MANDATORY)
public void define(final String currentUser, final String assumedRoles) {
define(toTask(request), toCurl(request), currentUser, assumedRoles);
public void define(final String currentSubject, final String assumedRoles) {
define(toTask(request), toCurl(request), currentSubject, assumedRoles);
}
@Transactional(propagation = MANDATORY)
public void define(
final String currentTask,
final String currentRequest,
final String currentUser,
final String currentSubject,
final String assumedRoles) {
final var query = em.createNativeQuery("""
call defineContext(
call base.defineContext(
cast(:currentTask as varchar(127)),
cast(:currentRequest as text),
cast(:currentUser as varchar(63)),
cast(:currentSubject as varchar(63)),
cast(:assumedRoles as varchar(1023)));
""");
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
query.setParameter("currentRequest", currentRequest);
query.setParameter("currentUser", currentUser);
query.setParameter("currentSubject", currentSubject);
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
query.executeUpdate();
}
public String getCurrentTask() {
public String fetchCurrentTask() {
return (String) em.createNativeQuery("select current_setting('hsadminng.currentTask');").getSingleResult();
}
public String getCurrentUser() {
return String.valueOf(em.createNativeQuery("select currentUser()").getSingleResult());
public String fetchCurrentSubject() {
return String.valueOf(em.createNativeQuery("select base.currentSubject()").getSingleResult());
}
public UUID getCurrentUserUUid() {
return (UUID) em.createNativeQuery("select currentUserUUid()", UUID.class).getSingleResult();
public UUID fetchCurrentSubjectUuid() {
return (UUID) em.createNativeQuery("select rbac.currentSubjectUuid()", UUID.class).getSingleResult();
}
public String[] getAssumedRoles() {
return (String[]) em.createNativeQuery("select assumedRoles() as roles", String[].class).getSingleResult();
public String[] fetchAssumedRoles() {
return (String[]) em.createNativeQuery("select base.assumedRoles() as roles", String[].class).getSingleResult();
}
public UUID[] currentSubjectsUuids() {
return (UUID[]) em.createNativeQuery("select currentSubjectsUuids() as uuids", UUID[].class).getSingleResult();
public UUID[] fetchCurrentSubjectOrAssumedRolesUuids() {
return (UUID[]) em.createNativeQuery("select rbac.currentSubjectOrAssumedRolesUuids() as uuids", UUID[].class).getSingleResult();
}
public static String getCallerMethodNameFromStackFrame(final int skipFrames) {

View File

@@ -14,7 +14,7 @@ import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type;

View File

@@ -41,10 +41,10 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsBookingItemResource>> listBookingItemsByProjectUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID projectUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = bookingItemRepo.findAllByProjectUuid(projectUuid);
@@ -55,11 +55,11 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override
@Transactional
public ResponseEntity<HsBookingItemResource> addBookingItem(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsBookingItemInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsBookingItemRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@@ -77,11 +77,11 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsBookingItemResource> getBookingItemByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID bookingItemUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = bookingItemRepo.findByUuid(bookingItemUuid);
result.ifPresent(entity -> em.detach(entity)); // prevent further LAZY-loading
@@ -94,10 +94,10 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteBookingIemByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID bookingItemUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = bookingItemRepo.deleteByUuid(bookingItemUuid);
return result == 0
@@ -108,12 +108,12 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override
@Transactional
public ResponseEntity<HsBookingItemResource> patchBookingItem(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID bookingItemUuid,
final HsBookingItemPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = bookingItemRepo.findByUuid(bookingItemUuid).orElseThrow();

View File

@@ -5,8 +5,8 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
@@ -15,19 +15,20 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import java.io.IOException;
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.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
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.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
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.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_booking_item_rv")
@@ -45,8 +46,8 @@ public class HsBookingItemRbacEntity extends HsBookingItem {
.withIdentityView(SQL.projection("caption"))
.withRestrictedViewOrderBy(SQL.expression("validity"))
.withUpdatableColumns("version", "caption", "validity", "resources")
.toRole("global", ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.toRole("global", ADMIN).grantPermission(DELETE)
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
.importEntityAlias("project", HsBookingProject.class, usingDefaultCase(),
dependsOnColumn("projectUuid"),
@@ -74,7 +75,7 @@ public class HsBookingItemRbacEntity extends HsBookingItem {
with.permission(SELECT);
})
.limitDiagramTo("bookingItem", "project", "global");
.limitDiagramTo("bookingItem", "project", "rbac.global");
}
public static void main(String[] args) throws IOException {

View File

@@ -5,9 +5,9 @@ import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
@@ -17,15 +17,16 @@ import java.util.UUID;
import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
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.ColumnValue.usingDefaultCase;
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.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
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.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@MappedSuperclass
@@ -69,7 +70,7 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
public static RbacView rbac() {
return rbacViewFor("project", HsBookingProject.class)
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
"""))
@@ -91,7 +92,7 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
"""),
NOT_NULL)
.toRole("debitorRel", ADMIN).grantPermission(INSERT)
.toRole("global", ADMIN).grantPermission(DELETE)
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
.createRole(OWNER, (with) -> {
with.incomingSuperRole("debitorRel", AGENT).unassumed();
@@ -105,7 +106,7 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
with.permission(SELECT);
})
.limitDiagramTo("project", "debitorRel", "global");
.limitDiagramTo("project", "debitorRel", "rbac.global");
}
public static void main(String[] args) throws IOException {

View File

@@ -36,10 +36,10 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsBookingProjectResource>> listBookingProjectsByDebitorUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID debitorUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = bookingProjectRepo.findAllByDebitorUuid(debitorUuid);
@@ -50,11 +50,11 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override
@Transactional
public ResponseEntity<HsBookingProjectResource> addBookingProject(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsBookingProjectInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsBookingProjectRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@@ -72,11 +72,11 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsBookingProjectResource> getBookingProjectByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID bookingProjectUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = bookingProjectRepo.findByUuid(bookingProjectUuid);
return result
@@ -88,10 +88,10 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteBookingIemByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID bookingProjectUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = bookingProjectRepo.deleteByUuid(bookingProjectUuid);
return result == 0
@@ -102,12 +102,12 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override
@Transactional
public ResponseEntity<HsBookingProjectResource> patchBookingProject(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID bookingProjectUuid,
final HsBookingProjectPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = bookingProjectRepo.findByUuid(bookingProjectUuid).orElseThrow();

View File

@@ -6,29 +6,30 @@ import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import java.io.IOException;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
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.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
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.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
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.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_booking_project_rv")
@@ -41,7 +42,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
public static RbacView rbac() {
return rbacViewFor("project", HsBookingProjectRbacEntity.class)
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
"""))
@@ -63,7 +64,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
"""),
NOT_NULL)
.toRole("debitorRel", ADMIN).grantPermission(INSERT)
.toRole("global", ADMIN).grantPermission(DELETE)
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
.createRole(OWNER, (with) -> {
with.incomingSuperRole("debitorRel", AGENT).unassumed();
@@ -77,7 +78,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
with.permission(SELECT);
})
.limitDiagramTo("project", "debitorRel", "global");
.limitDiagramTo("project", "debitorRel", "rbac.global");
}
public static void main(String[] args) throws IOException {

View File

@@ -14,7 +14,7 @@ import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type;

View File

@@ -49,12 +49,12 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsHostingAssetResource>> listAssets(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID debitorUuid,
final UUID parentAssetUuid,
final HsHostingAssetTypeResource type) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = rbacAssetRepo.findAllByCriteria(debitorUuid, parentAssetUuid, HsHostingAssetType.of(type));
@@ -66,11 +66,11 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override
@Transactional
public ResponseEntity<HsHostingAssetResource> addAsset(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsHostingAssetInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entity = mapper.map(body, HsHostingAssetRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@@ -94,11 +94,11 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsHostingAssetResource> getAssetByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID assetUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = rbacAssetRepo.findByUuid(assetUuid);
return result
@@ -110,10 +110,10 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteAssetUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID assetUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = rbacAssetRepo.deleteByUuid(assetUuid);
return result == 0
@@ -124,12 +124,12 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override
@Transactional
public ResponseEntity<HsHostingAssetResource> patchAsset(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID assetUuid,
final HsHostingAssetPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entity = rbacAssetRepo.findByUuid(assetUuid).orElseThrow();

View File

@@ -6,31 +6,31 @@ import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import java.io.IOException;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
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.GLOBAL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
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.RbacUserReference.UserRole.CREATOR;
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.GUEST;
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.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef.inCaseOf;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.GUEST;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.REFERRER;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_hosting_asset_rv")
@@ -106,7 +106,7 @@ public class HsHostingAssetRbacEntity extends HsHostingAsset {
"parentAsset",
"assignedToAsset",
"alarmContact",
"global");
"rbac.global");
}
public static void main(String[] args) throws IOException {

View File

@@ -32,10 +32,10 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeBankAccountResource>> listBankAccounts(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final String holder) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = bankAccountRepo.findByOptionalHolderLike(holder);
@@ -46,11 +46,11 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeBankAccountResource> addBankAccount(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficeBankAccountInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
IbanUtil.validate(body.getIban());
BicUtil.validate(body.getBic());
@@ -72,11 +72,11 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeBankAccountResource> getBankAccountByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID bankAccountUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = bankAccountRepo.findByUuid(bankAccountUuid);
if (result.isEmpty()) {
@@ -88,10 +88,10 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteBankAccountByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID BankAccountUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = bankAccountRepo.deleteByUuid(BankAccountUuid);
if (result == 0) {

View File

@@ -3,8 +3,8 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
import lombok.*;
import lombok.experimental.FieldNameConstants;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
@@ -12,10 +12,10 @@ import jakarta.persistence.*;
import java.io.IOException;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.*;
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.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@@ -62,7 +62,7 @@ public class HsOfficeBankAccountEntity implements BaseEntity<HsOfficeBankAccount
.withIdentityView(SQL.projection("iban"))
.withUpdatableColumns("holder", "iban", "bic")
.toRole("global", GUEST).grantPermission(INSERT)
.toRole(GLOBAL, GUEST).grantPermission(INSERT)
.createRole(OWNER, (with) -> {
with.owningUser(CREATOR);

View File

@@ -11,7 +11,7 @@ import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator;

View File

@@ -34,10 +34,10 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeContactResource>> listContacts(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final String caption) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = contactRepo.findContactByOptionalCaptionLike(caption);
@@ -48,11 +48,11 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeContactResource> addContact(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficeContactInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficeContactRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@@ -70,11 +70,11 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeContactResource> getContactByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID contactUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = contactRepo.findByUuid(contactUuid);
if (result.isEmpty()) {
@@ -86,10 +86,10 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteContactByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID contactUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = contactRepo.deleteByUuid(contactUuid);
if (result == 0) {
@@ -102,12 +102,12 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeContactResource> patchContact(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID contactUuid,
final HsOfficeContactPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = contactRepo.findByUuid(contactUuid).orElseThrow();

View File

@@ -3,17 +3,17 @@ package net.hostsharing.hsadminng.hs.office.contact;
import lombok.*;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import jakarta.persistence.*;
import java.io.IOException;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
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.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_office_contact_rv")

View File

@@ -37,12 +37,12 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeCoopAssetsTransactionResource>> listCoopAssets(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID membershipUuid,
final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate,
final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
membershipUuid,
@@ -56,11 +56,11 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
@Override
@Transactional
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> addCoopAssetsTransaction(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficeCoopAssetsTransactionInsertResource requestBody) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
validate(requestBody);
final var entityToSave = mapper.map(requestBody, HsOfficeCoopAssetsTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@@ -79,9 +79,9 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> getCoopAssetTransactionByUuid(
final String currentUser, final String assumedRoles, final UUID assetTransactionUuid) {
final String currentSubject, final String assumedRoles, final UUID assetTransactionUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = coopAssetsTransactionRepo.findByUuid(assetTransactionUuid);
if (result.isEmpty()) {

View File

@@ -8,8 +8,8 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator;
@@ -21,16 +21,16 @@ import java.time.LocalDate;
import java.util.UUID;
import static java.util.Optional.ofNullable;
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.Nullable.NOT_NULL;
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.AGENT;
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.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity

View File

@@ -39,12 +39,12 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> listCoopShares(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID membershipUuid,
final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate,
final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
membershipUuid,
@@ -58,11 +58,11 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
@Override
@Transactional
public ResponseEntity<HsOfficeCoopSharesTransactionResource> addCoopSharesTransaction(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficeCoopSharesTransactionInsertResource requestBody) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
validate(requestBody);
final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@@ -81,9 +81,9 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeCoopSharesTransactionResource> getCoopShareTransactionByUuid(
final String currentUser, final String assumedRoles, final UUID shareTransactionUuid) {
final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid);
if (result.isEmpty()) {

View File

@@ -7,9 +7,9 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
@@ -19,16 +19,16 @@ import java.time.LocalDate;
import java.util.UUID;
import static java.util.Optional.ofNullable;
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.Nullable.NOT_NULL;
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.AGENT;
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.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity

View File

@@ -8,7 +8,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebito
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import org.apache.commons.lang3.Validate;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
@@ -48,11 +48,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeDebitorResource>> listDebitors(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final String name,
final Integer debitorNumber) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = debitorNumber != null
? debitorRepo.findDebitorByDebitorNumber(debitorNumber)
@@ -65,11 +65,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeDebitorResource> addDebitor(
String currentUser,
String currentSubject,
String assumedRoles,
HsOfficeDebitorInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
@@ -112,11 +112,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeDebitorResource> getDebitorByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID debitorUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = debitorRepo.findByUuid(debitorUuid);
if (result.isEmpty()) {
@@ -128,10 +128,10 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteDebitorByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID debitorUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = debitorRepo.deleteByUuid(debitorUuid);
if (result == 0) {
@@ -144,12 +144,12 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeDebitorResource> patchDebitor(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID debitorUuid,
final HsOfficeDebitorPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow();

View File

@@ -11,9 +11,9 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator;
@@ -40,16 +40,17 @@ import static jakarta.persistence.CascadeType.PERSIST;
import static jakarta.persistence.CascadeType.REFRESH;
import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
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.ColumnValue.usingDefaultCase;
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.Permission.*;
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.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@@ -188,7 +189,7 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
"vatBusiness",
"vatReverseCharge",
"defaultPrefix")
.toRole("global", ADMIN).grantPermission(INSERT)
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
directlyFetchedByDependsOnColumn(),

View File

@@ -32,11 +32,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeMembershipResource>> listMemberships(
final String currentUser,
final String currentSubject,
final String assumedRoles,
UUID partnerUuid,
Integer memberNumber) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = ( memberNumber != null)
? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber))
@@ -50,11 +50,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeMembershipResource> addMembership(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficeMembershipInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class);
@@ -73,11 +73,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeMembershipResource> getMembershipByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID membershipUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = membershipRepo.findByUuid(membershipUuid);
if (result.isEmpty()) {
@@ -90,10 +90,10 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteMembershipByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID membershipUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = membershipRepo.deleteByUuid(membershipUuid);
if (result == 0) {
@@ -106,12 +106,12 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeMembershipResource> patchMembership(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID membershipUuid,
final HsOfficeMembershipPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = membershipRepo.findByUuid(membershipUuid).orElseThrow();

View File

@@ -9,10 +9,10 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type;
@@ -38,20 +38,21 @@ import static io.hypersistence.utils.hibernate.type.range.Range.emptyRange;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.lowerInclusiveFromPostgresDateRange;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.upperInclusiveFromPostgresDateRange;
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.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
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.RbacUserReference.UserRole.CREATOR;
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.OWNER;
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.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@@ -174,7 +175,7 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
WHERE partner.uuid = ${REF}.partnerUuid
"""),
NOT_NULL)
.toRole("global", ADMIN).grantPermission(INSERT)
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
.createRole(OWNER, (with) -> {
with.owningUser(CREATOR);

View File

@@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -50,10 +50,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficePartnerResource>> listPartners(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final String name) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
@@ -64,11 +64,11 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override
@Transactional
public ResponseEntity<HsOfficePartnerResource> addPartner(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficePartnerInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = createPartnerEntity(body);
@@ -86,11 +86,11 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficePartnerResource> getPartnerByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID partnerUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = partnerRepo.findByUuid(partnerUuid);
if (result.isEmpty()) {
@@ -102,10 +102,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override
@Transactional
public ResponseEntity<Void> deletePartnerByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID partnerUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var partnerToDelete = partnerRepo.findByUuid(partnerUuid);
if (partnerToDelete.isEmpty()) {
@@ -122,12 +122,12 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override
@Transactional
public ResponseEntity<HsOfficePartnerResource> patchPartner(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID partnerUuid,
final HsOfficePartnerPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = partnerRepo.findByUuid(partnerUuid).orElseThrow();
final var previousPartnerRel = current.getPartnerRel();

View File

@@ -2,9 +2,9 @@ package net.hostsharing.hsadminng.hs.office.partner;
import lombok.*;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
@@ -13,9 +13,10 @@ import java.io.IOException;
import java.time.LocalDate;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@@ -82,7 +83,7 @@ public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerD
"birthName",
"birthday",
"dateOfDeath")
.toRole("global", ADMIN).grantPermission(INSERT)
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
// The grants are defined in HsOfficePartnerEntity.rbac()
// because they have to be changed when its partnerRel changes,

View File

@@ -10,10 +10,10 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.NotFound;
@@ -24,13 +24,14 @@ import java.io.IOException;
import java.util.UUID;
import static jakarta.persistence.CascadeType.*;
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.SELECT;
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.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@@ -103,7 +104,7 @@ public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOffice
return rbacViewFor("partner", HsOfficePartnerEntity.class)
.withIdentityView(SQL.projection("'P-' || partnerNumber"))
.withUpdatableColumns("partnerRelUuid")
.toRole("global", ADMIN).grantPermission(INSERT)
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
usingDefaultCase(),

View File

@@ -31,10 +31,10 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficePersonResource>> listPersons(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final String caption) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = personRepo.findPersonByOptionalNameLike(caption);
@@ -45,11 +45,11 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override
@Transactional
public ResponseEntity<HsOfficePersonResource> addPerson(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficePersonInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficePersonEntity.class);
@@ -67,11 +67,11 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficePersonResource> getPersonByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID personUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = personRepo.findByUuid(personUuid);
if (result.isEmpty()) {
@@ -83,10 +83,10 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override
@Transactional
public ResponseEntity<Void> deletePersonByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID personUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = personRepo.deleteByUuid(personUuid);
if (result == 0) {
@@ -99,12 +99,12 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override
@Transactional
public ResponseEntity<HsOfficePersonResource> patchPerson(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID personUuid,
final HsOfficePersonPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = personRepo.findByUuid(personUuid).orElseThrow();

View File

@@ -3,9 +3,9 @@ package net.hostsharing.hsadminng.hs.office.person;
import lombok.*;
import lombok.experimental.FieldNameConstants;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.apache.commons.lang3.StringUtils;
@@ -14,11 +14,11 @@ import jakarta.persistence.*;
import java.io.IOException;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
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.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@@ -80,7 +80,7 @@ public class HsOfficePersonEntity implements BaseEntity<HsOfficePersonEntity>, S
return rbacViewFor("person", HsOfficePersonEntity.class)
.withIdentityView(SQL.projection("concat(tradeName, familyName, givenName)"))
.withUpdatableColumns("personType", "title", "salutation", "tradeName", "givenName", "familyName")
.toRole("global", GUEST).grantPermission(INSERT)
.toRole(GLOBAL, GUEST).grantPermission(INSERT)
.createRole(OWNER, (with) -> {
with.permission(DELETE);

View File

@@ -5,7 +5,7 @@ import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;

View File

@@ -45,11 +45,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeRelationResource>> listRelations(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID personUuid,
final HsOfficeRelationTypeResource relationType) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = relationRbacRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid,
mapper.map(relationType, HsOfficeRelationType.class));
@@ -62,11 +62,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeRelationResource> addRelation(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficeRelationInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = new HsOfficeRelationRbacEntity();
entityToSave.setType(HsOfficeRelationType.valueOf(body.getType()));
@@ -96,11 +96,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeRelationResource> getRelationByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID relationUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = relationRbacRepo.findByUuid(relationUuid);
if (result.isEmpty()) {
@@ -112,10 +112,10 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override
@Transactional
public ResponseEntity<Void> deleteRelationByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID relationUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = relationRbacRepo.deleteByUuid(relationUuid);
if (result == 0) {
@@ -128,12 +128,12 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override
@Transactional
public ResponseEntity<HsOfficeRelationResource> patchRelation(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID relationUuid,
final HsOfficeRelationPatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = relationRbacRepo.findByUuid(relationUuid).orElseThrow();

View File

@@ -7,31 +7,31 @@ import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import java.io.IOException;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inOtherCases;
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.GLOBAL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
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.RbacUserReference.UserRole.CREATOR;
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.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.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef.inCaseOf;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef.inOtherCases;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.REFERRER;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_office_relation_rv")

View File

@@ -39,10 +39,10 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeSepaMandateResource>> listSepaMandatesByIban(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final String iban) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entities = sepaMandateRepo.findSepaMandateByOptionalIban(iban);
@@ -54,11 +54,11 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override
@Transactional
public ResponseEntity<HsOfficeSepaMandateResource> addSepaMandate(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final HsOfficeSepaMandateInsertResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficeSepaMandateEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER);
@@ -77,11 +77,11 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<HsOfficeSepaMandateResource> getSepaMandateByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID sepaMandateUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = sepaMandateRepo.findByUuid(sepaMandateUuid);
if (result.isEmpty()) {
@@ -94,10 +94,10 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override
@Transactional
public ResponseEntity<Void> deleteSepaMandateByUuid(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID sepaMandateUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = sepaMandateRepo.deleteByUuid(sepaMandateUuid);
if (result == 0) {
@@ -110,12 +110,12 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override
@Transactional
public ResponseEntity<HsOfficeSepaMandateResource> patchSepaMandate(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID sepaMandateUuid,
final HsOfficeSepaMandatePatchResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = sepaMandateRepo.findByUuid(sepaMandateUuid).orElseThrow();

View File

@@ -7,8 +7,8 @@ import net.hostsharing.hsadminng.errors.DisplayAs;
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type;
@@ -20,16 +20,16 @@ import java.util.UUID;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.*;
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.ColumnValue.usingDefaultCase;
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.Permission.*;
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.SQL.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import java.util.Optional;
import java.util.Set;
@@ -6,12 +6,12 @@ import java.util.function.BinaryOperator;
import java.util.stream.Stream;
import static java.util.stream.Collectors.joining;
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.GUEST;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.NEW;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.GUEST;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.apache.commons.lang3.StringUtils.uncapitalize;
@@ -46,7 +46,7 @@ public class InsertTriggerGenerator {
private void generateInsertPermissionGrants(final StringWriter plPgSql) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${liquibaseTagPrefix}-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset InsertTriggerGenerator:${liquibaseTagPrefix}-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
-- ----------------------------------------------------------------------------
""",
with("liquibaseTagPrefix", liquibaseTagPrefix));
@@ -55,7 +55,7 @@ public class InsertTriggerGenerator {
plPgSql.writeLn("""
-- granting INSERT permission to ${rawSubTable} ----------------------------
""",
with("rawSubTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()));
with("rawSubTable", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()));
if (isGrantToADifferentTable(g)) {
plPgSql.writeLn(
@@ -67,13 +67,13 @@ public class InsertTriggerGenerator {
declare
row ${rawSuperTable};
begin
call defineContext('create INSERT INTO ${rawSubTable} permissions for pre-exising ${rawSuperTable} rows');
call base.defineContext('create INSERT INTO ${rawSubTable} permissions for pre-exising ${rawSuperTable} rows');
FOR row IN SELECT * FROM ${rawSuperTable}
${whenCondition}
LOOP
call grantPermissionToRole(
createPermission(row.uuid, 'INSERT', '${rawSubTable}'),
call rbac.grantPermissionToRole(
rbac.createPermission(row.uuid, 'INSERT', '${rawSubTable}'),
${superRoleRef});
END LOOP;
end;
@@ -84,40 +84,40 @@ public class InsertTriggerGenerator {
? "WHERE type = '${value}'"
.replace("${value}", g.getSuperRoleDef().getEntityAlias().usingCase().value)
: "-- unconditional for all rows in that table"),
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()),
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()),
with("superRoleRef", toRoleDescriptor(g.getSuperRoleDef(), "row")));
} else {
plPgSql.writeLn("""
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
-- because there cannot yet be any pre-existing rows in the same table yet.
""",
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()));
}
plPgSql.writeLn("""
/**
Grants ${rawSubTable} INSERT permission to specified role of new ${rawSuperTable} rows.
*/
create or replace function new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tf()
create or replace function ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf()
returns trigger
language plpgsql
strict as $$
begin
${ifConditionThen}
call grantPermissionToRole(
createPermission(NEW.uuid, 'INSERT', '${rawSubTable}'),
call rbac.grantPermissionToRole(
rbac.createPermission(NEW.uuid, 'INSERT', '${rawSubTable}'),
${superRoleRef});
${ifConditionEnd}
return NEW;
end; $$;
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
create trigger z_new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tg
after insert on ${rawSuperTable}
create trigger z_new_${rawSubTable}_grants_after_insert_tg
after insert on ${rawSuperTableWithSchema}
for each row
execute procedure new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tf();
execute procedure ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf();
""",
with("ifConditionThen", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
// TODO.impl: .type needs to be dynamically generated
@@ -127,8 +127,12 @@ public class InsertTriggerGenerator {
? "end if;"
: "-- end."),
with("superRoleRef", toRoleDescriptor(g.getSuperRoleDef(), NEW.name())),
with("rawSuperTableWithSchema", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
with("rawSuperTableShortName", g.getSuperRoleDef().getEntityAlias().getRawTableShortName()),
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
with("rawSuperTableSchemaName", g.getSuperRoleDef().getEntityAlias().getRawTableSchemaPrefix()),
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()),
with("rawSubTableShortName", g.getPermDef().getEntityAlias().getRawTableShortName()));
});
}
@@ -136,7 +140,7 @@ public class InsertTriggerGenerator {
private void generateInsertPermissionTriggerAlwaysDisallow(final StringWriter plPgSql) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${liquibaseTagPrefix}-rbac-ALWAYS-DISALLOW-INSERT:1 endDelimiter:--//
--changeset InsertTriggerGenerator:${liquibaseTagPrefix}-rbac-ALWAYS-DISALLOW-INSERT endDelimiter:--//
-- ----------------------------------------------------------------------------
""",
with("liquibaseTagPrefix", liquibaseTagPrefix));
@@ -152,13 +156,13 @@ public class InsertTriggerGenerator {
begin
raise exception '[403] insert into ${rawSubTable} values(%) not allowed regardless of current subject, no insert permissions granted at all', NEW;
end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg
before insert on ${rawSubTable}
for each row
execute procedure ${rawSubTable}_insert_permission_missing_tf();
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
plPgSql.writeLn("--//");
}
@@ -179,7 +183,7 @@ public class InsertTriggerGenerator {
private void generateInsertPermissionsCheckHeader(final StringWriter plPgSql) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
--changeset InsertTriggerGenerator:${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
-- ----------------------------------------------------------------------------
/**
@@ -192,7 +196,7 @@ public class InsertTriggerGenerator {
superObjectUuid uuid;
begin
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
plPgSql.chopEmptyLines();
}
@@ -206,7 +210,7 @@ public class InsertTriggerGenerator {
if (g.getSuperRoleDef().isGlobal(GUEST)) {
plPgSql.writeLn(
"""
-- check INSERT INSERT permission for global anyone
-- check INSERT INSERT permission for rbac.global anyone
if ${caseCondition}true then
return NEW;
end if;
@@ -215,8 +219,8 @@ public class InsertTriggerGenerator {
} else if (g.getSuperRoleDef().isGlobal(ADMIN)) {
plPgSql.writeLn(
"""
-- check INSERT INSERT if global ADMIN
if ${caseCondition}isGlobalAdmin() then
-- check INSERT INSERT if rbac.global ADMIN
if ${caseCondition}rbac.isGlobalAdmin() then
return NEW;
end if;
""",
@@ -225,25 +229,25 @@ public class InsertTriggerGenerator {
plPgSql.writeLn(
"""
-- check INSERT permission via direct foreign key: NEW.${refColumn}
if ${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then
if ${caseCondition}rbac.hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then
return NEW;
end if;
""",
with("caseCondition", caseCondition),
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
} else {
plPgSql.writeLn(
"""
-- check INSERT permission via indirect foreign key: NEW.${refColumn}
superObjectUuid := (${fetchSql});
assert superObjectUuid is not null, 'object uuid fetched depending on ${rawSubTable}.${refColumn} must not be null, also check fetchSql in RBAC DSL';
if ${caseCondition}hasInsertPermission(superObjectUuid, '${rawSubTable}') then
if ${caseCondition}rbac.hasInsertPermission(superObjectUuid, '${rawSubTable}') then
return NEW;
end if;
""",
with("caseCondition", caseCondition),
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()),
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()),
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
with("fetchSql", g.getSuperRoleDef().getEntityAlias().fetchSql().sql),
with("columns", g.getSuperRoleDef().getEntityAlias().aliasName() + ".uuid"),
@@ -255,7 +259,7 @@ public class InsertTriggerGenerator {
plPgSql.writeLn();
plPgSql.writeLn("""
raise exception '[403] insert into ${rawSubTable} values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids();
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg
@@ -264,7 +268,7 @@ public class InsertTriggerGenerator {
execute procedure ${rawSubTable}_insert_permission_check_tf();
--//
""",
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
}
private String toStringList(final Set<RbacView.CaseDef> cases) {
@@ -272,7 +276,7 @@ public class InsertTriggerGenerator {
}
private boolean isGrantToADifferentTable(final RbacView.RbacGrantDefinition g) {
return !rbacDef.getRootEntityAlias().getRawTableName().equals(g.getSuperRoleDef().getEntityAlias().getRawTableName());
return !rbacDef.getRootEntityAlias().getRawTableNameWithSchema().equals(g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema());
}
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
public enum PostgresTriggerReference {
NEW, OLD

View File

@@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
public class RbacIdentityViewGenerator {
private final RbacView rbacDef;
@@ -12,13 +12,13 @@ public class RbacIdentityViewGenerator {
this.rbacDef = rbacDef;
this.liquibaseTagPrefix = liquibaseTagPrefix;
this.simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
}
void generateTo(final StringWriter plPgSql) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${liquibaseTagPrefix}-rbac-IDENTITY-VIEW:1 endDelimiter:--//
--changeset RbacIdentityViewGenerator:${liquibaseTagPrefix}-rbac-IDENTITY-VIEW endDelimiter:--//
-- ----------------------------------------------------------------------------
""",
with("liquibaseTagPrefix", liquibaseTagPrefix));
@@ -26,13 +26,13 @@ public class RbacIdentityViewGenerator {
plPgSql.writeLn(
switch (rbacDef.getIdentityViewSqlQuery().part) {
case SQL_PROJECTION -> """
call generateRbacIdentityViewFromProjection('${rawTableName}',
call rbac.generateRbacIdentityViewFromProjection('${rawTableName}',
$idName$
${identityViewSqlPart}
$idName$);
""";
case SQL_QUERY -> """
call generateRbacIdentityViewFromQuery('${rawTableName}',
call rbac.generateRbacIdentityViewFromQuery('${rawTableName}',
$idName$
${identityViewSqlPart}
$idName$);

View File

@@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
public class RbacObjectGenerator {
@@ -9,17 +9,17 @@ public class RbacObjectGenerator {
public RbacObjectGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
this.liquibaseTagPrefix = liquibaseTagPrefix;
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
}
void generateTo(final StringWriter plPgSql) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${liquibaseTagPrefix}-rbac-OBJECT:1 endDelimiter:--//
--changeset RbacObjectGenerator:${liquibaseTagPrefix}-rbac-OBJECT endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRelatedRbacObject('${rawTableName}');
call rbac.generateRelatedRbacObject('${rawTableName}');
--//
""",
with("liquibaseTagPrefix", liquibaseTagPrefix),
with("rawTableName", rawTableName));

View File

@@ -1,9 +1,9 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import static java.util.stream.Collectors.joining;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.indented;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.indented;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
public class RbacRestrictedViewGenerator {
private final RbacView rbacDef;
@@ -13,15 +13,15 @@ public class RbacRestrictedViewGenerator {
public RbacRestrictedViewGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
this.rbacDef = rbacDef;
this.liquibaseTagPrefix = liquibaseTagPrefix;
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
}
void generateTo(final StringWriter plPgSql) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${liquibaseTagPrefix}-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
--changeset RbacRestrictedViewGenerator:${liquibaseTagPrefix}-rbac-RESTRICTED-VIEW endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacRestrictedView('${rawTableName}',
call rbac.generateRbacRestrictedView('${rawTableName}',
$orderBy$
${orderBy}
$orderBy$,

View File

@@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
public class RbacRoleDescriptorsGenerator {
@@ -11,15 +11,15 @@ public class RbacRoleDescriptorsGenerator {
public RbacRoleDescriptorsGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
this.liquibaseTagPrefix = liquibaseTagPrefix;
this.simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
}
void generateTo(final StringWriter plPgSql) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${liquibaseTagPrefix}-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
--changeset RbacRoleDescriptorsGenerator:${liquibaseTagPrefix}-rbac-ROLE-DESCRIPTORS endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacRoleDescriptors('${simpleEntityVarName}', '${rawTableName}');
call rbac.generateRbacRoleDescriptors('${simpleEntityVarName}', '${rawTableName}');
--//
""",

View File

@@ -1,8 +1,8 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner;
@@ -23,12 +23,12 @@ import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.max;
import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.ROLE_TO_ROLE;
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.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.ROLE_TO_ROLE;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.Part.AUTO_FETCH;
import static org.apache.commons.collections4.SetUtils.hashSet;
import static org.apache.commons.lang3.StringUtils.uncapitalize;
@@ -36,12 +36,12 @@ import static org.apache.commons.lang3.StringUtils.uncapitalize;
// TODO.refa: rename to RbacDSL
public class RbacView {
public static final String GLOBAL = "global";
public static final String GLOBAL = "rbac.global";
public static final String OUTPUT_BASEDIR = "src/main/resources/db/changelog";
private final EntityAlias rootEntityAlias;
private final Set<RbacUserReference> userDefs = new LinkedHashSet<>();
private final Set<RbacSubjectReference> userDefs = new LinkedHashSet<>();
private final Set<RbacRoleDefinition> roleDefs = new LinkedHashSet<>();
private final Set<RbacPermissionDefinition> permDefs = new LinkedHashSet<>();
private final Map<String, EntityAlias> entityAliases = new HashMap<>() {
@@ -97,8 +97,8 @@ public class RbacView {
RbacView(final String alias, final Class<? extends BaseEntity> entityClass) {
rootEntityAlias = new EntityAlias(alias, entityClass);
entityAliases.put(alias, rootEntityAlias);
new RbacUserReference(CREATOR);
entityAliases.put("global", new EntityAlias("global"));
new RbacSubjectReference(CREATOR);
entityAliases.put("rbac.global", new EntityAlias("rbac.global"));
}
/**
@@ -467,7 +467,7 @@ public class RbacView {
return new RbacExampleRole(entityAlias, role);
}
private RbacGrantDefinition grantRoleToUser(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
private RbacGrantDefinition grantRoleToSubject(final RbacRoleDefinition roleDefinition, final RbacSubjectReference user) {
return findOrCreateGrantDef(roleDefinition, user).toCreate();
}
@@ -548,7 +548,7 @@ public class RbacView {
}
public RbacView grantPermission(final Permission perm) {
final var forTable = rootEntityAlias.getRawTableName();
final var forTable = rootEntityAlias.getRawTableNameWithSchema();
findOrCreateGrantDef(findRbacPerm(rootEntityAlias, perm, forTable), superRoleDef).toCreate();
return RbacView.this;
}
@@ -564,7 +564,7 @@ public class RbacView {
@EqualsAndHashCode
public class RbacGrantDefinition {
private final RbacUserReference userDef;
private final RbacSubjectReference userDef;
private final RbacRoleDefinition superRoleDef;
private final RbacRoleDefinition subRoleDef;
private final RbacPermissionDefinition permDef;
@@ -605,7 +605,7 @@ public class RbacView {
register(this);
}
public RbacGrantDefinition(final RbacRoleDefinition roleDef, final RbacUserReference userDef) {
public RbacGrantDefinition(final RbacRoleDefinition roleDef, final RbacSubjectReference userDef) {
this.userDef = userDef;
this.subRoleDef = roleDef;
this.superRoleDef = null;
@@ -770,8 +770,8 @@ public class RbacView {
* @return
* The grant definition for further chained calls.
*/
public RbacGrantDefinition owningUser(final RbacUserReference.UserRole userRole) {
return grantRoleToUser(this, findUserRef(userRole));
public RbacGrantDefinition owningUser(final RbacSubjectReference.UserRole userRole) {
return grantRoleToSubject(this, findUserRef(userRole));
}
/**
@@ -833,12 +833,12 @@ public class RbacView {
}
}
public RbacUserReference findUserRef(final RbacUserReference.UserRole userRole) {
public RbacSubjectReference findUserRef(final RbacSubjectReference.UserRole userRole) {
return userDefs.stream().filter(u -> u.role == userRole).findFirst().orElseThrow();
}
@EqualsAndHashCode
public class RbacUserReference {
public class RbacSubjectReference {
public enum UserRole {
GLOBAL_ADMIN,
@@ -847,7 +847,7 @@ public class RbacView {
final UserRole role;
public RbacUserReference(final UserRole creator) {
public RbacSubjectReference(final UserRole creator) {
this.role = creator;
userDefs.add(this);
}
@@ -885,7 +885,7 @@ public class RbacView {
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, perm, tableName, true)); // TODO: true => toCreate
}
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacSubjectReference user) {
return grantDefs.stream()
.filter(g -> g.subRoleDef == roleDefinition && g.userDef == user)
.findFirst()
@@ -922,7 +922,7 @@ public class RbacView {
}
boolean isGlobal() {
return aliasName().equals("global");
return aliasName().equals("rbac.global");
}
boolean isPlaceholder() {
@@ -937,7 +937,7 @@ public class RbacView {
return switch (fetchSql.part) {
case SQL_QUERY -> fetchSql;
case AUTO_FETCH ->
SQL.query("SELECT * FROM " + getRawTableName() + " WHERE uuid = ${ref}." + dependsOnColum.column);
SQL.query("SELECT * FROM " + getRawTableNameWithSchema() + " WHERE uuid = ${ref}." + dependsOnColum.column);
default -> throw new IllegalStateException("unexpected SQL definition: " + fetchSql);
};
}
@@ -960,13 +960,39 @@ public class RbacView {
: uncapitalize(withoutEntitySuffix(entityClass.getSimpleName()));
}
String getRawTableName() {
if ( aliasName.equals("global")) {
return "global"; // TODO: maybe we should introduce a GlobalEntity class?
String getRawTableNameWithSchema() {
if ( aliasName.equals("rbac.global")) {
return "rbac.global"; // TODO: maybe we should introduce a GlobalEntity class?
}
return withoutRvSuffix(entityClass.getAnnotation(Table.class).name());
}
String getRawTableSchemaPrefix() {
final var rawTableNameWithSchema = getRawTableNameWithSchema();
final var parts = rawTableNameWithSchema.split("\\.");
final var rawTableSchemaPrefix = parts.length > 1 ? parts[0] + "." : "";
return rawTableSchemaPrefix;
}
String getRawTableName() {
final var rawTableNameWithSchema = getRawTableNameWithSchema();
final var parts = rawTableNameWithSchema.split("\\.");
final var rawTableName = parts.length > 1 ? parts[1] : rawTableNameWithSchema;
return rawTableName;
}
String getRawTableShortName() {
// TODO.impl: some combined function and trigger names are too long
// maybe we should shorten the table name e.g. hs_office_coopsharestransaction -> hsof.coopsharetx
// this is just a workaround:
return getRawTableName()
.replace("hs_office_", "hsof_")
.replace("hs_booking_", "hsbk_")
.replace("hs_hosting_", "hsho_")
.replace("coopsharestransaction", "coopsharetx")
.replace("coopassetstransaction", "coopassettx");
}
String dependsOnColumName() {
if (dependsOnColum == null) {
throw new IllegalStateException(
@@ -1166,7 +1192,7 @@ public class RbacView {
}
String map(final String originalAliasName) {
if (outerAliasNames.contains(originalAliasName) || originalAliasName.equals("global")) {
if (outerAliasNames.contains(originalAliasName) || originalAliasName.equals("rbac.global")) {
return originalAliasName;
}
if (originalAliasName.equals(importedRbacView.rootEntityAlias.aliasName)) {

View File

@@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import lombok.SneakyThrows;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef;
import net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef;
import org.apache.commons.lang3.StringUtils;
import java.nio.file.*;
@@ -12,7 +12,7 @@ import java.util.stream.Stream;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.joining;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.*;
public class RbacViewMermaidFlowchartGenerator {

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import lombok.SneakyThrows;
@@ -6,8 +6,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.NEW;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
public class RbacViewPostgresGenerator {
@@ -17,7 +17,7 @@ public class RbacViewPostgresGenerator {
public RbacViewPostgresGenerator(final RbacView forRbacDef) {
rbacDef = forRbacDef;
liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableName().replace("_", "-");
liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableNameWithSchema().replace("_", "-");
plPgSql.writeLn("""
--liquibase formatted sql
-- This code generated was by ${generator}, do not amend manually.

View File

@@ -1,8 +1,8 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacPermissionDefinition;
import net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef;
import net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition;
import net.hostsharing.hsadminng.rbac.generator.RbacView.RbacPermissionDefinition;
import java.util.HashSet;
import java.util.List;
@@ -13,12 +13,12 @@ import java.util.stream.Stream;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.OLD;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.NEW;
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.OLD;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.apache.commons.lang3.StringUtils.uncapitalize;
@@ -40,7 +40,7 @@ class RolesGrantsAndPermissionsGenerator {
simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
simpleEntityName = capitalize(simpleEntityVarName);
rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
}
void generateTo(final StringWriter plPgSql) {
@@ -53,7 +53,7 @@ class RolesGrantsAndPermissionsGenerator {
private void generateHeader(final StringWriter plPgSql, final String triggerType) {
plPgSql.writeLn("""
-- ============================================================================
--changeset ${liquibaseTagPrefix}-rbac-${triggerType}-trigger:1 endDelimiter:--//
--changeset RolesGrantsAndPermissionsGenerator:${liquibaseTagPrefix}-rbac-${triggerType}-trigger endDelimiter:--//
-- ----------------------------------------------------------------------------
""",
with("liquibaseTagPrefix", liquibaseTagPrefix),
@@ -77,17 +77,17 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.writeLn("declare");
plPgSql.indented(() -> {
referencedEntityAliases()
.forEach((ea) -> plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableName() + ";"));
.forEach((ea) -> plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableNameWithSchema() + ";"));
});
plPgSql.writeLn();
plPgSql.writeLn("begin");
plPgSql.indented(() -> {
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
plPgSql.writeLn("call rbac.enterTriggerForObjectUuid(NEW.uuid);");
plPgSql.writeLn();
generateCreateRolesAndGrantsAfterInsert(plPgSql);
plPgSql.ensureSingleEmptyLine();
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
plPgSql.writeLn("call rbac.leaveTriggerForObjectUuid(NEW.uuid);");
});
plPgSql.writeLn("end; $$;");
plPgSql.writeLn();
@@ -114,7 +114,7 @@ class RolesGrantsAndPermissionsGenerator {
begin
if ${updateConditions} then
delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid;
delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid;
call buildRbacSystemFor${simpleEntityName}(NEW);
end if;
end; $$;
@@ -145,19 +145,19 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.indented(() -> {
referencedEntityAliases()
.forEach((ea) -> {
plPgSql.writeLn(entityRefVar(OLD, ea) + " " + ea.getRawTableName() + ";");
plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableName() + ";");
plPgSql.writeLn(entityRefVar(OLD, ea) + " " + ea.getRawTableNameWithSchema() + ";");
plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableNameWithSchema() + ";");
});
});
plPgSql.writeLn();
plPgSql.writeLn("begin");
plPgSql.indented(() -> {
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
plPgSql.writeLn("call rbac.enterTriggerForObjectUuid(NEW.uuid);");
plPgSql.writeLn();
generateUpdateRolesAndGrantsAfterUpdate(plPgSql);
plPgSql.ensureSingleEmptyLine();
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
plPgSql.writeLn("call rbac.leaveTriggerForObjectUuid(NEW.uuid);");
});
plPgSql.writeLn("end; $$;");
plPgSql.writeLn();
@@ -309,10 +309,10 @@ class RolesGrantsAndPermissionsGenerator {
private String generateRevoke(RbacGrantDefinition grantDef) {
return switch (grantDef.grantType()) {
case ROLE_TO_USER -> throw new IllegalArgumentException("unexpected grant");
case ROLE_TO_ROLE -> "call revokeRoleFromRole(${subRoleRef}, ${superRoleRef});"
case ROLE_TO_ROLE -> "call rbac.revokeRoleFromRole(${subRoleRef}, ${superRoleRef});"
.replace("${subRoleRef}", roleRef(OLD, grantDef.getSubRoleDef()))
.replace("${superRoleRef}", roleRef(OLD, grantDef.getSuperRoleDef()));
case PERM_TO_ROLE -> "call revokePermissionFromRole(${permRef}, ${superRoleRef});"
case PERM_TO_ROLE -> "call rbac.revokePermissionFromRole(${permRef}, ${superRoleRef});"
.replace("${permRef}", getPerm(OLD, grantDef.getPermDef()))
.replace("${superRoleRef}", roleRef(OLD, grantDef.getSuperRoleDef()));
};
@@ -321,13 +321,13 @@ class RolesGrantsAndPermissionsGenerator {
private String generateGrant(RbacGrantDefinition grantDef) {
final var grantSql = switch (grantDef.grantType()) {
case ROLE_TO_USER -> throw new IllegalArgumentException("unexpected grant");
case ROLE_TO_ROLE -> "call grantRoleToRole(${subRoleRef}, ${superRoleRef}${assumed});"
.replace("${assumed}", grantDef.isAssumed() ? "" : ", unassumed()")
case ROLE_TO_ROLE -> "call rbac.grantRoleToRole(${subRoleRef}, ${superRoleRef}${assumed});"
.replace("${assumed}", grantDef.isAssumed() ? "" : ", rbac.unassumed()")
.replace("${subRoleRef}", roleRef(NEW, grantDef.getSubRoleDef()))
.replace("${superRoleRef}", roleRef(NEW, grantDef.getSuperRoleDef()));
case PERM_TO_ROLE ->
grantDef.getPermDef().getPermission() == INSERT ? ""
: "call grantPermissionToRole(${permRef}, ${superRoleRef});"
: "call rbac.grantPermissionToRole(${permRef}, ${superRoleRef});"
.replace("${permRef}", createPerm(NEW, grantDef.getPermDef()))
.replace("${superRoleRef}", roleRef(NEW, grantDef.getSuperRoleDef()));
};
@@ -335,15 +335,15 @@ class RolesGrantsAndPermissionsGenerator {
}
private String findPerm(final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
return permRef("findPermissionId", ref, permDef);
return permRef("rbac.findPermissionId", ref, permDef);
}
private String getPerm(final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
return permRef("getPermissionId", ref, permDef);
return permRef("rbac.getPermissionId", ref, permDef);
}
private String createPerm(final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
return permRef("createPermission", ref, permDef);
return permRef("rbac.createPermission", ref, permDef);
}
private String permRef(final String functionName, final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
@@ -364,7 +364,7 @@ class RolesGrantsAndPermissionsGenerator {
System.out.println("null");
}
if (roleDef.getEntityAlias().isGlobal()) {
return "globalAdmin()";
return "rbac.globalAdmin()";
}
final String entityRefVar = entityRefVar(rootRefVar, roleDef.getEntityAlias());
return roleDef.getEntityAlias().simpleName() + capitalize(roleDef.getRole().name())
@@ -389,7 +389,7 @@ class RolesGrantsAndPermissionsGenerator {
}
plPgSql.writeLn();
plPgSql.writeLn("perform createRoleWithGrants(");
plPgSql.writeLn("perform rbac.defineRoleWithGrants(");
plPgSql.indented(() -> {
plPgSql.writeLn("${simpleVarName)${roleSuffix}(NEW),"
.replace("${simpleVarName)", simpleEntityVarName)
@@ -415,7 +415,7 @@ class RolesGrantsAndPermissionsGenerator {
.map(this::toPlPgSqlReference)
.toList();
plPgSql.indented(() ->
plPgSql.writeLn("userUuids => array[" + joinArrayElements(arrayElements, 2) + "],\n"));
plPgSql.writeLn("subjectUuids => array[" + joinArrayElements(arrayElements, 2) + "],\n"));
rbacGrants.removeAll(grantsToUsers);
}
}
@@ -578,9 +578,9 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.writeLn();
}
private String toPlPgSqlReference(final RbacView.RbacUserReference userRef) {
private String toPlPgSqlReference(final RbacView.RbacSubjectReference userRef) {
return switch (userRef.role) {
case CREATOR -> "currentUserUuid()";
case CREATOR -> "rbac.currentSubjectUuid()";
default -> throw new IllegalArgumentException("unknown user role: " + userRef);
};
}
@@ -589,9 +589,9 @@ class RolesGrantsAndPermissionsGenerator {
final PostgresTriggerReference triggerRef,
final RbacView.RbacRoleDefinition roleDef,
final boolean assumed) {
final var assumedArg = assumed ? "" : ", unassumed()";
final var assumedArg = assumed ? "" : ", rbac.unassumed()";
return toRoleRef(roleDef) +
(roleDef.getEntityAlias().isGlobal() ? ( assumed ? "()" : "(unassumed())")
(roleDef.getEntityAlias().isGlobal() ? ( assumed ? "()" : "(rbac.unassumed())")
: rbacDef.isRootEntityAlias(roleDef.getEntityAlias()) ? ("(" + triggerRef.name() + ")")
: "(" + toTriggerReference(triggerRef, roleDef.getEntityAlias()) + assumedArg + ")");
}

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
import org.apache.commons.lang3.StringUtils;

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacdef;
package net.hostsharing.hsadminng.rbac.generator;
// TODO: The whole code in this package is more like a quick hack to solve an urgent problem.
// It should be re-written in PostgreSQL pl/pgsql,

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
package net.hostsharing.hsadminng.rbac.grant;
import lombok.*;
import org.springframework.data.annotation.Immutable;
@@ -12,7 +12,7 @@ import java.util.List;
import java.util.UUID;
@Entity
@Table(name = "rbacgrants_ev")
@Table(schema = "rbac", name = "grants_ev")
@Getter
@Setter
@Builder

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
package net.hostsharing.hsadminng.rbac.grant;
import org.springframework.data.repository.Repository;

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
package net.hostsharing.hsadminng.rbac.grant;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.mapper.Mapper;
@@ -33,14 +33,14 @@ public class RbacGrantController implements RbacGrantsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<RbacGrantResource> getGrantById(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID grantedRoleUuid,
final UUID granteeUserUuid) {
final UUID granteeSubjectUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var id = new RbacGrantId(granteeUserUuid, grantedRoleUuid);
final var id = new RbacGrantId(granteeSubjectUuid, grantedRoleUuid);
final var result = rbacGrantRepository.findById(id);
if (result == null) {
return ResponseEntity.notFound().build();
@@ -50,23 +50,23 @@ public class RbacGrantController implements RbacGrantsApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<RbacGrantResource>> listUserGrants(
final String currentUser,
public ResponseEntity<List<RbacGrantResource>> listSubjectGrants(
final String currentSubject,
final String assumedRoles) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
return ResponseEntity.ok(mapper.mapList(rbacGrantRepository.findAll(), RbacGrantResource.class));
}
@Override
@Transactional
public ResponseEntity<RbacGrantResource> grantRoleToUser(
final String currentUser,
public ResponseEntity<RbacGrantResource> grantRoleToSubject(
final String currentSubject,
final String assumedRoles,
final RbacGrantResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var granted = rbacGrantRepository.save(mapper.map(body, RbacGrantEntity.class));
em.flush();
@@ -82,28 +82,28 @@ public class RbacGrantController implements RbacGrantsApi {
@Override
@Transactional
public ResponseEntity<Void> revokeRoleFromUser(
final String currentUser,
public ResponseEntity<Void> revokeRoleFromSubject(
final String currentSubject,
final String assumedRoles,
final UUID grantedRoleUuid,
final UUID granteeUserUuid) {
final UUID granteeSubjectUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeUserUuid, grantedRoleUuid));
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeSubjectUuid, grantedRoleUuid));
return ResponseEntity.noContent().build();
}
// TODO: implement an endpoint to create a Mermaid flowchart with all grants of a given user
// TODO.feat: implement an endpoint to create a Mermaid flowchart with all grants of a given user
// @GetMapping(
// path = "/api/rbac/users/{userUuid}/grants",
// path = "/api/rbac/subjects/{subjectUuid}/grants",
// produces = {"text/vnd.mermaid"})
// @Transactional(readOnly = true)
// public ResponseEntity<String> allGrantsOfUserAsMermaid(
// @RequestHeader(name = "current-user") String currentUser,
// @RequestHeader(name = "current-subject") String currentSubject,
// @RequestHeader(name = "assumed-roles", required = false) String assumedRoles) {
// final var graph = RbacGrantsDiagramService.allGrantsToUser(currentUser);
// final var graph = RbacGrantsDiagramService.allGrantsToUser(currentSubject);
// return ResponseEntity.ok(graph);
// }

View File

@@ -1,14 +1,14 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
package net.hostsharing.hsadminng.rbac.grant;
import lombok.*;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleType;
import net.hostsharing.hsadminng.rbac.role.RbacRoleType;
import org.springframework.data.annotation.Immutable;
import jakarta.persistence.*;
import java.util.UUID;
@Entity
@Table(name = "rbacgrants_rv")
@Table(schema = "rbac", name = "grants_rv")
@IdClass(RbacGrantId.class)
@Getter
@Setter
@@ -33,11 +33,11 @@ public class RbacGrantEntity {
private UUID grantedRoleUuid;
@Column(name = "username", updatable = false, insertable = false)
private String granteeUserName;
private String granteeSubjectName;
@Id
@Column(name = "useruuid")
private UUID granteeUserUuid;
@Column(name = "subjectuuid")
private UUID granteeSubjectUuid;
private boolean assumed;
@@ -55,12 +55,12 @@ public class RbacGrantEntity {
private RbacRoleType grantedRoleType;
RbacGrantId getRbacGrantId() {
return new RbacGrantId(granteeUserUuid, grantedRoleUuid);
return new RbacGrantId(granteeSubjectUuid, grantedRoleUuid);
}
public String toDisplay() {
return "{ grant role:" + grantedRoleIdName +
" to user:" + granteeUserName +
" to user:" + granteeSubjectName +
" by role:" + grantedByRoleIdName +
(assumed ? " and assume" : "") +
" }";

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
package net.hostsharing.hsadminng.rbac.grant;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
@@ -14,6 +14,6 @@ import java.util.UUID;
@AllArgsConstructor
public class RbacGrantId implements Serializable {
private UUID granteeUserUuid;
private UUID granteeSubjectUuid;
private UUID grantedRoleUuid;
}

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
package net.hostsharing.hsadminng.rbac.grant;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
@@ -11,7 +11,7 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
@Query(value = """
select g from RbacGrantEntity as g
where g.grantedRoleUuid=:#{#rbacGrantId.grantedRoleUuid}
and g.granteeUserUuid=:#{#rbacGrantId.granteeUserUuid}
and g.granteeSubjectUuid=:#{#rbacGrantId.granteeSubjectUuid}
""")
RbacGrantEntity findById(RbacGrantId rbacGrantId);
@@ -25,7 +25,7 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
@Query(value = """
delete from RbacGrantEntity as g
where g.grantedRoleUuid=:#{#rbacGrantId.grantedRoleUuid}
and g.granteeUserUuid=:#{#rbacGrantId.granteeUserUuid}
and g.granteeSubjectUuid=:#{#rbacGrantId.granteeSubjectUuid}
""")
void deleteByRbacGrantId(RbacGrantId rbacGrantId);
}

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
package net.hostsharing.hsadminng.rbac.grant;
import net.hostsharing.hsadminng.context.Context;
import org.springframework.beans.factory.annotation.Autowired;
@@ -16,7 +16,7 @@ import java.util.stream.Stream;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
import static net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService.Include.*;
import static net.hostsharing.hsadminng.rbac.grant.RbacGrantsDiagramService.Include.*;
// TODO: cleanup - this code was 'hacked' to quickly fix a specific problem, needs refactoring
@Service
@@ -64,9 +64,9 @@ public class RbacGrantsDiagramService {
private Map<UUID, List<RawRbacGrantEntity>> descendantsByUuid = new HashMap<>();
public String allGrantsToCurrentUser(final EnumSet<Include> includes) {
public String allGrantsTocurrentSubject(final EnumSet<Include> includes) {
final var graph = new LimitedHashSet<RawRbacGrantEntity>();
for ( UUID subjectUuid: context.currentSubjectsUuids() ) {
for ( UUID subjectUuid: context.fetchCurrentSubjectOrAssumedRolesUuids() ) {
traverseGrantsTo(graph, subjectUuid, includes);
}
return toMermaidFlowchart(graph, includes);
@@ -78,7 +78,7 @@ public class RbacGrantsDiagramService {
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) {
return;
}
if ( !g.getDescendantIdName().startsWith("role:global")) {
if ( !g.getDescendantIdName().startsWith("role:rbac.global")) {
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":test_")) {
return;
}
@@ -94,7 +94,7 @@ public class RbacGrantsDiagramService {
}
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbacpermission WHERE objectuuid=:targetObject AND op=:op")
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op")
.setParameter("targetObject", targetObject)
.setParameter("op", op)
.getSingleResult();

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacobject;
package net.hostsharing.hsadminng.rbac.object;
import org.hibernate.Hibernate;

View File

@@ -1,46 +0,0 @@
package net.hostsharing.hsadminng.rbac.rbacuser;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.UUID;
public interface RbacUserRepository extends Repository<RbacUserEntity, UUID> {
@Query("""
select u from RbacUserEntity u
where :userName is null or u.name like concat(cast(:userName as text), '%')
order by u.name
""")
List<RbacUserEntity> findByOptionalNameLike(String userName);
// bypasses the restricted view, to be able to grant rights to arbitrary user
@Query(value = "select * from rbacuser where name=:userName", nativeQuery = true)
RbacUserEntity findByName(String userName);
RbacUserEntity findByUuid(UUID uuid);
@Query(value = "select * from grantedPermissions(:userUuid)", nativeQuery = true)
List<RbacUserPermission> findPermissionsOfUserByUuid(UUID userUuid);
/*
Can't use save/saveAndFlush from SpringData because the uuid is not generated on the entity level,
but explicitly, and then SpringData check's if it exists using an SQL SELECT.
And SQL SELECT needs a currentUser which we don't yet have in the case of self registration.
*/
@Modifying
@Query(value = "insert into RBacUser_RV (uuid, name) values( :#{#newUser.uuid}, :#{#newUser.name})", nativeQuery = true)
void insert(final RbacUserEntity newUser);
default RbacUserEntity create(final RbacUserEntity rbacUserEntity) {
if (rbacUserEntity.getUuid() == null) {
rbacUserEntity.setUuid(UUID.randomUUID());
}
insert(rbacUserEntity);
return rbacUserEntity;
}
void deleteByUuid(UUID userUuid);
}

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
package net.hostsharing.hsadminng.rbac.role;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.mapper.Mapper;
@@ -26,10 +26,10 @@ public class RbacRoleController implements RbacRolesApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<RbacRoleResource>> listRoles(
final String currentUser,
final String currentSubject,
final String assumedRoles) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final List<RbacRoleEntity> result = rbacRoleRepository.findAll();

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
package net.hostsharing.hsadminng.rbac.role;
import lombok.*;
import org.hibernate.annotations.Formula;
@@ -8,7 +8,7 @@ import jakarta.persistence.*;
import java.util.UUID;
@Entity
@Table(name = "rbacrole_rv")
@Table(schema = "rbac", name = "role_rv")
@Getter
@Setter
@ToString

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
package net.hostsharing.hsadminng.rbac.role;
import org.springframework.data.repository.Repository;

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
package net.hostsharing.hsadminng.rbac.role;
public enum RbacRoleType {
OWNER, ADMIN, AGENT, TENANT, GUEST, REFERRER

View File

@@ -1,10 +1,10 @@
package net.hostsharing.hsadminng.rbac.rbacuser;
package net.hostsharing.hsadminng.rbac.subject;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacUsersApi;
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacUserPermissionResource;
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacUserResource;
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacSubjectsApi;
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectPermissionResource;
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
@@ -15,7 +15,7 @@ import java.util.List;
import java.util.UUID;
@RestController
public class RbacUserController implements RbacUsersApi {
public class RbacSubjectController implements RbacSubjectsApi {
@Autowired
private Context context;
@@ -24,81 +24,81 @@ public class RbacUserController implements RbacUsersApi {
private Mapper mapper;
@Autowired
private RbacUserRepository rbacUserRepository;
private RbacSubjectRepository rbacSubjectRepository;
@Override
@Transactional
public ResponseEntity<RbacUserResource> createUser(
final RbacUserResource body
public ResponseEntity<RbacSubjectResource> createSubject(
final RbacSubjectResource body
) {
context.define(null);
if (body.getUuid() == null) {
body.setUuid(UUID.randomUUID());
}
final var saved = mapper.map(body, RbacUserEntity.class);
rbacUserRepository.create(saved);
final var saved = mapper.map(body, RbacSubjectEntity.class);
rbacSubjectRepository.create(saved);
final var uri =
MvcUriComponentsBuilder.fromController(getClass())
.path("/api/rbac.yaml/users/{id}")
.buildAndExpand(saved.getUuid())
.toUri();
return ResponseEntity.created(uri).body(mapper.map(saved, RbacUserResource.class));
return ResponseEntity.created(uri).body(mapper.map(saved, RbacSubjectResource.class));
}
@Override
@Transactional
public ResponseEntity<Void> deleteUserByUuid(
final String currentUser,
public ResponseEntity<Void> deleteSubjectByUuid(
final String currentSubject,
final String assumedRoles,
final UUID userUuid
final UUID subjectUuid
) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
rbacUserRepository.deleteByUuid(userUuid);
rbacSubjectRepository.deleteByUuid(subjectUuid);
return ResponseEntity.noContent().build();
}
@Override
@Transactional(readOnly = true)
public ResponseEntity<RbacUserResource> getUserById(
final String currentUser,
public ResponseEntity<RbacSubjectResource> getSubjectById(
final String currentSubject,
final String assumedRoles,
final UUID userUuid) {
final UUID subjectUuid) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = rbacUserRepository.findByUuid(userUuid);
final var result = rbacSubjectRepository.findByUuid(subjectUuid);
if (result == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(mapper.map(result, RbacUserResource.class));
return ResponseEntity.ok(mapper.map(result, RbacSubjectResource.class));
}
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<RbacUserResource>> listUsers(
final String currentUser,
public ResponseEntity<List<RbacSubjectResource>> listSubjects(
final String currentSubject,
final String assumedRoles,
final String userName
) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
return ResponseEntity.ok(mapper.mapList(rbacUserRepository.findByOptionalNameLike(userName), RbacUserResource.class));
return ResponseEntity.ok(mapper.mapList(rbacSubjectRepository.findByOptionalNameLike(userName), RbacSubjectResource.class));
}
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<RbacUserPermissionResource>> listUserPermissions(
final String currentUser,
public ResponseEntity<List<RbacSubjectPermissionResource>> listSubjectPermissions(
final String currentSubject,
final String assumedRoles,
final UUID userUuid
final UUID subjectUuid
) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
return ResponseEntity.ok(mapper.mapList(
rbacUserRepository.findPermissionsOfUserByUuid(userUuid),
RbacUserPermissionResource.class));
rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid),
RbacSubjectPermissionResource.class));
}
}

View File

@@ -1,4 +1,4 @@
package net.hostsharing.hsadminng.rbac.rbacuser;
package net.hostsharing.hsadminng.rbac.subject;
import lombok.*;
import org.springframework.data.annotation.Immutable;
@@ -13,14 +13,14 @@ import java.time.temporal.ChronoUnit;
import java.util.UUID;
@Entity
@Table(name = "rbacuser_rv")
@Table(schema = "rbac", name = "subject_rv")
@Getter
@Setter
@ToString
@Immutable
@NoArgsConstructor
@AllArgsConstructor
public class RbacUserEntity {
public class RbacSubjectEntity {
private static final int MAX_VALIDITY_DAYS = 21;
private static DateTimeFormatter DATE_FORMAT_WITH_FULLHOUR = DateTimeFormatter.ofPattern("MM-dd-yyyy HH");

View File

@@ -1,8 +1,8 @@
package net.hostsharing.hsadminng.rbac.rbacuser;
package net.hostsharing.hsadminng.rbac.subject;
import java.util.UUID;
public interface RbacUserPermission {
public interface RbacSubjectPermission {
UUID getRoleUuid();
String getRoleName();

View File

@@ -0,0 +1,46 @@
package net.hostsharing.hsadminng.rbac.subject;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.UUID;
public interface RbacSubjectRepository extends Repository<RbacSubjectEntity, UUID> {
@Query("""
select u from RbacSubjectEntity u
where :userName is null or u.name like concat(cast(:userName as text), '%')
order by u.name
""")
List<RbacSubjectEntity> findByOptionalNameLike(String userName);
// bypasses the restricted view, to be able to grant rights to arbitrary user
@Query(value = "select * from rbac.subject where name=:userName", nativeQuery = true)
RbacSubjectEntity findByName(String userName);
RbacSubjectEntity findByUuid(UUID uuid);
@Query(value = "select * from rbac.grantedPermissions(:subjectUuid)", nativeQuery = true)
List<RbacSubjectPermission> findPermissionsOfUserByUuid(UUID subjectUuid);
/*
Can't use save/saveAndFlush from SpringData because the uuid is not generated on the entity level,
but explicitly, and then SpringData check's if it exists using an SQL SELECT.
And SQL SELECT needs a currentSubject which we don't yet have in the case of self registration.
*/
@Modifying
@Query(value = "insert into rbac.subject_rv (uuid, name) values( :#{#newUser.uuid}, :#{#newUser.name})", nativeQuery = true)
void insert(final RbacSubjectEntity newUser);
default RbacSubjectEntity create(final RbacSubjectEntity rbacSubjectEntity) {
if (rbacSubjectEntity.getUuid() == null) {
rbacSubjectEntity.setUuid(UUID.randomUUID());
}
insert(rbacSubjectEntity);
return rbacSubjectEntity;
}
void deleteByUuid(UUID subjectUuid);
}

View File

@@ -32,11 +32,11 @@ public class TestCustomerController implements TestCustomersApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<TestCustomerResource>> listCustomers(
String currentUser,
String currentSubject,
String assumedRoles,
String prefix
) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(prefix);
@@ -46,11 +46,11 @@ public class TestCustomerController implements TestCustomersApi {
@Override
@Transactional
public ResponseEntity<TestCustomerResource> addCustomer(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final TestCustomerResource customer) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var saved = testCustomerRepository.save(mapper.map(customer, TestCustomerEntity.class));
final var uri =

View File

@@ -5,19 +5,19 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import jakarta.persistence.*;
import java.io.IOException;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
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.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "test_customer_rv")
@@ -46,7 +46,7 @@ public class TestCustomerEntity implements BaseEntity<TestCustomerEntity> {
.withIdentityView(SQL.projection("prefix"))
.withRestrictedViewOrderBy(SQL.expression("reference"))
.withUpdatableColumns("reference", "prefix", "adminUserName")
.toRole("global", ADMIN).grantPermission(INSERT)
.toRole("rbac.global", ADMIN).grantPermission(INSERT)
.createRole(OWNER, (with) -> {
with.owningUser(CREATOR).unassumed();

View File

@@ -4,22 +4,22 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.test.pac.TestPackageEntity;
import jakarta.persistence.*;
import java.io.IOException;
import java.util.UUID;
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.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
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.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "test_domain_rv")

View File

@@ -29,11 +29,11 @@ public class TestPackageController implements TestPackagesApi {
@Override
@Transactional(readOnly = true)
public ResponseEntity<List<TestPackageResource>> listPackages(
String currentUser,
String currentSubject,
String assumedRoles,
String name
) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var result = testPackageRepository.findAllByOptionalNameLike(name);
return ResponseEntity.ok(mapper.mapList(result, TestPackageResource.class));
@@ -42,12 +42,12 @@ public class TestPackageController implements TestPackagesApi {
@Override
@Transactional
public ResponseEntity<TestPackageResource> updatePackage(
final String currentUser,
final String currentSubject,
final String assumedRoles,
final UUID packageUuid,
final TestPackageUpdateResource body) {
context.define(currentUser, assumedRoles);
context.define(currentSubject, assumedRoles);
final var current = testPackageRepository.findByUuid(packageUuid);
OptionalFromJson.of(body.getDescription()).ifPresent(current::setDescription);

View File

@@ -4,22 +4,22 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.test.cust.TestCustomerEntity;
import jakarta.persistence.*;
import java.io.IOException;
import java.util.UUID;
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.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.*;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "test_package_rv")

View File

@@ -3,13 +3,13 @@ components:
parameters:
currentUser:
name: current-user
currentSubject:
name: current-subject
in: header
required: true
schema:
type: string
description: Identifying name of the currently logged in user.
description: Identifying name of the current subject (e.g. user).
assumedRoles:
name: assumed-roles
@@ -17,4 +17,4 @@ components:
required: false
schema:
type: string
description: Semicolon-separated list of roles to assume. The current user needs to have the right to assume these roles.
description: Semicolon-separated list of roles to assume. The current subject needs to have the right to assume these roles.

View File

@@ -8,13 +8,13 @@ components:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: The current user is unknown or not authorized.
description: The current subject is unknown or not authorized.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: The current user or none of the assumed or roles is granted access to the resource.
description: The current subject or none of the assumed or roles is granted access to the resource.
content:
application/json:
schema:

View File

@@ -3,13 +3,13 @@ components:
parameters:
currentUser:
name: current-user
currentSubject:
name: current-subject
in: header
required: true
schema:
type: string
description: Identifying name of the currently logged in user.
description: Identifying name of the currently logged in subject.
assumedRoles:
name: assumed-roles
@@ -17,4 +17,4 @@ components:
required: false
schema:
type: string
description: Semicolon-separated list of roles to assume. The current user needs to have the right to assume these roles.
description: Semicolon-separated list of roles to assume. The current subject needs to have the right to assume these roles.

View File

@@ -8,13 +8,13 @@ components:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: The current user is unknown or not authorized.
description: The current subject is unknown or not authorized.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: The current user or none of the assumed or roles is granted access to the resource.
description: The current subject or none of the assumed or roles is granted access to the resource.
content:
application/json:
schema:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single booking item its uuid, if visible for the current subject.'
operationId: getBookingItemByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingItemUuid
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single booking item identified by its uuid, if permitted for the current subject.'
operationId: patchBookingItem
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingItemUuid
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single booking item identified by its uuid, if permitted for the current subject.'
operationId: deleteBookingIemByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingItemUuid
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of all booking items for a specified project.
description: Returns the list of all booking items for a specified project which are visible to the current user or any of it's assumed roles.
description: Returns the list of all booking items for a specified project which are visible to the current subject or any of it's assumed roles.
tags:
- hs-booking-items
operationId: listBookingItemsByProjectUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: projectUuid
in: query
@@ -34,7 +34,7 @@ post:
- hs-booking-items
operationId: addBookingItem
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
description: A JSON object describing the new booking item.

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single booking project its uuid, if visible for the current subject.'
operationId: getBookingProjectByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingProjectUuid
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single booking project identified by its uuid, if permitted for the current subject.'
operationId: patchBookingProject
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingProjectUuid
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single booking project identified by its uuid, if permitted for the current subject.'
operationId: deleteBookingIemByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingProjectUuid
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of all booking projects for a specified debitor.
description: Returns the list of all booking projects for a specified debitor which are visible to the current user or any of it's assumed roles.
description: Returns the list of all booking projects for a specified debitor which are visible to the current subject or any of it's assumed roles.
tags:
- hs-booking-projects
operationId: listBookingProjectsByDebitorUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUuid
in: query
@@ -34,7 +34,7 @@ post:
- hs-booking-projects
operationId: addBookingProject
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
description: A JSON object describing the new booking project.

View File

@@ -3,13 +3,13 @@ components:
parameters:
currentUser:
name: current-user
currentSubject:
name: current-subject
in: header
required: true
schema:
type: string
description: Identifying name of the currently logged in user.
description: Identifying name of the currently logged in subject.
assumedRoles:
name: assumed-roles
@@ -17,4 +17,4 @@ components:
required: false
schema:
type: string
description: Semicolon-separated list of roles to assume. The current user needs to have the right to assume these roles.
description: Semicolon-separated list of roles to assume. The current subject needs to have the right to assume these roles.

View File

@@ -8,13 +8,13 @@ components:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: The current user is unknown or not authorized.
description: The current subject is unknown or not authorized.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Forbidden:
description: The current user or none of the assumed or roles is granted access to the resource.
description: The current subject or none of the assumed or roles is granted access to the resource.
content:
application/json:
schema:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single managed asset by its uuid, if visible for the current subject.'
operationId: getAssetByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetUuid
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single hosting asset identified by its uuid, if permitted for the current subject.'
operationId: patchAsset
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetUuid
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single hosting asset identified by its uuid, if permitted for the current subject.'
operationId: deleteAssetUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetUuid
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a filtered list of all hosting assets.
description: Returns the list of all hosting assets which match the given filters and are visible to the current user or any of it's assumed roles.
description: Returns the list of all hosting assets which match the given filters and are visible to the current subject or any of it's assumed roles.
tags:
- hs-hosting-assets
operationId: listAssets
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: projectUuid
in: query
@@ -47,7 +47,7 @@ post:
- hs-hosting-assets
operationId: addAsset
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
description: A JSON object describing the new hosting asset.

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single bank account by its uuid, if visible for the current subject.'
operationId: getBankAccountByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bankAccountUUID
in: path
@@ -31,7 +31,7 @@ delete:
description: 'Delete a single bank account by its uuid, if permitted for the current subject.'
operationId: deleteBankAccountByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bankAccountUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) bankaccounts.
description: Returns the list of (optionally filtered) bankaccounts which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) bankaccounts which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-bank-accounts
operationId: listBankAccounts
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: holder
in: query
@@ -33,7 +33,7 @@ post:
- hs-office-bank-accounts
operationId: addBankAccount
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
content:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single business contact by its uuid, if visible for the current subject.'
operationId: getContactByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: contactUUID
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single contact by its uuid, if permitted for the current subject.'
operationId: patchContact
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: contactUUID
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single business contact by its uuid, if permitted for the current subject.'
operationId: deleteContactByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: contactUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) contacts.
description: Returns the list of (optionally filtered) contacts which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) contacts which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-contacts
operationId: listContacts
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name
in: query
@@ -33,7 +33,7 @@ post:
- hs-office-contacts
operationId: addContact
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
content:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single asset transaction by its uuid, if visible for the current subject.'
operationId: getCoopAssetTransactionByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetTransactionUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) cooperative asset transactions.
description: Returns the list of (optionally filtered) cooperative asset transactions which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) cooperative asset transactions which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-coopAssets
operationId: listCoopAssets
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUuid
in: query
@@ -48,7 +48,7 @@ post:
- hs-office-coopAssets
operationId: addCoopAssetsTransaction
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
description: A JSON object describing the new cooperative assets transaction.

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single share transaction by its uuid, if visible for the current subject.'
operationId: getCoopShareTransactionByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: shareTransactionUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) cooperative share transactions.
description: Returns the list of (optionally filtered) cooperative share transactions which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) cooperative share transactions which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-coopShares
operationId: listCoopShares
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUuid
in: query
@@ -48,7 +48,7 @@ post:
- hs-office-coopShares
operationId: addCoopSharesTransaction
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
description: A JSON object describing the new cooperative shares transaction.

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single debitor by its uuid, if visible for the current subject.'
operationId: getDebitorByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUUID
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single debitor by its uuid, if permitted for the current subject.'
operationId: patchDebitor
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUUID
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single debitor by its uuid, if permitted for the current subject.'
operationId: deleteDebitorByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) debitors.
description: Returns the list of (optionally filtered) debitors which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) debitors which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-debitors
operationId: listDebitors
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name
in: query
@@ -39,7 +39,7 @@ post:
- hs-office-debitors
operationId: addDebitor
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
content:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single membership by its uuid, if visible for the current subject.'
operationId: getMembershipByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUUID
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single membership by its uuid, if permitted for the current subject.'
operationId: patchMembership
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUUID
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single membership by its uuid, if permitted for the current subject.'
operationId: deleteMembershipByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUUID
in: path

View File

@@ -1,12 +1,12 @@
get:
summary: Returns a list of (optionally filtered) memberships.
description: Returns the list of memberships which are visible to the current user or any of it's assumed roles.
description: Returns the list of memberships which are visible to the current subject or any of it's assumed roles.
The list can optionally be filtered by either the `partnerUuid` or the `memberNumber` - not both at the same time.
tags:
- hs-office-memberships
operationId: listMemberships
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUuid
in: query
@@ -41,7 +41,7 @@ post:
- hs-office-memberships
operationId: addMembership
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
description: A JSON object describing the new membership.

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single business partner by its uuid, if visible for the current subject.'
operationId: getPartnerByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUUID
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single business partner by its uuid, if permitted for the current subject.'
operationId: patchPartner
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUUID
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single business partner by its uuid, if permitted for the current subject.'
operationId: deletePartnerByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) business partners.
description: Returns the list of (optionally filtered) business partners which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) business partners which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-partners
operationId: listPartners
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name
in: query
@@ -33,7 +33,7 @@ post:
- hs-office-partners
operationId: addPartner
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
content:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single business person by its uuid, if visible for the current subject.'
operationId: getPersonByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUUID
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single person by its uuid, if permitted for the current subject.'
operationId: patchPerson
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUUID
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single business person by its uuid, if permitted for the current subject.'
operationId: deletePersonByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) persons.
description: Returns the list of (optionally filtered) persons which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) persons which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-persons
operationId: listPersons
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name
in: query
@@ -33,7 +33,7 @@ post:
- hs-office-persons
operationId: addPerson
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
content:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single person relation by its uuid, if visible for the current subject.'
operationId: getRelationByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: relationUUID
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single person relation by its uuid, if permitted for the current subject.'
operationId: patchRelation
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: relationUUID
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single person relation by its uuid, if permitted for the current subject.'
operationId: deleteRelationByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: relationUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) person relations for a given person.
description: Returns the list of (optionally filtered) person relations of a given person and which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) person relations of a given person and which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-relations
operationId: listRelations
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUuid
in: query
@@ -40,7 +40,7 @@ post:
- hs-office-relations
operationId: addRelation
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
content:

View File

@@ -4,7 +4,7 @@ get:
description: 'Fetch a single SEPA Mandate by its uuid, if visible for the current subject.'
operationId: getSepaMandateByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: sepaMandateUUID
in: path
@@ -32,7 +32,7 @@ patch:
description: 'Updates a single SEPA Mandate by its uuid, if permitted for the current subject.'
operationId: patchSepaMandate
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: sepaMandateUUID
in: path
@@ -63,7 +63,7 @@ delete:
description: 'Delete a single SEPA Mandate by its uuid, if permitted for the current subject.'
operationId: deleteSepaMandateByUuid
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: sepaMandateUUID
in: path

View File

@@ -1,11 +1,11 @@
get:
summary: Returns a list of (optionally filtered) SEPA Mandates.
description: Returns the list of (optionally filtered) SEPA Mandates which are visible to the current user or any of it's assumed roles.
description: Returns the list of (optionally filtered) SEPA Mandates which are visible to the current subject or any of it's assumed roles.
tags:
- hs-office-sepaMandates
operationId: listSepaMandatesByIBAN
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name
in: query
@@ -33,7 +33,7 @@ post:
- hs-office-sepaMandates
operationId: addSepaMandate
parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser'
- $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody:
description: A JSON object describing the new SEPA-Mandate.

View File

@@ -18,11 +18,11 @@ components:
grantedRoleUuid:
type: string
format: uuid
granteeUserName:
granteeSubjectName:
type: string
granteeUserUuid:
granteeSubjectUuid:
type: string
format: uuid
required:
- grantedRoleUuid
- granteeUserUuid
- granteeSubjectUuid

Some files were not shown because too many files have changed in this diff Show More