spring-boot-3-2-upgrade #32
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,7 +4,6 @@
|
|||||||
/build/www/**
|
/build/www/**
|
||||||
/src/test/javascript/coverage/
|
/src/test/javascript/coverage/
|
||||||
/worktrees/
|
/worktrees/
|
||||||
TODO-progress.png
|
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Node
|
# Node
|
||||||
|
@ -380,12 +380,6 @@ You can explore the prototype as follows:
|
|||||||
`src/`
|
`src/`
|
||||||
The actual source-code, see [Source Code Package Structure](#source-code-package-structure) for details.
|
The actual source-code, see [Source Code Package Structure](#source-code-package-structure) for details.
|
||||||
|
|
||||||
`TODO.md`
|
|
||||||
Requirements of initial project. Do not touch!
|
|
||||||
|
|
||||||
`TODO-progress.png`
|
|
||||||
Generated diagram image of the project progress.
|
|
||||||
|
|
||||||
`tools/`
|
`tools/`
|
||||||
Some shell-scripts to useful tasks.
|
Some shell-scripts to useful tasks.
|
||||||
|
|
||||||
@ -765,5 +759,4 @@ The output will list the generated files.
|
|||||||
## Further Documentation
|
## Further Documentation
|
||||||
|
|
||||||
- the `doc` directory contains architecture concepts and a glossary
|
- the `doc` directory contains architecture concepts and a glossary
|
||||||
- TODO.md tracks requirements and progress for the contract of the initial project,
|
- the `ideas` directory contains unstructured ideas for future development or documentation
|
||||||
please do not amend anything in this document
|
|
||||||
|
@ -694,7 +694,7 @@ Users can view only the roles to which are granted to them.
|
|||||||
|
|
||||||
Grant can be `empowered`, this means that the grantee user can grant the granted role to other users
|
Grant can be `empowered`, this means that the grantee user can grant the granted role to other users
|
||||||
and revoke grants to that role.
|
and revoke grants to that role.
|
||||||
(TODO: access control part not yet implemented)
|
(TODO: access control part not yet implemented, currently all accessible roles can be granted to other users)
|
||||||
|
|
||||||
Grants can be `managed`, which means they are created and deleted by system-defined rules.
|
Grants can be `managed`, which means they are created and deleted by system-defined rules.
|
||||||
If a grant is not managed, it was created by an empowered user and can be deleted by empowered users.
|
If a grant is not managed, it was created by an empowered user and can be deleted by empowered users.
|
||||||
|
@ -87,7 +87,7 @@ Acceptance-Tests run on a fully integrated and deployed system with deployed dou
|
|||||||
|
|
||||||
Acceptance-tests, are blackbox-tests and do <u>not</u> count into test-code-coverage.
|
Acceptance-tests, are blackbox-tests and do <u>not</u> count into test-code-coverage.
|
||||||
|
|
||||||
TODO: Complete the Acceptance-Tests test concept.
|
TODO.test: Complete the Acceptance-Tests test concept.
|
||||||
|
|
||||||
|
|
||||||
#### Performance-Tests
|
#### Performance-Tests
|
||||||
@ -107,4 +107,4 @@ We define System-Integration-Tests as test in which this system is deployed in a
|
|||||||
|
|
||||||
System-Integration-tests, are blackbox-tests and do <u>not</u> count into test-code-coverage.
|
System-Integration-tests, are blackbox-tests and do <u>not</u> count into test-code-coverage.
|
||||||
|
|
||||||
TODO: Complete the System-Integration-Tests test concept.
|
TODO.test: Complete the System-Integration-Tests test concept.
|
||||||
|
@ -18,8 +18,8 @@ CREATE OR REPLACE FUNCTION historicize()
|
|||||||
RETURNS trigger
|
RETURNS trigger
|
||||||
LANGUAGE plpgsql STRICT AS $$
|
LANGUAGE plpgsql STRICT AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
currentUser VARCHAR(64);
|
currentUser VARCHAR(63);
|
||||||
currentTask varchar;
|
currentTask VARCHAR(127);
|
||||||
"row" RECORD;
|
"row" RECORD;
|
||||||
"alive" BOOLEAN;
|
"alive" BOOLEAN;
|
||||||
"sql" varchar;
|
"sql" varchar;
|
||||||
@ -37,27 +37,27 @@ END IF;
|
|||||||
|
|
||||||
-- determine task
|
-- determine task
|
||||||
currentTask = current_setting('hsadminng.currentTask');
|
currentTask = current_setting('hsadminng.currentTask');
|
||||||
IF (currentTask IS NULL OR length(currentTask) < 12) THEN
|
assert currentTask IS NOT NULL AND length(currentTask) >= 12,
|
||||||
RAISE EXCEPTION 'hsadminng.currentTask (%) must be defined and min 12 characters long, please use "SET LOCAL ...;"', currentTask;
|
format('hsadminng.currentTask (%s) must be defined and min 12 characters long, please use "SET LOCAL ...;"', currentTask);
|
||||||
END IF;
|
assert length(currentTask) <= 127,
|
||||||
RAISE NOTICE 'currentTask: %', currentTask;
|
format('hsadminng.currentTask (%s) must not be longer than 127 characters"', currentTask);
|
||||||
|
|
||||||
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
|
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE') THEN
|
||||||
"row" := NEW;
|
"row" := NEW;
|
||||||
"alive" := TRUE;
|
"alive" := TRUE;
|
||||||
ELSE -- DELETE or TRUNCATE
|
ELSE -- DELETE or TRUNCATE
|
||||||
"row" := OLD;
|
"row" := OLD;
|
||||||
"alive" := FALSE;
|
"alive" := FALSE;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
sql := format('INSERT INTO tx_history VALUES (txid_current(), now(), %1L, %2L) ON CONFLICT DO NOTHING', currentUser, currentTask);
|
sql := format('INSERT INTO tx_history VALUES (txid_current(), now(), %1L, %2L) ON CONFLICT DO NOTHING', currentUser, currentTask);
|
||||||
RAISE NOTICE 'sql: %', sql;
|
RAISE NOTICE 'sql: %', sql;
|
||||||
EXECUTE sql;
|
EXECUTE sql;
|
||||||
sql := format('INSERT INTO %3$I_versions VALUES (DEFAULT, txid_current(), %1$L, %2$L, $1.*)', TG_OP, alive, TG_TABLE_NAME);
|
sql := format('INSERT INTO %3$I_versions VALUES (DEFAULT, txid_current(), %1$L, %2$L, $1.*)', TG_OP, alive, TG_TABLE_NAME);
|
||||||
RAISE NOTICE 'sql: %', sql;
|
RAISE NOTICE 'sql: %', sql;
|
||||||
EXECUTE sql USING "row";
|
EXECUTE sql USING "row";
|
||||||
|
|
||||||
RETURN "row";
|
RETURN "row";
|
||||||
END; $$;
|
END; $$;
|
||||||
|
|
||||||
CREATE OR REPLACE PROCEDURE create_historical_view(baseTable varchar)
|
CREATE OR REPLACE PROCEDURE create_historical_view(baseTable varchar)
|
||||||
|
@ -55,16 +55,15 @@ public class Context {
|
|||||||
final String currentRequest,
|
final String currentRequest,
|
||||||
final String currentUser,
|
final String currentUser,
|
||||||
final String assumedRoles) {
|
final String assumedRoles) {
|
||||||
final var query = em.createNativeQuery(
|
final var query = em.createNativeQuery("""
|
||||||
"""
|
|
||||||
call defineContext(
|
call defineContext(
|
||||||
cast(:currentTask as varchar),
|
cast(:currentTask as varchar(127)),
|
||||||
cast(:currentRequest as varchar),
|
cast(:currentRequest as text),
|
||||||
cast(:currentUser as varchar),
|
cast(:currentUser as varchar(63)),
|
||||||
cast(:assumedRoles as varchar));
|
cast(:assumedRoles as varchar(1023)));
|
||||||
""");
|
""");
|
||||||
query.setParameter("currentTask", shortenToMaxLength(currentTask, 96));
|
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
|
||||||
query.setParameter("currentRequest", shortenToMaxLength(currentRequest, 512)); // TODO.spec: length?
|
query.setParameter("currentRequest", currentRequest);
|
||||||
query.setParameter("currentUser", currentUser);
|
query.setParameter("currentUser", currentUser);
|
||||||
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
|
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
|
||||||
query.executeUpdate();
|
query.executeUpdate();
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
@DisplayName("BankAccount")
|
@DisplayName("BankAccount")
|
||||||
public class HsOfficeBankAccountEntity implements HasUuid, Stringifyable {
|
public class HsOfficeBankAccountEntity implements RbacObject, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
|
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
|
||||||
.withIdProp(HsOfficeBankAccountEntity::getIban)
|
.withIdProp(HsOfficeBankAccountEntity::getIban)
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
@DisplayName("Contact")
|
@DisplayName("Contact")
|
||||||
public class HsOfficeContactEntity implements Stringifyable, HasUuid {
|
public class HsOfficeContactEntity implements Stringifyable, RbacObject {
|
||||||
|
|
||||||
private static Stringify<HsOfficeContactEntity> toString = stringify(HsOfficeContactEntity.class, "contact")
|
private static Stringify<HsOfficeContactEntity> toString = stringify(HsOfficeContactEntity.class, "contact")
|
||||||
.withProp(Fields.label, HsOfficeContactEntity::getLabel)
|
.withProp(Fields.label, HsOfficeContactEntity::getLabel)
|
||||||
@ -43,13 +43,13 @@ public class HsOfficeContactEntity implements Stringifyable, HasUuid {
|
|||||||
private String label;
|
private String label;
|
||||||
|
|
||||||
@Column(name = "postaladdress")
|
@Column(name = "postaladdress")
|
||||||
private String postalAddress; // TODO: check if we really want multiple, if so: JSON-Array or Postgres-Array?
|
private String postalAddress; // TODO.spec: check if we really want multiple, if so: JSON-Array or Postgres-Array?
|
||||||
|
|
||||||
@Column(name = "emailaddresses", columnDefinition = "json")
|
@Column(name = "emailaddresses", columnDefinition = "json")
|
||||||
private String emailAddresses; // TODO: check if we can really add multiple. format: ["eins@...", "zwei@..."]
|
private String emailAddresses; // TODO.spec: check if we can really add multiple. format: ["eins@...", "zwei@..."]
|
||||||
|
|
||||||
@Column(name = "phonenumbers", columnDefinition = "json")
|
@Column(name = "phonenumbers", columnDefinition = "json")
|
||||||
private String phoneNumbers; // TODO: check if we can really add multiple. format: { "office": "+49 40 12345-10", "fax": "+49 40 12345-05" }
|
private String phoneNumbers; // TODO.spec: check if we can really add multiple. format: { "office": "+49 40 12345-10", "fax": "+49 40 12345-05" }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -4,7 +4,7 @@ package net.hostsharing.hsadminng.hs.office.coopassets;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("CoopAssetsTransaction")
|
@DisplayName("CoopAssetsTransaction")
|
||||||
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, HasUuid {
|
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacObject {
|
||||||
|
|
||||||
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
|
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
|
||||||
.withIdProp(HsOfficeCoopAssetsTransactionEntity::getTaggedMemberNumber)
|
.withIdProp(HsOfficeCoopAssetsTransactionEntity::getTaggedMemberNumber)
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
@ -32,7 +32,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("CoopShareTransaction")
|
@DisplayName("CoopShareTransaction")
|
||||||
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, HasUuid {
|
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacObject {
|
||||||
|
|
||||||
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
||||||
.withProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged)
|
.withProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged)
|
||||||
|
@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.errors.DisplayName;
|
|||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
@ -43,7 +43,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("Debitor")
|
@DisplayName("Debitor")
|
||||||
public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
public class HsOfficeDebitorEntity implements RbacObject, Stringifyable {
|
||||||
|
|
||||||
public static final String DEBITOR_NUMBER_TAG = "D-";
|
public static final String DEBITOR_NUMBER_TAG = "D-";
|
||||||
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
||||||
@ -153,7 +153,7 @@ public class HsOfficeDebitorEntity implements HasUuid, Stringifyable {
|
|||||||
"vatCountryCode",
|
"vatCountryCode",
|
||||||
"vatBusiness",
|
"vatBusiness",
|
||||||
"vatReverseCharge",
|
"vatReverseCharge",
|
||||||
"defaultPrefix" /* TODO: do we want that updatable? */)
|
"defaultPrefix" /* TODO.spec: do we want that updatable? */)
|
||||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||||
|
|
||||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
|
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationEntity.class,
|
||||||
|
@ -5,7 +5,7 @@ import com.vladmihalcea.hibernate.type.range.Range;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
@ -42,7 +42,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("Membership")
|
@DisplayName("Membership")
|
||||||
public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
|
public class HsOfficeMembershipEntity implements RbacObject, Stringifyable {
|
||||||
|
|
||||||
public static final String MEMBER_NUMBER_TAG = "M-";
|
public static final String MEMBER_NUMBER_TAG = "M-";
|
||||||
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
||||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("PartnerDetails")
|
@DisplayName("PartnerDetails")
|
||||||
public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
public class HsOfficePartnerDetailsEntity implements RbacObject, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
|
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
|
||||||
HsOfficePartnerDetailsEntity.class,
|
HsOfficePartnerDetailsEntity.class,
|
||||||
|
@ -8,7 +8,7 @@ import lombok.Setter;
|
|||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
@ -45,7 +45,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("Partner")
|
@DisplayName("Partner")
|
||||||
public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
public class HsOfficePartnerEntity implements Stringifyable, RbacObject {
|
||||||
|
|
||||||
public static final String PARTNER_NUMBER_TAG = "P-";
|
public static final String PARTNER_NUMBER_TAG = "P-";
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public interface HsOfficePartnerRepository extends Repository<HsOfficePartnerEnt
|
|||||||
|
|
||||||
Optional<HsOfficePartnerEntity> findByUuid(UUID id);
|
Optional<HsOfficePartnerEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
List<HsOfficePartnerEntity> findAll(); // TODO: move to a repo in test sources
|
List<HsOfficePartnerEntity> findAll(); // TODO.impl: move to a repo in test sources
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT partner FROM HsOfficePartnerEntity partner
|
SELECT partner FROM HsOfficePartnerEntity partner
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
@DisplayName("Person")
|
@DisplayName("Person")
|
||||||
public class HsOfficePersonEntity implements HasUuid, Stringifyable {
|
public class HsOfficePersonEntity implements RbacObject, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
|
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
|
||||||
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType)
|
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType)
|
||||||
|
@ -4,7 +4,7 @@ import lombok.*;
|
|||||||
import lombok.experimental.FieldNameConstants;
|
import lombok.experimental.FieldNameConstants;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
@ -32,7 +32,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@FieldNameConstants
|
@FieldNameConstants
|
||||||
public class HsOfficeRelationEntity implements HasUuid, Stringifyable {
|
public class HsOfficeRelationEntity implements RbacObject, Stringifyable {
|
||||||
|
|
||||||
private static Stringify<HsOfficeRelationEntity> toString = stringify(HsOfficeRelationEntity.class, "rel")
|
private static Stringify<HsOfficeRelationEntity> toString = stringify(HsOfficeRelationEntity.class, "rel")
|
||||||
.withProp(Fields.anchor, HsOfficeRelationEntity::getAnchor)
|
.withProp(Fields.anchor, HsOfficeRelationEntity::getAnchor)
|
||||||
|
@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.errors.DisplayName;
|
|||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
@ -37,7 +37,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@DisplayName("SEPA-Mandate")
|
@DisplayName("SEPA-Mandate")
|
||||||
public class HsOfficeSepaMandateEntity implements Stringifyable, HasUuid {
|
public class HsOfficeSepaMandateEntity implements Stringifyable, RbacObject {
|
||||||
|
|
||||||
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
|
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
|
||||||
.withProp(e -> e.getBankAccount().getIban())
|
.withProp(e -> e.getBankAccount().getIban())
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.persistence;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
|
||||||
|
|
||||||
// TODO: remove this interface, I just wanted to avoid to many changes in that PR
|
|
||||||
public interface HasUuid extends RbacObject {
|
|
||||||
}
|
|
@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.test.cust.TestCustomerEntity;
|
import net.hostsharing.hsadminng.test.cust.TestCustomerEntity;
|
||||||
import net.hostsharing.hsadminng.test.dom.TestDomainEntity;
|
import net.hostsharing.hsadminng.test.dom.TestDomainEntity;
|
||||||
@ -277,7 +277,7 @@ public class RbacView {
|
|||||||
*/
|
*/
|
||||||
public <EC extends RbacObject> RbacView importRootEntityAliasProxy(
|
public <EC extends RbacObject> RbacView importRootEntityAliasProxy(
|
||||||
final String aliasName,
|
final String aliasName,
|
||||||
final Class<? extends HasUuid> entityClass,
|
final Class<? extends RbacObject> entityClass,
|
||||||
final SQL fetchSql,
|
final SQL fetchSql,
|
||||||
final Column dependsOnColum) {
|
final Column dependsOnColum) {
|
||||||
if (rootEntityAliasProxy != null) {
|
if (rootEntityAliasProxy != null) {
|
||||||
@ -300,7 +300,7 @@ public class RbacView {
|
|||||||
* a JPA entity class extending RbacObject
|
* a JPA entity class extending RbacObject
|
||||||
*/
|
*/
|
||||||
public RbacView importSubEntityAlias(
|
public RbacView importSubEntityAlias(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends RbacObject> entityClass,
|
||||||
final SQL fetchSql, final Column dependsOnColum) {
|
final SQL fetchSql, final Column dependsOnColum) {
|
||||||
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, true, NOT_NULL);
|
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, true, NOT_NULL);
|
||||||
return this;
|
return this;
|
||||||
@ -334,7 +334,7 @@ public class RbacView {
|
|||||||
* a JPA entity class extending RbacObject
|
* a JPA entity class extending RbacObject
|
||||||
*/
|
*/
|
||||||
public RbacView importEntityAlias(
|
public RbacView importEntityAlias(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends RbacObject> entityClass,
|
||||||
final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
|
final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
|
||||||
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false, nullable);
|
importEntityAliasImpl(aliasName, entityClass, fetchSql, dependsOnColum, false, nullable);
|
||||||
return this;
|
return this;
|
||||||
@ -342,14 +342,14 @@ public class RbacView {
|
|||||||
|
|
||||||
// TODO: remove once it's not used in HsOffice...Entity anymore
|
// TODO: remove once it's not used in HsOffice...Entity anymore
|
||||||
public RbacView importEntityAlias(
|
public RbacView importEntityAlias(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends RbacObject> entityClass,
|
||||||
final Column dependsOnColum) {
|
final Column dependsOnColum) {
|
||||||
importEntityAliasImpl(aliasName, entityClass, directlyFetchedByDependsOnColumn(), dependsOnColum, false, null);
|
importEntityAliasImpl(aliasName, entityClass, directlyFetchedByDependsOnColumn(), dependsOnColum, false, null);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EntityAlias importEntityAliasImpl(
|
private EntityAlias importEntityAliasImpl(
|
||||||
final String aliasName, final Class<? extends HasUuid> entityClass,
|
final String aliasName, final Class<? extends RbacObject> entityClass,
|
||||||
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
||||||
final var entityAlias = new EntityAlias(aliasName, entityClass, fetchSql, dependsOnColum, asSubEntity, nullable);
|
final var entityAlias = new EntityAlias(aliasName, entityClass, fetchSql, dependsOnColum, asSubEntity, nullable);
|
||||||
entityAliases.put(aliasName, entityAlias);
|
entityAliases.put(aliasName, entityAlias);
|
||||||
@ -1046,7 +1046,7 @@ public class RbacView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void generateRbacView(final Class<? extends HasUuid> c) {
|
private static void generateRbacView(final Class<? extends RbacObject> c) {
|
||||||
final Method mainMethod = stream(c.getMethods()).filter(
|
final Method mainMethod = stream(c.getMethods()).filter(
|
||||||
m -> isStatic(m.getModifiers()) && m.getName().equals("main")
|
m -> isStatic(m.getModifiers()) && m.getName().equals("main")
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
|||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class TestCustomerEntity implements HasUuid {
|
public class TestCustomerEntity implements RbacObject {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.test.pac.TestPackageEntity;
|
import net.hostsharing.hsadminng.test.pac.TestPackageEntity;
|
||||||
@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
|||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class TestDomainEntity implements HasUuid {
|
public class TestDomainEntity implements RbacObject {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||||
import net.hostsharing.hsadminng.test.cust.TestCustomerEntity;
|
import net.hostsharing.hsadminng.test.cust.TestCustomerEntity;
|
||||||
@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
|||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class TestPackageEntity implements HasUuid {
|
public class TestPackageEntity implements RbacObject {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
|
@ -23,7 +23,7 @@ components:
|
|||||||
- ADMIN
|
- ADMIN
|
||||||
- AGENT
|
- AGENT
|
||||||
- TENANT
|
- TENANT
|
||||||
- GUEST
|
|
||||||
- REFERRER
|
- REFERRER
|
||||||
|
- GUEST
|
||||||
roleName:
|
roleName:
|
||||||
type: string
|
type: string
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
This function will be overwritten by later changesets.
|
This function will be overwritten by later changesets.
|
||||||
*/
|
*/
|
||||||
create procedure contextDefined(
|
create procedure contextDefined(
|
||||||
currentTask varchar,
|
currentTask varchar(127),
|
||||||
currentRequest varchar,
|
currentRequest text,
|
||||||
currentUser varchar,
|
currentUser varchar(63),
|
||||||
assumedRoles varchar
|
assumedRoles varchar(1023)
|
||||||
)
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
|
@ -248,7 +248,7 @@ declare
|
|||||||
objectUuidOfRole uuid;
|
objectUuidOfRole uuid;
|
||||||
roleUuid uuid;
|
roleUuid uuid;
|
||||||
begin
|
begin
|
||||||
-- TODO.refact: extract function toRbacRoleDescriptor(roleIdName varchar) + find other occurrences
|
-- TODO.refa: extract function toRbacRoleDescriptor(roleIdName varchar) + find other occurrences
|
||||||
roleParts = overlay(roleIdName placing '#' from length(roleIdName) + 1 - strpos(reverse(roleIdName), ':'));
|
roleParts = overlay(roleIdName placing '#' from length(roleIdName) + 1 - strpos(reverse(roleIdName), ':'));
|
||||||
objectTableFromRoleIdName = split_part(roleParts, '#', 1);
|
objectTableFromRoleIdName = split_part(roleParts, '#', 1);
|
||||||
objectNameFromRoleIdName = split_part(roleParts, '#', 2);
|
objectNameFromRoleIdName = split_part(roleParts, '#', 2);
|
||||||
@ -356,16 +356,13 @@ create trigger deleteRbacRolesOfRbacObject_Trigger
|
|||||||
/*
|
/*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
create domain RbacOp as varchar(67) -- TODO: shorten to 8, once the deprecated values are gone
|
create domain RbacOp as varchar(6)
|
||||||
check (
|
check (
|
||||||
VALUE = 'DELETE'
|
VALUE = 'DELETE'
|
||||||
or VALUE = 'UPDATE'
|
or VALUE = 'UPDATE'
|
||||||
or VALUE = 'SELECT'
|
or VALUE = 'SELECT'
|
||||||
or VALUE = 'INSERT'
|
or VALUE = 'INSERT'
|
||||||
or VALUE = 'ASSUME'
|
or VALUE = 'ASSUME'
|
||||||
-- TODO: all values below are deprecated, use insert with table
|
|
||||||
or VALUE ~ '^add-[a-z]+$'
|
|
||||||
or VALUE ~ '^new-[a-z-]+$'
|
|
||||||
);
|
);
|
||||||
|
|
||||||
create table RbacPermission
|
create table RbacPermission
|
||||||
@ -417,37 +414,6 @@ begin
|
|||||||
return permissionUuid;
|
return permissionUuid;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
-- TODO: deprecated, remove and amend all usages to createPermission
|
|
||||||
create or replace function createPermissions(forObjectUuid uuid, permitOps RbacOp[])
|
|
||||||
returns uuid[]
|
|
||||||
language plpgsql as $$
|
|
||||||
declare
|
|
||||||
refId uuid;
|
|
||||||
permissionIds uuid[] = array []::uuid[];
|
|
||||||
begin
|
|
||||||
if (forObjectUuid is null) then
|
|
||||||
raise exception 'forObjectUuid must not be null';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
for i in array_lower(permitOps, 1)..array_upper(permitOps, 1)
|
|
||||||
loop
|
|
||||||
refId = (select uuid from RbacPermission where objectUuid = forObjectUuid and op = permitOps[i]);
|
|
||||||
if (refId is null) then
|
|
||||||
insert
|
|
||||||
into RbacReference ("type")
|
|
||||||
values ('RbacPermission')
|
|
||||||
returning uuid into refId;
|
|
||||||
insert
|
|
||||||
into RbacPermission (uuid, objectUuid, op)
|
|
||||||
values (refId, forObjectUuid, permitOps[i]);
|
|
||||||
end if;
|
|
||||||
permissionIds = permissionIds || refId;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return permissionIds;
|
|
||||||
end;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
create or replace function findEffectivePermissionId(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
|
create or replace function findEffectivePermissionId(forObjectUuid uuid, forOp RbacOp, forOpTableName text = null)
|
||||||
returns uuid
|
returns uuid
|
||||||
returns null on null input
|
returns null on null input
|
||||||
@ -649,25 +615,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
-- TODO: deprecated, remove and use grantPermissionToRole(...)
|
|
||||||
create or replace procedure grantPermissionsToRole(roleUuid uuid, permissionIds uuid[])
|
|
||||||
language plpgsql as $$
|
|
||||||
begin
|
|
||||||
if cardinality(permissionIds) = 0 then return; end if;
|
|
||||||
|
|
||||||
for i in array_lower(permissionIds, 1)..array_upper(permissionIds, 1)
|
|
||||||
loop
|
|
||||||
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
|
|
||||||
perform assertReferenceType('permissionId (descendant)', permissionIds[i], 'RbacPermission');
|
|
||||||
|
|
||||||
insert
|
|
||||||
into RbacGrants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed)
|
|
||||||
values (currentTriggerObjectUuid(), roleUuid, permissionIds[i], true)
|
|
||||||
on conflict do nothing; -- allow granting multiple times
|
|
||||||
end loop;
|
|
||||||
end;
|
|
||||||
$$;
|
|
||||||
|
|
||||||
create or replace procedure grantRoleToRole(subRoleId uuid, superRoleId uuid, doAssume bool = true)
|
create or replace procedure grantRoleToRole(subRoleId uuid, superRoleId uuid, doAssume bool = true)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
@ -691,7 +638,7 @@ declare
|
|||||||
superRoleId uuid;
|
superRoleId uuid;
|
||||||
subRoleId uuid;
|
subRoleId uuid;
|
||||||
begin
|
begin
|
||||||
-- TODO: maybe separate method grantRoleToRoleIfNotNull(...) for NULLABLE references
|
-- TODO.refa: maybe separate method grantRoleToRoleIfNotNull(...) for NULLABLE references
|
||||||
if superRole.objectUuid is null or subRole.objectuuid is null then
|
if superRole.objectUuid is null or subRole.objectuuid is null then
|
||||||
return;
|
return;
|
||||||
end if;
|
end if;
|
||||||
|
@ -85,10 +85,10 @@ end; $$;
|
|||||||
This function will be overwritten by later changesets.
|
This function will be overwritten by later changesets.
|
||||||
*/
|
*/
|
||||||
create or replace procedure contextDefined(
|
create or replace procedure contextDefined(
|
||||||
currentTask varchar,
|
currentTask varchar(127),
|
||||||
currentRequest varchar,
|
currentRequest text,
|
||||||
currentUser varchar,
|
currentUser varchar(63),
|
||||||
assumedRoles varchar
|
assumedRoles varchar(1023)
|
||||||
)
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
|
@ -1,18 +1,5 @@
|
|||||||
--liquibase formatted sql
|
--liquibase formatted sql
|
||||||
|
|
||||||
-- ============================================================================
|
|
||||||
-- PERMISSIONS
|
|
||||||
--changeset rbac-role-builder-to-uuids:1 endDelimiter:--//
|
|
||||||
-- ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
create or replace function toPermissionUuids(forObjectUuid uuid, permitOps RbacOp[])
|
|
||||||
returns uuid[]
|
|
||||||
language plpgsql
|
|
||||||
strict as $$
|
|
||||||
begin
|
|
||||||
return createPermissions(forObjectUuid, permitOps);
|
|
||||||
end; $$;
|
|
||||||
|
|
||||||
|
|
||||||
-- =================================================================
|
-- =================================================================
|
||||||
-- CREATE ROLE
|
-- CREATE ROLE
|
||||||
@ -32,6 +19,8 @@ create or replace function createRoleWithGrants(
|
|||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
roleUuid uuid;
|
roleUuid uuid;
|
||||||
|
permission RbacOp;
|
||||||
|
permissionUuid uuid;
|
||||||
subRoleDesc RbacRoleDescriptor;
|
subRoleDesc RbacRoleDescriptor;
|
||||||
superRoleDesc RbacRoleDescriptor;
|
superRoleDesc RbacRoleDescriptor;
|
||||||
subRoleUuid uuid;
|
subRoleUuid uuid;
|
||||||
@ -41,9 +30,11 @@ declare
|
|||||||
begin
|
begin
|
||||||
roleUuid := createRole(roleDescriptor);
|
roleUuid := createRole(roleDescriptor);
|
||||||
|
|
||||||
if cardinality(permissions) > 0 then
|
foreach permission in array permissions
|
||||||
call grantPermissionsToRole(roleUuid, toPermissionUuids(roleDescriptor.objectuuid, permissions));
|
loop
|
||||||
end if;
|
permissionUuid := createPermission(roleDescriptor.objectuuid, permission);
|
||||||
|
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||||
|
end loop;
|
||||||
|
|
||||||
foreach superRoleDesc in array array_remove(incomingSuperRoles, null)
|
foreach superRoleDesc in array array_remove(incomingSuperRoles, null)
|
||||||
loop
|
loop
|
||||||
@ -60,7 +51,7 @@ begin
|
|||||||
if cardinality(userUuids) > 0 then
|
if cardinality(userUuids) > 0 then
|
||||||
-- direct grants to users need a grantedByRole which can revoke the grant
|
-- direct grants to users need a grantedByRole which can revoke the grant
|
||||||
if grantedByRole is null then
|
if grantedByRole is null then
|
||||||
userGrantsByRoleUuid := roleUuid; -- TODO: or do we want to require an explicit userGrantsByRoleUuid?
|
userGrantsByRoleUuid := roleUuid; -- TODO.spec: or do we want to require an explicit userGrantsByRoleUuid?
|
||||||
else
|
else
|
||||||
userGrantsByRoleUuid := getRoleId(grantedByRole);
|
userGrantsByRoleUuid := getRoleId(grantedByRole);
|
||||||
end if;
|
end if;
|
||||||
|
@ -73,15 +73,6 @@ begin
|
|||||||
return roleDescriptor('%2$s', entity.uuid, 'TENANT', assumed);
|
return roleDescriptor('%2$s', entity.uuid, 'TENANT', assumed);
|
||||||
end; $f$;
|
end; $f$;
|
||||||
|
|
||||||
-- TODO: remove guest role
|
|
||||||
create or replace function %1$sGuest(entity %2$s, assumed boolean = true)
|
|
||||||
returns RbacRoleDescriptor
|
|
||||||
language plpgsql
|
|
||||||
strict as $f$
|
|
||||||
begin
|
|
||||||
return roleDescriptor('%2$s', entity.uuid, 'GUEST', assumed);
|
|
||||||
end; $f$;
|
|
||||||
|
|
||||||
create or replace function %1$sReferrer(entity %2$s)
|
create or replace function %1$sReferrer(entity %2$s)
|
||||||
returns RbacRoleDescriptor
|
returns RbacRoleDescriptor
|
||||||
language plpgsql
|
language plpgsql
|
||||||
|
@ -121,7 +121,7 @@ public class ArchitectureTest {
|
|||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage(
|
.resideInAnyPackage(
|
||||||
"..hs.office.(*)..",
|
"..hs.office.(*)..",
|
||||||
"..rbac.rbacgrant" // TODO: just because of RbacGrantsDiagramServiceIntegrationTest
|
"..rbac.rbacgrant" // TODO.test: just because of RbacGrantsDiagramServiceIntegrationTest
|
||||||
);
|
);
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
|
@ -28,10 +28,10 @@ class ContextUnitTest {
|
|||||||
|
|
||||||
private static final String DEFINE_CONTEXT_QUERY_STRING = """
|
private static final String DEFINE_CONTEXT_QUERY_STRING = """
|
||||||
call defineContext(
|
call defineContext(
|
||||||
cast(:currentTask as varchar),
|
cast(:currentTask as varchar(127)),
|
||||||
cast(:currentRequest as varchar),
|
cast(:currentRequest as text),
|
||||||
cast(:currentUser as varchar),
|
cast(:currentUser as varchar(63)),
|
||||||
cast(:assumedRoles as varchar));
|
cast(:assumedRoles as varchar(1023)));
|
||||||
""";
|
""";
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@ -71,7 +71,7 @@ class ContextUnitTest {
|
|||||||
context.define("current-user");
|
context.define("current-user");
|
||||||
|
|
||||||
verify(em).createNativeQuery(DEFINE_CONTEXT_QUERY_STRING);
|
verify(em).createNativeQuery(DEFINE_CONTEXT_QUERY_STRING);
|
||||||
verify(nativeQuery).setParameter("currentRequest", "");
|
verify(nativeQuery).setParameter("currentRequest", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +142,8 @@ class ContextUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shortensCurrentTaskTo96Chars() throws IOException {
|
void shortensCurrentTaskToMaxLength() throws IOException {
|
||||||
givenRequest("GET", "http://localhost:9999/api/endpoint/" + "0123456789".repeat(10),
|
givenRequest("GET", "http://localhost:9999/api/endpoint/" + "0123456789".repeat(13),
|
||||||
Map.ofEntries(
|
Map.ofEntries(
|
||||||
Map.entry("current-user", "given-user"),
|
Map.entry("current-user", "given-user"),
|
||||||
Map.entry("content-type", "application/json"),
|
Map.entry("content-type", "application/json"),
|
||||||
@ -153,26 +153,7 @@ class ContextUnitTest {
|
|||||||
context.define("current-user");
|
context.define("current-user");
|
||||||
|
|
||||||
verify(em).createNativeQuery(DEFINE_CONTEXT_QUERY_STRING);
|
verify(em).createNativeQuery(DEFINE_CONTEXT_QUERY_STRING);
|
||||||
verify(nativeQuery).setParameter(eq("currentTask"), argThat((String t) -> t.length() == 96));
|
verify(nativeQuery).setParameter(eq("currentTask"), argThat((String t) -> t.length() == 127));
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shortensCurrentRequestTo512Chars() throws IOException {
|
|
||||||
givenRequest("GET", "http://localhost:9999/api/endpoint",
|
|
||||||
Map.ofEntries(
|
|
||||||
Map.entry("current-user", "given-user"),
|
|
||||||
Map.entry("content-type", "application/json"),
|
|
||||||
Map.entry("user-agent", "given-user-agent")),
|
|
||||||
"""
|
|
||||||
{
|
|
||||||
"dummy": "%s"
|
|
||||||
}
|
|
||||||
""".formatted("0123456789".repeat(60)));
|
|
||||||
|
|
||||||
context.define("current-user");
|
|
||||||
|
|
||||||
verify(em).createNativeQuery(DEFINE_CONTEXT_QUERY_STRING);
|
|
||||||
verify(nativeQuery).setParameter(eq("currentRequest"), argThat((String t) -> t.length() == 512));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void givenRequest(final String method, final String url, final Map<String, String> headers, final String body)
|
private void givenRequest(final String method, final String url, final Map<String, String> headers, final String body)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.test;
|
package net.hostsharing.hsadminng.hs.office.test;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
import net.hostsharing.hsadminng.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
||||||
@ -66,7 +66,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
|
|||||||
return merged;
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID toCleanup(final Class<? extends HasUuid> entityClass, final UUID uuidToCleanup) {
|
public UUID toCleanup(final Class<? extends RbacObject> entityClass, final UUID uuidToCleanup) {
|
||||||
out.println("toCleanup(" + entityClass.getSimpleName() + ", " + uuidToCleanup);
|
out.println("toCleanup(" + entityClass.getSimpleName() + ", " + uuidToCleanup);
|
||||||
entitiesToCleanup.put(uuidToCleanup, entityClass);
|
entitiesToCleanup.put(uuidToCleanup, entityClass);
|
||||||
return uuidToCleanup;
|
return uuidToCleanup;
|
||||||
@ -81,7 +81,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void cleanupAllNew(final Class<? extends HasUuid> entityClass) {
|
protected void cleanupAllNew(final Class<? extends RbacObject> entityClass) {
|
||||||
if (initialRbacObjects == null) {
|
if (initialRbacObjects == null) {
|
||||||
out.println("skipping cleanupAllNew: " + entityClass.getSimpleName());
|
out.println("skipping cleanupAllNew: " + entityClass.getSimpleName());
|
||||||
return; // TODO: seems @AfterEach is called without any @BeforeEach
|
return; // TODO: seems @AfterEach is called without any @BeforeEach
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.test;
|
package net.hostsharing.hsadminng.hs.office.test;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
|
|
||||||
public class EntityList {
|
public class EntityList {
|
||||||
|
|
||||||
public static <E extends HasUuid> E one(final List<E> entities) {
|
public static <E extends RbacObject> E one(final List<E> entities) {
|
||||||
assertThat(entities).hasSize(1);
|
assertThat(entities).hasSize(1);
|
||||||
return entities.stream().findFirst().orElseThrow();
|
return entities.stream().findFirst().orElseThrow();
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,6 @@ public class JpaAttempt {
|
|||||||
final Class<? extends RuntimeException> expectedExceptionClass,
|
final Class<? extends RuntimeException> expectedExceptionClass,
|
||||||
final String... expectedRootCauseMessages) {
|
final String... expectedRootCauseMessages) {
|
||||||
assertThat(wasSuccessful()).as("wasSuccessful").isFalse();
|
assertThat(wasSuccessful()).as("wasSuccessful").isFalse();
|
||||||
// TODO: also check the expected exception class itself
|
|
||||||
final String firstRootCauseMessageLine = firstRootCauseMessageLineOf(caughtException(expectedExceptionClass));
|
final String firstRootCauseMessageLine = firstRootCauseMessageLineOf(caughtException(expectedExceptionClass));
|
||||||
for (String expectedRootCauseMessage : expectedRootCauseMessages) {
|
for (String expectedRootCauseMessage : expectedRootCauseMessages) {
|
||||||
assertThat(firstRootCauseMessageLine).contains(expectedRootCauseMessage);
|
assertThat(firstRootCauseMessageLine).contains(expectedRootCauseMessage);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.test;
|
package net.hostsharing.test;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.persistence.HasUuid;
|
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||||
import org.junit.jupiter.api.Named;
|
import org.junit.jupiter.api.Named;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -233,7 +233,7 @@ public abstract class PatchUnitTestBase<R, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class JsonNullableProperty<R, RV, E extends HasUuid, EV> extends Property<R, RV, E, EV> {
|
protected static class JsonNullableProperty<R, RV, E extends RbacObject, EV> extends Property<R, RV, E, EV> {
|
||||||
|
|
||||||
private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
|
private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
|
||||||
public final RV givenPatchValue;
|
public final RV givenPatchValue;
|
||||||
|
Loading…
Reference in New Issue
Block a user