Initialisiere VoTiAn NG mit Docker-Build, .env-Konfiguration und Cookie-Sitzungen

This commit is contained in:
Sven committed 2026-10-05 17:45:38 +02:00
commit 1a30233269
63 files changed
+12138

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
"""Run read-only metadata diagnostics through the backend's shared DatabaseService."""
import importlib.util
import json
import os
from pathlib import Path
import sys
ROOT = Path(__file__).resolve().parents[1]
spec = importlib.util.spec_from_file_location("legacy_config", ROOT / "scripts/run-backend.py")
config = importlib.util.module_from_spec(spec)
spec.loader.exec_module(config)
def failure(message):
print(json.dumps({"connected": False, "reason": "CONFIGURATION_ERROR", "errorCode": None,
"message": message, "applicationRowsRead": 0, "writes": 0},
ensure_ascii=False, indent=2))
return 2
def main():
try:
jar = config.backend_jar(ROOT)
except FileNotFoundError:
return failure("Kein eindeutiges Backend-JAR. Zuerst ./build.sh ausführen.")
try:
env = config.database_environment(ROOT, dict(os.environ))
os.chdir(ROOT / "backend")
# Credentials are passed only in the environment, never as process arguments.
os.execvpe("java", ["java", "-jar", str(jar), "--database-check"], env)
except (OSError, ValueError):
return failure("Backend-Start oder DB_URL, DB_USER und DB_PASSWORD in .env/Umgebung prüfen.")
return 0
if __name__ == "__main__":
sys.exit(main())
+91
View File
@@ -0,0 +1,91 @@
"""Read local environment configuration without evaluating its contents."""
from __future__ import annotations
import os
import re
import sys
from pathlib import Path
_ASSIGNMENT = re.compile(r"(?:export[ \t]+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)")
def load_environment(path: Path, current: dict[str, str]) -> dict[str, str]:
"""Merge a local .env file with the current environment, which takes priority.
Values are literal: shell commands, variable references, backslashes and
inline ``#`` characters are never interpreted. Optional surrounding quotes
are removed, without interpreting escapes. Keep the project's .env values
unquoted (and omit ``export``) for compatibility with Docker ``--env-file``.
"""
try:
contents = path.read_bytes()
except FileNotFoundError:
return dict(current)
values: dict[str, str] = {}
for line_number, raw_line in enumerate(contents.split(b"\n"), start=1):
# Accept both LF and CRLF, but not embedded line breaks in a value.
raw_line = raw_line.removesuffix(b"\r")
try:
line = raw_line.decode("utf-8")
except UnicodeDecodeError:
raise ValueError(f"Invalid .env syntax at line {line_number}") from None
if "\x00" in line or "\r" in line:
raise ValueError(f"Invalid .env syntax at line {line_number}")
line = line.lstrip(" \t")
if not line or line.startswith("#"):
continue
match = _ASSIGNMENT.fullmatch(line)
if match is None:
raise ValueError(f"Invalid .env syntax at line {line_number}")
key, value = match.groups()
if value.startswith(("'", '"')):
quoted_value = value.rstrip(" \t")
if len(quoted_value) < 2 or quoted_value[-1] != quoted_value[0]:
raise ValueError(f"Invalid .env syntax at line {line_number}")
value = quoted_value[1:-1]
values[key] = value
values.update(current)
return values
def main(argv: list[str] | None = None) -> int:
"""Run a command with the project's .env, retaining the caller's directory."""
command = sys.argv[1:] if argv is None else argv
if not command or command[0] in ("-h", "--help"):
print(
"Usage: python3 scripts/env_config.py COMMAND [ARGS...]\n"
"Run COMMAND with the project .env; existing environment variables take priority.\n"
"The working directory is preserved. From backend, for example:\n"
" python3 ../scripts/env_config.py ./mvnw test",
file=sys.stderr if not command else sys.stdout,
)
return 2 if not command else 0
try:
environment = load_environment(Path(__file__).resolve().parents[1] / ".env", dict(os.environ))
except ValueError as error:
message = str(error)
if re.fullmatch(r"Invalid \.env syntax at line [0-9]+", message) is None:
message = "Invalid .env syntax."
print(message, file=sys.stderr)
return 1
except OSError:
print("Unable to read .env.", file=sys.stderr)
return 1
try:
os.execvpe(command[0], command, environment)
except OSError:
print("Unable to start command.", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())
+1
View File
@@ -0,0 +1 @@
# No Python database driver is required. check-database.py delegates to the built Java backend.
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Start Spring Boot with database credentials from .env or the process environment."""
from __future__ import annotations
import argparse
import os
from pathlib import Path
import sys
sys.path.insert(0, str(Path(__file__).resolve().parent))
from env_config import load_environment
ROOT = Path(__file__).resolve().parents[1]
def database_environment(root: Path, current: dict[str, str]) -> dict[str, str]:
env = load_environment(root / ".env", current)
required = ("DB_URL", "DB_USER", "DB_PASSWORD")
if any(key not in env for key in required) or not env["DB_URL"] or not env["DB_USER"]:
raise ValueError("DB_URL, DB_USER und DB_PASSWORD müssen konfiguriert sein.")
return env
def backend_jar(root: Path) -> Path:
jars = sorted((root / "backend/target").glob("votian-backend-*.jar"))
if len(jars) != 1 or not jars[0].is_file():
raise FileNotFoundError("Kein eindeutiges Backend-JAR. Zuerst ./build.sh ausführen.")
return jars[0]
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--check-config", action="store_true", help="Nur Konfiguration prüfen; keine DB-Verbindung")
parser.add_argument("--port", type=int, help="Port aus .env/Umgebung überschreiben (Standard 8080)")
args = parser.parse_args()
try:
env = database_environment(ROOT, dict(os.environ))
port = args.port if args.port is not None else int(env.get("PORT", "8080"))
if not 1 <= port <= 65535:
raise ValueError("Ungültiger Port.")
env["PORT"] = str(port)
except (OSError, ValueError):
print("Konfiguration nicht lesbar/ungültig. DB_URL, DB_USER und DB_PASSWORD in .env oder der Umgebung sowie PORT prüfen.", file=sys.stderr)
return 2
if args.check_config:
print("Datenbankkonfiguration aus .env/Umgebung geprüft. Keine Verbindung hergestellt; keine Daten verändert.")
return 0
try:
jar = backend_jar(ROOT)
except FileNotFoundError:
print("Kein eindeutiges Backend-JAR. Zuerst ./build.sh ausführen.", file=sys.stderr)
return 2
os.chdir(ROOT / "backend")
os.execvpe("java", ["java", "-jar", str(jar)], env)
return 0
if __name__ == "__main__":
raise SystemExit(main())