migrate from CAS to Oauth2-JWT Auth (#197)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/197 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
@@ -74,11 +74,15 @@ function importLegacyData() {
|
|||||||
alias gw-importHostingAssets='importLegacyData importHostingAssets'
|
alias gw-importHostingAssets='importLegacyData importHostingAssets'
|
||||||
|
|
||||||
function gradlewBootRun() {
|
function gradlewBootRun() {
|
||||||
local port=${1:-8080}
|
local serverPort=${1:-8080}; shift
|
||||||
shift
|
local managementPort=${2:-$((serverPort + 1))}; shift
|
||||||
local additional_args="$@"
|
local additional_args="$@"
|
||||||
echo gw bootRun --args="--spring.profiles.active=dev,fakeCasAuthenticator,complete,test-data --server.port=${port} ${additional_args}"
|
unset HSADMINNG_JWT_ISSUER
|
||||||
./gradlew bootRun --args="--spring.profiles.active=dev,fakeCasAuthenticator,complete,test-data --server.port=${port} ${additional_args}"
|
unset HSADMINNG_JWT_JWKS_URL
|
||||||
|
unset HSADMINNG_JWT_TOKEN_URL
|
||||||
|
set -x
|
||||||
|
./gradlew bootRun --args="--spring.profiles.active=dev,fake-jwt,complete,test-data --server.port=${serverPort} --management.server.port=${managementPort} ${additional_args}"
|
||||||
|
set +x
|
||||||
}
|
}
|
||||||
alias gw-bootRun=gradlewBootRun
|
alias gw-bootRun=gradlewBootRun
|
||||||
|
|
||||||
@@ -97,7 +101,7 @@ alias pg-sql-restore='gunzip --stdout | docker exec -i hsadmin-ng-postgres psql
|
|||||||
|
|
||||||
alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l'
|
alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l'
|
||||||
|
|
||||||
alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResources'
|
alias gw-spotless='./gradlew compile spotlessApply -x pitest -x test -x :processResources'
|
||||||
alias gw-check='. .aliases; . .tc-environment; gw test check -x pitest'
|
alias gw-check='. .aliases; . .tc-environment; gw test check -x pitest'
|
||||||
|
|
||||||
# HOWTO: run all 'normal' tests (by default without scenario+import-tests): `gw-test`
|
# HOWTO: run all 'normal' tests (by default without scenario+import-tests): `gw-test`
|
||||||
@@ -143,7 +147,7 @@ function _gwTest() {
|
|||||||
alias gw-test=_gwTest
|
alias gw-test=_gwTest
|
||||||
|
|
||||||
alias howto=bin/howto
|
alias howto=bin/howto
|
||||||
alias cas-curl=bin/cas-curl
|
alias jwt-curl=bin/jwt-curl
|
||||||
|
|
||||||
# etc/docker-compose.yml limits CPUs+MEM and includes a PostgreSQL config for analysing slow queries
|
# etc/docker-compose.yml limits CPUs+MEM and includes a PostgreSQL config for analysing slow queries
|
||||||
alias gw-importHostingAssets-in-docker-compose='
|
alias gw-importHostingAssets-in-docker-compose='
|
||||||
|
|||||||
+2
-1
@@ -3,6 +3,7 @@ source .unset-environment
|
|||||||
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
export HSADMINNG_POSTGRES_RESTRICTED_USERNAME=restricted
|
||||||
export HSADMINNG_POSTGRES_ADMIN_USERNAME=admin
|
export HSADMINNG_POSTGRES_ADMIN_USERNAME=admin
|
||||||
export HSADMINNG_SUPERUSER=import-superuser@hostsharing.net
|
export HSADMINNG_SUPERUSER=import-superuser@hostsharing.net
|
||||||
export HSADMINNG_CAS_SERVER=
|
export HSADMINNG_OFFICE_DATA_SQL_FILE
|
||||||
|
export HSADMINNG_JWT_TOKEN_URL=http://localhost:8080/fake-jwt/token
|
||||||
|
|
||||||
export LANG=en_US.UTF-8
|
export LANG=en_US.UTF-8
|
||||||
|
|||||||
+6
-1
@@ -5,5 +5,10 @@ unset HSADMINNG_POSTGRES_RESTRICTED_USERNAME
|
|||||||
unset HSADMINNG_SUPERUSER
|
unset HSADMINNG_SUPERUSER
|
||||||
unset HSADMINNG_MIGRATION_DATA_PATH
|
unset HSADMINNG_MIGRATION_DATA_PATH
|
||||||
unset HSADMINNG_OFFICE_DATA_SQL_FILE
|
unset HSADMINNG_OFFICE_DATA_SQL_FILE
|
||||||
unset HSADMINNG_CAS_SERVER=
|
|
||||||
|
unset HSADMINNG_JWT_ISSUER
|
||||||
|
unset HSADMINNG_JWT_JWKS_URL
|
||||||
|
unset HSADMINNG_JWT_USERNAME
|
||||||
|
unset HSADMINNG_JWT_PASSWORD
|
||||||
|
unset HSADMINNG_JWT_TOKEN_URL
|
||||||
|
|
||||||
|
|||||||
@@ -87,13 +87,10 @@ If you have at least Docker and the Java JDK installed in appropriate versions a
|
|||||||
# if the container has been built already and you want to keep the data, run this:
|
# if the container has been built already and you want to keep the data, run this:
|
||||||
pg-sql-start
|
pg-sql-start
|
||||||
|
|
||||||
Next, compile and run the application on `localhost:8080` and the management server on `localhost:8081`:
|
Next, compile and run the application with in dev-mode with all modules, test-data and fake-JWT-authentication::
|
||||||
|
|
||||||
# this disables CAS-authentication, for using the REST-API with CAS-authentication, see `bin/cas-curl`.
|
# on `localhost:8080` and the management server on `localhost:8081`:
|
||||||
export HSADMINNG_CAS_SERVER=
|
gw-bootRun
|
||||||
|
|
||||||
# this runs the application with test-data and all modules:
|
|
||||||
gw bootRun --args='--spring.profiles.active=dev,fakeCasAuthenticator,complete,test-data'
|
|
||||||
|
|
||||||
# there is also an alias which takes an optional port as an argument:
|
# there is also an alias which takes an optional port as an argument:
|
||||||
gw-bootRun 8888
|
gw-bootRun 8888
|
||||||
@@ -101,53 +98,75 @@ Next, compile and run the application on `localhost:8080` and the management ser
|
|||||||
The meaning of these profiles is:
|
The meaning of these profiles is:
|
||||||
|
|
||||||
- **dev**: the PostgreSQL users are created via Liquibase
|
- **dev**: the PostgreSQL users are created via Liquibase
|
||||||
- **fakeCasAuthenticator**: The username is simply taken from whatever is after "Bearer " in the "Authorization" header.
|
- **fake-jwt**: the app starts with a build-in fake OAuth2/JWT server
|
||||||
- **complete**: all modules are started
|
- **complete**: all modules are started
|
||||||
- **test-data**: some test data inserted
|
- **test-data**: some test data inserted
|
||||||
|
|
||||||
Now we can access the REST API, e.g. using curl:
|
Now we can access the REST API, e.g. using curl. But you need to use JWT authentication.
|
||||||
|
To make this a bit easier to handle, we use `bin/jwt-curl` (or `jwt-curl` alias).
|
||||||
|
|
||||||
# the following command should reply with "pong":
|
Make sure you replace `8080` with the port you used to run the application.`
|
||||||
curl -f -s http://localhost:8080/api/ping
|
|
||||||
|
# the following command does not need authentication and should reply with "pinged ...".
|
||||||
|
curl http://localhost:8080/api/ping
|
||||||
|
|
||||||
|
# but when you try endpoints which need authentication, you will get a 401 error:
|
||||||
|
curl http://localhost:8080/api/pong
|
||||||
|
|
||||||
|
# For the follinging commands we need to be authenticated by a valid JWT token.
|
||||||
|
# To make JWT handling a bit easier, there is a wrapper scropt `jwt-curl`.
|
||||||
|
# Make sure the following variable is set to the fake JWT issuer:
|
||||||
|
export HSADMINNG_JWT_TOKEN_URL=http://localhost:8080/fake-jwt/token
|
||||||
|
|
||||||
|
# optionally, you can set the username and password to in env-vars as well:
|
||||||
|
export HSADMINNG_JWT_USERNAME=superuser-alex@hostsharing.net
|
||||||
|
export HSADMINNG_JWT_PASSWORD=whatever-as-its-not-checked-by-fake-jwt-auth
|
||||||
|
|
||||||
|
# also optionally, you can login explicitly:
|
||||||
|
jwt-curl login
|
||||||
|
|
||||||
|
# now, the following command should reply with "ponged ... superuser-alex@hostsharing.net":
|
||||||
|
jwt-curl GET http://localhost:8080/api/pong
|
||||||
|
|
||||||
# the following command should return a JSON array with just all customers:
|
# the following command should return a JSON array with just all customers:
|
||||||
curl -f -s\
|
jwt-curl GET http://localhost:8080/api/test/customers \
|
||||||
-H 'Authorization: Bearer superuser-alex@hostsharing.net' \
|
|
||||||
http://localhost:8080/api/test/customers \
|
|
||||||
| jq # just if `jq` is installed, to prettyprint the output
|
| jq # just if `jq` is installed, to prettyprint the output
|
||||||
|
|
||||||
# the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
|
# the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
|
||||||
curl -f -s\
|
jwt-curl ASSUME 'rbactest.customer#yyy:ADMIN'
|
||||||
-H 'Authorization: Bearer superuser-alex@hostsharing.net' -H 'assumed-roles: rbactest.customer#yyy:ADMIN' \
|
jwt-curl GET http://localhost:8080/api/test/packages \
|
||||||
http://localhost:8080/api/test/packages \
|
|
||||||
| jq
|
| jq
|
||||||
|
jwt-curl UNASSUME
|
||||||
|
|
||||||
# add a new customer
|
# add a new customer
|
||||||
curl -f -s\
|
jwt-curl POST \
|
||||||
-H 'Authorization: Bearer superuser-alex@hostsharing.net' -H "Content-Type: application/json" \
|
|
||||||
-d '{ "prefix":"ttt", "reference":80001, "adminUserName":"admin@ttt.example.com" }' \
|
-d '{ "prefix":"ttt", "reference":80001, "adminUserName":"admin@ttt.example.com" }' \
|
||||||
-X POST http://localhost:8080/api/test/customers \
|
http://localhost:8080/api/test/customers \
|
||||||
| jq
|
| jq
|
||||||
|
|
||||||
If you wonder who 'superuser-alex@hostsharing.net' and 'superuser-fran@hostsharing.net' are and where the data comes from:
|
If you wonder who 'superuser-alex@hostsharing.net' and 'superuser-fran@hostsharing.net' are and where the data comes from:
|
||||||
Mike and Sven are just example global admin accounts as part of the example data which is automatically inserted in Testcontainers and Development environments.
|
Alex and Fran are just example global admin accounts as part of the example data which is automatically inserted in Testcontainers and Development environments.
|
||||||
Also try for example 'admin@xxx.example.com' or 'unknown@example.org'.
|
Also, for example, try 'admin@xxx.example.com' or 'unknown@example.org'.
|
||||||
|
|
||||||
If you want a formatted JSON output, you can pipe the result to `jq` or similar.
|
If you want a formatted JSON output, you can pipe the result to `jq` or similar.
|
||||||
|
|
||||||
And to see the full, currently implemented, API, open http://localhost:8080/swagger-ui/index.html).
|
And to see the full, currently implemented, API, open http://localhost:8080/swagger-ui/index.html.
|
||||||
For a locally running app without CAS-authentication (export HSADMINNG_CAS_SERVER=''),
|
|
||||||
authorize using the name of the subject (e.g. "superuser-alex@hostsharing.net" in case of test-data).
|
|
||||||
Otherwise, use a valid CAS-ticket.
|
|
||||||
|
|
||||||
If you want to run the application with real CAS-Authentication:
|
If you want to run the application with real (OAuth2) JWT-authentication:
|
||||||
|
|
||||||
# set the CAS-SERVER-Root, also see `bin/cas-curl`.
|
# set the JWT-issuer URI, e.g.
|
||||||
export HSADMINNG_CAS_SERVER=https://login.hostsharing.net # or whatever your CAS-Server-URL you want to use
|
export HSADMINNG_JWT_ISSUER=https://login.hshsngdev.hs-example.de/realms/HSAdminDEV
|
||||||
|
|
||||||
# run the application against the real CAS authenticator
|
# and the JWT JWKS callback URI:
|
||||||
gw bootRun --args='--spring.profiles.active=dev,realCasAuthenticator,complete,test-data'
|
export HSADMINNG_JWT_JWKS_URL=https://login.hshsngdev.hs-example.de/realms/HSAdminDEV/.well-known/openid-configuration
|
||||||
|
|
||||||
|
# as well as the JWT token endpoint URI:
|
||||||
|
export HSADMINNG_JWT_TOKEN_URL=https://login.hshsngdev.hs-example.de/realms/HSAdminDEV/protocol/openid-connect/token
|
||||||
|
|
||||||
|
# run the application against the specified JWT authenticator, do NOT add the 'fake-jwt' profile:
|
||||||
|
gw bootRun --args='--spring.profiles.active=dev,complete,test-data'
|
||||||
|
|
||||||
|
Also run `bin/jwt-curl` (or the alias `jwt-curl`) without any parameters to see the available commands.
|
||||||
|
|
||||||
### PostgreSQL Server
|
### PostgreSQL Server
|
||||||
|
|
||||||
@@ -156,7 +175,7 @@ You might amend the port and user settings in `src/main/resources/application.ym
|
|||||||
|
|
||||||
But the easiest way to run PostgreSQL is via Docker.
|
But the easiest way to run PostgreSQL is via Docker.
|
||||||
|
|
||||||
Initially, pull an image compatible to current PostgreSQL version of Hostsharing:
|
Initially, pull an image compatible to the current PostgreSQL version of Hostsharing:
|
||||||
|
|
||||||
docker pull postgres:15.5-bookworm
|
docker pull postgres:15.5-bookworm
|
||||||
|
|
||||||
@@ -674,7 +693,7 @@ howto
|
|||||||
Add `--args='--spring.profiles.active=...` with the wanted profile selector:
|
Add `--args='--spring.profiles.active=...` with the wanted profile selector:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
gw bootRun --args='--spring.profiles.active=fakeCasAuthenticator,external-db,only-prod-schema,without-test-data'
|
gw bootRun --args='--spring.profiles.active=external-db,only-prod-schema,without-test-data'
|
||||||
```
|
```
|
||||||
|
|
||||||
These profiles mean:
|
These profiles mean:
|
||||||
@@ -712,7 +731,7 @@ If it's selected, just hit the *bug*-symbol next to it.
|
|||||||
If you frequently need to run with a fresh database and a clean build, you can use this:
|
If you frequently need to run with a fresh database and a clean build, you can use this:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export HSADMINNG_CAS_SERVER=
|
# replace `gw bootRun` by the proper command as described above
|
||||||
gw clean && pg-sql-reset && sleep 5 && gw bootRun' 2>&1 | tee log
|
gw clean && pg-sql-reset && sleep 5 && gw bootRun' 2>&1 | tee log
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -851,9 +870,16 @@ This port can be changed in
|
|||||||
Or on the command line, add ` --server.port=...` to the `--args` parameter of the `bootRun` task, e.g.:
|
Or on the command line, add ` --server.port=...` to the `--args` parameter of the `bootRun` task, e.g.:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
gw bootRun --args='--spring.profiles.active=dev,fakeCasAuthenticator,complete,test-data --server.port=8888'
|
gw bootRun --args='--spring.profiles.active=dev,fake-jwt,complete,test-data --server.port=8888'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
or, for local development, simply:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gw-bootRun 8888
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### How to Use a Persistent Database for Integration Tests?
|
### How to Use a Persistent Database for Integration Tests?
|
||||||
|
|
||||||
Usually, the `DataJpaTest` integration tests run against a database in a temporary docker container.
|
Usually, the `DataJpaTest` integration tests run against a database in a temporary docker container.
|
||||||
@@ -888,7 +914,7 @@ Therefore, during initial development, it's good approach just to amend the exis
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
pg-sql-reset
|
pg-sql-reset
|
||||||
gw bootRun
|
gw bootRun # with the proper command line arguments
|
||||||
```
|
```
|
||||||
|
|
||||||
<big>**⚠**</big>
|
<big>**⚠**</big>
|
||||||
|
|||||||
-261
@@ -1,261 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [ "$2" == "--show-password" ]; then
|
|
||||||
HSADMINNG_CAS_SHOW_PASSWORD=yes
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
HSADMINNG_CAS_SHOW_PASSWORD=
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$1" == "--trace" ]; then
|
|
||||||
function trace() {
|
|
||||||
echo "$*" >&2
|
|
||||||
}
|
|
||||||
function doCurl() {
|
|
||||||
set -x
|
|
||||||
if [ -z "$HSADMINNG_CAS_ASSUME" ]; then
|
|
||||||
curl --fail-with-body \
|
|
||||||
--header "Authorization: $HSADMINNG_CAS_TICKET" \
|
|
||||||
"$@"
|
|
||||||
else
|
|
||||||
curl --fail-with-body \
|
|
||||||
--header "Authorization: $HSADMINNG_CAS_TICKET" \
|
|
||||||
--header "assumed-roles: $HSADMINNG_CAS_ASSUME" \
|
|
||||||
"$@"
|
|
||||||
fi
|
|
||||||
set +x
|
|
||||||
}
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
function trace() {
|
|
||||||
: # noop
|
|
||||||
}
|
|
||||||
function doCurl() {
|
|
||||||
curl --fail-with-body --header "Authorization: $HSADMINNG_CAS_TICKET" "$@"
|
|
||||||
}
|
|
||||||
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" ] || \
|
|
||||||
[ -z "$HSADMINNG_CAS_SERVICE_ID" ]; then
|
|
||||||
cat >&2 <<EOF
|
|
||||||
ERROR: environment incomplete
|
|
||||||
|
|
||||||
please set the following environment variables:
|
|
||||||
export HSADMINNG_CAS_LOGIN=https://login.hostsharing.net/cas/v1/tickets
|
|
||||||
export HSADMINNG_CAS_VALIDATE=https://login.hostsharing.net/cas/proxyValidate
|
|
||||||
export HSADMINNG_CAS_USERNAME=<<optionally, your username, or leave empty after '='>>
|
|
||||||
export HSADMINNG_CAS_PASSWORD=<<optionally, your password, or leave empty after '='>>
|
|
||||||
export HSADMINNG_CAS_SERVICE_ID=https://hsadminng.hostsharing.net:443/
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
function casCurlDocumentation() {
|
|
||||||
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() {
|
|
||||||
# ticket granting ticket exists and not expired?
|
|
||||||
if find ~/.cas-login-tgt -type f -size +0c -mmin -60 2>/dev/null | grep -q .; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$HSADMINNG_CAS_USERNAME" ]; then
|
|
||||||
read -e -p "Username: " HSADMINNG_CAS_USERNAME
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$HSADMINNG_CAS_PASSWORD" ]; then
|
|
||||||
read -s -e -p "Password: " HSADMINNG_CAS_PASSWORD
|
|
||||||
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.
|
|
||||||
trace "+ curl --fail-with-body -s -i -X POST \
|
|
||||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
|
||||||
-d \"username=$HSADMINNG_CAS_USERNAME&password=$HSADMINNG_CAS_PASSWORD_DISPLAY\" \
|
|
||||||
$HSADMINNG_CAS_LOGIN -o ~/.cas-login-tgt.response -D -"
|
|
||||||
HSADMINNG_CAS_TGT=`curl --fail-with-body -s -i -X POST \
|
|
||||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
|
||||||
-d "username=$HSADMINNG_CAS_USERNAME&password=$HSADMINNG_CAS_PASSWORD" \
|
|
||||||
$HSADMINNG_CAS_LOGIN -o ~/.cas-login-tgt.response -D - \
|
|
||||||
| grep -i "^Location: " | sed -e 's/^Location: //' -e 's/\\r//'`
|
|
||||||
if [ -z "$HSADMINNG_CAS_TGT" ]; then
|
|
||||||
echo "ERROR: could not get ticket granting ticket" >&2
|
|
||||||
cat ~/.cas-login-tgt.response >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "$HSADMINNG_CAS_TGT" >~/.cas-login-tgt
|
|
||||||
trace "$HSADMINNG_CAS_TGT"
|
|
||||||
}
|
|
||||||
|
|
||||||
function casLogout() {
|
|
||||||
rm -f ~/.cas-login-tgt
|
|
||||||
}
|
|
||||||
|
|
||||||
function casTicket() {
|
|
||||||
HSADMINNG_CAS_TGT=$(<~/.cas-login-tgt)
|
|
||||||
if [[ -z "$HSADMINNG_CAS_TGT" ]]; then
|
|
||||||
echo "ERROR: cannot get CAS ticket granting ticket for $HSADMINNG_CAS_USERNAME" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
trace "CAS-TGT: $HSADMINNG_CAS_TGT"
|
|
||||||
|
|
||||||
trace "fetching CAS service ticket"
|
|
||||||
trace "curl -s -d \"service=$HSADMINNG_CAS_SERVICE_ID\" $HSADMINNG_CAS_TGT"
|
|
||||||
HSADMINNG_CAS_TICKET=$(curl -s -d "service=$HSADMINNG_CAS_SERVICE_ID" $HSADMINNG_CAS_TGT)
|
|
||||||
if [[ -z "$HSADMINNG_CAS_TICKET" ]]; then
|
|
||||||
echo "ERROR: cannot get CAS service ticket" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo $HSADMINNG_CAS_TICKET
|
|
||||||
}
|
|
||||||
|
|
||||||
function casTgt() {
|
|
||||||
HSADMINNG_CAS_TGT=$(<~/.cas-login-tgt)
|
|
||||||
if [[ -z "$HSADMINNG_CAS_TGT" ]]; then
|
|
||||||
echo "ERROR: cannot get CAS ticket granting ticket for $HSADMINNG_CAS_USERNAME" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "CAS-TGT: $HSADMINNG_CAS_TGT"
|
|
||||||
}
|
|
||||||
|
|
||||||
function casValidate() {
|
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
|
||||||
|
|
||||||
trace "validating CAS-TICKET: $HSADMINNG_CAS_TICKET"
|
|
||||||
# Do NOT use doCurl here! We do not pass a CAS service ticket.
|
|
||||||
trace curl -i -s $HSADMINNG_CAS_VALIDATE?ticket=${HSADMINNG_CAS_TICKET}\&service=${HSADMINNG_CAS_SERVICE_ID}
|
|
||||||
HSADMINNG_CAS_USER=`curl -i -s $HSADMINNG_CAS_VALIDATE?ticket=${HSADMINNG_CAS_TICKET}\&service=${HSADMINNG_CAS_SERVICE_ID} | grep -oPm1 "(?<=<cas:user>)[^<]+"`
|
|
||||||
if [ -z "$HSADMINNG_CAS_USER" ]; then
|
|
||||||
echo "validation failed" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "CAS-User: $HSADMINNG_CAS_USER"
|
|
||||||
}
|
|
||||||
|
|
||||||
case "${1,,}" in
|
|
||||||
|
|
||||||
# -- 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
|
|
||||||
export HSADMINNG_CAS_USERNAME=
|
|
||||||
export HSADMINNG_CAS_PASSWORD=
|
|
||||||
casLogin
|
|
||||||
;;
|
|
||||||
"assume") ## assumes the given comma-separated roles
|
|
||||||
# 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
|
|
||||||
;;
|
|
||||||
"unassume") ## do not assume any particular role anymore, use the plain user as RBAC subject
|
|
||||||
rm ~/.cas-curl-assume
|
|
||||||
;;
|
|
||||||
"tgt") ## prints the current ticket granting ticket
|
|
||||||
casTgt
|
|
||||||
;;
|
|
||||||
"validate") ## validates current ticket granting ticket and prints currently logged in user
|
|
||||||
casValidate
|
|
||||||
;;
|
|
||||||
"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
|
|
||||||
casLogin
|
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
|
||||||
doCurl "$*"
|
|
||||||
;;
|
|
||||||
"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
|
|
||||||
casLogin
|
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
|
||||||
doCurl --header "Content-Type: application/json" -X POST "$@"
|
|
||||||
;;
|
|
||||||
"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
|
|
||||||
casLogin
|
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
|
||||||
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
|
|
||||||
# example: cas-curl DELETE http://localhost:8080/api/hs/office/persons/ae90ac2a-4728-4ca9-802e-a0d0108b2324
|
|
||||||
shift
|
|
||||||
casLogin
|
|
||||||
HSADMINNG_CAS_TICKET=`casTicket`
|
|
||||||
curl -X POST "$@"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
cat >&2 <<EOF
|
|
||||||
unknown command: '$1'
|
|
||||||
valid commands: help, login, logout, validate, get, post, patch, delete
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Executable
+279
@@ -0,0 +1,279 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ "$1" == "--show-password" ]; then
|
||||||
|
HSADMINNG_JWT_SHOW_PASSWORD=yes
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
HSADMINNG_JWT_SHOW_PASSWORD=
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" == "--trace" ]; then
|
||||||
|
function trace() {
|
||||||
|
echo "$*" >&2
|
||||||
|
}
|
||||||
|
function doCurl() {
|
||||||
|
set -x
|
||||||
|
if [ -z "$HSADMINNG_JWT_ASSUME" ]; then
|
||||||
|
curl --fail-with-body \
|
||||||
|
--header "Authorization: Bearer $HSADMINNG_JWT_TOKEN" \
|
||||||
|
"$@"
|
||||||
|
else
|
||||||
|
curl --fail-with-body \
|
||||||
|
--header "Authorization: Bearer $HSADMINNG_JWT_TOKEN" \
|
||||||
|
--header "assumed-roles: $HSADMINNG_JWT_ASSUME" \
|
||||||
|
"$@"
|
||||||
|
fi
|
||||||
|
set +x
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
function trace() {
|
||||||
|
: # noop
|
||||||
|
}
|
||||||
|
function doCurl() {
|
||||||
|
if [ -z "$HSADMINNG_JWT_ASSUME" ]; then
|
||||||
|
curl --fail-with-body --header "Authorization: Bearer $HSADMINNG_JWT_TOKEN" "$@"
|
||||||
|
else
|
||||||
|
curl --fail-with-body \
|
||||||
|
--header "Authorization: Bearer $HSADMINNG_JWT_TOKEN" \
|
||||||
|
--header "assumed-roles: $HSADMINNG_JWT_ASSUME" \
|
||||||
|
"$@"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
export HSADMINNG_JWT_ASSUME_HEADER
|
||||||
|
if [ -f ~/.cas-curl-assume ]; then
|
||||||
|
HSADMINNG_JWT_ASSUME="$(cat ~/.cas-curl-assume)"
|
||||||
|
else
|
||||||
|
HSADMINNG_JWT_ASSUME=
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$HSADMINNG_JWT_TOKEN_URL" ]; then
|
||||||
|
cat >&2 <<EOF
|
||||||
|
ERROR: environment incomplete
|
||||||
|
|
||||||
|
please set the following environment variables:
|
||||||
|
export HSADMINNG_JWT_TOKEN_URL=https://login.hostsharing.net/oauth/token
|
||||||
|
export HSADMINNG_JWT_USERNAME=<<optionally, your username, or leave empty after '='>>
|
||||||
|
export HSADMINNG_JWT_PASSWORD=<<optionally, your password, or leave empty after '='>>
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
function jwtCurlDocumentation() {
|
||||||
|
cat <<EOF
|
||||||
|
curl-wrapper utilizing JWT-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 jwtLogin() {
|
||||||
|
# JWT token exists and not expired?
|
||||||
|
if [ -f ~/.jwt-token ]; then
|
||||||
|
# Check if token is still valid (simple expiry check - you might want to add JWT parsing for more precise validation)
|
||||||
|
if find ~/.jwt-token -type f -size +0c -mmin -55 2>/dev/null | grep -q .; then
|
||||||
|
HSADMINNG_JWT_TOKEN=$(<~/.jwt-token)
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$HSADMINNG_JWT_USERNAME" ]; then
|
||||||
|
read -e -p "Username: " HSADMINNG_JWT_USERNAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$HSADMINNG_JWT_PASSWORD" ]; then
|
||||||
|
read -s -e -p "Password: " HSADMINNG_JWT_PASSWORD
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$HSADMINNG_JWT_SHOW_PASSWORD" == "yes" ]; then
|
||||||
|
HSADMINNG_JWT_PASSWORD_DISPLAY=$HSADMINNG_JWT_PASSWORD
|
||||||
|
else
|
||||||
|
HSADMINNG_JWT_PASSWORD_DISPLAY="<<password hidden - use --show-password to show>>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OAuth2 Resource Owner Password Credentials Grant (public client)
|
||||||
|
trace "+ curl --fail-with-body --show-error -X POST \
|
||||||
|
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||||||
|
-d \"grant_type=password&username=$HSADMINNG_JWT_USERNAME&password=$HSADMINNG_JWT_PASSWORD_DISPLAY\" \
|
||||||
|
$HSADMINNG_JWT_TOKEN_URL -o ~/.jwt-token.response"
|
||||||
|
|
||||||
|
JWT_RESPONSE=$(curl --fail-with-body --show-error -X POST \
|
||||||
|
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||||||
|
-d "grant_type=password&username=$HSADMINNG_JWT_USERNAME&password=$HSADMINNG_JWT_PASSWORD" \
|
||||||
|
$HSADMINNG_JWT_TOKEN_URL 2>&1 | tee ~/.jwt-token.response)
|
||||||
|
|
||||||
|
# Extract access token from JSON response
|
||||||
|
HSADMINNG_JWT_TOKEN=$(echo "$JWT_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||||
|
|
||||||
|
if [ -z "$HSADMINNG_JWT_TOKEN" ]; then
|
||||||
|
echo "ERROR: could not get JWT access token: $JWT_RESPONSE" >&2
|
||||||
|
echo >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$HSADMINNG_JWT_TOKEN" > ~/.jwt-token
|
||||||
|
trace "JWT Token acquired (length: ${#HSADMINNG_JWT_TOKEN})"
|
||||||
|
}
|
||||||
|
|
||||||
|
function jwtLogout() {
|
||||||
|
rm -f ~/.jwt-token ~/.jwt-token.response
|
||||||
|
}
|
||||||
|
|
||||||
|
function jwtValidate() {
|
||||||
|
if [ ! -f ~/.jwt-token ]; then
|
||||||
|
echo "ERROR: no JWT token found, please login first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
HSADMINNG_JWT_TOKEN=$(<~/.jwt-token)
|
||||||
|
|
||||||
|
# Simple JWT validation - decode payload (base64 decode the middle part)
|
||||||
|
JWT_PAYLOAD=$(echo "$HSADMINNG_JWT_TOKEN" | cut -d'.' -f2)
|
||||||
|
# Add padding if needed for base64 decoding
|
||||||
|
case $((${#JWT_PAYLOAD} % 4)) in
|
||||||
|
2) JWT_PAYLOAD="${JWT_PAYLOAD}==" ;;
|
||||||
|
3) JWT_PAYLOAD="${JWT_PAYLOAD}=" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if command -v base64 >/dev/null 2>&1; then
|
||||||
|
JWT_DECODED=$(echo "$JWT_PAYLOAD" | base64 -d 2>/dev/null)
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
OAUTH_USER=$(echo "$JWT_DECODED" | grep -o '"sub":"[^"]*' | cut -d'"' -f4)
|
||||||
|
if [ -z "$OAUTH_USER" ]; then
|
||||||
|
OAUTH_USER=$(echo "$JWT_DECODED" | grep -o '"preferred_username":"[^"]*' | cut -d'"' -f4)
|
||||||
|
fi
|
||||||
|
if [ -z "$OAUTH_USER" ]; then
|
||||||
|
OAUTH_USER=$(echo "$JWT_DECODED" | grep -o '"username":"[^"]*' | cut -d'"' -f4)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$OAUTH_USER" ]; then
|
||||||
|
echo "OAuth User: $OAUTH_USER"
|
||||||
|
# Check expiry
|
||||||
|
EXP=$(echo "$JWT_DECODED" | grep -o '"exp":[0-9]*' | cut -d':' -f2)
|
||||||
|
if [ -n "$EXP" ]; then
|
||||||
|
CURRENT_TIME=$(date +%s)
|
||||||
|
if [ "$EXP" -lt "$CURRENT_TIME" ]; then
|
||||||
|
echo "WARNING: JWT token has expired" >&2
|
||||||
|
else
|
||||||
|
echo "Token expires: $(date -d "@$EXP" 2>/dev/null || date -r "$EXP" 2>/dev/null || echo "unknown")"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Could not extract user from JWT token" >&2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Could not decode JWT token" >&2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "JWT token present but cannot validate (base64 command not available)" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function jwtToken() {
|
||||||
|
if [ ! -f ~/.jwt-token ]; then
|
||||||
|
echo "ERROR: no JWT token found, please login first" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
HSADMINNG_JWT_TOKEN=$(<~/.jwt-token)
|
||||||
|
echo "$HSADMINNG_JWT_TOKEN"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1,,}" in
|
||||||
|
|
||||||
|
# -- generic commands --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
""|"-h"|"--help"|"help") ## prints documentation about commands and options
|
||||||
|
jwtCurlDocumentation
|
||||||
|
exit
|
||||||
|
;;
|
||||||
|
|
||||||
|
"env") ## prints all related HSADMINNG_JWT_... environment variables; use '--show-password' to show the password as well
|
||||||
|
# example: jwt-curl -show-password env
|
||||||
|
echo "export HSADMINNG_JWT_TOKEN_URL=$HSADMINNG_JWT_TOKEN_URL"
|
||||||
|
echo "export HSADMINNG_JWT_USERNAME=$HSADMINNG_JWT_USERNAME"
|
||||||
|
if [ "$HSADMINNG_JWT_SHOW_PASSWORD" == "yes" ]; then
|
||||||
|
echo "export HSADMINNG_JWT_PASSWORD=$HSADMINNG_JWT_PASSWORD"
|
||||||
|
elif [ -z "$HSADMINNG_JWT_PASSWORD" ]; then
|
||||||
|
echo "export HSADMINNG_JWT_PASSWORD=#<<not given>>"
|
||||||
|
else
|
||||||
|
echo "export HSADMINNG_JWT_PASSWORD=#<<given, but hidden - add --show-password to show>>"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
# --- authentication-related commands ------------------------------------------------------------
|
||||||
|
|
||||||
|
"login") ## reads username+password and fetches JWT access token (bypasses HSADMINNG_JWT_USERNAME+HSADMINNG_JWT_PASSWORD)
|
||||||
|
# example: jwt-curl login
|
||||||
|
jwtLogout
|
||||||
|
export HSADMINNG_JWT_USERNAME=
|
||||||
|
export HSADMINNG_JWT_PASSWORD=
|
||||||
|
jwtLogin
|
||||||
|
;;
|
||||||
|
"assume") ## assumes the given comma-separated roles
|
||||||
|
# example using object-id-name: jwt-curl assume 'hs_office.relation#ExampleMandant-with-PARTNER-ExamplePartner:AGENT'
|
||||||
|
# example using object-uuid: jwt-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
|
||||||
|
;;
|
||||||
|
"unassume") ## do not assume any particular role anymore, use the plain user as RBAC subject
|
||||||
|
rm -f ~/.cas-curl-assume
|
||||||
|
;;
|
||||||
|
"token") ## prints the current JWT access token
|
||||||
|
jwtToken
|
||||||
|
;;
|
||||||
|
"validate") ## validates current JWT token and prints currently logged in user
|
||||||
|
jwtValidate
|
||||||
|
;;
|
||||||
|
"logout") ## logout, deletes JWT token
|
||||||
|
jwtLogout
|
||||||
|
;;
|
||||||
|
|
||||||
|
# --- HTTP-commands ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
"get") ## HTTP GET, add URL as parameter
|
||||||
|
# example: jwt-curl GET http://localhost:8080/api/hs/office/partners/P-10003 | jq
|
||||||
|
# hint: '| jq' is just for human-readable formatted JSON output
|
||||||
|
shift
|
||||||
|
jwtLogin
|
||||||
|
doCurl "$*"
|
||||||
|
;;
|
||||||
|
"post") ## HTTP POST, add curl options to specify the request body and the URL as last parameter
|
||||||
|
# example: jwt-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
|
||||||
|
jwtLogin
|
||||||
|
doCurl --header "Content-Type: application/json" -X POST "$@"
|
||||||
|
;;
|
||||||
|
"patch") ## HTTP PATCH, add curl options to specify the request body and the URL as last parameterparameter
|
||||||
|
# example: jwt-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
|
||||||
|
jwtLogin
|
||||||
|
doCurl --header "Content-Type: application/json" -X POST "$*"
|
||||||
|
;;
|
||||||
|
|
||||||
|
# --- unknown command --------------------------------------------------------------------
|
||||||
|
*)
|
||||||
|
cat >&2 <<EOF
|
||||||
|
unknown command: '$1'
|
||||||
|
valid commands: help, login, logout, validate, get, post, patch, delete
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -92,6 +92,7 @@ dependencies {
|
|||||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-security")
|
implementation("org.springframework.boot:spring-boot-starter-security")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
|
||||||
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6")
|
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6")
|
||||||
implementation("com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.11.0")
|
implementation("com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.11.0")
|
||||||
implementation("org.postgresql:postgresql")
|
implementation("org.postgresql:postgresql")
|
||||||
@@ -346,6 +347,9 @@ configure<JacocoPluginExtension> {
|
|||||||
|
|
||||||
tasks.named<JacocoReport>("jacocoTestReport") {
|
tasks.named<JacocoReport>("jacocoTestReport") {
|
||||||
dependsOn(tasks.named("test")) // Depends on the main test task
|
dependsOn(tasks.named("test")) // Depends on the main test task
|
||||||
|
dependsOn(tasks.named("compileJava")) // Add explicit dependency on compileJava
|
||||||
|
dependsOn(tasks.named("openApiGenerate")) // Add explicit dependency on openApiGenerate
|
||||||
|
|
||||||
reports {
|
reports {
|
||||||
xml.required.set(true) // Common requirement for CI/CD
|
xml.required.set(true) // Common requirement for CI/CD
|
||||||
csv.required.set(false)
|
csv.required.set(false)
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityScheme;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||||
|
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.RSA_KEY;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
// securitySchemes should work in OpenAPI yaml, but the Spring templates seem not to support it
|
||||||
|
@SecurityScheme(
|
||||||
|
name = "bearerAuth",
|
||||||
|
type = SecuritySchemeType.HTTP,
|
||||||
|
scheme = "bearer",
|
||||||
|
bearerFormat = "JWT"
|
||||||
|
)
|
||||||
|
public abstract class BaseWebSecurityConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception {
|
||||||
|
return http
|
||||||
|
.authorizeHttpRequests(authorize -> authorize
|
||||||
|
.requestMatchers(
|
||||||
|
// only list endpoints implemented in libraries here
|
||||||
|
"/swagger-ui/**",
|
||||||
|
"/v3/api-docs/**",
|
||||||
|
"/actuator/**",
|
||||||
|
"/fake-jwt/**"
|
||||||
|
// otherwise use @PreAuthorize annotation at the controller class / endpoint method level
|
||||||
|
).permitAll()
|
||||||
|
.requestMatchers("/api/**").permitAll() // controlled at method level
|
||||||
|
.anyRequest().denyAll()
|
||||||
|
)
|
||||||
|
.oauth2ResourceServer(oauth ->
|
||||||
|
oauth.jwt(Customizer.withDefaults()))
|
||||||
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
|
.cors(AbstractHttpConfigurer::disable)
|
||||||
|
.exceptionHandling(exception -> exception
|
||||||
|
.authenticationEntryPoint((request, response, authException) ->
|
||||||
|
// For unknown reason Spring security returns 403 FORBIDDEN for a BadCredentialsException.
|
||||||
|
// But it should return 401 UNAUTHORIZED.
|
||||||
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri:http://localhost:${server.port}/fake-jwt/.well-known/jwks.json}")
|
||||||
|
private String jwkSetUri;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Profile("!fake-jwt")
|
||||||
|
public JwtDecoder jwtDecoder() {
|
||||||
|
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Profile("fake-jwt")
|
||||||
|
@SneakyThrows
|
||||||
|
public JwtDecoder fakeJwtDecoder() {
|
||||||
|
// For fake-jwt profile, use the same RSA key as JwtFakeBearer
|
||||||
|
return NimbusJwtDecoder.withPublicKey(RSA_KEY.toRSAPublicKey()).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
// Do NOT use @Component (or similar) here, this would register the filter directly.
|
|
||||||
// But we need to register it in the SecurityFilterChain created by WebSecurityConfig.
|
|
||||||
// The bean gets created in net.hostsharing.hsadminng.config.WebSecurityConfig.authenticationFilter.
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class CasAuthenticationFilter extends OncePerRequestFilter {
|
|
||||||
|
|
||||||
private CasAuthenticator authenticator;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SneakyThrows
|
|
||||||
protected void doFilterInternal(
|
|
||||||
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
|
|
||||||
|
|
||||||
if (request.getHeader("authorization") != null) {
|
|
||||||
final var authenticatedRequest = new AuthenticatedHttpServletRequestWrapper(request);
|
|
||||||
final var currentSubject = authenticator.authenticate(request);
|
|
||||||
final var authentication = new UsernamePasswordAuthenticationToken(currentSubject, null, null);
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
|
||||||
filterChain.doFilter(authenticatedRequest, response);
|
|
||||||
} else {
|
|
||||||
filterChain.doFilter(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
public interface CasAuthenticator {
|
|
||||||
|
|
||||||
String authenticate(final HttpServletRequest httpRequest);
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
public class FakeCasAuthenticator implements CasAuthenticator {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SneakyThrows
|
|
||||||
public String authenticate(final HttpServletRequest httpRequest) {
|
|
||||||
return httpRequest.getHeader("Authorization").replaceAll("^Bearer ", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
|
import io.micrometer.core.annotation.Timed;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@Profile("fake-jwt")
|
||||||
|
@NoSecurityRequirement
|
||||||
|
@Slf4j
|
||||||
|
public class FakeJwtController {
|
||||||
|
|
||||||
|
@PostMapping(value = "/fake-jwt/token", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
|
@Timed("app.config.jwt.token")
|
||||||
|
public ResponseEntity<Map<String, Object>> token(
|
||||||
|
@RequestParam String username,
|
||||||
|
@RequestParam String password,
|
||||||
|
@RequestParam(defaultValue = "openid profile") String scope) {
|
||||||
|
|
||||||
|
log.info("Fake JWT: Issuing token for user: {}", username);
|
||||||
|
|
||||||
|
// Accept any username/password for local testing
|
||||||
|
String token = JwtFakeBearer.bearer(username).replace("Bearer ", "");
|
||||||
|
|
||||||
|
return ResponseEntity.ok(Map.of(
|
||||||
|
"access_token", token,
|
||||||
|
"token_type", "Bearer",
|
||||||
|
"expires_in", 3600,
|
||||||
|
"scope", scope
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,18 +11,16 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||||
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class JsonObjectMapperConfiguration {
|
public class JsonObjectMapperConfiguration {
|
||||||
|
|
||||||
public static ObjectMapper build() {
|
public static ObjectMapper build() {
|
||||||
return new JsonObjectMapperConfiguration().customObjectMapper().build();
|
return new JsonObjectMapperConfiguration().customObjectMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Primary
|
@Primary
|
||||||
public Jackson2ObjectMapperBuilder customObjectMapper() {
|
public ObjectMapper customObjectMapper() {
|
||||||
// HOWTO: add JSON converters and specify other JSON mapping configurations
|
|
||||||
return new Jackson2ObjectMapperBuilder()
|
return new Jackson2ObjectMapperBuilder()
|
||||||
.modules(new JsonNullableModule(), new JavaTimeModule())
|
.modules(new JsonNullableModule(), new JavaTimeModule())
|
||||||
.featuresToEnable(
|
.featuresToEnable(
|
||||||
@@ -30,6 +28,7 @@ public class JsonObjectMapperConfiguration {
|
|||||||
DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,
|
DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,
|
||||||
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
|
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
|
||||||
)
|
)
|
||||||
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
|
import com.nimbusds.jose.JWSAlgorithm;
|
||||||
|
import com.nimbusds.jose.JWSHeader;
|
||||||
|
import com.nimbusds.jose.crypto.RSASSASigner;
|
||||||
|
import com.nimbusds.jose.jwk.RSAKey;
|
||||||
|
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
|
||||||
|
import com.nimbusds.jwt.JWTClaimsSet;
|
||||||
|
import com.nimbusds.jwt.SignedJWT;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a fake JWT bearer generator.
|
||||||
|
*/
|
||||||
|
public class JwtFakeBearer {
|
||||||
|
|
||||||
|
public static final RSAKey RSA_KEY = generateRSAKey(2048, "test-key");
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static String bearer(final String subject) {
|
||||||
|
val claims = new JWTClaimsSet.Builder()
|
||||||
|
.subject(subject)
|
||||||
|
.issuer("http://test-issuer")
|
||||||
|
.audience("api")
|
||||||
|
.expirationTime(new Date(System.currentTimeMillis() + 3600_000))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
val signed = new SignedJWT(
|
||||||
|
new JWSHeader.Builder(JWSAlgorithm.RS256)
|
||||||
|
.keyID(RSA_KEY.getKeyID()).build(), claims);
|
||||||
|
signed.sign(new RSASSASigner(RSA_KEY.toPrivateKey()));
|
||||||
|
return "Bearer " + signed.serialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static RSAKey generateRSAKey(final int size, final String keyID) {
|
||||||
|
return new RSAKeyGenerator(size).keyID(keyID).generate();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
// HOWTO add logger
|
|
||||||
@Slf4j
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class RealCasAuthenticator implements CasAuthenticator {
|
|
||||||
|
|
||||||
@Value("${hsadminng.cas.server}")
|
|
||||||
private String casServerUrl;
|
|
||||||
|
|
||||||
@Value("${hsadminng.cas.service}")
|
|
||||||
private String serviceUrl;
|
|
||||||
|
|
||||||
private final MessageTranslator messageTranslator;
|
|
||||||
|
|
||||||
private final RestTemplate restTemplate = new RestTemplate();
|
|
||||||
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
@Timed("app.cas.authenticate")
|
|
||||||
public String authenticate(final HttpServletRequest httpRequest) {
|
|
||||||
final var ticket = httpRequest.getHeader("authorization").replaceAll("^Bearer ", "");
|
|
||||||
final var serviceTicket = ticket.startsWith("TGT-")
|
|
||||||
? fetchServiceTicket(ticket)
|
|
||||||
: ticket;
|
|
||||||
final var userName = extractUserName(verifyServiceTicket(serviceTicket));
|
|
||||||
// HOWTO log some message for a certain log level (trace, debug, info, warn, error)
|
|
||||||
log.debug("CAS-user: {}", userName);
|
|
||||||
return userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String fetchServiceTicket(final String ticketGrantingTicket) {
|
|
||||||
final var tgtUrl = casServerUrl + "/cas/v1/tickets/" + ticketGrantingTicket;
|
|
||||||
|
|
||||||
final var restTemplate = new RestTemplate();
|
|
||||||
final var formData = new LinkedMultiValueMap<String, String>();
|
|
||||||
formData.add("service", serviceUrl);
|
|
||||||
|
|
||||||
return restTemplate.postForObject(tgtUrl, formData, String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Document verifyServiceTicket(final String serviceTicket) throws SAXException, IOException, ParserConfigurationException {
|
|
||||||
if ( !serviceTicket.startsWith("ST-") ) {
|
|
||||||
throwBadCredentialsException("auth.unknown-authorization-ticket");
|
|
||||||
}
|
|
||||||
|
|
||||||
final var url = casServerUrl + "/cas/p3/serviceValidate" +
|
|
||||||
"?service=" + serviceUrl +
|
|
||||||
"&ticket=" + serviceTicket;
|
|
||||||
|
|
||||||
final var response = restTemplate.getForObject(url, String.class);
|
|
||||||
|
|
||||||
return DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
|
||||||
.parse(new java.io.ByteArrayInputStream(response.getBytes()));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private String extractUserName(final Document verification) {
|
|
||||||
|
|
||||||
if (verification.getElementsByTagName("cas:authenticationSuccess").getLength() == 0) {
|
|
||||||
throwBadCredentialsException("auth.cas-service-ticket-could-not-be-verified");
|
|
||||||
}
|
|
||||||
return verification.getElementsByTagName("cas:user").item(0).getTextContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void throwBadCredentialsException(final String messageKey) {
|
|
||||||
final var translatedMessage = messageTranslator.translate(messageKey);
|
|
||||||
throw new BadCredentialsException(translatedMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +1,12 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
|
|
||||||
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
|
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityScheme;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
|
||||||
import org.springframework.security.web.authentication.AuthenticationFilter;
|
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@Profile("!test")
|
||||||
@EnableMethodSecurity(prePostEnabled = true) // Add this annotation
|
@EnableMethodSecurity // this does not work with @WebMvcTest, see WebSecurityConfigForWebMvcTests
|
||||||
// TODO.impl: securitySchemes should work in OpenAPI yaml, but the Spring templates seem not to support it
|
public class WebSecurityConfig extends BaseWebSecurityConfig {
|
||||||
@SecurityScheme(type = SecuritySchemeType.HTTP, name = "casTicket", scheme = "bearer", bearerFormat = "CAS ticket", description = "CAS ticket", in = SecuritySchemeIn.HEADER)
|
|
||||||
public class WebSecurityConfig {
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
@Autowired
|
|
||||||
private CasAuthenticationFilter authenticationFilter;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MessageTranslator messageTranslator;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Profile("!test")
|
|
||||||
public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception {
|
|
||||||
return http
|
|
||||||
.authorizeHttpRequests(authorize -> authorize
|
|
||||||
.requestMatchers(
|
|
||||||
// only list endpoints implemented in libraries here
|
|
||||||
"/swagger-ui/**",
|
|
||||||
"/v3/api-docs/**",
|
|
||||||
"/actuator/**"
|
|
||||||
// otherwise use @PreAuthorize annotation at the controller class / endpoint method level
|
|
||||||
).permitAll()
|
|
||||||
.requestMatchers("/api/**").permitAll() // controlled at method level
|
|
||||||
.anyRequest().denyAll()
|
|
||||||
)
|
|
||||||
.addFilterBefore(authenticationFilter, AuthenticationFilter.class)
|
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
|
||||||
.exceptionHandling(exception -> exception
|
|
||||||
.authenticationEntryPoint((request, response, authException) ->
|
|
||||||
// For unknown reasons Spring security returns 403 FORBIDDEN for a BadCredentialsException.
|
|
||||||
// But it should return 401 UNAUTHORIZED.
|
|
||||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Profile("realCasAuthenticator")
|
|
||||||
public CasAuthenticator realCasServiceTicketValidator() {
|
|
||||||
return new RealCasAuthenticator(messageTranslator);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Profile("fakeCasAuthenticator")
|
|
||||||
public CasAuthenticator fakeCasServiceTicketValidator() {
|
|
||||||
return new FakeCasAuthenticator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public CasAuthenticationFilter authenticationFilter(final CasAuthenticator authenticator) {
|
|
||||||
return new CasAuthenticationFilter(authenticator);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -5,19 +5,17 @@ import java.util.List;
|
|||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import net.hostsharing.hsadminng.config.NoSecurityRequirement;
|
import net.hostsharing.hsadminng.config.NoSecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.accounts.generated.api.v1.api.ContextsApi;
|
import net.hostsharing.hsadminng.accounts.generated.api.v1.api.ContextsApi;
|
||||||
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.ContextResource;
|
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.ContextResource;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
|
||||||
@NoSecurityRequirement
|
@NoSecurityRequirement
|
||||||
public class HsCredentialsContextsController implements ContextsApi {
|
public class HsCredentialsContextsController implements ContextsApi {
|
||||||
|
|
||||||
@@ -33,7 +31,6 @@ public class HsCredentialsContextsController implements ContextsApi {
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Timed("app.credentials.contexts.getListOfLoginContexts")
|
@Timed("app.credentials.contexts.getListOfLoginContexts")
|
||||||
@PreAuthorize("permitAll()")
|
|
||||||
public ResponseEntity<List<ContextResource>> getListOfContexts(final String assumedRoles) {
|
public ResponseEntity<List<ContextResource>> getListOfContexts(final String assumedRoles) {
|
||||||
if (SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
|
if (SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) {
|
||||||
context.assumeRoles(assumedRoles);
|
context.assumeRoles(assumedRoles);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import net.hostsharing.hsadminng.accounts.generated.api.v1.model.ContextResource
|
|||||||
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.CurrentLoginUserResource;
|
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.CurrentLoginUserResource;
|
||||||
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.RbacSubjectResource;
|
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.RbacSubjectResource;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.accounts.generated.api.v1.api.CredentialsApi;
|
import net.hostsharing.hsadminng.accounts.generated.api.v1.api.CredentialsApi;
|
||||||
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.CredentialsInsertResource;
|
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.CredentialsInsertResource;
|
||||||
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.CredentialsPatchResource;
|
import net.hostsharing.hsadminng.accounts.generated.api.v1.model.CredentialsPatchResource;
|
||||||
@@ -42,7 +42,7 @@ import static java.util.Optional.of;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsCredentialsController implements CredentialsApi {
|
public class HsCredentialsController implements CredentialsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingItemsApi;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingItemsApi;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource;
|
||||||
@@ -35,7 +35,7 @@ import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateR
|
|||||||
@RestController
|
@RestController
|
||||||
@Profile("!only-prod-schema")
|
@Profile("!only-prod-schema")
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsBookingItemController implements HsBookingItemsApi {
|
public class HsBookingItemController implements HsBookingItemsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.project;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjectsApi;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjectsApi;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
||||||
@@ -25,7 +25,7 @@ import java.util.function.BiConsumer;
|
|||||||
@RestController
|
@RestController
|
||||||
@Profile("!only-prod-schema")
|
@Profile("!only-prod-schema")
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsBookingProjectController implements HsBookingProjectsApi {
|
public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityS
|
|||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetInsertResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
|
||||||
@@ -32,7 +32,7 @@ import java.util.function.BiConsumer;
|
|||||||
@RestController
|
@RestController
|
||||||
@Profile("!only-prod-schema")
|
@Profile("!only-prod-schema")
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsHostingAssetController implements HsHostingAssetsApi {
|
public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
-4
@@ -7,7 +7,6 @@ import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetP
|
|||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -16,12 +15,10 @@ import java.util.Map;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@Profile("!only-prod-schema")
|
@Profile("!only-prod-schema")
|
||||||
@PreAuthorize("isAuthenticated()")
|
|
||||||
@NoSecurityRequirement
|
@NoSecurityRequirement
|
||||||
public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PreAuthorize("permitAll()")
|
|
||||||
@Timed("app.hosting.assets.api.getListOfHostingAssetTypes")
|
@Timed("app.hosting.assets.api.getListOfHostingAssetTypes")
|
||||||
public ResponseEntity<List<String>> getListOfHostingAssetTypes() {
|
public ResponseEntity<List<String>> getListOfHostingAssetTypes() {
|
||||||
final var resource = HostingAssetEntityValidatorRegistry.types().stream()
|
final var resource = HostingAssetEntityValidatorRegistry.types().stream()
|
||||||
@@ -31,7 +28,6 @@ public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PreAuthorize("permitAll()")
|
|
||||||
@Timed("app.hosting.assets.api.getListOfHostingAssetTypeProps")
|
@Timed("app.hosting.assets.api.getListOfHostingAssetTypeProps")
|
||||||
public ResponseEntity<List<Object>> getListOfHostingAssetTypeProps(
|
public ResponseEntity<List<Object>> getListOfHostingAssetTypeProps(
|
||||||
final HsHostingAssetTypeResource assetType) {
|
final HsHostingAssetTypeResource assetType) {
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeBankAccountsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeBankAccountsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeBankAccountResource;
|
||||||
@@ -21,7 +21,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
|||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeContactsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeContactsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeContactPatchResource;
|
||||||
@@ -23,7 +23,7 @@ import static net.hostsharing.hsadminng.errors.Validate.validate;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeContactController implements HsOfficeContactsApi {
|
public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopassets;
|
|||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopAssetsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopAssetsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionInsertResource;
|
||||||
@@ -40,7 +40,7 @@ import static net.hostsharing.hsadminng.lambda.WithNonNull.withNonNull;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAssetsApi {
|
public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAssetsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
|||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
import net.hostsharing.hsadminng.errors.MultiValidationException;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource;
|
||||||
@@ -31,7 +31,7 @@ import static net.hostsharing.hsadminng.hs.validation.UuidResolver.resolve;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopSharesApi {
|
public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopSharesApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.debitor;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitorsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeDebitorsApi;
|
||||||
@@ -35,7 +35,7 @@ import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeMembershipsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeMembershipsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeMembershipPatchResource;
|
||||||
@@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
|||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.errors.ReferenceNotFoundException;
|
import net.hostsharing.hsadminng.errors.ReferenceNotFoundException;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactFromResourceConverter;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactFromResourceConverter;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
@@ -39,7 +39,7 @@ import static net.hostsharing.hsadminng.repr.TaggedNumber.cropTag;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficePartnerController implements HsOfficePartnersApi {
|
public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person;
|
|||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePersonsApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficePersonsApi;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficePersonPatchResource;
|
||||||
@@ -20,7 +20,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficePersonController implements HsOfficePersonsApi {
|
public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.relation;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.errors.Validate;
|
import net.hostsharing.hsadminng.errors.Validate;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
@@ -29,7 +29,7 @@ import static net.hostsharing.hsadminng.mapper.KeyValueMap.from;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.sepamandate;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeSepaMandatesApi;
|
||||||
@@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateR
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -6,19 +6,16 @@ import net.hostsharing.hsadminng.config.NoSecurityRequirement;
|
|||||||
import net.hostsharing.hsadminng.generated.api.v1.api.TestApi;
|
import net.hostsharing.hsadminng.generated.api.v1.api.TestApi;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
|
||||||
@NoSecurityRequirement
|
@NoSecurityRequirement
|
||||||
public class PingController implements TestApi {
|
public class PingController implements TestApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MessageTranslator messageTranslator;
|
private MessageTranslator messageTranslator;
|
||||||
|
|
||||||
@PreAuthorize("permitAll()")
|
|
||||||
@Timed("app.api.ping")
|
@Timed("app.api.ping")
|
||||||
public ResponseEntity<String> ping() {
|
public ResponseEntity<String> ping() {
|
||||||
// HOWTO translate text with placeholders - also see in resource files i18n/messages_*.properties.
|
// HOWTO translate text with placeholders - also see in resource files i18n/messages_*.properties.
|
||||||
@@ -26,7 +23,6 @@ public class PingController implements TestApi {
|
|||||||
return ResponseEntity.ok(translatedMessage + "\n");
|
return ResponseEntity.ok(translatedMessage + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("isAuthenticated()")
|
|
||||||
@Timed("app.api.pong")
|
@Timed("app.api.pong")
|
||||||
public ResponseEntity<String> pong() {
|
public ResponseEntity<String> pong() {
|
||||||
final var userName = SecurityContextHolder.getContext().getAuthentication().getName();
|
final var userName = SecurityContextHolder.getContext().getAuthentication().getName();
|
||||||
|
|||||||
+25
-2
@@ -1,7 +1,8 @@
|
|||||||
package net.hostsharing.hsadminng.context;
|
package net.hostsharing.hsadminng.rbac.context;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.val;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
@@ -9,6 +10,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityExistsException;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
@@ -74,7 +76,7 @@ public class Context {
|
|||||||
""");
|
""");
|
||||||
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
|
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
|
||||||
query.setParameter("currentRequest", currentRequest);
|
query.setParameter("currentRequest", currentRequest);
|
||||||
query.setParameter("currentSubject", currentSubject);
|
query.setParameter("currentSubject", subjectName(currentSubject));
|
||||||
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
|
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
|
||||||
query.executeUpdate();
|
query.executeUpdate();
|
||||||
}
|
}
|
||||||
@@ -119,6 +121,27 @@ public class Context {
|
|||||||
.orElse("unknown");
|
.orElse("unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String subjectName(final String nameOrUuid) {
|
||||||
|
if (nameOrUuid == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// TODO.impl: maybe it should be the other way around: UUID as the default and just optionally the name
|
||||||
|
try {
|
||||||
|
val authenticatedUuid = UUID.fromString(nameOrUuid);
|
||||||
|
val subjectName = findSubjectNameByUuid(authenticatedUuid)
|
||||||
|
.orElseThrow(() -> new EntityExistsException("Subject not found"));
|
||||||
|
return subjectName;
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
|
return nameOrUuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> findSubjectNameByUuid(final UUID authenticatedUuid) {
|
||||||
|
return Optional.ofNullable(em.createNativeQuery("SELECT name FROM rbac.subject s WHERE s.uuid=:uuid")
|
||||||
|
.setParameter("uuid", authenticatedUuid)
|
||||||
|
.getSingleResult()).map(Object::toString);
|
||||||
|
}
|
||||||
|
|
||||||
private String toTask(final HttpServletRequest request) {
|
private String toTask(final HttpServletRequest request) {
|
||||||
if (isRequestScopeAvailable()) {
|
if (isRequestScopeAvailable()) {
|
||||||
return request.getMethod() + " " + request.getRequestURI();
|
return request.getMethod() + " " + request.getRequestURI();
|
||||||
@@ -2,7 +2,6 @@ package net.hostsharing.hsadminng.rbac.context;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacContextApi;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacContextApi;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacContextResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacContextResource;
|
||||||
@@ -23,7 +22,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class RbacContextController implements RbacContextApi {
|
public class RbacContextController implements RbacContextApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.grant;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacGrantsApi;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacGrantsApi;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacGrantResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacGrantResource;
|
||||||
@@ -20,7 +20,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class RbacGrantController implements RbacGrantsApi {
|
public class RbacGrantController implements RbacGrantsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.rbac.grant;
|
package net.hostsharing.hsadminng.rbac.grant;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.role;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacRolesApi;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacRolesApi;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacRoleResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacRoleResource;
|
||||||
@@ -16,7 +16,7 @@ import java.util.List;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class RbacRoleController implements RbacRolesApi {
|
public class RbacRoleController implements RbacRolesApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.subject;
|
|||||||
|
|
||||||
import io.micrometer.core.annotation.Timed;
|
import io.micrometer.core.annotation.Timed;
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacSubjectsApi;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacSubjectsApi;
|
||||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectPermissionResource;
|
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectPermissionResource;
|
||||||
@@ -19,7 +19,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class RbacSubjectController implements RbacSubjectsApi {
|
public class RbacSubjectController implements RbacSubjectsApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.rbac.test.cust;
|
package net.hostsharing.hsadminng.rbac.test.cust;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestCustomersApi;
|
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestCustomersApi;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestCustomerResource;
|
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestCustomerResource;
|
||||||
@@ -18,7 +18,7 @@ import java.util.List;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class TestCustomerController implements TestCustomersApi {
|
public class TestCustomerController implements TestCustomersApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.rbac.test.pac;
|
|||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestPackagesApi;
|
import net.hostsharing.hsadminng.test.generated.api.v1.api.TestPackagesApi;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestPackageResource;
|
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestPackageResource;
|
||||||
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestPackageUpdateResource;
|
import net.hostsharing.hsadminng.test.generated.api.v1.model.TestPackageUpdateResource;
|
||||||
@@ -18,7 +18,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@PreAuthorize("isAuthenticated()")
|
@PreAuthorize("isAuthenticated()")
|
||||||
@SecurityRequirement(name = "casTicket")
|
@SecurityRequirement(name = "bearerAuth")
|
||||||
public class TestPackageController implements TestPackagesApi {
|
public class TestPackageController implements TestPackagesApi {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -147,15 +147,11 @@ public final class Stringify<B> {
|
|||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
PropertyValue(final B object, final Property<B, ?> prop) {
|
PropertyValue(final B object, final Property<B, ?> prop) {
|
||||||
// FIXME: simplify
|
this.prop = (Property<B, V>) prop;
|
||||||
final var typedProp = (Property<B, V>) prop;
|
this.value = (V) this.prop.getValue(object);
|
||||||
final var value = typedProp.getValue(object);
|
this.stringValue = this.value instanceof Stringifyable s
|
||||||
final var stringifiedValue = value instanceof Stringifyable stringifyable
|
? s.toShortString()
|
||||||
? stringifyable.toShortString()
|
: Objects.toString(this.value);
|
||||||
: Objects.toString(value);
|
|
||||||
this.prop = typedProp;
|
|
||||||
this.value = (V) value;
|
|
||||||
this.stringValue = stringifiedValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean notNullAndNotEmpty() {
|
boolean notNullAndNotEmpty() {
|
||||||
|
|||||||
@@ -54,12 +54,16 @@ spring:
|
|||||||
liquibase:
|
liquibase:
|
||||||
contexts: ${spring.profiles.active}
|
contexts: ${spring.profiles.active}
|
||||||
|
|
||||||
|
security:
|
||||||
|
oauth2:
|
||||||
|
resourceserver:
|
||||||
|
jwt:
|
||||||
|
issuer-uri: ${HSADMINNG_JWT_ISSUER:}
|
||||||
|
jwk-set-uri: ${HSADMINNG_JWT_JWKS_URL:}
|
||||||
|
|
||||||
hsadminng:
|
hsadminng:
|
||||||
postgres:
|
postgres:
|
||||||
leakproof:
|
leakproof:
|
||||||
cas:
|
|
||||||
server: https://login.hostsharing.net/cas # use empty string to bypass CAS-validation and directly use current-subject
|
|
||||||
service: https://hsadminng.hostsharing.net:443 # TODO.conf: deployment target + matching CAS service ID
|
|
||||||
|
|
||||||
metrics:
|
metrics:
|
||||||
distribution:
|
distribution:
|
||||||
@@ -78,3 +82,17 @@ logging:
|
|||||||
# HOWTO configure logging, e.g. logging to a separate file, see:
|
# HOWTO configure logging, e.g. logging to a separate file, see:
|
||||||
# https://docs.spring.io/spring-boot/reference/features/logging.html
|
# https://docs.spring.io/spring-boot/reference/features/logging.html
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
spring:
|
||||||
|
config:
|
||||||
|
activate:
|
||||||
|
on-profile: fake-jwt
|
||||||
|
security:
|
||||||
|
oauth2:
|
||||||
|
resourceserver:
|
||||||
|
jwt:
|
||||||
|
issuer-uri: "http://localhost:${server.port}/fake-jwt"
|
||||||
|
jwk-set-uri: "http://localhost:${server.port}/fake-jwt/.well-known/jwks.json"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -384,6 +384,7 @@ public class ArchitectureTest {
|
|||||||
classes().that(belongToProductionClasses()
|
classes().that(belongToProductionClasses()
|
||||||
.and(are(annotatedWith(RestController.class))))
|
.and(are(annotatedWith(RestController.class))))
|
||||||
.should(havePreAuthorizeWithValue("isAuthenticated()"))
|
.should(havePreAuthorizeWithValue("isAuthenticated()"))
|
||||||
|
.orShould().beAnnotatedWith(NoSecurityRequirement.class)
|
||||||
.because("Every REST controller should require authentication by default, use @PreAuthorize(...) to override this at the endpoint method level.");
|
.because("Every REST controller should require authentication by default, use @PreAuthorize(...) to override this at the endpoint method level.");
|
||||||
|
|
||||||
private static ArchCondition<JavaClass> havePreAuthorizeWithValue(String expectedValue) {
|
private static ArchCondition<JavaClass> havePreAuthorizeWithValue(String expectedValue) {
|
||||||
|
|||||||
-109
@@ -1,109 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
|
||||||
import net.hostsharing.hsadminng.test.LogbackLogPattern;
|
|
||||||
import org.junit.jupiter.api.Tag;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.logging.LogLevel;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.boot.test.system.CapturedOutput;
|
|
||||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
|
||||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
|
||||||
import org.springframework.http.HttpEntity;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
|
||||||
import org.springframework.test.context.TestPropertySource;
|
|
||||||
|
|
||||||
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
|
||||||
import static java.util.Map.entry;
|
|
||||||
import static net.hostsharing.hsadminng.config.HttpHeadersBuilder.headers;
|
|
||||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
||||||
@TestPropertySource(properties = {
|
|
||||||
"server.port=0",
|
|
||||||
"hsadminng.cas.server=http://localhost:8088",
|
|
||||||
|
|
||||||
"logging.level.root=DEBUG"
|
|
||||||
})
|
|
||||||
@ActiveProfiles({"wiremock", "realCasAuthenticator"}) // IMPORTANT: To test prod config, do NOT use test profile!
|
|
||||||
@Tag("generalIntegrationTest")
|
|
||||||
@ExtendWith(OutputCaptureExtension.class)
|
|
||||||
class CasAuthenticationFilterIntegrationTest {
|
|
||||||
|
|
||||||
@Value("${local.server.port}")
|
|
||||||
private int serverPort;
|
|
||||||
|
|
||||||
@Value("${hsadminng.cas.service}")
|
|
||||||
private String serviceUrl;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TestRestTemplate restTemplate;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WireMockServer wireMockServer;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldAcceptRequestWithValidCasTicket(final CapturedOutput capturedOutput) {
|
|
||||||
// given
|
|
||||||
final var username = "test-user-" + randomAlphanumeric(4);
|
|
||||||
wireMockServer.stubFor(get(urlEqualTo("/cas/p3/serviceValidate?service=" + serviceUrl + "&ticket=ST-valid"))
|
|
||||||
.willReturn(aResponse()
|
|
||||||
.withStatus(200)
|
|
||||||
.withBody("""
|
|
||||||
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
|
|
||||||
<cas:authenticationSuccess>
|
|
||||||
<cas:user>%{username}</cas:user>
|
|
||||||
</cas:authenticationSuccess>
|
|
||||||
</cas:serviceResponse>
|
|
||||||
""".replace("%{username}", username)
|
|
||||||
)));
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var result = restTemplate.exchange(
|
|
||||||
"http://localhost:" + this.serverPort + "/api/pong",
|
|
||||||
HttpMethod.GET,
|
|
||||||
new HttpEntity<>(null, headers(entry("Authorization", "ST-valid"))),
|
|
||||||
String.class
|
|
||||||
);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
|
||||||
assertThat(result.getBody()).startsWith("ponged " + username);
|
|
||||||
// HOWTO assert log messages
|
|
||||||
assertThat(capturedOutput.getOut()).containsPattern(
|
|
||||||
LogbackLogPattern.of(LogLevel.DEBUG, RealCasAuthenticator.class, "CAS-user: " + username));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void shouldRejectRequestWithInvalidCasTicket() {
|
|
||||||
// given
|
|
||||||
wireMockServer.stubFor(get(urlEqualTo("/cas/p3/serviceValidate?service=" + serviceUrl + "&ticket=invalid"))
|
|
||||||
.willReturn(aResponse()
|
|
||||||
.withStatus(200)
|
|
||||||
.withBody("""
|
|
||||||
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
|
|
||||||
<cas:authenticationFailure code="INVALID_REQUEST"></cas:authenticationFailure>
|
|
||||||
</cas:serviceResponse>
|
|
||||||
""")));
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var result = restTemplate.exchange(
|
|
||||||
"http://localhost:" + this.serverPort + "/api/ping",
|
|
||||||
HttpMethod.GET,
|
|
||||||
new HttpEntity<>(null, headers(entry("Authorization", "invalid"))),
|
|
||||||
String.class
|
|
||||||
);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-4
@@ -10,12 +10,11 @@ import org.springframework.test.context.ActiveProfiles;
|
|||||||
|
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
|
|
||||||
|
@Tag("generalIntegrationTest")
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Tag("generalIntegrationTest")
|
|
||||||
class CustomActuatorEndpointAcceptanceTest {
|
class CustomActuatorEndpointAcceptanceTest {
|
||||||
|
|
||||||
@LocalManagementPort
|
@LocalManagementPort
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
|
||||||
|
|
||||||
import org.springframework.boot.test.context.TestConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Profile;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
|
||||||
|
|
||||||
@TestConfiguration
|
|
||||||
public class DisableSecurityConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Profile("test")
|
|
||||||
public SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception {
|
|
||||||
http
|
|
||||||
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
|
|
||||||
.csrf(AbstractHttpConfigurer::disable);
|
|
||||||
return http.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Profile("test")
|
|
||||||
public CasAuthenticator fakeAuthenticator() {
|
|
||||||
return new FakeCasAuthenticator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
|
import lombok.val;
|
||||||
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||||
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
|
import static net.hostsharing.hsadminng.config.HttpHeadersBuilder.headers;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@Tag("generalIntegrationTest")
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = HsadminNgApplication.class)
|
||||||
|
@TestPropertySource(properties = {
|
||||||
|
"server.port=0",
|
||||||
|
"logging.level.root=DEBUG"
|
||||||
|
})
|
||||||
|
@ActiveProfiles("fake-jwt")
|
||||||
|
@ExtendWith(OutputCaptureExtension.class)
|
||||||
|
class JwtAuthenticationFilterIntegrationTest {
|
||||||
|
|
||||||
|
@Value("${local.server.port}")
|
||||||
|
private int serverPort;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TestRestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldAcceptRequestWithValidJwt() {
|
||||||
|
// given
|
||||||
|
val givenSubject = "some-subject";
|
||||||
|
val bearer = bearer(givenSubject);
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = restTemplate.exchange(
|
||||||
|
"http://localhost:" + this.serverPort + "/api/pong",
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(null, headers(entry("Authorization", bearer))),
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
assertThat(result.getBody()).startsWith("ponged " + givenSubject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRejectRequestWithInvalidJwt() {
|
||||||
|
// given
|
||||||
|
val givenInvalidBearer = "Bearer invalid";
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = restTemplate.exchange(
|
||||||
|
"http://localhost:" + this.serverPort + "/api/pong",
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(null, headers(entry("Authorization", givenInvalidBearer))),
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
}
|
||||||
-6
@@ -7,11 +7,8 @@ import org.junit.jupiter.params.provider.EnumSource;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -29,9 +26,6 @@ class MessageTranslatorIntegrationTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private WebApplicationContext webApplicationContext;
|
private WebApplicationContext webApplicationContext;
|
||||||
|
|
||||||
@MockitoBean
|
|
||||||
private Context contextMock; // avoiding dependency issues
|
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
enum TestCases {
|
enum TestCases {
|
||||||
ENGLISH_KNOWN(Locale.ENGLISH, "test.ponged-{0}--in-your-language",
|
ENGLISH_KNOWN(Locale.ENGLISH, "test.ponged-{0}--in-your-language",
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.test.context.TestConfiguration;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
|
||||||
|
|
||||||
|
@TestConfiguration
|
||||||
|
// @EnableMethodSecurity breaks RestTests, endpoints won't be reachable anymore, all return 404
|
||||||
|
// that's the reason why this class even exists in the first place
|
||||||
|
@Profile("test")
|
||||||
|
public class WebSecurityConfigForWebMvcTests extends BaseWebSecurityConfig {
|
||||||
|
|
||||||
|
}
|
||||||
+34
-131
@@ -1,12 +1,9 @@
|
|||||||
package net.hostsharing.hsadminng.config;
|
package net.hostsharing.hsadminng.config;
|
||||||
|
|
||||||
import java.util.Map;
|
import lombok.val;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
@@ -18,134 +15,57 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
import java.util.Map;
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.get;
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.post;
|
|
||||||
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
||||||
@TestPropertySource(properties = {"management.port=0", "server.port=0", "hsadminng.cas.server=http://localhost:8088"})
|
|
||||||
@ActiveProfiles({"wiremock", "realCasAuthenticator"}) // IMPORTANT: To test prod config, do NOT use test profile!
|
|
||||||
@Tag("generalIntegrationTest")
|
@Tag("generalIntegrationTest")
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@TestPropertySource(properties = { "management.port=0", "server.port=0" })
|
||||||
|
@ActiveProfiles("fake-jwt") // IMPORTANT: In this test, want to test the prod config, do NOT use test profile!
|
||||||
class WebSecurityConfigIntegrationTest {
|
class WebSecurityConfigIntegrationTest {
|
||||||
|
|
||||||
|
public static final String GIVEN_FAKE_SUBJECT = "fake-user-name";
|
||||||
@Value("${local.server.port}")
|
@Value("${local.server.port}")
|
||||||
private int serverPort;
|
private int serverPort;
|
||||||
|
|
||||||
@Value("${local.management.port}")
|
@Value("${local.management.port}")
|
||||||
private int managementPort;
|
private int managementPort;
|
||||||
|
|
||||||
@Value("${hsadminng.cas.service}")
|
|
||||||
private String serviceUrl;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TestRestTemplate restTemplate;
|
private TestRestTemplate restTemplate;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WireMockServer wireMockServer;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
wireMockServer.stubFor(get(anyUrl())
|
|
||||||
.willReturn(aResponse()
|
|
||||||
.withStatus(200)
|
|
||||||
.withBody("""
|
|
||||||
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
|
|
||||||
<cas:authenticationFailure/>
|
|
||||||
</cas:serviceResponse>
|
|
||||||
""")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void accessToApiWithValidServiceTicketSouldBePermitted() {
|
void accessToApiWithValidJwtShouldBePermitted() {
|
||||||
// given
|
|
||||||
givenCasTicketValidationResponse("ST-fake-cas-ticket", "fake-user-name");
|
|
||||||
|
|
||||||
// http request
|
|
||||||
final var result = restTemplate.exchange(
|
|
||||||
"http://localhost:" + this.serverPort + "/api/pong",
|
|
||||||
HttpMethod.GET,
|
|
||||||
httpHeaders(entry("Authorization", "Bearer ST-fake-cas-ticket")),
|
|
||||||
String.class
|
|
||||||
);
|
|
||||||
|
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
|
||||||
assertThat(result.getBody()).startsWith("ponged fake-user-name");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void accessToApiWithValidTicketGrantingTicketShouldBePermitted() {
|
|
||||||
// given
|
|
||||||
givenCasServiceTicketForTicketGrantingTicket("TGT-fake-cas-ticket", "ST-fake-cas-ticket");
|
|
||||||
givenCasTicketValidationResponse("ST-fake-cas-ticket", "fake-user-name");
|
|
||||||
|
|
||||||
// http request
|
|
||||||
final var result = restTemplate.exchange(
|
|
||||||
"http://localhost:" + this.serverPort + "/api/pong",
|
|
||||||
HttpMethod.GET,
|
|
||||||
httpHeaders(entry("Authorization", "Bearer TGT-fake-cas-ticket")),
|
|
||||||
String.class
|
|
||||||
);
|
|
||||||
|
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
|
||||||
assertThat(result.getBody()).startsWith("ponged fake-user-name");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void accessToOpenApiWithInvalidTicketGrantingTicketShouldBePermitted() {
|
|
||||||
// given
|
|
||||||
givenCasServiceTicketForTicketGrantingTicket("TGT-fake-cas-ticket", "ST-fake-cas-ticket");
|
|
||||||
givenCasTicketValidationResponse("ST-fake-cas-ticket", "fake-user-name");
|
|
||||||
|
|
||||||
// http request
|
|
||||||
final var result = restTemplate.exchange(
|
|
||||||
"http://localhost:" + this.serverPort + "/api/ping",
|
|
||||||
HttpMethod.GET,
|
|
||||||
httpHeaders(entry("Authorization", "Bearer TGT-WRONG-cas-ticket")),
|
|
||||||
String.class
|
|
||||||
);
|
|
||||||
|
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void accessToOpenApiWithoutTokenShouldBePermitted() {
|
|
||||||
final var result = this.restTemplate.getForEntity(
|
|
||||||
"http://localhost:" + this.serverPort + "/api/ping", String.class);
|
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void accessToProtectedApiWithValidTokenShouldBePermitted() {
|
|
||||||
// given
|
|
||||||
givenCasTicketValidationResponse("ST-fake-cas-ticket", "fake-user-name");
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = restTemplate.exchange(
|
val result = restTemplate.exchange(
|
||||||
"http://localhost:" + this.serverPort + "/api/pong",
|
serverUrl("/api/pong"),
|
||||||
HttpMethod.GET,
|
HttpMethod.GET,
|
||||||
httpHeaders(entry("Authorization", "Bearer ST-fake-cas-ticket")),
|
httpHeaders(entry("Authorization", bearer(GIVEN_FAKE_SUBJECT))),
|
||||||
String.class
|
String.class
|
||||||
);
|
);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
|
assertThat(result.getBody()).startsWith("ponged " + GIVEN_FAKE_SUBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void accessToOpenApiWithoutTokenShouldBePermitted() {
|
||||||
|
val result = this.restTemplate.getForEntity(
|
||||||
|
serverUrl("/api/ping"), String.class);
|
||||||
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void accessToProtectedApiWithInvalidTokenShouldBeDenied() {
|
void accessToProtectedApiWithInvalidTokenShouldBeDenied() {
|
||||||
// given
|
|
||||||
givenCasTicketValidationResponse("ST-fake-cas-ticket", "fake-user-name");
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = restTemplate.exchange(
|
val result = restTemplate.exchange(
|
||||||
"http://localhost:" + this.serverPort + "/api/pong",
|
serverUrl("/api/pong"),
|
||||||
HttpMethod.GET,
|
HttpMethod.GET,
|
||||||
httpHeaders(entry("Authorization", "Bearer ST-WRONG-cas-ticket")),
|
httpHeaders(entry("Authorization", "Bearer INVALID-JWT")),
|
||||||
String.class
|
String.class
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -155,59 +75,42 @@ class WebSecurityConfigIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void accessToActuatorShouldBePermitted() {
|
void accessToActuatorShouldBePermitted() {
|
||||||
final var result = this.restTemplate.getForEntity(
|
val result = this.restTemplate.getForEntity(
|
||||||
"http://localhost:" + this.managementPort + "/actuator", Map.class);
|
"http://localhost:" + this.managementPort + "/actuator", Map.class);
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void accessToSwaggerUiShouldBePermitted() {
|
void accessToSwaggerUiShouldBePermitted() {
|
||||||
final var result = this.restTemplate.getForEntity(
|
val result = this.restTemplate.getForEntity(
|
||||||
"http://localhost:" + this.serverPort + "/swagger-ui/index.html", String.class);
|
serverUrl("/swagger-ui/index.html"), String.class);
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void accessToApiDocsEndpointShouldBePermitted() {
|
void accessToApiDocsEndpointShouldBePermitted() {
|
||||||
final var result = this.restTemplate.getForEntity(
|
val result = this.restTemplate.getForEntity(
|
||||||
"http://localhost:" + this.serverPort + "/v3/api-docs/swagger-config", String.class);
|
serverUrl("/v3/api-docs/swagger-config"), String.class);
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(result.getBody()).contains("\"configUrl\":\"/v3/api-docs/swagger-config\"");
|
assertThat(result.getBody()).contains("\"configUrl\":\"/v3/api-docs/swagger-config\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void accessToActuatorEndpointShouldBePermitted() {
|
void accessToActuatorEndpointShouldBePermitted() {
|
||||||
final var result = this.restTemplate.getForEntity(
|
val result = this.restTemplate.getForEntity(
|
||||||
"http://localhost:" + this.managementPort + "/actuator/health", Map.class);
|
"http://localhost:" + this.managementPort + "/actuator/health", Map.class);
|
||||||
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||||
assertThat(result.getBody().get("status")).isEqualTo("UP");
|
assertThat(result.getBody().get("status")).isEqualTo("UP");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void givenCasServiceTicketForTicketGrantingTicket(final String ticketGrantingTicket, final String serviceTicket) {
|
private @NotNull String serverUrl(final String path) {
|
||||||
wireMockServer.stubFor(post(urlEqualTo("/cas/v1/tickets/" + ticketGrantingTicket))
|
return "http://localhost:" + this.serverPort + path;
|
||||||
.withFormParam("service", equalTo(serviceUrl))
|
|
||||||
.willReturn(aResponse()
|
|
||||||
.withStatus(201)
|
|
||||||
.withBody(serviceTicket)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void givenCasTicketValidationResponse(final String casToken, final String userName) {
|
|
||||||
wireMockServer.stubFor(get(urlEqualTo("/cas/p3/serviceValidate?service=" + serviceUrl + "&ticket=" + casToken))
|
|
||||||
.willReturn(aResponse()
|
|
||||||
.withStatus(200)
|
|
||||||
.withBody("""
|
|
||||||
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
|
|
||||||
<cas:authenticationSuccess>
|
|
||||||
<cas:user>${userName}</cas:user>
|
|
||||||
</cas:authenticationSuccess>
|
|
||||||
</cas:serviceResponse>
|
|
||||||
""".replace("${userName}", userName))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
private HttpEntity<?> httpHeaders(final Map.Entry<String, String>... headerValues) {
|
private HttpEntity<?> httpHeaders(final Map.Entry<String, String>... headerValues) {
|
||||||
final var headers = new HttpHeaders();
|
val headers = new HttpHeaders();
|
||||||
for ( Map.Entry<String, String> headerValue: headerValues ) {
|
for (Map.Entry<String, String> headerValue : headerValues) {
|
||||||
headers.add(headerValue.getKey(), headerValue.getValue());
|
headers.add(headerValue.getKey(), headerValue.getValue());
|
||||||
}
|
}
|
||||||
return new HttpEntity<>(headers);
|
return new HttpEntity<>(headers);
|
||||||
|
|||||||
+7
-5
@@ -1,9 +1,8 @@
|
|||||||
package net.hostsharing.hsadminng.errors;
|
package net.hostsharing.hsadminng.errors;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import org.junit.jupiter.api.Tag;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
@@ -21,9 +20,12 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(controllers = RestResponseEntityExceptionHandlerRestTest.TestController.class)
|
@WebMvcTest(controllers = RestResponseEntityExceptionHandlerRestTest.TestController.class)
|
||||||
@Import({JsonObjectMapperConfiguration.class, MessageTranslator.class, DisableSecurityConfig.class, RestResponseEntityExceptionHandler.class, RestResponseEntityExceptionHandlerRestTest.TestConfig.class})
|
@Import({ JsonObjectMapperConfiguration.class,
|
||||||
@Tag("generalIntegrationTest")
|
MessageTranslator.class,
|
||||||
@ActiveProfiles("test")
|
RestResponseEntityExceptionHandler.class,
|
||||||
|
RestResponseEntityExceptionHandlerRestTest.TestConfig.class,
|
||||||
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
class RestResponseEntityExceptionHandlerRestTest {
|
class RestResponseEntityExceptionHandlerRestTest {
|
||||||
|
|
||||||
@TestConfiguration
|
@TestConfiguration
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.accounts;
|
package net.hostsharing.hsadminng.hs.accounts;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.accounts;
|
package net.hostsharing.hsadminng.hs.accounts;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
|
|||||||
+12
-7
@@ -1,6 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.accounts;
|
package net.hostsharing.hsadminng.hs.accounts;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -13,12 +14,13 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -37,8 +39,11 @@ import jakarta.persistence.EntityManagerFactory;
|
|||||||
import jakarta.persistence.SynchronizationType;
|
import jakarta.persistence.SynchronizationType;
|
||||||
|
|
||||||
@WebMvcTest(HsCredentialsContextsController.class)
|
@WebMvcTest(HsCredentialsContextsController.class)
|
||||||
@Import({ StrictMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class, MessageTranslator.class})
|
@Import({ StrictMapper.class,
|
||||||
@ActiveProfiles("test")
|
MessageTranslator.class,
|
||||||
|
JsonObjectMapperConfiguration.class,
|
||||||
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
class HsCredentialsContextsControllerRestTest {
|
class HsCredentialsContextsControllerRestTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -85,7 +90,7 @@ class HsCredentialsContextsControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/accounts/contexts")
|
.get("/api/hs/accounts/contexts")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(print())
|
.andDo(print())
|
||||||
|
|
||||||
@@ -105,7 +110,7 @@ class HsCredentialsContextsControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/accounts/contexts")
|
.get("/api/hs/accounts/contexts")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("Bearer superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(print())
|
.andDo(print())
|
||||||
|
|
||||||
@@ -147,7 +152,7 @@ class HsCredentialsContextsControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/accounts/contexts")
|
.get("/api/hs/accounts/contexts")
|
||||||
.header("Authorization", "Bearer drew@hostsharing.org")
|
.header("Authorization", bearer("drew@hostsharing.org"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(print())
|
.andDo(print())
|
||||||
|
|
||||||
|
|||||||
+14
-16
@@ -3,9 +3,7 @@ package net.hostsharing.hsadminng.hs.accounts;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.hs.accounts.HsCredentialsEntity.HsCredentialsEntityBuilder;
|
import net.hostsharing.hsadminng.hs.accounts.HsCredentialsEntity.HsCredentialsEntityBuilder;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
@@ -31,6 +29,7 @@ import java.util.Set;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
|
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.LEGAL_PERSON;
|
||||||
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.NATURAL_PERSON;
|
import static net.hostsharing.hsadminng.hs.office.person.HsOfficePersonType.NATURAL_PERSON;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
@@ -41,18 +40,17 @@ import static org.hamcrest.Matchers.is;
|
|||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
|
||||||
|
@Tag("generalIntegrationTest")
|
||||||
@Transactional
|
@Transactional
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
|
||||||
)
|
)
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles("fake-jwt")
|
||||||
@Tag("generalIntegrationTest")
|
|
||||||
// too complex database interaction for just a RestTest, thus a fully integrated test
|
// too complex database interaction for just a RestTest, thus a fully integrated test
|
||||||
class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
private Integer port;
|
Integer port;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
Context context;
|
Context context;
|
||||||
@@ -93,7 +91,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/accounts/current")
|
.get("http://localhost/api/hs/accounts/current")
|
||||||
@@ -120,7 +118,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer " + credentialsEntity.getSubject().getName())
|
.header("Authorization", bearer(credentialsEntity.getSubject().getName()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/accounts/credentials/" + credentialsEntity.getUuid())
|
.get("http://localhost/api/hs/accounts/credentials/" + credentialsEntity.getUuid())
|
||||||
@@ -188,7 +186,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -228,7 +226,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -268,7 +266,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -314,7 +312,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -350,7 +348,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -388,7 +386,7 @@ class HsCredentialsControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/accounts/credentials/" + credentialsEntity.getUuid() + "/used")
|
.post("http://localhost/api/hs/accounts/credentials/" + credentialsEntity.getUuid() + "/used")
|
||||||
|
|||||||
+1
-2
@@ -1,9 +1,8 @@
|
|||||||
package net.hostsharing.hsadminng.hs.accounts;
|
package net.hostsharing.hsadminng.hs.accounts;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
|
|||||||
+9
-31
@@ -1,43 +1,19 @@
|
|||||||
package net.hostsharing.hsadminng.hs.accounts.scenarios;
|
package net.hostsharing.hsadminng.hs.accounts.scenarios;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import net.hostsharing.hsadminng.hs.scenarios.Produces;
|
import net.hostsharing.hsadminng.hs.scenarios.Produces;
|
||||||
import net.hostsharing.hsadminng.hs.scenarios.Requires;
|
import net.hostsharing.hsadminng.hs.scenarios.Requires;
|
||||||
import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest;
|
import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
import net.hostsharing.hsadminng.mapper.Array;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
|
||||||
import net.hostsharing.hsadminng.test.IgnoreOnFailureExtension;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.ClassOrderer;
|
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
import org.junit.jupiter.api.Tag;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestClassOrder;
|
|
||||||
import org.junit.jupiter.api.TestInfo;
|
import org.junit.jupiter.api.TestInfo;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
|
||||||
|
|
||||||
@Tag("scenarioTest")
|
|
||||||
@SpringBootTest(
|
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class },
|
|
||||||
properties = {
|
|
||||||
"spring.datasource.url=${HSADMINNG_POSTGRES_JDBC_URL:jdbc:tc:postgresql:15.5-bookworm:///scenariosTC}",
|
|
||||||
"spring.datasource.username=${HSADMINNG_POSTGRES_ADMIN_USERNAME:ADMIN}",
|
|
||||||
"spring.datasource.password=${HSADMINNG_POSTGRES_ADMIN_PASSWORD:password}",
|
|
||||||
"hsadminng.superuser=${HSADMINNG_SUPERUSER:superuser-alex@hostsharing.net}"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
|
|
||||||
@ExtendWith(IgnoreOnFailureExtension.class)
|
|
||||||
class CredentialsScenarioTests extends ScenarioTest {
|
class CredentialsScenarioTests extends ScenarioTest {
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@@ -105,9 +81,10 @@ class CredentialsScenarioTests extends ScenarioTest {
|
|||||||
.given("smsNumber", "+49123456789")
|
.given("smsNumber", "+49123456789")
|
||||||
.given("globalUid", 21011)
|
.given("globalUid", 21011)
|
||||||
.given("globalGid", 21011)
|
.given("globalGid", 21011)
|
||||||
.given("contexts", Array.of(
|
.given(
|
||||||
Pair.of("HSADMIN", "prod")
|
"contexts", Array.of(
|
||||||
))
|
Pair.of("HSADMIN", "prod")
|
||||||
|
))
|
||||||
.given("onboardingToken", "fake-unboarding-token")
|
.given("onboardingToken", "fake-unboarding-token")
|
||||||
.doRun()
|
.doRun()
|
||||||
.keep();
|
.keep();
|
||||||
@@ -126,10 +103,11 @@ class CredentialsScenarioTests extends ScenarioTest {
|
|||||||
.given("emailAddress", "susan.firby@example.org")
|
.given("emailAddress", "susan.firby@example.org")
|
||||||
.given("phonePassword", "securePass987")
|
.given("phonePassword", "securePass987")
|
||||||
.given("smsNumber", "+49987654321")
|
.given("smsNumber", "+49987654321")
|
||||||
.given("contexts", Array.of(
|
.given(
|
||||||
Pair.of("HSADMIN", "prod"),
|
"contexts", Array.of(
|
||||||
Pair.of("SSH", "internal")
|
Pair.of("HSADMIN", "prod"),
|
||||||
))
|
Pair.of("SSH", "internal")
|
||||||
|
))
|
||||||
.doRun();
|
.doRun();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.hs.scenarios.UseCase;
|
|||||||
|
|
||||||
|
|
||||||
import static io.restassured.http.ContentType.JSON;
|
import static io.restassured.http.ContentType.JSON;
|
||||||
|
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.bearerTemplate;
|
||||||
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.resolve;
|
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.resolve;
|
||||||
import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS;
|
import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -33,7 +34,7 @@ public class CurrentLoginUser extends UseCase<CurrentLoginUser> {
|
|||||||
"Current Login User", () ->
|
"Current Login User", () ->
|
||||||
httpGet(
|
httpGet(
|
||||||
"/api/hs/accounts/current", req -> req
|
"/api/hs/accounts/current", req -> req
|
||||||
.header("Authorization", resolve("Bearer %{subjectName}", DROP_COMMENTS))
|
.header("Authorization", bearerTemplate("%{subjectName}"))
|
||||||
)
|
)
|
||||||
.expecting(OK).expecting(JSON).expectObject()
|
.expecting(OK).expecting(JSON).expectObject()
|
||||||
.extractValue("subject.name", "returnedSubjectName")
|
.extractValue("subject.name", "returnedSubjectName")
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import net.hostsharing.hsadminng.hs.scenarios.UseCase;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static io.restassured.http.ContentType.JSON;
|
import static io.restassured.http.ContentType.JSON;
|
||||||
|
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.bearerTemplate;
|
||||||
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.resolve;
|
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.resolve;
|
||||||
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.resolveJsonArray;
|
import static net.hostsharing.hsadminng.hs.scenarios.ScenarioTest.resolveJsonArray;
|
||||||
import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS;
|
import static net.hostsharing.hsadminng.hs.scenarios.TemplateResolver.Resolver.DROP_COMMENTS;
|
||||||
@@ -27,7 +28,7 @@ public class FetchRbacContext extends UseCase<FetchRbacContext> {
|
|||||||
"RBAC Context", () ->
|
"RBAC Context", () ->
|
||||||
httpGet(
|
httpGet(
|
||||||
"/api/rbac/context", req -> req
|
"/api/rbac/context", req -> req
|
||||||
.header("Authorization", resolve("Bearer %{subjectName}", DROP_COMMENTS))
|
.header("Authorization", bearerTemplate("%{subjectName}"))
|
||||||
.header("assumed-roles", resolve("%{assumedRoles}", DROP_COMMENTS))
|
.header("assumed-roles", resolve("%{assumedRoles}", DROP_COMMENTS))
|
||||||
)
|
)
|
||||||
.expecting(OK).expecting(JSON).expectObject()
|
.expecting(OK).expecting(JSON).expectObject()
|
||||||
|
|||||||
+16
-17
@@ -12,7 +12,6 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealRepository;
|
|||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.ClassOrderer;
|
import org.junit.jupiter.api.ClassOrderer;
|
||||||
@@ -36,6 +35,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
|
||||||
@@ -43,14 +43,13 @@ import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.matchesRegex;
|
import static org.hamcrest.Matchers.matchesRegex;
|
||||||
|
|
||||||
|
@Tag("bookingIntegrationTest")
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class}
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
|
||||||
@TestClassOrder(ClassOrderer.OrderAnnotation.class) // fail early on fetching problems
|
@TestClassOrder(ClassOrderer.OrderAnnotation.class) // fail early on fetching problems
|
||||||
@Tag("bookingIntegrationTest")
|
@Transactional
|
||||||
class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -87,7 +86,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/items?projectUuid=" + givenProject.getUuid())
|
.get("http://localhost/api/hs/booking/items?projectUuid=" + givenProject.getUuid())
|
||||||
@@ -151,7 +150,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -201,7 +200,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -271,7 +270,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -361,7 +360,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -454,7 +453,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
||||||
@@ -488,7 +487,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
||||||
@@ -506,7 +505,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", "hs_booking.project#D-1000313-D-1000313defaultproject:ADMIN")
|
.header("assumed-roles", "hs_booking.project#D-1000313-D-1000313defaultproject:ADMIN")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
@@ -550,7 +549,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", "hs_booking.project#D-1000111-D-1000111defaultproject:AGENT")
|
.header("assumed-roles", "hs_booking.project#D-1000111-D-1000111defaultproject:AGENT")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -605,7 +604,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
.delete("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
@@ -624,7 +623,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
.delete("http://localhost/api/hs/booking/items/" + givenBookingItem.getUuid())
|
||||||
|
|||||||
+12
-9
@@ -3,25 +3,25 @@ package net.hostsharing.hsadminng.hs.booking.item;
|
|||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.context.TestConfiguration;
|
import org.springframework.boot.test.context.TestConfiguration;
|
||||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
@@ -32,20 +32,24 @@ import java.time.LocalDate;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.matchesRegex;
|
import static org.hamcrest.Matchers.matchesRegex;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsBookingItemController.class)
|
@WebMvcTest(HsBookingItemController.class)
|
||||||
@Import({StrictMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class, MessageTranslator.class})
|
@Import({StrictMapper.class,
|
||||||
@ActiveProfiles("test")
|
JsonObjectMapperConfiguration.class,
|
||||||
|
MessageTranslator.class,
|
||||||
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
class HsBookingItemControllerRestTest {
|
class HsBookingItemControllerRestTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -77,7 +81,6 @@ class HsBookingItemControllerRestTest {
|
|||||||
public EntityManager entityManager() {
|
public EntityManager entityManager() {
|
||||||
return mock(EntityManager.class);
|
return mock(EntityManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -107,7 +110,7 @@ class HsBookingItemControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/booking/items")
|
.post("/api/hs/booking/items")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
@@ -158,7 +161,7 @@ class HsBookingItemControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/booking/items")
|
.post("/api/hs/booking/items")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.booking.item;
|
package net.hostsharing.hsadminng.hs.booking.item;
|
||||||
|
|
||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||||
|
|||||||
+12
-13
@@ -6,7 +6,6 @@ import net.hostsharing.hsadminng.HsadminNgApplication;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -20,17 +19,17 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.matchesRegex;
|
import static org.hamcrest.Matchers.matchesRegex;
|
||||||
|
|
||||||
|
@Tag("bookingIntegrationTest")
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Tag("bookingIntegrationTest")
|
@ActiveProfiles("fake-jwt")
|
||||||
class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -62,7 +61,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/projects?debitorUuid=" + givenDebitor.getUuid())
|
.get("http://localhost/api/hs/booking/projects?debitorUuid=" + givenDebitor.getUuid())
|
||||||
@@ -93,7 +92,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -133,7 +132,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/projects/" + givenBookingProjectUuid)
|
.get("http://localhost/api/hs/booking/projects/" + givenBookingProjectUuid)
|
||||||
@@ -156,7 +155,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/projects/" + givenBookingProjectUuid)
|
.get("http://localhost/api/hs/booking/projects/" + givenBookingProjectUuid)
|
||||||
@@ -172,7 +171,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer person-TuckerJack@example.com")
|
.header("Authorization", bearer("person-TuckerJack@example.com"))
|
||||||
.header("assumed-roles", "hs_booking.project#D-1000313-D-1000313defaultproject:AGENT")
|
.header("assumed-roles", "hs_booking.project#D-1000313-D-1000313defaultproject:AGENT")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
@@ -198,7 +197,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -237,7 +236,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/booking/projects/" + givenBookingProject.getUuid())
|
.delete("http://localhost/api/hs/booking/projects/" + givenBookingProject.getUuid())
|
||||||
@@ -255,7 +254,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/booking/projects/" + givenBookingProject.getUuid())
|
.delete("http://localhost/api/hs/booking/projects/" + givenBookingProject.getUuid())
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.booking.project;
|
package net.hostsharing.hsadminng.hs.booking.project;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
||||||
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;
|
||||||
|
|||||||
+117
-115
@@ -14,7 +14,6 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.ClassOrderer;
|
import org.junit.jupiter.api.ClassOrderer;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -34,6 +33,7 @@ import java.util.UUID;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ALIAS;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ALIAS;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||||
@@ -43,14 +43,13 @@ import static net.hostsharing.hsadminng.test.JsonMatcher.strictlyEquals;
|
|||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.matchesRegex;
|
import static org.hamcrest.Matchers.matchesRegex;
|
||||||
|
|
||||||
|
@Tag("hostingIntegrationTest")
|
||||||
@Transactional
|
@Transactional
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@TestClassOrder(ClassOrderer.OrderAnnotation.class) // fail early on fetching problems
|
@TestClassOrder(ClassOrderer.OrderAnnotation.class) // fail early on fetching problems
|
||||||
@Tag("hostingIntegrationTest")
|
|
||||||
class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -89,12 +88,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/hosting/assets?projectUuid=" + givenProject.getUuid() + "&type=MANAGED_WEBSPACE")
|
.get("http://localhost/api/hs/hosting/assets?projectUuid=" + givenProject.getUuid() + "&type=MANAGED_WEBSPACE")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
@@ -107,7 +106,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""));
|
"""));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -118,15 +117,15 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", "hs_hosting.asset#fir01:AGENT")
|
.header("assumed-roles", "hs_hosting.asset#fir01:AGENT")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
. get("http://localhost/api/hs/hosting/assets?type=" + EMAIL_ALIAS)
|
. get("http://localhost/api/hs/hosting/assets?type=" + EMAIL_ALIAS)
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"type": "EMAIL_ALIAS",
|
"type": "EMAIL_ALIAS",
|
||||||
@@ -154,7 +153,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
void globalAdmin_canAddBookedAsset() {
|
void globalAdmin_canAddBookedAsset() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItem = newBookingItem("D-1000111 default project",
|
final var givenBookingItem = newBookingItem(
|
||||||
|
"D-1000111 default project",
|
||||||
HsBookingItemType.MANAGED_WEBSPACE, "separate ManagedWebspace BI",
|
HsBookingItemType.MANAGED_WEBSPACE, "separate ManagedWebspace BI",
|
||||||
Map.ofEntries(
|
Map.ofEntries(
|
||||||
entry("SSD", 50),
|
entry("SSD", 50),
|
||||||
@@ -166,9 +166,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"bookingItem.uuid": "%s",
|
"bookingItem.uuid": "%s",
|
||||||
"type": "MANAGED_WEBSPACE",
|
"type": "MANAGED_WEBSPACE",
|
||||||
@@ -178,13 +178,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"config": {}
|
"config": {}
|
||||||
}
|
}
|
||||||
""".formatted(givenBookingItem.getUuid(), givenParentAsset.getUuid()))
|
""".formatted(givenBookingItem.getUuid(), givenParentAsset.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/hosting/assets")
|
.post("http://localhost/api/hs/hosting/assets")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"type": "MANAGED_WEBSPACE",
|
"type": "MANAGED_WEBSPACE",
|
||||||
"identifier": "fir10",
|
"identifier": "fir10",
|
||||||
@@ -194,9 +194,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
.replace("{lastUnixUserId}", expectedUnixUserId.toString())
|
.replace("{lastUnixUserId}", expectedUnixUserId.toString())
|
||||||
))
|
))
|
||||||
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
// the new asset can be accessed under the generated UUID
|
// the new asset can be accessed under the generated UUID
|
||||||
@@ -206,7 +206,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
toCleanup(HsHostingAssetRbacEntity.class, newWebspaceUuid);
|
toCleanup(HsHostingAssetRbacEntity.class, newWebspaceUuid);
|
||||||
|
|
||||||
// and a default user got created
|
// and a default user got created
|
||||||
final var webspaceUnixUser = em.createQuery("SELECT ha FROM HsHostingAssetRealEntity ha WHERE ha.parentAsset.uuid=:webspaceUUID")
|
final var webspaceUnixUser = em.createQuery(
|
||||||
|
"SELECT ha FROM HsHostingAssetRealEntity ha WHERE ha.parentAsset.uuid=:webspaceUUID")
|
||||||
.setParameter("webspaceUUID", newWebspaceUuid)
|
.setParameter("webspaceUUID", newWebspaceUuid)
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
assertThat(webspaceUnixUser).isNotNull().extracting(Object::toString)
|
assertThat(webspaceUnixUser).isNotNull().extracting(Object::toString)
|
||||||
@@ -227,10 +228,10 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", "hs_hosting.asset#vm1011:ADMIN")
|
.header("assumed-roles", "hs_hosting.asset#vm1011:ADMIN")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"parentAsset.uuid": "%s",
|
"parentAsset.uuid": "%s",
|
||||||
"type": "UNIX_USER",
|
"type": "UNIX_USER",
|
||||||
@@ -239,13 +240,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"config": {}
|
"config": {}
|
||||||
}
|
}
|
||||||
""".formatted(givenParentAsset.getUuid()))
|
""".formatted(givenParentAsset.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/hosting/assets")
|
.post("http://localhost/api/hs/hosting/assets")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(201)
|
.statusCode(201)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"type": "UNIX_USER",
|
"type": "UNIX_USER",
|
||||||
"identifier": "fir01-temp",
|
"identifier": "fir01-temp",
|
||||||
@@ -253,7 +254,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"config": {}
|
"config": {}
|
||||||
}
|
}
|
||||||
"""))
|
"""))
|
||||||
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
||||||
.extract().header("Location"); // @formatter:on
|
.extract().header("Location"); // @formatter:on
|
||||||
|
|
||||||
// finally, the new asset can be accessed under the generated UUID
|
// finally, the new asset can be accessed under the generated UUID
|
||||||
@@ -270,18 +271,18 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
final var givenProject = realProjectRepo.findByCaption("D-1000111 default project").stream()
|
final var givenProject = realProjectRepo.findByCaption("D-1000111 default project").stream()
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
final var bookingItem = givenSomeTemporaryBookingItem(() ->
|
final var bookingItem = givenSomeTemporaryBookingItem(() ->
|
||||||
HsBookingItemRealEntity.builder()
|
HsBookingItemRealEntity.builder()
|
||||||
.project(givenProject)
|
.project(givenProject)
|
||||||
.type(HsBookingItemType.DOMAIN_SETUP)
|
.type(HsBookingItemType.DOMAIN_SETUP)
|
||||||
.caption("some temp domain setup booking item")
|
.caption("some temp domain setup booking item")
|
||||||
.resources(Map.ofEntries(
|
.resources(Map.ofEntries(
|
||||||
entry("domainName", "example.com")))
|
entry("domainName", "example.com")))
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -327,9 +328,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"bookingItem.uuid": "%s",
|
"bookingItem.uuid": "%s",
|
||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
@@ -338,13 +339,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"config": { "monit_max_ssd_usage": 0, "monit_max_cpu_usage": 101, "extra": 42 }
|
"config": { "monit_max_ssd_usage": 0, "monit_max_cpu_usage": 101, "extra": 42 }
|
||||||
}
|
}
|
||||||
""".formatted(givenBookingItem.getUuid()))
|
""".formatted(givenBookingItem.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/hosting/assets")
|
.post("http://localhost/api/hs/hosting/assets")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(400)
|
.statusCode(400)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"statusPhrase": "Bad Request",
|
"statusPhrase": "Bad Request",
|
||||||
"message": "ERROR: [400] [
|
"message": "ERROR: [400] [
|
||||||
@@ -364,12 +365,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
assertThat(givenHostingAsset.getBookingItem().getResources().get("Multi"))
|
assertThat(givenHostingAsset.getBookingItem().getResources().get("Multi"))
|
||||||
.as("precondition failed")
|
.as("precondition failed")
|
||||||
.isEqualTo(1);
|
.isEqualTo(1);
|
||||||
final var preExistingUnixUserCount = realAssetRepo.findAllByCriteria(null, givenHostingAsset.getUuid(), UNIX_USER).size();
|
final var preExistingUnixUserCount = realAssetRepo.findAllByCriteria(null, givenHostingAsset.getUuid(), UNIX_USER)
|
||||||
|
.size();
|
||||||
final var UNIX_USER_PER_MULTI_OPTION = 25;
|
final var UNIX_USER_PER_MULTI_OPTION = 25;
|
||||||
|
|
||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION-preExistingUnixUserCount; ++n) {
|
for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION - preExistingUnixUserCount; ++n) {
|
||||||
toCleanup(realAssetRepo.save(
|
toCleanup(realAssetRepo.save(
|
||||||
HsHostingAssetRealEntity.builder()
|
HsHostingAssetRealEntity.builder()
|
||||||
.type(UNIX_USER)
|
.type(UNIX_USER)
|
||||||
@@ -382,9 +384,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"parentAsset.uuid": "%s",
|
"parentAsset.uuid": "%s",
|
||||||
"type": "UNIX_USER",
|
"type": "UNIX_USER",
|
||||||
@@ -393,13 +395,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"config": { }
|
"config": { }
|
||||||
}
|
}
|
||||||
""".formatted(givenHostingAsset.getUuid()))
|
""".formatted(givenHostingAsset.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.post("http://localhost/api/hs/hosting/assets")
|
.post("http://localhost/api/hs/hosting/assets")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(400)
|
.statusCode(400)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"statusPhrase": "Bad Request",
|
"statusPhrase": "Bad Request",
|
||||||
"message": "ERROR: [400] ['D-1000111:D-1000111 default project:separate ManagedWebspace.resources.Multi=1 allows at maximum 25 unix users, but 26 found]"
|
"message": "ERROR: [400] ['D-1000111:D-1000111 default project:separate ManagedWebspace.resources.Multi=1 allows at maximum 25 unix users, but 26 found]"
|
||||||
@@ -420,12 +422,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/hosting/assets/" + givenAssetUuid)
|
.get("http://localhost/api/hs/hosting/assets/" + givenAssetUuid)
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
@@ -445,12 +447,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/hosting/assets/" + givenAssetUuid)
|
.get("http://localhost/api/hs/hosting/assets/" + givenAssetUuid)
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(404); // @formatter:on
|
.statusCode(404); // @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,13 +464,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer person-TuckerJack@example.com")
|
.header("Authorization", bearer("person-TuckerJack@example.com"))
|
||||||
.header("assumed-roles", "hs_booking.project#D-1000313-D-1000313defaultproject:AGENT")
|
.header("assumed-roles", "hs_booking.project#D-1000313-D-1000313defaultproject:AGENT")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/hosting/assets/" + givenAssetUuid)
|
.get("http://localhost/api/hs/hosting/assets/" + givenAssetUuid)
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
@@ -507,8 +509,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
final var alarmContactUuid = givenContact().getUuid();
|
final var alarmContactUuid = givenContact().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -521,9 +523,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}
|
}
|
||||||
""".formatted(alarmContactUuid))
|
""".formatted(alarmContactUuid))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
.patch("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
@@ -545,7 +547,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""));
|
"""));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
// finally, the asset is actually updated
|
// finally, the asset is actually updated
|
||||||
em.clear();
|
em.clear();
|
||||||
@@ -556,13 +558,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.isEqualTo("contact-admin@secondcontact.example.com");
|
.isEqualTo("contact-admin@secondcontact.example.com");
|
||||||
assertThat(asset.getConfig().toString())
|
assertThat(asset.getConfig().toString())
|
||||||
.isEqualToIgnoringWhitespace("""
|
.isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
"monit_max_cpu_usage": 90,
|
"monit_max_cpu_usage": 90,
|
||||||
"monit_max_ram_usage": 70,
|
"monit_max_ram_usage": 70,
|
||||||
"monit_max_ssd_usage": 85,
|
"monit_max_ssd_usage": 85,
|
||||||
"monit_min_free_ssd": 5
|
"monit_min_free_ssd": 5
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -581,10 +583,10 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
//.header("assumed-roles", "hs_hosting.asset#vm2001:ADMIN")
|
//.header("assumed-roles", "hs_hosting.asset#vm2001:ADMIN")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"caption" : "some patched test-unix-user",
|
"caption" : "some patched test-unix-user",
|
||||||
"config": {
|
"config": {
|
||||||
@@ -594,13 +596,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
.patch("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"type": "UNIX_USER",
|
"type": "UNIX_USER",
|
||||||
"identifier": "fir01-temp",
|
"identifier": "fir01-temp",
|
||||||
@@ -628,12 +630,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.matches(asset -> {
|
.matches(asset -> {
|
||||||
assertThat(asset.getCaption()).isEqualTo("some patched test-unix-user");
|
assertThat(asset.getCaption()).isEqualTo("some patched test-unix-user");
|
||||||
assertThat(asset.getConfig().toString()).isEqualToIgnoringWhitespace("""
|
assertThat(asset.getConfig().toString()).isEqualToIgnoringWhitespace("""
|
||||||
{
|
{
|
||||||
"password": "$6$Jr5w/Y8zo8pCkqg7$/rePRbvey3R6Sz/02YTlTQcRt5qdBPTj2h5.hz.rB8NfIoND8pFOjeB7orYcPs9JNf3JDxPP2V.6MQlE5BwAY/",
|
"password": "$6$Jr5w/Y8zo8pCkqg7$/rePRbvey3R6Sz/02YTlTQcRt5qdBPTj2h5.hz.rB8NfIoND8pFOjeB7orYcPs9JNf3JDxPP2V.6MQlE5BwAY/",
|
||||||
"shell": "/bin/bash",
|
"shell": "/bin/bash",
|
||||||
"totpKey": "0x1234567890abcdef0123456789abcdef"
|
"totpKey": "0x1234567890abcdef0123456789abcdef"
|
||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -663,12 +665,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
))
|
))
|
||||||
.build());
|
.build());
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
.delete("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
||||||
.then().log().body().assertThat()
|
.then().log().body().assertThat()
|
||||||
.statusCode(204); // @formatter:on
|
.statusCode(204); // @formatter:on
|
||||||
|
|
||||||
// then the given assets is gone
|
// then the given assets is gone
|
||||||
@@ -695,12 +697,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
))
|
))
|
||||||
.build());
|
.build());
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
.delete("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(404); // @formatter:on
|
.statusCode(404); // @formatter:on
|
||||||
|
|
||||||
// then the given asset is still there
|
// then the given asset is still there
|
||||||
@@ -739,7 +741,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var project = realProjectRepo.findByCaption(projectCaption).getFirst();
|
final var project = realProjectRepo.findByCaption(projectCaption).getFirst();
|
||||||
final var resources = switch (bookingItemType) {
|
final var resources = switch (bookingItemType) {
|
||||||
case MANAGED_SERVER -> Map.<String, Object>ofEntries(entry("CPU", 1),
|
case MANAGED_SERVER -> Map.<String, Object>ofEntries(
|
||||||
|
entry("CPU", 1),
|
||||||
entry("RAM", 20),
|
entry("RAM", 20),
|
||||||
entry("SSD", 25),
|
entry("SSD", 25),
|
||||||
entry("Traffic", 250));
|
entry("Traffic", 250));
|
||||||
@@ -783,9 +786,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}).returnedValue();
|
}).returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Integer nextUnixUserId() {
|
private Integer nextUnixUserId() {
|
||||||
final Object result = em.createNativeQuery("SELECT nextval('hs_hosting.asset_unixuser_system_id_seq')", Integer.class)
|
final Object result = em.createNativeQuery("select nextval('hs_hosting.asset_unixuser_system_id_seq')", Integer.class)
|
||||||
.getSingleResult();
|
.getSingleResult();
|
||||||
return (Integer) result + 1;
|
return (Integer) result + 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -7,12 +7,12 @@ import com.fasterxml.jackson.databind.SerializationFeature;
|
|||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
import net.hostsharing.hsadminng.mapper.Array;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
@@ -38,6 +38,7 @@ import java.util.Optional;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY;
|
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY;
|
||||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
|
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY;
|
||||||
@@ -49,13 +50,16 @@ import static org.mockito.ArgumentMatchers.any;
|
|||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
|
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsHostingAssetController.class)
|
@WebMvcTest(HsHostingAssetController.class)
|
||||||
@Import({ StrictMapper.class, JsonObjectMapperConfiguration.class, DisableSecurityConfig.class, MessageTranslator.class })
|
@Import({ StrictMapper.class,
|
||||||
@ActiveProfiles("test")
|
JsonObjectMapperConfiguration.class,
|
||||||
|
MessageTranslator.class,
|
||||||
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
public class HsHostingAssetControllerRestTest {
|
public class HsHostingAssetControllerRestTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -592,7 +596,7 @@ public class HsHostingAssetControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
final var result = mockMvc.perform(MockMvcRequestBuilders
|
final var result = mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/hosting/assets?type="+testCase.name())
|
.get("/api/hs/hosting/assets?type="+testCase.name())
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -662,7 +666,7 @@ public class HsHostingAssetControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
final var result = mockMvc.perform(MockMvcRequestBuilders
|
final var result = mockMvc.perform(MockMvcRequestBuilders
|
||||||
.patch("/api/hs/hosting/assets/" + givenDomainHttpSetupUuid)
|
.patch("/api/hs/hosting/assets/" + givenDomainHttpSetupUuid)
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-6
@@ -2,8 +2,6 @@ package net.hostsharing.hsadminng.hs.hosting.asset;
|
|||||||
|
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
@@ -12,12 +10,11 @@ import org.springframework.test.context.ActiveProfiles;
|
|||||||
|
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
|
|
||||||
|
@Tag("hostingIntegrationTest")
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Tag("hostingIntegrationTest")
|
|
||||||
class HsHostingAssetPropsControllerAcceptanceTest {
|
class HsHostingAssetPropsControllerAcceptanceTest {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ class DomainSetupHostingAssetFactoryUnitTest {
|
|||||||
private EntityManagerWrapper emw = emwFake;
|
private EntityManagerWrapper emw = emwFake;
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper();
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private StrictMapper StrictMapper = new StrictMapper(emw);
|
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@ class HsBookingItemCreatedListenerUnitTest {
|
|||||||
private EntityManagerWrapper emw = emwFake;
|
private EntityManagerWrapper emw = emwFake;
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper();
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private StrictMapper StrictMapper = new StrictMapper(emw);
|
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ class ManagedWebspaceHostingAssetFactoryUnitTest {
|
|||||||
private EntityManagerWrapper emw = emwFake;
|
private EntityManagerWrapper emw = emwFake;
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper().build();
|
private ObjectMapper jsonMapper = new JsonObjectMapperConfiguration().customObjectMapper();
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private StrictMapper StrictMapper = new StrictMapper(emw);
|
private StrictMapper StrictMapper = new StrictMapper(emw);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.migration;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hash.HashGenerator;
|
import net.hostsharing.hsadminng.hash.HashGenerator;
|
||||||
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
|
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
|
||||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||||
|
|||||||
+21
-17
@@ -3,13 +3,17 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
@@ -20,19 +24,19 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
@SpringBootTest(
|
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
|
||||||
)
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Tag("officeIntegrationTest")
|
@Tag("officeIntegrationTest")
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = HsadminNgApplication.class)
|
||||||
|
@ActiveProfiles("fake-jwt")
|
||||||
class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -58,7 +62,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/bankaccounts")
|
.get("http://localhost/api/hs/office/bankaccounts")
|
||||||
@@ -124,7 +128,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -163,7 +167,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/bankaccounts/" + givenBankAccountUuid)
|
.get("http://localhost/api/hs/office/bankaccounts/" + givenBankAccountUuid)
|
||||||
@@ -184,7 +188,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/bankaccounts/" + givenBankAccountUuid)
|
.get("http://localhost/api/hs/office/bankaccounts/" + givenBankAccountUuid)
|
||||||
@@ -200,7 +204,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer bankaccount-admin@firstbankaccount.example.com")
|
.header("Authorization", bearer("bankaccount-admin@firstbankaccount.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/bankaccounts/" + givenBankAccountUuid)
|
.get("http://localhost/api/hs/office/bankaccounts/" + givenBankAccountUuid)
|
||||||
@@ -228,7 +232,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -266,7 +270,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/bankaccounts/" + givenBankAccount.getUuid())
|
.delete("http://localhost/api/hs/office/bankaccounts/" + givenBankAccount.getUuid())
|
||||||
@@ -283,7 +287,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-test-user@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-test-user@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/bankaccounts/" + givenBankAccount.getUuid())
|
.delete("http://localhost/api/hs/office/bankaccounts/" + givenBankAccount.getUuid())
|
||||||
@@ -304,7 +308,7 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/bankaccounts/" + givenBankAccount.getUuid())
|
.delete("http://localhost/api/hs/office/bankaccounts/" + givenBankAccount.getUuid())
|
||||||
|
|||||||
+9
-7
@@ -1,27 +1,29 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsOfficeBankAccountController.class)
|
@WebMvcTest(HsOfficeBankAccountController.class)
|
||||||
@Import({DisableSecurityConfig.class, MessageTranslator.class})
|
@Import({ MessageTranslator.class,
|
||||||
@ActiveProfiles("test")
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
class HsOfficeBankAccountControllerRestTest {
|
class HsOfficeBankAccountControllerRestTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -69,7 +71,7 @@ class HsOfficeBankAccountControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/bankaccounts")
|
.post("/api/hs/office/bankaccounts")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
@@ -116,7 +118,7 @@ class HsOfficeBankAccountControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/bankaccounts")
|
.post("/api/hs/office/bankaccounts")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
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;
|
||||||
|
|||||||
+16
-17
@@ -3,10 +3,9 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
@@ -27,6 +26,7 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -34,13 +34,12 @@ import static org.hamcrest.Matchers.hasEntry;
|
|||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
@SpringBootTest(
|
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
|
||||||
)
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Tag("officeIntegrationTest")
|
@Tag("officeIntegrationTest")
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = HsadminNgApplication.class)
|
||||||
|
@ActiveProfiles("fake-jwt")
|
||||||
class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -69,7 +68,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/contacts")
|
.get("http://localhost/api/hs/office/contacts")
|
||||||
@@ -107,7 +106,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -156,7 +155,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/contacts/" + givenContactUuid)
|
.get("http://localhost/api/hs/office/contacts/" + givenContactUuid)
|
||||||
@@ -177,7 +176,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/contacts/" + givenContactUuid)
|
.get("http://localhost/api/hs/office/contacts/" + givenContactUuid)
|
||||||
@@ -192,7 +191,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer contact-admin@firstcontact.example.com")
|
.header("Authorization", bearer("contact-admin@firstcontact.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/contacts/" + givenContactUuid)
|
.get("http://localhost/api/hs/office/contacts/" + givenContactUuid)
|
||||||
@@ -224,7 +223,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -282,7 +281,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -328,7 +327,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/contacts/" + givenContact.getUuid())
|
.delete("http://localhost/api/hs/office/contacts/" + givenContact.getUuid())
|
||||||
@@ -348,7 +347,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-test-user@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-test-user@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/contacts/" + givenContact.getUuid())
|
.delete("http://localhost/api/hs/office/contacts/" + givenContact.getUuid())
|
||||||
@@ -369,7 +368,7 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/contacts/" + givenContact.getUuid())
|
.delete("http://localhost/api/hs/office/contacts/" + givenContact.getUuid())
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.contact;
|
package net.hostsharing.hsadminng.hs.office.contact;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
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;
|
||||||
|
|||||||
+22
-26
@@ -3,13 +3,10 @@ package net.hostsharing.hsadminng.hs.office.coopassets;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
|
||||||
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -27,6 +24,7 @@ import java.math.BigDecimal;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.DEPOSIT;
|
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.DEPOSIT;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
@@ -34,14 +32,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
@Tag("officeIntegrationTest")
|
||||||
|
@Transactional
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class,
|
classes = HsadminNgApplication.class)
|
||||||
MessagesResourceConfig.class, MessageTranslator.class}
|
@ActiveProfiles("fake-jwt")
|
||||||
)
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
|
||||||
@Tag("officeIntegrationTest")
|
|
||||||
class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -70,14 +66,14 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopassetstransactions")
|
.get("http://localhost/api/hs/office/coopassetstransactions")
|
||||||
.then().log().all().assertThat()
|
.then().log().all().assertThat()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.body("", hasSize(3*6)); // @formatter:on
|
.body("", hasSize(3 * 6)); // @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -88,7 +84,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopassetstransactions?membershipUuid="+givenMembership.getUuid())
|
.get("http://localhost/api/hs/office/coopassetstransactions?membershipUuid="+givenMembership.getUuid())
|
||||||
@@ -211,7 +207,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopassetstransactions?membershipUuid="
|
.get("http://localhost/api/hs/office/coopassetstransactions?membershipUuid="
|
||||||
@@ -244,7 +240,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -290,18 +286,18 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
// TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...)
|
// TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...)
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
return coopAssetsTransactionRepo.save(HsOfficeCoopAssetsTransactionEntity.builder()
|
return coopAssetsTransactionRepo.save(HsOfficeCoopAssetsTransactionEntity.builder()
|
||||||
.transactionType(DEPOSIT)
|
.transactionType(DEPOSIT)
|
||||||
.valueDate(LocalDate.of(2022, 10, 20))
|
.valueDate(LocalDate.of(2022, 10, 20))
|
||||||
.membership(givenMembership)
|
.membership(givenMembership)
|
||||||
.assetValue(new BigDecimal("256.00"))
|
.assetValue(new BigDecimal("256.00"))
|
||||||
.reference("test ref")
|
.reference("test ref")
|
||||||
.build());
|
.build());
|
||||||
}).assertSuccessful().assertNotNull().returnedValue();
|
}).assertSuccessful().assertNotNull().returnedValue();
|
||||||
toCleanup(HsOfficeCoopAssetsTransactionEntity.class, givenTransaction.getUuid());
|
toCleanup(HsOfficeCoopAssetsTransactionEntity.class, givenTransaction.getUuid());
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -357,7 +353,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -398,7 +394,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given().header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.given().header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
|
.get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
|
||||||
@@ -421,7 +417,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given().header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.given().header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
|
.get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
|
||||||
@@ -439,7 +435,7 @@ class HsOfficeCoopAssetsTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer person-FirstGmbH@example.com")
|
.header("Authorization", bearer("person-FirstGmbH@example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
|
.get("http://localhost/api/hs/office/coopassetstransactions/" + givenCoopAssetTransactionUuid)
|
||||||
|
|||||||
+11
-10
@@ -2,15 +2,16 @@ package net.hostsharing.hsadminng.hs.office.coopassets;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
import net.hostsharing.hsadminng.config.JsonObjectMapperConfiguration;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import net.hostsharing.hsadminng.test.TestUuidGenerator;
|
import net.hostsharing.hsadminng.test.TestUuidGenerator;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -37,6 +38,7 @@ import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsT
|
|||||||
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.DISBURSAL;
|
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.DISBURSAL;
|
||||||
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.REVERSAL;
|
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.REVERSAL;
|
||||||
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.TRANSFER;
|
import static net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionType.TRANSFER;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.JsonBuilder.jsonObject;
|
import static net.hostsharing.hsadminng.rbac.test.JsonBuilder.jsonObject;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@@ -54,8 +56,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
MessagesResourceConfig.class,
|
MessagesResourceConfig.class,
|
||||||
MessageTranslator.class,
|
MessageTranslator.class,
|
||||||
JsonObjectMapperConfiguration.class,
|
JsonObjectMapperConfiguration.class,
|
||||||
DisableSecurityConfig.class })
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
class HsOfficeCoopAssetsTransactionControllerRestTest {
|
class HsOfficeCoopAssetsTransactionControllerRestTest {
|
||||||
|
|
||||||
// If you need to run just a single test-case in this data-driven test-method, set SINGLE_TEST_CASE_EXECUTION to true!
|
// If you need to run just a single test-case in this data-driven test-method, set SINGLE_TEST_CASE_EXECUTION to true!
|
||||||
@@ -662,7 +664,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/coopassetstransactions")
|
.post("/api/hs/office/coopassetstransactions")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(testCase.givenRequestBody())
|
.content(testCase.givenRequestBody())
|
||||||
@@ -838,7 +840,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/coopassetstransactions")
|
.post("/api/hs/office/coopassetstransactions")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(testCase.givenRequestBody())
|
.content(testCase.givenRequestBody())
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
@@ -857,7 +859,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/coopassetstransactions/" + SOME_REVERTED_TRANSFER_ASSET_TX_ENTITY.getUuid())
|
.get("/api/hs/office/coopassetstransactions/" + SOME_REVERTED_TRANSFER_ASSET_TX_ENTITY.getUuid())
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -873,7 +875,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/coopassetstransactions/" + UNAVAILABLE_UUID)
|
.get("/api/hs/office/coopassetstransactions/" + UNAVAILABLE_UUID)
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -899,7 +901,7 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/coopassetstransactions")
|
.get("/api/hs/office/coopassetstransactions")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -950,5 +952,4 @@ class HsOfficeCoopAssetsTransactionControllerRestTest {
|
|||||||
private String suffixOf(final String memberNumber) {
|
private String suffixOf(final String memberNumber) {
|
||||||
return memberNumber.substring("M-".length() + 5);
|
return memberNumber.substring("M-".length() + 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopassets;
|
package net.hostsharing.hsadminng.hs.office.coopassets;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||||
|
|||||||
+34
-26
@@ -3,12 +3,10 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -22,21 +20,22 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
|
||||||
classes = {HsadminNgApplication.class, DisableSecurityConfig.class, MessageTranslator.class, JpaAttempt.class})
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Tag("officeIntegrationTest")
|
@Tag("officeIntegrationTest")
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = HsadminNgApplication.class)
|
||||||
|
@ActiveProfiles("fake-jwt")
|
||||||
class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -76,7 +75,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopsharestransactions")
|
.get("http://localhost/api/hs/office/coopsharestransactions")
|
||||||
@@ -94,7 +93,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopsharestransactions?membershipUuid=" + givenMembership.getUuid())
|
.get("http://localhost/api/hs/office/coopsharestransactions?membershipUuid=" + givenMembership.getUuid())
|
||||||
@@ -158,7 +157,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopsharestransactions?membershipUuid=" + givenMembership.getUuid() + "&fromValueDate=2020-01-01&toValueDate=2021-12-31")
|
.get("http://localhost/api/hs/office/coopsharestransactions?membershipUuid=" + givenMembership.getUuid() + "&fromValueDate=2020-01-01&toValueDate=2021-12-31")
|
||||||
@@ -191,7 +190,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON).body("""
|
.contentType(ContentType.JSON).body("""
|
||||||
{
|
{
|
||||||
@@ -240,18 +239,18 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
// TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...)
|
// TODO.impl: introduce something like transactedAsSuperuser / transactedAs("...", ...)
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
return coopSharesTransactionRepo.save(HsOfficeCoopSharesTransactionEntity.builder()
|
return coopSharesTransactionRepo.save(HsOfficeCoopSharesTransactionEntity.builder()
|
||||||
.transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION)
|
.transactionType(HsOfficeCoopSharesTransactionType.SUBSCRIPTION)
|
||||||
.valueDate(LocalDate.of(2022, 10, 20))
|
.valueDate(LocalDate.of(2022, 10, 20))
|
||||||
.membership(givenMembership)
|
.membership(givenMembership)
|
||||||
.shareCount(13)
|
.shareCount(13)
|
||||||
.reference("test ref")
|
.reference("test ref")
|
||||||
.build());
|
.build());
|
||||||
}).assertSuccessful().assertNotNull().returnedValue();
|
}).assertSuccessful().assertNotNull().returnedValue();
|
||||||
toCleanup(HsOfficeCoopSharesTransactionEntity.class, givenTransaction.getUuid());
|
toCleanup(HsOfficeCoopSharesTransactionEntity.class, givenTransaction.getUuid());
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -294,7 +293,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
// finally, the new coopAssetsTransaction can be accessed under the generated UUID
|
// finally, the new coopAssetsTransaction can be accessed under the generated UUID
|
||||||
final var newShareTxUuid = UUID.fromString(
|
final var newShareTxUuid = UUID.fromString(
|
||||||
location.substring(location.lastIndexOf('/') + 1));
|
location.substring(location.lastIndexOf('/') + 1));
|
||||||
assertThat(newShareTxUuid).isNotNull();
|
assertThat(newShareTxUuid).isNotNull();
|
||||||
toCleanup(HsOfficeCoopSharesTransactionEntity.class, newShareTxUuid);
|
toCleanup(HsOfficeCoopSharesTransactionEntity.class, newShareTxUuid);
|
||||||
}
|
}
|
||||||
@@ -307,7 +306,7 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -344,11 +343,14 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
@Test
|
@Test
|
||||||
void globalAdmin_withoutAssumedRole_canGetArbitraryCoopShareTransaction() {
|
void globalAdmin_withoutAssumedRole_canGetArbitraryCoopShareTransaction() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenCoopShareTransactionUuid = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(null, LocalDate.of(2010, 3, 15), LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
final var givenCoopShareTransactionUuid = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
||||||
|
null,
|
||||||
|
LocalDate.of(2010, 3, 15),
|
||||||
|
LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopsharestransactions/" + givenCoopShareTransactionUuid)
|
.get("http://localhost/api/hs/office/coopsharestransactions/" + givenCoopShareTransactionUuid)
|
||||||
@@ -366,11 +368,14 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
@Test
|
@Test
|
||||||
void normalUser_canNotGetUnrelatedCoopShareTransaction() {
|
void normalUser_canNotGetUnrelatedCoopShareTransaction() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenCoopShareTransactionUuid = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(null, LocalDate.of(2010, 3, 15), LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
final var givenCoopShareTransactionUuid = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
||||||
|
null,
|
||||||
|
LocalDate.of(2010, 3, 15),
|
||||||
|
LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.get("http://localhost/api/hs/office/coopsharestransactions/" + givenCoopShareTransactionUuid)
|
.get("http://localhost/api/hs/office/coopsharestransactions/" + givenCoopShareTransactionUuid)
|
||||||
.then().log().body()
|
.then().log().body()
|
||||||
@@ -381,11 +386,14 @@ class HsOfficeCoopSharesTransactionControllerAcceptanceTest extends ContextBased
|
|||||||
@Test
|
@Test
|
||||||
void partnerPersonUser_canGetRelatedCoopShareTransaction() {
|
void partnerPersonUser_canGetRelatedCoopShareTransaction() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenCoopShareTransactionUuid = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(null, LocalDate.of(2010, 3, 15), LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
final var givenCoopShareTransactionUuid = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
||||||
|
null,
|
||||||
|
LocalDate.of(2010, 3, 15),
|
||||||
|
LocalDate.of(2010, 3, 15)).get(0).getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer person-FirstGmbH@example.com")
|
.header("Authorization", bearer("person-FirstGmbH@example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/coopsharestransactions/" + givenCoopShareTransactionUuid)
|
.get("http://localhost/api/hs/office/coopsharestransactions/" + givenCoopShareTransactionUuid)
|
||||||
|
|||||||
+9
-8
@@ -2,11 +2,12 @@ package net.hostsharing.hsadminng.hs.office.coopshares;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
import net.hostsharing.hsadminng.rbac.test.JsonBuilder;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -21,6 +22,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.JsonBuilder.jsonObject;
|
import static net.hostsharing.hsadminng.rbac.test.JsonBuilder.jsonObject;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
@@ -28,10 +30,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsOfficeCoopSharesTransactionController.class)
|
@WebMvcTest(HsOfficeCoopSharesTransactionController.class)
|
||||||
@Import({DisableSecurityConfig.class,
|
@Import({ MessagesResourceConfig.class,
|
||||||
MessagesResourceConfig.class,
|
MessageTranslator.class,
|
||||||
MessageTranslator.class})
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
class HsOfficeCoopSharesTransactionControllerRestTest {
|
class HsOfficeCoopSharesTransactionControllerRestTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -126,7 +128,7 @@ class HsOfficeCoopSharesTransactionControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/coopsharestransactions")
|
.post("/api/hs/office/coopsharestransactions")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content(testCase.givenRequestBody())
|
.content(testCase.givenRequestBody())
|
||||||
@@ -138,5 +140,4 @@ class HsOfficeCoopSharesTransactionControllerRestTest {
|
|||||||
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
|
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
|
||||||
.andExpect(jsonPath("message", containsString(testCase.expectedErrorMessage)));
|
.andExpect(jsonPath("message", containsString(testCase.expectedErrorMessage)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.coopshares;
|
package net.hostsharing.hsadminng.hs.office.coopshares;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
import net.hostsharing.hsadminng.rbac.grant.RawRbacGrantRepository;
|
||||||
|
|||||||
+21
-22
@@ -3,16 +3,15 @@ package net.hostsharing.hsadminng.hs.office.debitor;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||||
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -28,6 +27,7 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||||
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
|
import static net.hostsharing.hsadminng.rbac.role.RbacRoleType.ADMIN;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
@@ -38,13 +38,12 @@ import static org.hamcrest.Matchers.equalTo;
|
|||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
@Tag("officeIntegrationTest")
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles({ "fake-jwt"})
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Tag("officeIntegrationTest")
|
|
||||||
class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
private static final int LOWEST_TEMP_DEBITOR_SUFFIX = 90;
|
private static final int LOWEST_TEMP_DEBITOR_SUFFIX = 90;
|
||||||
@@ -93,7 +92,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
.get("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
||||||
@@ -120,7 +119,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors/D-1000212")
|
.get("http://localhost/api/hs/office/debitors/D-1000212")
|
||||||
@@ -151,7 +150,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors")
|
.get("http://localhost/api/hs/office/debitors")
|
||||||
@@ -306,7 +305,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors?partnerNumber=P-10002")
|
.get("http://localhost/api/hs/office/debitors?partnerNumber=P-10002")
|
||||||
@@ -351,7 +350,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -396,7 +395,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -447,7 +446,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -482,7 +481,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -513,7 +512,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
|
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
|
||||||
@@ -578,7 +577,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
|
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
|
||||||
@@ -593,7 +592,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer contact-admin@firstcontact.example.com")
|
.header("Authorization", bearer("contact-admin@firstcontact.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
|
.get("http://localhost/api/hs/office/debitors/" + givenDebitorUuid)
|
||||||
@@ -623,7 +622,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -705,7 +704,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
// @formatter:on
|
// @formatter:on
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", givenDebitor.getDebitorRel().getContact().roleId(ADMIN) )
|
.header("assumed-roles", givenDebitor.getDebitorRel().getContact().roleId(ADMIN) )
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -734,7 +733,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
||||||
@@ -753,7 +752,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer contact-admin@tenthcontact.example.com")
|
.header("Authorization", bearer("contact-admin@tenthcontact.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
||||||
@@ -772,7 +771,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
.delete("http://localhost/api/hs/office/debitors/" + givenDebitor.getUuid())
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.debitor;
|
package net.hostsharing.hsadminng.hs.office.debitor;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
|
|||||||
+21
-20
@@ -4,11 +4,10 @@ import io.hypersistence.utils.hibernate.type.range.Range;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -25,20 +24,22 @@ import jakarta.persistence.PersistenceContext;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus.ACTIVE;
|
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus.ACTIVE;
|
||||||
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus.CANCELLED;
|
import static net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipStatus.CANCELLED;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
@Tag("officeIntegrationTest")
|
||||||
|
@Transactional
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
|
||||||
@Tag("officeIntegrationTest")
|
|
||||||
class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
private static final String TEMP_MEMBER_NUMBER_SUFFIX = "90";
|
private static final String TEMP_MEMBER_NUMBER_SUFFIX = "90";
|
||||||
@@ -72,7 +73,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/memberships")
|
.get("http://localhost/api/hs/office/memberships")
|
||||||
@@ -118,7 +119,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.queryParam("partnerUuid", partner.getUuid() )
|
.queryParam("partnerUuid", partner.getUuid() )
|
||||||
@@ -146,7 +147,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.queryParam("partnerNumber", "P-10002" )
|
.queryParam("partnerNumber", "P-10002" )
|
||||||
@@ -183,7 +184,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -226,7 +227,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
||||||
@@ -252,7 +253,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
.get("http://localhost/api/hs/office/memberships/" + givenMembershipUuid)
|
||||||
@@ -267,7 +268,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", "hs_office.relation#HostsharingeG-with-PARTNER-ThirdOHG:AGENT")
|
.header("assumed-roles", "hs_office.relation#HostsharingeG-with-PARTNER-ThirdOHG:AGENT")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
@@ -299,7 +300,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -343,7 +344,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
// when
|
// when
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", givenPartnerAdmin)
|
.header("assumed-roles", givenPartnerAdmin)
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
@@ -378,7 +379,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())
|
.delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())
|
||||||
@@ -396,7 +397,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("assumed-roles", "hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT")
|
.header("assumed-roles", "hs_office.relation#HostsharingeG-with-PARTNER-FirstGmbH:AGENT")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
@@ -415,7 +416,7 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())
|
.delete("http://localhost/api/hs/office/memberships/" + givenMembership.getUuid())
|
||||||
|
|||||||
+16
-14
@@ -3,14 +3,15 @@ package net.hostsharing.hsadminng.hs.office.membership;
|
|||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
|
import net.hostsharing.hsadminng.hs.office.coopassets.HsOfficeCoopAssetsTransactionRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRbacEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
@@ -30,6 +31,7 @@ import java.util.Optional;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static io.hypersistence.utils.hibernate.type.range.Range.localDateRange;
|
import static io.hypersistence.utils.hibernate.type.range.Range.localDateRange;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
@@ -42,8 +44,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@WebMvcTest(HsOfficeMembershipController.class)
|
@WebMvcTest(HsOfficeMembershipController.class)
|
||||||
@Import({ StrictMapper.class, DisableSecurityConfig.class, MessagesResourceConfig.class, MessageTranslator.class})
|
@Import({ StrictMapper.class, MessagesResourceConfig.class, MessageTranslator.class,
|
||||||
@ActiveProfiles("test")
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
public class HsOfficeMembershipControllerRestTest {
|
public class HsOfficeMembershipControllerRestTest {
|
||||||
|
|
||||||
private static final HsOfficePartnerRealEntity PARTNER_12345 = HsOfficePartnerRealEntity.builder()
|
private static final HsOfficePartnerRealEntity PARTNER_12345 = HsOfficePartnerRealEntity.builder()
|
||||||
@@ -112,7 +115,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/memberships?partnerNumber=P-12345")
|
.get("/api/hs/office/memberships?partnerNumber=P-12345")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -134,7 +137,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/memberships?partnerNumber=P-12345")
|
.get("/api/hs/office/memberships?partnerNumber=P-12345")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
@@ -199,7 +202,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/memberships/" + givenUuid)
|
.get("/api/hs/office/memberships/" + givenUuid)
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -218,7 +221,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/memberships/" + UUID.randomUUID())
|
.get("/api/hs/office/memberships/" + UUID.randomUUID())
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -236,7 +239,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/memberships/M-1234501")
|
.get("/api/hs/office/memberships/M-1234501")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -255,7 +258,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/memberships/M-0000000")
|
.get("/api/hs/office/memberships/M-0000000")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -273,7 +276,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/memberships")
|
.post("/api/hs/office/memberships")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
@@ -303,7 +306,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/memberships")
|
.post("/api/hs/office/memberships")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
@@ -331,7 +334,7 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/memberships")
|
.post("/api/hs/office/memberships")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
@@ -366,5 +369,4 @@ public class HsOfficeMembershipControllerRestTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.membership;
|
package net.hostsharing.hsadminng.hs.office.membership;
|
||||||
|
|
||||||
import io.hypersistence.utils.hibernate.type.range.Range;
|
import io.hypersistence.utils.hibernate.type.range.Range;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRealRepository;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
import net.hostsharing.hsadminng.mapper.Array;
|
||||||
|
|||||||
+54
-27
@@ -13,8 +13,10 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealReposito
|
|||||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
@@ -23,18 +25,20 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
|
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.EX_PARTNER;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
|
||||||
|
@Tag("officeIntegrationTest")
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Tag("officeIntegrationTest")
|
|
||||||
class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
private static final UUID GIVEN_NON_EXISTING_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
private static final UUID GIVEN_NON_EXISTING_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
||||||
@@ -66,7 +70,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/partners")
|
.get("http://localhost/api/hs/office/partners")
|
||||||
@@ -94,13 +98,19 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
void globalAdmin_withoutAssumedRole_canPostNewPartner() {
|
void globalAdmin_withoutAssumedRole_canPostNewPartner() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenMandantPerson = personRealRepo.findPersonByOptionalNameLike("Hostsharing eG").stream().findFirst().orElseThrow();
|
final var givenMandantPerson = personRealRepo.findPersonByOptionalNameLike("Hostsharing eG")
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
final var givenPerson = personRealRepo.findPersonByOptionalNameLike("Winkler").stream().findFirst().orElseThrow();
|
final var givenPerson = personRealRepo.findPersonByOptionalNameLike("Winkler").stream().findFirst().orElseThrow();
|
||||||
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("fourth").stream().findFirst().orElseThrow();
|
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike("fourth")
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -159,7 +169,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -195,7 +205,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -238,7 +248,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/partners/" + givenPartnerUuid)
|
.get("http://localhost/api/hs/office/partners/" + givenPartnerUuid)
|
||||||
@@ -270,7 +280,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/partners/" + givenPartnerUuid)
|
.get("http://localhost/api/hs/office/partners/" + givenPartnerUuid)
|
||||||
@@ -285,7 +295,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer contact-admin@firstcontact.example.com")
|
.header("Authorization", bearer("contact-admin@firstcontact.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/partners/" + givenPartnerUuid)
|
.get("http://localhost/api/hs/office/partners/" + givenPartnerUuid)
|
||||||
@@ -316,7 +326,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -384,7 +394,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -411,7 +421,12 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
// and an ex-partner-relation got created
|
// and an ex-partner-relation got created
|
||||||
final var newPartnerPersonUuid = givenPartner.getPartnerRel().getHolder().getUuid();
|
final var newPartnerPersonUuid = givenPartner.getPartnerRel().getHolder().getUuid();
|
||||||
assertThat(relationRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(newPartnerPersonUuid, EX_PARTNER, null, null, null))
|
assertThat(relationRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
|
||||||
|
newPartnerPersonUuid,
|
||||||
|
EX_PARTNER,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null))
|
||||||
.map(HsOfficeRelation::toShortString)
|
.map(HsOfficeRelation::toShortString)
|
||||||
.contains("rel(anchor='NP Winkler, Paul', type=EX_PARTNER, holder='UF Erben Bessler')");
|
.contains("rel(anchor='NP Winkler, Paul', type=EX_PARTNER, holder='UF Erben Bessler')");
|
||||||
}
|
}
|
||||||
@@ -424,7 +439,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -449,7 +464,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
// finally, the partner details and only the partner details are actually updated
|
// finally, the partner details and only the partner details are actually updated
|
||||||
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get()
|
assertThat(partnerRepo.findByUuid(givenPartner.getUuid())).isPresent().get()
|
||||||
.matches(partner -> {
|
.matches(partner -> {
|
||||||
assertThat(partner.getPartnerRel().getContact().getCaption()).isEqualTo(givenPartner.getPartnerRel().getContact().getCaption());
|
assertThat(partner.getPartnerRel().getContact().getCaption()).isEqualTo(givenPartner.getPartnerRel()
|
||||||
|
.getContact()
|
||||||
|
.getCaption());
|
||||||
assertThat(partner.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Leer");
|
assertThat(partner.getDetails().getRegistrationOffice()).isEqualTo("Temp Registergericht Leer");
|
||||||
assertThat(partner.getDetails().getRegistrationNumber()).isEqualTo("333333");
|
assertThat(partner.getDetails().getRegistrationNumber()).isEqualTo("333333");
|
||||||
assertThat(partner.getDetails().getBirthName()).isEqualTo("Maja Schmidt");
|
assertThat(partner.getDetails().getBirthName()).isEqualTo("Maja Schmidt");
|
||||||
@@ -472,7 +489,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
.delete("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
||||||
@@ -492,7 +509,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer contact-admin@fourthcontact.example.com")
|
.header("Authorization", bearer("contact-admin@fourthcontact.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
.delete("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
||||||
@@ -511,7 +528,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
.delete("http://localhost/api/hs/office/partners/" + givenPartner.getUuid())
|
||||||
@@ -528,9 +545,18 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
final String contactName) {
|
final String contactName) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenMandantPerson = personRealRepo.findPersonByOptionalNameLike("Hostsharing eG").stream().findFirst().orElseThrow();
|
final var givenMandantPerson = personRealRepo.findPersonByOptionalNameLike("Hostsharing eG")
|
||||||
final var givenPerson = personRealRepo.findPersonByOptionalNameLike(partnerHolderName).stream().findFirst().orElseThrow();
|
.stream()
|
||||||
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike(contactName).stream().findFirst().orElseThrow();
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
final var givenPerson = personRealRepo.findPersonByOptionalNameLike(partnerHolderName)
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
final var givenContact = contactRealRepo.findContactByOptionalCaptionLike(contactName)
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
final var partnerRel = new HsOfficeRelationRealEntity();
|
final var partnerRel = new HsOfficeRelationRealEntity();
|
||||||
partnerRel.setType(HsOfficeRelationType.PARTNER);
|
partnerRel.setType(HsOfficeRelationType.PARTNER);
|
||||||
@@ -541,6 +567,7 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
return partnerRel;
|
return partnerRel;
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HsOfficePartnerRbacEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
private HsOfficePartnerRbacEntity givenSomeTemporaryPartnerBessler(final Integer partnerNumber) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
|
|||||||
+11
-9
@@ -1,8 +1,8 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
import net.hostsharing.hsadminng.config.WebSecurityConfigForWebMvcTests;
|
||||||
import net.hostsharing.hsadminng.config.MessageTranslator;
|
import net.hostsharing.hsadminng.config.MessageTranslator;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactFromResourceConverter;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactFromResourceConverter;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
@@ -11,6 +11,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealReposito
|
|||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
import net.hostsharing.hsadminng.config.MessagesResourceConfig;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -32,6 +33,7 @@ import java.util.Map;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
@@ -46,8 +48,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
MessagesResourceConfig.class,
|
MessagesResourceConfig.class,
|
||||||
MessageTranslator.class,
|
MessageTranslator.class,
|
||||||
HsOfficeContactFromResourceConverter.class,
|
HsOfficeContactFromResourceConverter.class,
|
||||||
DisableSecurityConfig.class })
|
WebSecurityConfigForWebMvcTests.class })
|
||||||
@ActiveProfiles("test")
|
@ActiveProfiles({"fake-jwt", "test"})
|
||||||
class HsOfficePartnerControllerRestTest {
|
class HsOfficePartnerControllerRestTest {
|
||||||
|
|
||||||
static final UUID GIVEN_MANDANTE_UUID = UUID.randomUUID();
|
static final UUID GIVEN_MANDANTE_UUID = UUID.randomUUID();
|
||||||
@@ -112,7 +114,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/partners")
|
.post("/api/hs/office/partners")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.header("Accept-Language", "de")
|
.header("Accept-Language", "de")
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
@@ -147,7 +149,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.post("/api/hs/office/partners")
|
.post("/api/hs/office/partners")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.content("""
|
.content("""
|
||||||
{
|
{
|
||||||
@@ -190,7 +192,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/partners/P-12345")
|
.get("/api/hs/office/partners/P-12345")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
@@ -207,7 +209,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.get("/api/hs/office/partners/P-12345")
|
.get("/api/hs/office/partners/P-12345")
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
@@ -235,7 +237,7 @@ class HsOfficePartnerControllerRestTest {
|
|||||||
// when
|
// when
|
||||||
mockMvc.perform(MockMvcRequestBuilders
|
mockMvc.perform(MockMvcRequestBuilders
|
||||||
.delete("/api/hs/office/partners/" + givenPartnerUuid)
|
.delete("/api/hs/office/partners/" + givenPartnerUuid)
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(MediaType.APPLICATION_JSON)
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
.accept(MediaType.APPLICATION_JSON))
|
.accept(MediaType.APPLICATION_JSON))
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.partner;
|
package net.hostsharing.hsadminng.hs.office.partner;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.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.hs.office.relation.HsOfficeRelationRealEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||||
|
|||||||
+18
-17
@@ -3,10 +3,9 @@ package net.hostsharing.hsadminng.hs.office.person;
|
|||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -22,17 +21,19 @@ import jakarta.persistence.EntityManager;
|
|||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
@Tag("officeIntegrationTest")
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Tag("officeIntegrationTest")
|
|
||||||
class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -61,7 +62,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/persons")
|
.get("http://localhost/api/hs/office/persons")
|
||||||
@@ -81,7 +82,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -119,7 +120,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/persons/" + givenPersonUuid)
|
.get("http://localhost/api/hs/office/persons/" + givenPersonUuid)
|
||||||
@@ -142,7 +143,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/persons/" + givenPersonUuid)
|
.get("http://localhost/api/hs/office/persons/" + givenPersonUuid)
|
||||||
@@ -159,7 +160,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer person-ErbenBesslerMelBessler@example.com")
|
.header("Authorization", bearer("person-ErbenBesslerMelBessler@example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/persons/" + givenPersonUuid)
|
.get("http://localhost/api/hs/office/persons/" + givenPersonUuid)
|
||||||
@@ -188,7 +189,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -230,7 +231,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -274,7 +275,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid())
|
.delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid())
|
||||||
@@ -293,7 +294,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-test-user@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-test-user@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid())
|
.delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid())
|
||||||
@@ -313,7 +314,7 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid())
|
.delete("http://localhost/api/hs/office/persons/" + givenPerson.getUuid())
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.person;
|
package net.hostsharing.hsadminng.hs.office.person;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
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;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.person;
|
package net.hostsharing.hsadminng.hs.office.person;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
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;
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relation;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.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.HsOfficePersonRealEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
|
|||||||
+26
-26
@@ -2,14 +2,13 @@ package net.hostsharing.hsadminng.hs.office.relation;
|
|||||||
|
|
||||||
import io.restassured.RestAssured;
|
import io.restassured.RestAssured;
|
||||||
import io.restassured.http.ContentType;
|
import io.restassured.http.ContentType;
|
||||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationTypeResource;
|
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeRelationTypeResource;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRealRepository;
|
||||||
|
import net.hostsharing.hsadminng.rbac.context.Context;
|
||||||
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Tag;
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -22,19 +21,20 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.*;
|
|
||||||
import static org.hamcrest.Matchers.hasEntry;
|
import static org.hamcrest.Matchers.hasEntry;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
@SpringBootTest(
|
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
|
||||||
)
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Tag("officeIntegrationTest")
|
@Tag("officeIntegrationTest")
|
||||||
|
@SpringBootTest(
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
|
classes = HsadminNgApplication.class)
|
||||||
|
@ActiveProfiles("fake-jwt")
|
||||||
class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
public static final UUID GIVEN_NON_EXISTING_HOLDER_PERSON_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
public static final UUID GIVEN_NON_EXISTING_HOLDER_PERSON_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
||||||
@@ -68,7 +68,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relations?personUuid=%s&relationType=%s"
|
.get("http://localhost/api/hs/office/relations?personUuid=%s&relationType=%s"
|
||||||
@@ -126,7 +126,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relations?personUuid=%s"
|
.get("http://localhost/api/hs/office/relations?personUuid=%s"
|
||||||
@@ -183,7 +183,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relations?personData=firby&contactData=Contact-Admin@FirstContact.Example.COM")
|
.get("http://localhost/api/hs/office/relations?personData=firby&contactData=Contact-Admin@FirstContact.Example.COM")
|
||||||
@@ -235,7 +235,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -280,7 +280,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -348,7 +348,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -380,7 +380,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -413,7 +413,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -447,7 +447,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relations/" + givenRelationUuid)
|
.get("http://localhost/api/hs/office/relations/" + givenRelationUuid)
|
||||||
@@ -470,7 +470,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relations/" + givenRelationUuid)
|
.get("http://localhost/api/hs/office/relations/" + givenRelationUuid)
|
||||||
@@ -486,7 +486,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer contact-admin@firstcontact.example.com")
|
.header("Authorization", bearer("contact-admin@firstcontact.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
.get("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
@@ -529,7 +529,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -572,7 +572,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
@@ -591,7 +591,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer contact-admin@seventhcontact.example.com")
|
.header("Authorization", bearer("contact-admin@seventhcontact.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
@@ -610,7 +610,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
.delete("http://localhost/api/hs/office/relations/" + givenRelation.getUuid())
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.relation;
|
package net.hostsharing.hsadminng.hs.office.relation;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.rbac.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.lambda.Reducer;
|
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||||
|
|||||||
+2
-25
@@ -1,7 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.office.scenarios;
|
package net.hostsharing.hsadminng.hs.office.scenarios;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRbacEntity;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRbacEntity;
|
||||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRbacRepository;
|
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRbacRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.scenarios.contact.AddPhoneNumberToContactData;
|
import net.hostsharing.hsadminng.hs.office.scenarios.contact.AddPhoneNumberToContactData;
|
||||||
@@ -43,39 +42,16 @@ import net.hostsharing.hsadminng.hs.scenarios.Produces;
|
|||||||
import net.hostsharing.hsadminng.hs.scenarios.Requires;
|
import net.hostsharing.hsadminng.hs.scenarios.Requires;
|
||||||
import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest;
|
import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest;
|
||||||
import net.hostsharing.hsadminng.lambda.Reducer;
|
import net.hostsharing.hsadminng.lambda.Reducer;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import net.hostsharing.hsadminng.test.IgnoreOnFailureExtension;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.ClassOrderer;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
import org.junit.jupiter.api.Tag;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestClassOrder;
|
|
||||||
import org.junit.jupiter.api.TestInfo;
|
import org.junit.jupiter.api.TestInfo;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
|
||||||
|
|
||||||
@Tag("scenarioTest")
|
|
||||||
@SpringBootTest(
|
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class },
|
|
||||||
properties = {
|
|
||||||
"spring.datasource.url=${HSADMINNG_POSTGRES_JDBC_URL:jdbc:tc:postgresql:15.5-bookworm:///scenariosTC}",
|
|
||||||
"spring.datasource.username=${HSADMINNG_POSTGRES_ADMIN_USERNAME:ADMIN}",
|
|
||||||
"spring.datasource.password=${HSADMINNG_POSTGRES_ADMIN_PASSWORD:password}",
|
|
||||||
"hsadminng.superuser=${HSADMINNG_SUPERUSER:superuser-alex@hostsharing.net}"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@ActiveProfiles("test")
|
|
||||||
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
|
|
||||||
@ExtendWith(IgnoreOnFailureExtension.class)
|
|
||||||
class HsOfficeScenarioTests extends ScenarioTest {
|
class HsOfficeScenarioTests extends ScenarioTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -702,7 +678,8 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(6010)
|
@Order(6010)
|
||||||
@Requires("Debitor: D-3101100 - Michelle Matthieu") // which should also get updated
|
@Requires("Debitor: D-3101100 - Michelle Matthieu")
|
||||||
|
// which should also get updated
|
||||||
void shouldReplaceDeceasedPartnerByCommunityOfHeirs() {
|
void shouldReplaceDeceasedPartnerByCommunityOfHeirs() {
|
||||||
new ReplaceDeceasedPartnerWithCommunityOfHeirs(scenarioTest)
|
new ReplaceDeceasedPartnerWithCommunityOfHeirs(scenarioTest)
|
||||||
.given("partnerNumber", "P-31011")
|
.given("partnerNumber", "P-31011")
|
||||||
|
|||||||
+27
-24
@@ -8,7 +8,6 @@ import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountReposi
|
|||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
import net.hostsharing.hsadminng.config.DisableSecurityConfig;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@@ -26,18 +25,20 @@ import java.time.LocalDate;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
|
import static net.hostsharing.hsadminng.config.JwtFakeBearer.bearer;
|
||||||
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
import static net.hostsharing.hsadminng.rbac.test.IsValidUuidMatcher.isUuidValid;
|
||||||
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.test.JsonMatcher.lenientlyEquals;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
|
@Tag("officeIntegrationTest")
|
||||||
|
@Transactional
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||||
classes = { HsadminNgApplication.class, DisableSecurityConfig.class, JpaAttempt.class }
|
classes = HsadminNgApplication.class)
|
||||||
)
|
@ActiveProfiles("fake-jwt")
|
||||||
@ActiveProfiles("test")
|
|
||||||
@Transactional
|
|
||||||
@Tag("officeIntegrationTest")
|
|
||||||
class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCleanup {
|
||||||
|
|
||||||
@LocalServerPort
|
@LocalServerPort
|
||||||
@@ -66,7 +67,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/sepamandates")
|
.get("http://localhost/api/hs/office/sepamandates")
|
||||||
@@ -107,7 +108,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/sepamandates?iban=DE02120300000000202051")
|
.get("http://localhost/api/hs/office/sepamandates?iban=DE02120300000000202051")
|
||||||
@@ -145,7 +146,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -186,7 +187,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -211,7 +212,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -241,7 +242,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -275,7 +276,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/sepamandates/" + givenSepaMandateUuid)
|
.get("http://localhost/api/hs/office/sepamandates/" + givenSepaMandateUuid)
|
||||||
@@ -305,7 +306,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/sepamandates/" + givenSepaMandateUuid)
|
.get("http://localhost/api/hs/office/sepamandates/" + givenSepaMandateUuid)
|
||||||
@@ -322,7 +323,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer bankaccount-admin@FirstGmbH.example.com")
|
.header("Authorization", bearer("bankaccount-admin@FirstGmbH.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/office/sepamandates/" + givenSepaMandateUuid)
|
.get("http://localhost/api/hs/office/sepamandates/" + givenSepaMandateUuid)
|
||||||
@@ -354,7 +355,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -383,7 +384,8 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(D-1000111: rel(anchor='LP First GmbH', type=DEBITOR, holder='LP First GmbH'), fir)");
|
assertThat(mandate.getDebitor().toString()).isEqualTo(
|
||||||
|
"debitor(D-1000111: rel(anchor='LP First GmbH', type=DEBITOR, holder='LP First GmbH'), fir)");
|
||||||
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
||||||
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched");
|
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z - patched");
|
||||||
assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05");
|
assertThat(mandate.getValidFrom()).isEqualTo("2020-06-05");
|
||||||
@@ -400,7 +402,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -425,7 +427,8 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
assertThat(sepaMandateRepo.findByUuid(givenSepaMandate.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getDebitor().toString())
|
assertThat(mandate.getDebitor().toString())
|
||||||
.isEqualTo("debitor(D-1000111: rel(anchor='LP First GmbH', type=DEBITOR, holder='LP First GmbH'), fir)");
|
.isEqualTo(
|
||||||
|
"debitor(D-1000111: rel(anchor='LP First GmbH', type=DEBITOR, holder='LP First GmbH'), fir)");
|
||||||
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
assertThat(mandate.getBankAccount().toShortString()).isEqualTo("First GmbH");
|
||||||
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z");
|
assertThat(mandate.getReference()).isEqualTo("temp ref CAT Z");
|
||||||
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)");
|
assertThat(mandate.getValidity().asString()).isEqualTo("[2022-11-01,2023-01-01)");
|
||||||
@@ -441,7 +444,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
final var location = RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
@@ -475,7 +478,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer superuser-alex@hostsharing.net")
|
.header("Authorization", bearer("superuser-alex@hostsharing.net"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/sepamandates/" + givenSepaMandate.getUuid())
|
.delete("http://localhost/api/hs/office/sepamandates/" + givenSepaMandate.getUuid())
|
||||||
@@ -493,7 +496,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer bankaccount-admin@FirstGmbH.example.com")
|
.header("Authorization", bearer("bankaccount-admin@FirstGmbH.example.com"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/sepamandates/" + givenSepaMandate.getUuid())
|
.delete("http://localhost/api/hs/office/sepamandates/" + givenSepaMandate.getUuid())
|
||||||
@@ -511,7 +514,7 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
|||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("Authorization", "Bearer selfregistered-user-drew@hostsharing.org")
|
.header("Authorization", bearer("selfregistered-user-drew@hostsharing.org"))
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.delete("http://localhost/api/hs/office/sepamandates/" + givenSepaMandate.getUuid())
|
.delete("http://localhost/api/hs/office/sepamandates/" + givenSepaMandate.getUuid())
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user