assuming-long-roleidnames + object-uuid-based-rolenames (#139)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #139 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
parent
d89b4b4992
commit
9debaa1fc0
120
bin/cas-curl
120
bin/cas-curl
@ -1,14 +1,10 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ "$#" -eq 0 ] || [ "$1" == "help" ] || [ "$1" == "--help" ] || [ "$1" == "-h" ]; then
|
if [ "$2" == "--show-password" ]; then
|
||||||
cat <<EOF
|
HSADMINNG_CAS_SHOW_PASSWORD=yes
|
||||||
curl-wrapper utilizing CAS-authentication for hsadmin-ng
|
shift
|
||||||
usage: $0 [--trace] <<command>> [parameters]
|
else
|
||||||
|
HSADMINNG_CAS_SHOW_PASSWORD=
|
||||||
commands:
|
|
||||||
EOF
|
|
||||||
grep '") ''# ' $0
|
|
||||||
exit
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" == "--trace" ]; then
|
if [ "$1" == "--trace" ]; then
|
||||||
@ -17,7 +13,10 @@ if [ "$1" == "--trace" ]; then
|
|||||||
}
|
}
|
||||||
function doCurl() {
|
function doCurl() {
|
||||||
set -x
|
set -x
|
||||||
curl --fail-with-body --header "Authorization: $HSADMINNG_CAS_TICKET" "$@"
|
curl --fail-with-body \
|
||||||
|
--header "Authorization: $HSADMINNG_CAS_TICKET" \
|
||||||
|
--header "assumed-roles: $HSADMINNG_CAS_ASSUME" \
|
||||||
|
"$@"
|
||||||
set +x
|
set +x
|
||||||
}
|
}
|
||||||
shift
|
shift
|
||||||
@ -30,6 +29,13 @@ else
|
|||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export HSADMINNG_CAS_ASSUME_HEADER
|
||||||
|
if [ -f ~/.cas-curl-assume ]; then
|
||||||
|
HSADMINNG_CAS_ASSUME="$(cat ~/.cas-curl-assume)"
|
||||||
|
else
|
||||||
|
HSADMINNG_CAS_ASSUME=
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "$HSADMINNG_CAS_LOGIN" ] || [ -z "$HSADMINNG_CAS_VALIDATE" ] || \
|
if [ -z "$HSADMINNG_CAS_LOGIN" ] || [ -z "$HSADMINNG_CAS_VALIDATE" ] || \
|
||||||
[ -z "$HSADMINNG_CAS_SERVICE_ID" ]; then
|
[ -z "$HSADMINNG_CAS_SERVICE_ID" ]; then
|
||||||
cat >&2 <<EOF
|
cat >&2 <<EOF
|
||||||
@ -45,8 +51,16 @@ EOF
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function casLogout() {
|
function casCurlDocumentation() {
|
||||||
rm -f ~/.cas-login-tgt
|
cat <<EOF
|
||||||
|
curl-wrapper utilizing CAS-authentication for hsadmin-ng
|
||||||
|
usage: $0 [--trace] [--show-password] <<command>> [parameters]
|
||||||
|
|
||||||
|
commands:
|
||||||
|
EOF
|
||||||
|
# filters out help texts (containing double-# and following lines with leading single-#) from the commands itself
|
||||||
|
# (the '' makes sure that this line is not found, just the lines with actual help texts)
|
||||||
|
sed -n '/#''#/ {x; p; x; s/#''#//; p; :a; n; /^[[:space:]]*#/!b; s/^[[:space:]]*#//; p; ba}' <$0
|
||||||
}
|
}
|
||||||
|
|
||||||
function casLogin() {
|
function casLogin() {
|
||||||
@ -63,10 +77,16 @@ function casLogin() {
|
|||||||
read -s -e -p "Password: " HSADMINNG_CAS_PASSWORD
|
read -s -e -p "Password: " HSADMINNG_CAS_PASSWORD
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$HSADMINNG_CAS_SHOW_PASSWORD" == "--show-password" ]; then
|
||||||
|
HSADMINNG_CAS_PASSWORD_DISPLAY=$HSADMINNG_CAS_PASSWORD
|
||||||
|
else
|
||||||
|
HSADMINNG_CAS_PASSWORD_DISPLAY="<<password hidden - use --show-password to show>>"
|
||||||
|
fi
|
||||||
|
|
||||||
# Do NOT use doCurl here! We do neither want to print the password nor pass a CAS service ticket.
|
# Do NOT use doCurl here! We do neither want to print the password nor pass a CAS service ticket.
|
||||||
trace "+ curl --fail-with-body -s -i -X POST \
|
trace "+ curl --fail-with-body -s -i -X POST \
|
||||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||||||
-d \"username=$HSADMINNG_CAS_USERNAME&password=<<PASSWORD OMITTED>>\" \
|
-d \"username=$HSADMINNG_CAS_USERNAME&password=$HSADMINNG_CAS_PASSWORD_DISPLAY\" \
|
||||||
$HSADMINNG_CAS_LOGIN -o ~/.cas-login-tgt.response -D -"
|
$HSADMINNG_CAS_LOGIN -o ~/.cas-login-tgt.response -D -"
|
||||||
HSADMINNG_CAS_TGT=`curl --fail-with-body -s -i -X POST \
|
HSADMINNG_CAS_TGT=`curl --fail-with-body -s -i -X POST \
|
||||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||||||
@ -76,11 +96,16 @@ function casLogin() {
|
|||||||
if [ -z "$HSADMINNG_CAS_TGT" ]; then
|
if [ -z "$HSADMINNG_CAS_TGT" ]; then
|
||||||
echo "ERROR: could not get ticket granting ticket" >&2
|
echo "ERROR: could not get ticket granting ticket" >&2
|
||||||
cat ~/.cas-login-tgt.response >&2
|
cat ~/.cas-login-tgt.response >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "$HSADMINNG_CAS_TGT" >~/.cas-login-tgt
|
echo "$HSADMINNG_CAS_TGT" >~/.cas-login-tgt
|
||||||
trace "$HSADMINNG_CAS_TGT"
|
trace "$HSADMINNG_CAS_TGT"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function casLogout() {
|
||||||
|
rm -f ~/.cas-login-tgt
|
||||||
|
}
|
||||||
|
|
||||||
function casTicket() {
|
function casTicket() {
|
||||||
HSADMINNG_CAS_TGT=$(<~/.cas-login-tgt)
|
HSADMINNG_CAS_TGT=$(<~/.cas-login-tgt)
|
||||||
if [[ -z "$HSADMINNG_CAS_TGT" ]]; then
|
if [[ -z "$HSADMINNG_CAS_TGT" ]]; then
|
||||||
@ -115,37 +140,90 @@ function casValidate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "${1,,}" in
|
case "${1,,}" in
|
||||||
"login") # reads username+password and fetches ticket granting ticket (bypasses HSADMINNG_CAS_USERNAME+HSADMINNG_CAS_PASSWORD)
|
|
||||||
|
# -- generic commands --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
""|"-h"|"--help"|"help") ## prints documentation about commands and options
|
||||||
|
casCurlDocumentation
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
|
||||||
|
"env") ## prints all related HSADMINNG_CAS_... environment variables; use '--show-password' to show the password as well
|
||||||
|
# example: cas-curl env --show-password
|
||||||
|
echo "HSADMINNG_CAS_LOGIN: $HSADMINNG_CAS_LOGIN"
|
||||||
|
echo "HSADMINNG_CAS_VALIDATE: $HSADMINNG_CAS_VALIDATE"
|
||||||
|
echo "HSADMINNG_CAS_USERNAME: $HSADMINNG_CAS_USERNAME"
|
||||||
|
if [ "$2" == "--show-password" ]; then
|
||||||
|
echo "HSADMINNG_CAS_PASSWORD: $HSADMINNG_CAS_PASSWORD"
|
||||||
|
elif [ -z "$HSADMINNG_CAS_PASSWORD" ]; then
|
||||||
|
echo "HSADMINNG_CAS_PASSWORD: <<not given>>"
|
||||||
|
else
|
||||||
|
echo "HSADMINNG_CAS_PASSWORD: <<given, but hidden - add --show-password to show>>"
|
||||||
|
fi
|
||||||
|
echo "HSADMINNG_CAS_SERVICE_ID: $HSADMINNG_CAS_SERVICE_ID"
|
||||||
|
;;
|
||||||
|
|
||||||
|
# --- authentication-related commands ------------------------------------------------------------
|
||||||
|
|
||||||
|
"login") ## reads username+password and fetches ticket granting ticket (bypasses HSADMINNG_CAS_USERNAME+HSADMINNG_CAS_PASSWORD)
|
||||||
|
# example: cas-curl login
|
||||||
casLogout
|
casLogout
|
||||||
export HSADMINNG_CAS_USERNAME=
|
export HSADMINNG_CAS_USERNAME=
|
||||||
export HSADMINNG_CAS_PASSWORD=
|
export HSADMINNG_CAS_PASSWORD=
|
||||||
casLogin
|
casLogin
|
||||||
;;
|
;;
|
||||||
"logout") # logout, deleting ticket granting ticket
|
"assume") ## assumes the given comma-separated roles
|
||||||
casLogout
|
# example using object-id-name: cas-curl assume 'hs_office.relation#ExampleMandant-with-PARTNER-ExamplePartner:AGENT'
|
||||||
|
# example using object-uuid: cas-curl assume 'hs_office.relation#1d3bc468-c5c8-11ef-9d0d-4751ecfda2b7:AGENT'
|
||||||
|
shift
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "ERROR: requires comma-separated list of roles to assume" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "$1" >~/.cas-curl-assume
|
||||||
;;
|
;;
|
||||||
"validate") # validates ticket granting ticket and prints currently logged in user
|
"unassume") ## do not assume any particular role anymore, use the plain user as RBAC subject
|
||||||
|
rm ~/.cas-curl-assume
|
||||||
|
;;
|
||||||
|
"validate") ## validates current ticket granting ticket and prints currently logged in user
|
||||||
casValidate
|
casValidate
|
||||||
;;
|
;;
|
||||||
"get") # HTTP GET, add URL as parameter
|
"logout") ## logout, deletes ticket granting ticket
|
||||||
|
casLogout
|
||||||
|
;;
|
||||||
|
|
||||||
|
# --- HTTP-commands ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
"get") ## HTTP GET, add URL as parameter
|
||||||
|
# example: cas-curl GET http://localhost:8080/api/hs/office/partners/P-10003 | jq
|
||||||
|
# hint: '| jq' is just for human-readable formatted JSON output
|
||||||
shift
|
shift
|
||||||
casLogin
|
casLogin
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
HSADMINNG_CAS_TICKET=`casTicket`
|
||||||
doCurl "$*"
|
doCurl "$*"
|
||||||
;;
|
;;
|
||||||
"post") # HTTP POST, add curl options to specify the request body and the URL as last parameter
|
"post") ## HTTP POST, add curl options to specify the request body and the URL as last parameter
|
||||||
|
# example: cas-curl POST \
|
||||||
|
# -d '{ "prefix":"ttt", "reference":80001, "adminUserName":"admin@ttt.example.com" }' \
|
||||||
|
# http://localhost:8080/api/test/customers | jq
|
||||||
|
# hint: '| jq' is just for human-readable formatted JSON output
|
||||||
shift
|
shift
|
||||||
casLogin
|
casLogin
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
HSADMINNG_CAS_TICKET=`casTicket`
|
||||||
doCurl --header "Content-Type: application/json" -X POST "$@"
|
doCurl --header "Content-Type: application/json" -X POST "$@"
|
||||||
;;
|
;;
|
||||||
"patch") # HTTP PATCH, add curl options to specify the request body and the URL as last parameter
|
"patch") ## HTTP PATCH, add curl options to specify the request body and the URL as last parameterparameter
|
||||||
|
# example: cas-curl PATCH \
|
||||||
|
# -d '{ "reference":80002 }' \
|
||||||
|
# http://localhost:8080/api/test/customers/ae90ac2a-4728-4ca9-802e-a0d0108b2324 | jq
|
||||||
|
# hint: '| jq' is just for human-readable formatted JSON output
|
||||||
shift
|
shift
|
||||||
casLogin
|
casLogin
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
HSADMINNG_CAS_TICKET=`casTicket`
|
||||||
doCurl --header "Content-Type: application/json" -X POST "$*"
|
doCurl --header "Content-Type: application/json" -X POST "$*"
|
||||||
;;
|
;;
|
||||||
"delete") # HTTP DELETE, add curl options to specify the request body and the URL as last parameter
|
"delete") ## HTTP DELETE, add curl options to specify the request body and the URL as last parameter
|
||||||
|
# example: cas-curl DELETE http://localhost:8080/api/hs/office/persons/ae90ac2a-4728-4ca9-802e-a0d0108b2324
|
||||||
shift
|
shift
|
||||||
casLogin
|
casLogin
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
HSADMINNG_CAS_TICKET=`casTicket`
|
||||||
|
@ -58,7 +58,7 @@ public class Context {
|
|||||||
cast(:currentTask as varchar(127)),
|
cast(:currentTask as varchar(127)),
|
||||||
cast(:currentRequest as text),
|
cast(:currentRequest as text),
|
||||||
cast(:currentSubject as varchar(63)),
|
cast(:currentSubject as varchar(63)),
|
||||||
cast(:assumedRoles as varchar(1023)));
|
cast(:assumedRoles as text));
|
||||||
""");
|
""");
|
||||||
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
|
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
|
||||||
query.setParameter("currentRequest", currentRequest);
|
query.setParameter("currentRequest", currentRequest);
|
||||||
|
@ -42,22 +42,22 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
|
|||||||
toSqlLikeOperand(mark), toSqlLikeOperand(personData), toSqlLikeOperand(contactData));
|
toSqlLikeOperand(mark), toSqlLikeOperand(personData), toSqlLikeOperand(contactData));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use ELIKE instead of lower(...) LIKE ...? Or use jsonb_path with RegEx like emailAddressRegEx in ContactRepo?
|
// TODO: Or use jsonb_path with RegEx like emailAddressRegEx in ContactRepo?
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT rel FROM HsOfficeRelationRbacEntity AS rel
|
SELECT rel FROM HsOfficeRelationRbacEntity AS rel
|
||||||
WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType)
|
WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType)
|
||||||
AND ( :personUuid IS NULL
|
AND ( :personUuid IS NULL
|
||||||
OR rel.anchor.uuid = :personUuid OR rel.holder.uuid = :personUuid )
|
OR rel.anchor.uuid = :personUuid OR rel.holder.uuid = :personUuid )
|
||||||
AND ( :mark IS NULL OR lower(rel.mark) LIKE :mark )
|
AND ( :mark IS NULL OR rel.mark ILIKE :mark )
|
||||||
AND ( :personData IS NULL
|
AND ( :personData IS NULL
|
||||||
OR lower(rel.anchor.tradeName) LIKE :personData OR lower(rel.holder.tradeName) LIKE :personData
|
OR rel.anchor.tradeName ILIKE :personData OR rel.holder.tradeName ILIKE :personData
|
||||||
OR lower(rel.anchor.familyName) LIKE :personData OR lower(rel.holder.familyName) LIKE :personData
|
OR rel.anchor.familyName ILIKE :personData OR rel.holder.familyName ILIKE :personData
|
||||||
OR lower(rel.anchor.givenName) LIKE :personData OR lower(rel.holder.givenName) LIKE :personData )
|
OR rel.anchor.givenName ILIKE :personData OR rel.holder.givenName ILIKE :personData )
|
||||||
AND ( :contactData IS NULL
|
AND ( :contactData IS NULL
|
||||||
OR lower(rel.contact.caption) LIKE :contactData
|
OR rel.contact.caption ILIKE :contactData
|
||||||
OR lower(CAST(rel.contact.postalAddress AS String)) LIKE :contactData
|
OR CAST(rel.contact.postalAddress AS String) ILIKE :contactData
|
||||||
OR lower(CAST(rel.contact.emailAddresses AS String)) LIKE :contactData
|
OR CAST(rel.contact.emailAddresses AS String) ILIKE :contactData
|
||||||
OR lower(CAST(rel.contact.phoneNumbers AS String)) LIKE :contactData )
|
OR CAST(rel.contact.phoneNumbers AS String) ILIKE :contactData )
|
||||||
""")
|
""")
|
||||||
@Timed("app.office.relations.repo.findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl.rbac")
|
@Timed("app.office.relations.repo.findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl.rbac")
|
||||||
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
|
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
|
||||||
|
@ -14,24 +14,58 @@ public interface HsOfficeRelationRealRepository extends Repository<HsOfficeRelat
|
|||||||
@Timed("app.repo.relations.findByUuid.real")
|
@Timed("app.repo.relations.findByUuid.real")
|
||||||
Optional<HsOfficeRelationRealEntity> findByUuid(UUID id);
|
Optional<HsOfficeRelationRealEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
default List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidAndRelationType(@NotNull UUID personUuid, HsOfficeRelationType relationType) {
|
|
||||||
return findRelationRelatedToPersonUuidAndRelationTypeString(personUuid, relationType == null ? null : relationType.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT p.* FROM hs_office.relation AS p
|
SELECT p.* FROM hs_office.relation AS p
|
||||||
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
@Timed("app.repo.relations.findRelationRelatedToPersonUuid.real")
|
@Timed("app.repo.relations.findRelationRelatedToPersonUuid.real")
|
||||||
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds relations by a conjunction of optional criteria, including anchorPerson, holderPerson and contact data.
|
||||||
|
* *
|
||||||
|
* @param personUuid the optional UUID of the anchorPerson or holderPerson
|
||||||
|
* @param relationType the type of the relation
|
||||||
|
* @param mark the mark (use '%' for wildcard), case ignored
|
||||||
|
* @param personData a string to match the persons tradeName, familyName or givenName (use '%' for wildcard), case ignored
|
||||||
|
* @param contactData a string to match the contacts caption, postalAddress, emailAddresses or phoneNumbers (use '%' for wildcard), case ignored
|
||||||
|
* @return a list of (accessible) relations which match all given criteria
|
||||||
|
*/
|
||||||
|
default List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
|
||||||
|
final UUID personUuid,
|
||||||
|
final HsOfficeRelationType relationType,
|
||||||
|
final String mark,
|
||||||
|
final String personData,
|
||||||
|
final String contactData) {
|
||||||
|
return findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
|
||||||
|
personUuid, toStringOrNull(relationType),
|
||||||
|
toSqlLikeOperand(mark), toSqlLikeOperand(personData), toSqlLikeOperand(contactData));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Or use jsonb_path with RegEx like emailAddressRegEx in ContactRepo?
|
||||||
@Query(value = """
|
@Query(value = """
|
||||||
SELECT p.* FROM hs_office.relation AS p
|
SELECT rel FROM HsOfficeRelationRealEntity AS rel
|
||||||
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS hs_office.RelationType))
|
WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType)
|
||||||
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
AND ( :personUuid IS NULL
|
||||||
""", nativeQuery = true)
|
OR rel.anchor.uuid = :personUuid OR rel.holder.uuid = :personUuid )
|
||||||
@Timed("app.repo.relations.findRelationRelatedToPersonUuidAndRelationTypeString.real")
|
AND ( :mark IS NULL OR rel.mark ILIKE :mark )
|
||||||
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
|
AND ( :personData IS NULL
|
||||||
|
OR rel.anchor.tradeName ILIKE :personData OR rel.holder.tradeName ILIKE :personData
|
||||||
|
OR rel.anchor.familyName ILIKE :personData OR rel.holder.familyName ILIKE :personData
|
||||||
|
OR rel.anchor.givenName ILIKE :personData OR rel.holder.givenName ILIKE :personData )
|
||||||
|
AND ( :contactData IS NULL
|
||||||
|
OR rel.contact.caption ILIKE :contactData
|
||||||
|
OR CAST(rel.contact.postalAddress AS String) ILIKE :contactData
|
||||||
|
OR CAST(rel.contact.emailAddresses AS String) ILIKE :contactData
|
||||||
|
OR CAST(rel.contact.phoneNumbers AS String) ILIKE :contactData )
|
||||||
|
""")
|
||||||
|
@Timed("app.office.relations.repo.findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl.real")
|
||||||
|
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
|
||||||
|
final UUID personUuid,
|
||||||
|
final String relationType,
|
||||||
|
final String mark,
|
||||||
|
final String personData,
|
||||||
|
final String contactData);
|
||||||
|
|
||||||
@Timed("app.repo.relations.save.real")
|
@Timed("app.repo.relations.save.real")
|
||||||
HsOfficeRelationRealEntity save(final HsOfficeRelationRealEntity entity);
|
HsOfficeRelationRealEntity save(final HsOfficeRelationRealEntity entity);
|
||||||
@ -41,4 +75,11 @@ public interface HsOfficeRelationRealRepository extends Repository<HsOfficeRelat
|
|||||||
|
|
||||||
@Timed("app.repo.relations.deleteByUuid.real")
|
@Timed("app.repo.relations.deleteByUuid.real")
|
||||||
int deleteByUuid(UUID uuid);
|
int deleteByUuid(UUID uuid);
|
||||||
|
private static String toSqlLikeOperand(final String text) {
|
||||||
|
return text == null ? null : ("%" + text.toLowerCase() + "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toStringOrNull(final HsOfficeRelationType relationType) {
|
||||||
|
return relationType == null ? null : relationType.name();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ create procedure base.contextDefined(
|
|||||||
currentTask varchar(127),
|
currentTask varchar(127),
|
||||||
currentRequest text,
|
currentRequest text,
|
||||||
currentSubject varchar(63),
|
currentSubject varchar(63),
|
||||||
assumedRoles varchar(1023)
|
assumedRoles varchar(4096)
|
||||||
)
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
@ -26,7 +26,7 @@ create or replace procedure base.defineContext(
|
|||||||
currentTask varchar(127),
|
currentTask varchar(127),
|
||||||
currentRequest text = null,
|
currentRequest text = null,
|
||||||
currentSubject varchar(63) = null,
|
currentSubject varchar(63) = null,
|
||||||
assumedRoles varchar(1023) = null
|
assumedRoles text = null
|
||||||
)
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
begin
|
begin
|
||||||
@ -43,7 +43,7 @@ begin
|
|||||||
execute format('set local hsadminng.currentSubject to %L', currentSubject);
|
execute format('set local hsadminng.currentSubject to %L', currentSubject);
|
||||||
|
|
||||||
assumedRoles := coalesce(assumedRoles, '');
|
assumedRoles := coalesce(assumedRoles, '');
|
||||||
assert length(assumedRoles) <= 1023, FORMAT('assumedRoles must not be longer than 1023 characters: "%s"', assumedRoles);
|
assert length(assumedRoles) <= 4096, FORMAT('assumedRoles must not be longer than 4096 characters: "%s"', assumedRoles);
|
||||||
execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
|
execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
|
||||||
|
|
||||||
call base.contextDefined(currentTask, currentRequest, currentSubject, assumedRoles);
|
call base.contextDefined(currentTask, currentRequest, currentSubject, assumedRoles);
|
||||||
|
@ -251,9 +251,14 @@ begin
|
|||||||
execute sql into uuid;
|
execute sql into uuid;
|
||||||
exception
|
exception
|
||||||
when others then
|
when others then
|
||||||
raise exception 'function %_uuid_by_id_name(...) not found, add identity view support for table %', objectTable, objectTable;
|
raise exception 'function %_uuid_by_id_name(''%'') failed: %, SQLSTATE: %. If it could not be found, add identity view support to %\nSQL:%',
|
||||||
|
objectTable, objectIdName, SQLERRM, SQLSTATE, objectTable, sql;
|
||||||
end;
|
end;
|
||||||
return uuid;
|
if uuid is null then
|
||||||
|
raise exception 'SQL returned null: %', sql;
|
||||||
|
else
|
||||||
|
return uuid;
|
||||||
|
end if;
|
||||||
end ; $$;
|
end ; $$;
|
||||||
|
|
||||||
create or replace function rbac.findIdNameByObjectUuid(objectTable varchar, objectUuid uuid)
|
create or replace function rbac.findIdNameByObjectUuid(objectTable varchar, objectUuid uuid)
|
||||||
@ -270,7 +275,8 @@ begin
|
|||||||
execute sql into idName;
|
execute sql into idName;
|
||||||
exception
|
exception
|
||||||
when others then
|
when others then
|
||||||
raise exception 'function %_id_name_by_uuid(...) not found, add identity view support for table %', objectTable, objectTable;
|
raise exception 'function %_id_name_by_uuid(''%'') failed: %, SQLSTATE: %. If it could not be found, add identity view support to %',
|
||||||
|
objectTable, objectUuid, SQLERRM, SQLSTATE, objectTable;
|
||||||
end;
|
end;
|
||||||
return idName;
|
return idName;
|
||||||
end ; $$;
|
end ; $$;
|
||||||
|
@ -23,7 +23,7 @@ begin
|
|||||||
return currentSubjectUuid;
|
return currentSubjectUuid;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
create or replace function rbac.determinecurrentsubjectorassumedrolesuuids(currentSubjectOrAssumedRolesUuids uuid, assumedRoles varchar)
|
create or replace function rbac.determinecurrentsubjectorassumedrolesuuids(currentSubjectOrAssumedRolesUuids uuid, assumedRoles text)
|
||||||
returns uuid[]
|
returns uuid[]
|
||||||
stable -- leakproof
|
stable -- leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
@ -31,7 +31,7 @@ declare
|
|||||||
roleName text;
|
roleName text;
|
||||||
roleNameParts text;
|
roleNameParts text;
|
||||||
objectTableToAssume varchar(63);
|
objectTableToAssume varchar(63);
|
||||||
objectNameToAssume varchar(63);
|
objectNameToAssume varchar(1024); -- e.g. for relation: 2*(96+48+48)+length('-with-REPRESENTATIVE-') = 405
|
||||||
objectUuidToAssume uuid;
|
objectUuidToAssume uuid;
|
||||||
roleTypeToAssume rbac.RoleType;
|
roleTypeToAssume rbac.RoleType;
|
||||||
roleIdsToAssume uuid[];
|
roleIdsToAssume uuid[];
|
||||||
@ -55,7 +55,12 @@ begin
|
|||||||
objectNameToAssume = split_part(roleNameParts, '#', 2);
|
objectNameToAssume = split_part(roleNameParts, '#', 2);
|
||||||
roleTypeToAssume = split_part(roleNameParts, '#', 3);
|
roleTypeToAssume = split_part(roleNameParts, '#', 3);
|
||||||
|
|
||||||
objectUuidToAssume = rbac.findObjectUuidByIdName(objectTableToAssume, objectNameToAssume);
|
begin
|
||||||
|
objectUuidToAssume = objectNameToAssume::uuid;
|
||||||
|
exception when invalid_text_representation then
|
||||||
|
objectUuidToAssume = rbac.findObjectUuidByIdName(objectTableToAssume, objectNameToAssume);
|
||||||
|
end;
|
||||||
|
|
||||||
if objectUuidToAssume is null then
|
if objectUuidToAssume is null then
|
||||||
raise exception '[401] object % cannot be found in table % (from roleNameParts=%)', objectNameToAssume, objectTableToAssume, roleNameParts;
|
raise exception '[401] object % cannot be found in table % (from roleNameParts=%)', objectNameToAssume, objectTableToAssume, roleNameParts;
|
||||||
end if;
|
end if;
|
||||||
@ -88,7 +93,7 @@ create or replace procedure base.contextDefined(
|
|||||||
currentTask varchar(127),
|
currentTask varchar(127),
|
||||||
currentRequest text,
|
currentRequest text,
|
||||||
currentSubject varchar(63),
|
currentSubject varchar(63),
|
||||||
assumedRoles varchar(1023)
|
assumedRoles varchar(4096)
|
||||||
)
|
)
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
@ -104,7 +109,7 @@ begin
|
|||||||
|
|
||||||
execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
|
execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
|
||||||
execute format('set local hsadminng.currentSubjectOrAssumedRolesUuids to %L',
|
execute format('set local hsadminng.currentSubjectOrAssumedRolesUuids to %L',
|
||||||
(select array_to_string(rbac.determinecurrentsubjectorassumedrolesuuids(currentSubjectUuid, assumedRoles), ';')));
|
(select array_to_string(rbac.determineCurrentSubjectOrAssumedRolesUuids(currentSubjectUuid, assumedRoles), ';')));
|
||||||
|
|
||||||
raise notice 'Context defined as: %, %, %, [%]', currentTask, currentRequest, currentSubject, assumedRoles;
|
raise notice 'Context defined as: %, %, %, [%]', currentTask, currentRequest, currentSubject, assumedRoles;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
@ -45,7 +45,8 @@ do language plpgsql $$
|
|||||||
call hs_office.person_create_test_data('NP', null, 'Smith', 'Peter');
|
call hs_office.person_create_test_data('NP', null, 'Smith', 'Peter');
|
||||||
call hs_office.person_create_test_data('NP', null, 'Tucker', 'Jack');
|
call hs_office.person_create_test_data('NP', null, 'Tucker', 'Jack');
|
||||||
call hs_office.person_create_test_data('NP', null, 'Fouler', 'Ellie');
|
call hs_office.person_create_test_data('NP', null, 'Fouler', 'Ellie');
|
||||||
call hs_office.person_create_test_data('LP', 'Second e.K.', 'Smith', 'Peter');
|
-- the next tradeName is deliberately 63 chars in length, the max length for that field, also to test long rbac-role names
|
||||||
|
call hs_office.person_create_test_data('LP', 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'Smith', 'Peter');
|
||||||
call hs_office.person_create_test_data('IF', 'Third OHG');
|
call hs_office.person_create_test_data('IF', 'Third OHG');
|
||||||
call hs_office.person_create_test_data('LP', 'Fourth eG');
|
call hs_office.person_create_test_data('LP', 'Fourth eG');
|
||||||
call hs_office.person_create_test_data('UF', 'Erben Bessler', 'Mel', 'Bessler');
|
call hs_office.person_create_test_data('UF', 'Erben Bessler', 'Mel', 'Bessler');
|
||||||
|
@ -91,9 +91,9 @@ do language plpgsql $$
|
|||||||
call hs_office.relation_create_test_data('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
|
call hs_office.relation_create_test_data('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
|
||||||
call hs_office.relation_create_test_data('First GmbH', 'DEBITOR', 'First GmbH', 'first contact');
|
call hs_office.relation_create_test_data('First GmbH', 'DEBITOR', 'First GmbH', 'first contact');
|
||||||
|
|
||||||
call hs_office.relation_create_test_data('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
|
call hs_office.relation_create_test_data('Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
|
||||||
call hs_office.relation_create_test_data('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact');
|
call hs_office.relation_create_test_data('Smith', 'REPRESENTATIVE', 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact');
|
||||||
call hs_office.relation_create_test_data('Second e.K.', 'DEBITOR', 'Second e.K.', 'second contact');
|
call hs_office.relation_create_test_data('Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'DEBITOR', 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact');
|
||||||
|
|
||||||
call hs_office.relation_create_test_data('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
|
call hs_office.relation_create_test_data('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
|
||||||
call hs_office.relation_create_test_data('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
call hs_office.relation_create_test_data('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
||||||
|
@ -74,7 +74,7 @@ do language plpgsql $$
|
|||||||
call base.defineContext('creating partner test-data ', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
call base.defineContext('creating partner test-data ', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||||
|
|
||||||
call hs_office.partner_create_test_data('Hostsharing eG', 10001, 'First GmbH', 'first contact');
|
call hs_office.partner_create_test_data('Hostsharing eG', 10001, 'First GmbH', 'first contact');
|
||||||
call hs_office.partner_create_test_data('Hostsharing eG', 10002, 'Second e.K.', 'second contact');
|
call hs_office.partner_create_test_data('Hostsharing eG', 10002, 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact');
|
||||||
call hs_office.partner_create_test_data('Hostsharing eG', 10003, 'Third OHG', 'third contact');
|
call hs_office.partner_create_test_data('Hostsharing eG', 10003, 'Third OHG', 'third contact');
|
||||||
call hs_office.partner_create_test_data('Hostsharing eG', 10004, 'Fourth eG', 'fourth contact');
|
call hs_office.partner_create_test_data('Hostsharing eG', 10004, 'Fourth eG', 'fourth contact');
|
||||||
call hs_office.partner_create_test_data('Hostsharing eG', 10010, 'Smith', 'fifth contact');
|
call hs_office.partner_create_test_data('Hostsharing eG', 10010, 'Smith', 'fifth contact');
|
||||||
|
@ -13,7 +13,7 @@ create or replace procedure hs_office.bankaccount_create_test_data(givenHolder v
|
|||||||
declare
|
declare
|
||||||
emailAddr varchar;
|
emailAddr varchar;
|
||||||
begin
|
begin
|
||||||
emailAddr = 'bankaccount-admin@' || base.cleanIdentifier(givenHolder) || '.example.com';
|
emailAddr = 'bankaccount-admin@' || TRIM(SUBSTRING(base.cleanIdentifier(givenHolder) FOR 32)) || '.example.com';
|
||||||
perform rbac.create_subject(emailAddr);
|
perform rbac.create_subject(emailAddr);
|
||||||
call base.defineContext('creating bankaccount test-data', null, emailAddr);
|
call base.defineContext('creating bankaccount test-data', null, emailAddr);
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ do language plpgsql $$
|
|||||||
-- IBANs+BICs taken from https://ibanvalidieren.de/beispiele.html
|
-- IBANs+BICs taken from https://ibanvalidieren.de/beispiele.html
|
||||||
call hs_office.bankaccount_create_test_data('First GmbH', 'DE02120300000000202051', 'BYLADEM1001');
|
call hs_office.bankaccount_create_test_data('First GmbH', 'DE02120300000000202051', 'BYLADEM1001');
|
||||||
call hs_office.bankaccount_create_test_data('Peter Smith', 'DE02500105170137075030', 'INGDDEFF');
|
call hs_office.bankaccount_create_test_data('Peter Smith', 'DE02500105170137075030', 'INGDDEFF');
|
||||||
call hs_office.bankaccount_create_test_data('Second e.K.', 'DE02100500000054540402', 'BELADEBE');
|
call hs_office.bankaccount_create_test_data('Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'DE02100500000054540402', 'BELADEBE');
|
||||||
call hs_office.bankaccount_create_test_data('Third OHG', 'DE02300209000106531065', 'CMCIDEDD');
|
call hs_office.bankaccount_create_test_data('Third OHG', 'DE02300209000106531065', 'CMCIDEDD');
|
||||||
call hs_office.bankaccount_create_test_data('Fourth eG', 'DE02200505501015871393', 'HASPDEHH');
|
call hs_office.bankaccount_create_test_data('Fourth eG', 'DE02200505501015871393', 'HASPDEHH');
|
||||||
call hs_office.bankaccount_create_test_data('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF');
|
call hs_office.bankaccount_create_test_data('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF');
|
||||||
|
@ -53,7 +53,7 @@ do language plpgsql $$
|
|||||||
call base.defineContext('creating debitor test-data', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
call base.defineContext('creating debitor test-data', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||||
|
|
||||||
call hs_office.debitor_create_test_data(11, 'First GmbH', 'first contact', 'fir');
|
call hs_office.debitor_create_test_data(11, 'First GmbH', 'first contact', 'fir');
|
||||||
call hs_office.debitor_create_test_data(12, 'Second e.K.', 'second contact', 'sec');
|
call hs_office.debitor_create_test_data(12, 'Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', 'second contact', 'sec');
|
||||||
call hs_office.debitor_create_test_data(13, 'Third OHG', 'third contact', 'thi');
|
call hs_office.debitor_create_test_data(13, 'Third OHG', 'third contact', 'thi');
|
||||||
end;
|
end;
|
||||||
$$;
|
$$;
|
||||||
|
@ -97,7 +97,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
"bic": "INGDDEFF"
|
"bic": "INGDDEFF"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"holder": "Second e.K.",
|
"holder": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.",
|
||||||
"iban": "DE02100500000054540402",
|
"iban": "DE02100500000054540402",
|
||||||
"bic": "BELADEBE"
|
"bic": "BELADEBE"
|
||||||
},
|
},
|
||||||
|
@ -147,7 +147,7 @@ class HsOfficeBankAccountRepositoryIntegrationTest extends ContextBasedTestWithC
|
|||||||
"Mel Bessler",
|
"Mel Bessler",
|
||||||
"Paul Winkler",
|
"Paul Winkler",
|
||||||
"Peter Smith",
|
"Peter Smith",
|
||||||
"Second e.K.",
|
"Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.",
|
||||||
"Third OHG");
|
"Third OHG");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +227,8 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitorRel": {
|
"debitorRel": {
|
||||||
"anchor": {"tradeName": "Second e.K."},
|
"anchor": {"tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K."},
|
||||||
"holder": {"tradeName": "Second e.K."},
|
"holder": {"tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K."},
|
||||||
"type": "DEBITOR",
|
"type": "DEBITOR",
|
||||||
"contact": {
|
"contact": {
|
||||||
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
|
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
|
||||||
@ -240,7 +240,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
"partnerNumber": "P-10002",
|
"partnerNumber": "P-10002",
|
||||||
"partnerRel": {
|
"partnerRel": {
|
||||||
"anchor": {"tradeName": "Hostsharing eG"},
|
"anchor": {"tradeName": "Hostsharing eG"},
|
||||||
"holder": {"tradeName": "Second e.K."},
|
"holder": {"tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K."},
|
||||||
"type": "PARTNER",
|
"type": "PARTNER",
|
||||||
"contact": {
|
"contact": {
|
||||||
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
|
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
|
||||||
|
@ -240,7 +240,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
allTheseDebitorsAreReturned(
|
allTheseDebitorsAreReturned(
|
||||||
result,
|
result,
|
||||||
"debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)",
|
"debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)",
|
||||||
"debitor(D-1000212: rel(anchor='LP Second e.K.', type='DEBITOR', holder='LP Second e.K.'), sec)",
|
"debitor(D-1000212: rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='DEBITOR', holder='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.'), sec)",
|
||||||
"debitor(D-1000313: rel(anchor='IF Third OHG', type='DEBITOR', holder='IF Third OHG'), thi)");
|
"debitor(D-1000313: rel(anchor='IF Third OHG', type='DEBITOR', holder='IF Third OHG'), thi)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
// and an ex-partner-relation got created
|
// and an ex-partner-relation got created
|
||||||
final var anchorpartnerPersonUUid = givenPartner.getPartnerRel().getAnchor().getUuid();
|
final var anchorpartnerPersonUUid = givenPartner.getPartnerRel().getAnchor().getUuid();
|
||||||
assertThat(relationRepo.findRelationRelatedToPersonUuidAndRelationType(anchorpartnerPersonUUid, EX_PARTNER))
|
assertThat(relationRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(anchorpartnerPersonUUid, EX_PARTNER, null, null, null))
|
||||||
.map(HsOfficeRelation::toShortString)
|
.map(HsOfficeRelation::toShortString)
|
||||||
.contains("rel(anchor='LP Hostsharing eG', type='EX_PARTNER', holder='UF Erben Bessler')");
|
.contains("rel(anchor='LP Hostsharing eG', type='EX_PARTNER', holder='UF Erben Bessler')");
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
|||||||
allThesePartnersAreReturned(
|
allThesePartnersAreReturned(
|
||||||
result,
|
result,
|
||||||
"partner(P-10001: LP First GmbH, first contact)",
|
"partner(P-10001: LP First GmbH, first contact)",
|
||||||
"partner(P-10002: LP Second e.K., second contact)",
|
"partner(P-10002: LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K., second contact)",
|
||||||
"partner(P-10003: IF Third OHG, third contact)",
|
"partner(P-10003: IF Third OHG, third contact)",
|
||||||
"partner(P-10004: LP Fourth eG, fourth contact)",
|
"partner(P-10004: LP Fourth eG, fourth contact)",
|
||||||
"partner(P-10010: NP Smith, Peter, sixth contact)");
|
"partner(P-10010: NP Smith, Peter, sixth contact)");
|
||||||
|
@ -143,7 +143,7 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
allThesePersonsAreReturned(
|
allThesePersonsAreReturned(
|
||||||
result,
|
result,
|
||||||
"NP Smith, Peter",
|
"NP Smith, Peter",
|
||||||
"LP Second e.K.",
|
"LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.",
|
||||||
"IF Third OHG",
|
"IF Third OHG",
|
||||||
"UF Erben Bessler");
|
"UF Erben Bessler");
|
||||||
}
|
}
|
||||||
@ -171,10 +171,10 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
context("superuser-alex@hostsharing.net", null);
|
context("superuser-alex@hostsharing.net", null);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = personRbacRepo.findPersonByOptionalNameLike("Second");
|
final var result = personRbacRepo.findPersonByOptionalNameLike("Peter Smith - The Second Hand%");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyThesePersonsAreReturned(result, "Second e.K.");
|
exactlyThesePersonsAreReturned(result, "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -272,7 +272,7 @@ class HsOfficePersonRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
||||||
"[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]",
|
"[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]",
|
||||||
"[creating person test-data, hs_office.person, INSERT, First GmbH, null]",
|
"[creating person test-data, hs_office.person, INSERT, First GmbH, null]",
|
||||||
"[creating person test-data, hs_office.person, INSERT, Second e.K., null]",
|
"[creating person test-data, hs_office.person, INSERT, Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K., null]",
|
||||||
"[creating person test-data, hs_office.person, INSERT, Third OHG, null]");
|
"[creating person test-data, hs_office.person, INSERT, Third OHG, null]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
allThesePersonsAreReturned(
|
allThesePersonsAreReturned(
|
||||||
result,
|
result,
|
||||||
"NP Smith, Peter",
|
"NP Smith, Peter",
|
||||||
"LP Second e.K.",
|
"LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.",
|
||||||
"IF Third OHG",
|
"IF Third OHG",
|
||||||
"UF Erben Bessler");
|
"UF Erben Bessler");
|
||||||
}
|
}
|
||||||
@ -141,10 +141,10 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
context("selfregistered-user-drew@hostsharing.org");
|
context("selfregistered-user-drew@hostsharing.org");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = personRealRepo.findPersonByOptionalNameLike("Second");
|
final var result = personRealRepo.findPersonByOptionalNameLike("Peter Smith - The Second Hand%");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
exactlyThesePersonsAreReturned(result, "Second e.K.");
|
exactlyThesePersonsAreReturned(result, "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ class HsOfficePersonRealRepositoryIntegrationTest extends ContextBasedTestWithCl
|
|||||||
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
assertThat(customerLogEntries).map(Arrays::toString).contains(
|
||||||
"[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]",
|
"[creating person test-data, hs_office.person, INSERT, Hostsharing eG, null]",
|
||||||
"[creating person test-data, hs_office.person, INSERT, First GmbH, null]",
|
"[creating person test-data, hs_office.person, INSERT, First GmbH, null]",
|
||||||
"[creating person test-data, hs_office.person, INSERT, Second e.K., null]",
|
"[creating person test-data, hs_office.person, INSERT, Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K., null]",
|
||||||
"[creating person test-data, hs_office.person, INSERT, Third OHG, null]");
|
"[creating person test-data, hs_office.person, INSERT, Third OHG, null]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,13 +47,13 @@ class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
|
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = relationRealRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid, null);
|
final var result = relationRealRepo.findRelationRelatedToPersonUuid(personUuid);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
|
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
|
||||||
exactlyTheseRelationsAreReturned(
|
exactlyTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
|
"rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
|
||||||
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
|
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
|
||||||
"rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')",
|
"rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')",
|
||||||
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')"
|
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')"
|
||||||
@ -66,13 +66,13 @@ class HsOfficeRealRelationRepositoryIntegrationTest extends ContextBasedTestWith
|
|||||||
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
|
final var personUuid = determinePersonUuid(NATURAL_PERSON, "Smith");
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = relationRealRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid, REPRESENTATIVE);
|
final var result = relationRealRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(personUuid, REPRESENTATIVE, null, null, null);
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
|
context("superuser-alex@hostsharing.net"); // just to be able to access RBAc-entities persons+contact
|
||||||
exactlyTheseRelationsAreReturned(
|
exactlyTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')"
|
"rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
"anchor": { "personType": "LEGAL_PERSON", "tradeName": "Hostsharing eG" },
|
||||||
"holder": { "personType": "LEGAL_PERSON", "tradeName": "Second e.K.", "givenName": "Peter", "familyName": "Smith" },
|
"holder": { "personType": "LEGAL_PERSON", "tradeName": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.", "givenName": "Peter", "familyName": "Smith" },
|
||||||
"type": "PARTNER",
|
"type": "PARTNER",
|
||||||
"mark": null,
|
"mark": null,
|
||||||
"contact": { "caption": "second contact" }
|
"contact": { "caption": "second contact" }
|
||||||
|
@ -3,10 +3,11 @@ package net.hostsharing.hsadminng.hs.office.relation;
|
|||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||||
|
import net.hostsharing.hsadminng.mapper.Array;
|
||||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
import net.hostsharing.hsadminng.rbac.role.RawRbacRoleRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -30,17 +31,20 @@ import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@Import( { Context.class, JpaAttempt.class })
|
@Import({ Context.class, JpaAttempt.class })
|
||||||
class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeRelationRbacRepository relationRbacRepo;
|
HsOfficeRelationRbacRepository relationRbacRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
HsOfficeRelationRealRepository relationRealRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficePersonRealRepository personRepo;
|
HsOfficePersonRealRepository personRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeContactRealRepository contactrealRepo;
|
HsOfficeContactRealRepository contactRealRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RawRbacRoleRepository rawRoleRepo;
|
RawRbacRoleRepository rawRoleRepo;
|
||||||
@ -57,6 +61,29 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
@MockBean
|
@MockBean
|
||||||
HttpServletRequest request;
|
HttpServletRequest request;
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class AssumeRelationRole {
|
||||||
|
|
||||||
|
// TODO.test: these tests would be better placed in the rbac module,
|
||||||
|
// but for this we need an extra long object-idname in the rbac test data
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHostsharingAdminCanAssumeRelationRoleWithLongIdName() {
|
||||||
|
context(
|
||||||
|
"superuser-alex@hostsharing.net",
|
||||||
|
"hs_office.relation#HostsharingeG-with-PARTNER-PeterSmith-TheSecondHandandThriftStores-n-Shippinge.K.SmithPeter:AGENT");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHostsharingAdminCanAssumeRelationRoleWithUuid() {
|
||||||
|
final var relationUuid = relationRealRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
|
||||||
|
null, HsOfficeRelationType.PARTNER, null, "%Second%", null)
|
||||||
|
.stream().reduce(Reducer::toSingleElement).orElseThrow().getUuid();
|
||||||
|
|
||||||
|
context("superuser-alex@hostsharing.net", "hs_office.relation#" + relationUuid + ":AGENT");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class CreateRelation {
|
class CreateRelation {
|
||||||
|
|
||||||
@ -64,6 +91,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewRelation() {
|
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewRelation() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
|
|
||||||
final var count = relationRbacRepo.count();
|
final var count = relationRbacRepo.count();
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
|
||||||
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
|
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
|
||||||
@ -71,20 +99,21 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").stream()
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Paul").stream()
|
||||||
.filter(p -> p.getPersonType() == NATURAL_PERSON)
|
.filter(p -> p.getPersonType() == NATURAL_PERSON)
|
||||||
.findFirst().orElseThrow();
|
.findFirst().orElseThrow();
|
||||||
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").stream()
|
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("fourth contact").stream()
|
||||||
.findFirst().orElseThrow();
|
.findFirst().orElseThrow();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(
|
||||||
final var newRelation = HsOfficeRelationRbacEntity.builder()
|
em, () -> {
|
||||||
.anchor(givenAnchorPerson)
|
final var newRelation = HsOfficeRelationRbacEntity.builder()
|
||||||
.holder(givenHolderPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.type(HsOfficeRelationType.SUBSCRIBER)
|
.holder(givenHolderPerson)
|
||||||
.mark("operations-announce")
|
.type(HsOfficeRelationType.SUBSCRIBER)
|
||||||
.contact(givenContact)
|
.mark("operations-announce")
|
||||||
.build();
|
.contact(givenContact)
|
||||||
return toCleanup(relationRbacRepo.save(newRelation));
|
.build();
|
||||||
});
|
return toCleanup(relationRbacRepo.save(newRelation));
|
||||||
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertSuccessful();
|
result.assertSuccessful();
|
||||||
@ -93,7 +122,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
assertThat(relationRbacRepo.count()).isEqualTo(count + 1);
|
assertThat(relationRbacRepo.count()).isEqualTo(count + 1);
|
||||||
final var stored = relationRbacRepo.findByUuid(result.returnedValue().getUuid());
|
final var stored = relationRbacRepo.findByUuid(result.returnedValue().getUuid());
|
||||||
assertThat(stored).isNotEmpty().map(HsOfficeRelation::toString).get()
|
assertThat(stored).isNotEmpty().map(HsOfficeRelation::toString).get()
|
||||||
.isEqualTo("rel(anchor='UF Erben Bessler', type='SUBSCRIBER', mark='operations-announce', holder='NP Winkler, Paul', contact='fourth contact')");
|
.isEqualTo(
|
||||||
|
"rel(anchor='UF Erben Bessler', type='SUBSCRIBER', mark='operations-announce', holder='NP Winkler, Paul', contact='fourth contact')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -104,23 +134,24 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
|
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
attempt(em, () -> {
|
attempt(
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
|
em, () -> {
|
||||||
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Bessler").stream()
|
||||||
.findFirst().orElseThrow();
|
.filter(p -> p.getPersonType() == UNINCORPORATED_FIRM)
|
||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Bert").stream()
|
.findFirst().orElseThrow();
|
||||||
.filter(p -> p.getPersonType() == NATURAL_PERSON)
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike("Bert").stream()
|
||||||
.findFirst().orElseThrow();
|
.filter(p -> p.getPersonType() == NATURAL_PERSON)
|
||||||
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("fourth contact").stream()
|
.findFirst().orElseThrow();
|
||||||
.findFirst().orElseThrow();
|
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("fourth contact").stream()
|
||||||
final var newRelation = HsOfficeRelationRbacEntity.builder()
|
.findFirst().orElseThrow();
|
||||||
.anchor(givenAnchorPerson)
|
final var newRelation = HsOfficeRelationRbacEntity.builder()
|
||||||
.holder(givenHolderPerson)
|
.anchor(givenAnchorPerson)
|
||||||
.type(HsOfficeRelationType.REPRESENTATIVE)
|
.holder(givenHolderPerson)
|
||||||
.contact(givenContact)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.build();
|
.contact(givenContact)
|
||||||
return toCleanup(relationRbacRepo.save(newRelation));
|
.build();
|
||||||
});
|
return toCleanup(relationRbacRepo.save(newRelation));
|
||||||
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(Array.from(
|
||||||
@ -180,7 +211,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
allTheseRelationsAreReturned(
|
allTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
|
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
|
||||||
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
|
"rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
|
||||||
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')");
|
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,12 +224,17 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
.findFirst().orElseThrow();
|
.findFirst().orElseThrow();
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(person.getUuid(), null, null, null, null);
|
final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
|
||||||
|
person.getUuid(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
|
||||||
// then:
|
// then:
|
||||||
exactlyTheseRelationsAreReturned(
|
exactlyTheseRelationsAreReturned(
|
||||||
result,
|
result,
|
||||||
"rel(anchor='LP Second e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
|
"rel(anchor='LP Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K.', type='REPRESENTATIVE', holder='NP Smith, Peter', contact='second contact')",
|
||||||
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')",
|
"rel(anchor='IF Third OHG', type='SUBSCRIBER', mark='members-announce', holder='NP Smith, Peter', contact='third contact')",
|
||||||
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
|
"rel(anchor='LP Hostsharing eG', type='PARTNER', holder='NP Smith, Peter', contact='sixth contact')",
|
||||||
"rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')");
|
"rel(anchor='NP Smith, Peter', type='DEBITOR', holder='NP Smith, Peter', contact='third contact')");
|
||||||
@ -219,7 +255,10 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
givenRelation,
|
givenRelation,
|
||||||
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
"hs_office.person#ErbenBesslerMelBessler:ADMIN");
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike("sixth contact").stream().findFirst().orElseThrow();
|
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("sixth contact")
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
@ -258,13 +297,16 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = jpaAttempt.transacted(() -> {
|
final var result = jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net", "hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT");
|
context(
|
||||||
|
"superuser-alex@hostsharing.net",
|
||||||
|
"hs_office.relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerAnita:AGENT");
|
||||||
givenRelation.setContact(null);
|
givenRelation.setContact(null);
|
||||||
return relationRbacRepo.save(givenRelation);
|
return relationRbacRepo.save(givenRelation);
|
||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
result.assertExceptionWithRootCauseMessage(
|
||||||
|
JpaSystemException.class,
|
||||||
"[403] Subject ", " is not allowed to update hs_office.relation uuid");
|
"[403] Subject ", " is not allowed to update hs_office.relation uuid");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,7 +329,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
});
|
});
|
||||||
|
|
||||||
// then
|
// then
|
||||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
result.assertExceptionWithRootCauseMessage(
|
||||||
|
JpaSystemException.class,
|
||||||
"[403] Subject ", " is not allowed to update hs_office.relation uuid");
|
"[403] Subject ", " is not allowed to update hs_office.relation uuid");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +440,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
select currentTask, targetTable, targetOp, targetdelta->>'mark'
|
select currentTask, targetTable, targetOp, targetdelta->>'mark'
|
||||||
from base.tx_journal_v
|
from base.tx_journal_v
|
||||||
where targettable = 'hs_office.relation';
|
where targettable = 'hs_office.relation';
|
||||||
""");
|
""");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
|
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
|
||||||
@ -412,7 +455,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
final var givenAnchorPerson = personRepo.findPersonByOptionalNameLike("Erben Bessler").get(0);
|
||||||
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
final var givenHolderPerson = personRepo.findPersonByOptionalNameLike(holderPerson).get(0);
|
||||||
final var givenContact = contactrealRepo.findContactByOptionalCaptionLike(contact).get(0);
|
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike(contact).get(0);
|
||||||
final var newRelation = HsOfficeRelationRbacEntity.builder()
|
final var newRelation = HsOfficeRelationRbacEntity.builder()
|
||||||
.type(HsOfficeRelationType.REPRESENTATIVE)
|
.type(HsOfficeRelationType.REPRESENTATIVE)
|
||||||
.anchor(givenAnchorPerson)
|
.anchor(givenAnchorPerson)
|
||||||
|
@ -83,7 +83,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debitor": { "debitorNumber": "D-1000212" },
|
"debitor": { "debitorNumber": "D-1000212" },
|
||||||
"bankAccount": { "holder": "Second e.K." },
|
"bankAccount": { "holder": "Peter Smith - The Second Hand and Thrift Stores-n-Shipping e.K." },
|
||||||
"reference": "ref-10002-12",
|
"reference": "ref-10002-12",
|
||||||
"validFrom": "2022-10-01",
|
"validFrom": "2022-10-01",
|
||||||
"validTo": "2026-12-31"
|
"validTo": "2026-12-31"
|
||||||
|
@ -32,7 +32,7 @@ class ContextUnitTest {
|
|||||||
cast(:currentTask as varchar(127)),
|
cast(:currentTask as varchar(127)),
|
||||||
cast(:currentRequest as text),
|
cast(:currentRequest as text),
|
||||||
cast(:currentSubject as varchar(63)),
|
cast(:currentSubject as varchar(63)),
|
||||||
cast(:assumedRoles as varchar(1023)));
|
cast(:assumedRoles as text));
|
||||||
""";
|
""";
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -68,7 +68,7 @@ class RbacRoleRepositoryIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void globalAdmin_withAssumedglobalAdminRole_canViewAllRbacRoles() {
|
public void globalAdmin_withAssumedGlobalAdminRole_canViewAllRbacRoles() {
|
||||||
given:
|
given:
|
||||||
context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN");
|
context.define("superuser-alex@hostsharing.net", "rbac.global#global:ADMIN");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user