Server Up beheerde de Docker-daemon als root zonder enige vorm van authenticatie: elke /api/*-route was gelijk aan root-toegang op de host. - Authenticatie toegevoegd (core/auth.py): lokale accounts met scrypt-hash, sessiecookie (HttpOnly, SameSite=Strict) en optionele trusted-proxy-header SSO die alleen vanaf geconfigureerde proxy-IP's wordt vertrouwd. - before_request-guard schermt alle API-routes af; loginscherm en eerste-account-setup in de UI. - CSRF-token verplicht op elke mutatie; GET-varianten van state-wijzigende routes verwijderd (o.a. /api/docker/restart was via <img> te triggeren). - Path traversal in /api/store/install gedicht; gedeelde safe_name()-validatie voor stack-, instantie- en repo-namen. - Git-tokens worden niet meer teruggegeven via /api/repos en /api/settings (has_token-vlag); settings-PUT wist een bestaand token niet meer en kan AUTH niet overschrijven. - Git-URL's beperkt tot http(s)/ssh/scp-syntax; ext::-transport (voert een shell-commando uit) en file:// worden geweigerd. - Boilerplate-templates renderen in een SandboxedEnvironment (SSTI). - Automatisch syncen van repo's bij boot standaard uit (AUTO_SYNC_ON_BOOT), optionele commit-pinning per repo. - Waitress in plaats van de Flask-ontwikkelserver, MAX_CONTENT_LENGTH, ProxyFix, en CSP/X-Frame-Options/nosniff/Referrer-Policy headers. - Front-end libraries (Tailwind, Alpine, htmx) lokaal meegeleverd i.p.v. CDN; Google Fonts verwijderd. Werkt nu ook offline. - SSH host-key-verificatie aan (accept-new + /data/known_hosts). - Lichte /healthz voor de healthcheck i.p.v. `docker info`. - config.json en secret.key met 0600-rechten. - Poort standaard op 127.0.0.1 gebonden. - Audit-log gebruikt één gedeelde SQLite-verbinding (fd-lek per job verholpen); joblogs afgekapt op 2000 regels. - VERSION-bestand is de enige bron voor het versienummer. - pytest-suite toegevoegd (74 tests) en als stap in beide deploy-workflows. - fix-config.sh verwijderd (hardgecodeerd intern IP, overschreef config). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
"""Semver-vergelijking van de update-check."""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "server-up"))
|
|
|
|
from core import updater
|
|
|
|
|
|
@pytest.mark.parametrize("lager,hoger", [
|
|
("0.4.6", "0.4.60"), # tweecijferig patchnummer (zie CHANGELOG v0.4.60)
|
|
("0.4.60", "0.4.61"),
|
|
("0.4.9", "0.5.0"),
|
|
("1.0.0-beta1", "1.0.0"), # release wint van pre-release
|
|
("1.0.0-beta1", "1.0.0-beta2"),
|
|
("0.9.9", "1.0.0"),
|
|
])
|
|
def test_versievolgorde(lager, hoger):
|
|
assert updater._parse(lager) < updater._parse(hoger)
|
|
|
|
|
|
def test_v_prefix_maakt_niet_uit():
|
|
assert updater._parse("v1.2.3") == updater._parse("1.2.3")
|
|
|
|
|
|
@pytest.mark.parametrize("waarde", ["", "geen-versie", "1.2", None])
|
|
def test_onparseerbare_versies(waarde):
|
|
assert updater._parse(waarde) is None
|
|
|
|
|
|
def test_check_zonder_url_is_uitgeschakeld(monkeypatch, tmp_path):
|
|
monkeypatch.setenv("SU_CONFIG", str(tmp_path / "config.json"))
|
|
import core as cfg
|
|
cfg._path = tmp_path / "config.json"
|
|
cfg.patch({"UPDATE_API_URL": ""})
|
|
res = updater.check("0.4.60")
|
|
assert res["enabled"] is False
|
|
assert res["update_available"] is False
|