feat: add operator landing and login
This commit is contained in:
@@ -76,6 +76,13 @@ bash deploy/unraid/deploy-release.sh
|
||||
```
|
||||
|
||||
Set `GEOINTEL_POSTGRES_PASSWORD` to a unique value before that first start.
|
||||
|
||||
For a browser login, set `GEOINTEL_AUTH_ENABLED=true`, configure one exact
|
||||
`GEOINTEL_AUTH_USERNAME`, a `pbkdf2_sha256` password hash and an independent
|
||||
random `GEOINTEL_AUTH_SESSION_SECRET` of at least 32 characters. The plaintext
|
||||
password is never stored in the repository or container configuration. Browser
|
||||
API calls require the signed HttpOnly session cookie; direct loopback calls to
|
||||
the backend remain available to trusted in-container operator scripts.
|
||||
Production startup fails before replacing the active container when the
|
||||
password is empty or one of the documented defaults.
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
<Config Name="Postgres Password" Target="GEOINTEL_POSTGRES_PASSWORD" Default="change-me-before-shared-use" Mode="" Description="Embedded PostGIS database password. Change before shared use." Type="Variable" Display="advanced" Required="true" Mask="true">change-me-before-shared-use</Config>
|
||||
<Config Name="CORS Origins" Target="GEOINTEL_CORS_ORIGINS" Default="http://localhost:1202,http://127.0.0.1:1202,http://192.168.10.150:1202" Mode="" Description="Comma-separated browser origins allowed to call the backend directly." Type="Variable" Display="advanced" Required="false" Mask="false">http://localhost:1202,http://127.0.0.1:1202,http://192.168.10.150:1202</Config>
|
||||
<Config Name="Max Upload MB" Target="GEOINTEL_MAX_UPLOAD_MB" Default="500" Mode="" Description="Maximum upload size in MiB enforced consistently by nginx and the backend (1-2048)." Type="Variable" Display="advanced" Required="true" Mask="false">500</Config>
|
||||
<Config Name="Operator Login Enabled" Target="GEOINTEL_AUTH_ENABLED" Default="false" Mode="" Description="Require the single configured operator login before the browser may access workbench APIs." Type="Variable" Display="advanced" Required="true" Mask="false">false</Config>
|
||||
<Config Name="Operator Username" Target="GEOINTEL_AUTH_USERNAME" Default="" Mode="" Description="Exact username for the single operator account." Type="Variable" Display="advanced" Required="false" Mask="false"></Config>
|
||||
<Config Name="Operator Password Hash" Target="GEOINTEL_AUTH_PASSWORD_HASH" Default="" Mode="" Description="PBKDF2-SHA256 password hash. Never enter a plaintext password." Type="Variable" Display="advanced" Required="false" Mask="true"></Config>
|
||||
<Config Name="Operator Session Secret" Target="GEOINTEL_AUTH_SESSION_SECRET" Default="" Mode="" Description="Random secret of at least 32 characters used only to sign browser sessions." Type="Variable" Display="advanced" Required="false" Mask="true"></Config>
|
||||
<Config Name="Operator Session TTL" Target="GEOINTEL_AUTH_SESSION_TTL_SECONDS" Default="43200" Mode="" Description="Session lifetime in seconds (900-604800)." Type="Variable" Display="advanced" Required="true" Mask="false">43200</Config>
|
||||
<Config Name="Official Orthophoto Acquisition" Target="ORTHOPHOTO_ENABLED" Default="true" Mode="" Description="Allow explicit bounded map selections to request the official Digitaal Vlaanderen orthophoto WMS." Type="Variable" Display="advanced" Required="true" Mask="false">true</Config>
|
||||
<Config Name="Orthophoto WMS URL" Target="ORTHOPHOTO_WMS_URL" Default="https://geo.api.vlaanderen.be/OMWRGBMRVL/wms" Mode="" Description="Official Digitaal Vlaanderen most-recent winter orthophoto WMS endpoint." Type="Variable" Display="advanced" Required="true" Mask="false">https://geo.api.vlaanderen.be/OMWRGBMRVL/wms</Config>
|
||||
<Config Name="Orthophoto WMS Layer" Target="ORTHOPHOTO_WMS_LAYER" Default="Ortho" Mode="" Description="Allowlisted official orthophoto WMS layer identifier." Type="Variable" Display="advanced" Required="true" Mask="false">Ortho</Config>
|
||||
|
||||
@@ -29,6 +29,15 @@ GEOINTEL_CORS_ORIGINS=http://localhost:1202,http://127.0.0.1:1202,http://192.168
|
||||
# Upload guard in MiB. The same 1-2048 limit is applied by nginx and FastAPI.
|
||||
GEOINTEL_MAX_UPLOAD_MB=500
|
||||
|
||||
# Optional single-operator access gate. Never store a plaintext password here.
|
||||
# Generate the password hash with AuthService.hash_password and use a unique,
|
||||
# random session secret of at least 32 characters.
|
||||
GEOINTEL_AUTH_ENABLED=false
|
||||
GEOINTEL_AUTH_USERNAME=
|
||||
GEOINTEL_AUTH_PASSWORD_HASH=
|
||||
GEOINTEL_AUTH_SESSION_SECRET=
|
||||
GEOINTEL_AUTH_SESSION_TTL_SECONDS=43200
|
||||
|
||||
# Explicit, bounded acquisition from the official Digitaal Vlaanderen WMS.
|
||||
ORTHOPHOTO_ENABLED=true
|
||||
ORTHOPHOTO_WMS_URL=https://geo.api.vlaanderen.be/OMWRGBMRVL/wms
|
||||
|
||||
@@ -33,6 +33,11 @@ GEOINTEL_POSTGRES_USER="${GEOINTEL_POSTGRES_USER:-geointel}"
|
||||
GEOINTEL_POSTGRES_PASSWORD="${GEOINTEL_POSTGRES_PASSWORD:-}"
|
||||
GEOINTEL_CORS_ORIGINS="${GEOINTEL_CORS_ORIGINS:-http://localhost:${GEOINTEL_FRONTEND_PORT},http://127.0.0.1:${GEOINTEL_FRONTEND_PORT},http://192.168.10.150:${GEOINTEL_FRONTEND_PORT}}"
|
||||
GEOINTEL_MAX_UPLOAD_MB="${GEOINTEL_MAX_UPLOAD_MB:-500}"
|
||||
GEOINTEL_AUTH_ENABLED="${GEOINTEL_AUTH_ENABLED:-false}"
|
||||
GEOINTEL_AUTH_USERNAME="${GEOINTEL_AUTH_USERNAME:-}"
|
||||
GEOINTEL_AUTH_PASSWORD_HASH="${GEOINTEL_AUTH_PASSWORD_HASH:-}"
|
||||
GEOINTEL_AUTH_SESSION_SECRET="${GEOINTEL_AUTH_SESSION_SECRET:-}"
|
||||
GEOINTEL_AUTH_SESSION_TTL_SECONDS="${GEOINTEL_AUTH_SESSION_TTL_SECONDS:-43200}"
|
||||
ORTHOPHOTO_ENABLED="${ORTHOPHOTO_ENABLED:-true}"
|
||||
ORTHOPHOTO_WMS_URL="${ORTHOPHOTO_WMS_URL:-https://geo.api.vlaanderen.be/OMWRGBMRVL/wms}"
|
||||
ORTHOPHOTO_WMS_LAYER="${ORTHOPHOTO_WMS_LAYER:-Ortho}"
|
||||
@@ -171,6 +176,29 @@ validate_runtime_config() {
|
||||
return 2
|
||||
fi
|
||||
|
||||
case "$GEOINTEL_AUTH_ENABLED" in
|
||||
true|false) ;;
|
||||
*)
|
||||
echo "GEOINTEL_AUTH_ENABLED must be true or false." >&2
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
if [ "$GEOINTEL_AUTH_ENABLED" = "true" ]; then
|
||||
if [ -z "$GEOINTEL_AUTH_USERNAME" ] \
|
||||
|| [ -z "$GEOINTEL_AUTH_PASSWORD_HASH" ] \
|
||||
|| [ "${#GEOINTEL_AUTH_SESSION_SECRET}" -lt 32 ]; then
|
||||
echo "Enabled operator authentication requires username, password hash and a 32+ character session secret." >&2
|
||||
return 2
|
||||
fi
|
||||
case "$GEOINTEL_AUTH_PASSWORD_HASH" in
|
||||
pbkdf2_sha256\$*) ;;
|
||||
*)
|
||||
echo "GEOINTEL_AUTH_PASSWORD_HASH must use the pbkdf2_sha256 format." >&2
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "$GEOINTEL_POSTGRES_PASSWORD" in
|
||||
''|geointel|postgres|password|changeme|change-me-before-shared-use)
|
||||
echo "Refusing deployment with an empty or known-default PostGIS password." >&2
|
||||
@@ -241,6 +269,11 @@ docker run -d \
|
||||
-e GEOINTEL_STORAGE_ROOT=/app/storage \
|
||||
-e GEOINTEL_CORS_ORIGINS="$GEOINTEL_CORS_ORIGINS" \
|
||||
-e GEOINTEL_MAX_UPLOAD_MB="$GEOINTEL_MAX_UPLOAD_MB" \
|
||||
-e GEOINTEL_AUTH_ENABLED="$GEOINTEL_AUTH_ENABLED" \
|
||||
-e GEOINTEL_AUTH_USERNAME="$GEOINTEL_AUTH_USERNAME" \
|
||||
-e GEOINTEL_AUTH_PASSWORD_HASH="$GEOINTEL_AUTH_PASSWORD_HASH" \
|
||||
-e GEOINTEL_AUTH_SESSION_SECRET="$GEOINTEL_AUTH_SESSION_SECRET" \
|
||||
-e GEOINTEL_AUTH_SESSION_TTL_SECONDS="$GEOINTEL_AUTH_SESSION_TTL_SECONDS" \
|
||||
-e ORTHOPHOTO_ENABLED="$ORTHOPHOTO_ENABLED" \
|
||||
-e ORTHOPHOTO_WMS_URL="$ORTHOPHOTO_WMS_URL" \
|
||||
-e ORTHOPHOTO_WMS_LAYER="$ORTHOPHOTO_WMS_LAYER" \
|
||||
|
||||
Reference in New Issue
Block a user