131 lines
4.4 KiB
Python
131 lines
4.4 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
from config.settings import normalize_public_base_url
|
|
from scripts.configure_public_url import ConfigurationError, configure_env, normalize_public_url
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("raw", "origin", "host"),
|
|
[
|
|
(
|
|
"https://vacatureradar.itworx.tech/",
|
|
"https://vacatureradar.itworx.tech",
|
|
"vacatureradar.itworx.tech",
|
|
),
|
|
("https://jobs.example.be:8443", "https://jobs.example.be:8443", "jobs.example.be"),
|
|
("http://127.0.0.1:1226", "http://127.0.0.1:1226", "127.0.0.1"),
|
|
],
|
|
)
|
|
def test_public_url_normalization(raw, origin, host):
|
|
assert normalize_public_base_url(raw) == (origin, host)
|
|
assert normalize_public_url(raw) == (origin, host)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"raw",
|
|
[
|
|
"vacatureradar.itworx.tech",
|
|
"ftp://vacatureradar.itworx.tech",
|
|
"https://user:secret@example.org",
|
|
"https://example.org/app",
|
|
"https://example.org?debug=1",
|
|
],
|
|
)
|
|
def test_public_url_rejects_unsafe_or_unsupported_values(raw):
|
|
with pytest.raises((ImproperlyConfigured, ConfigurationError)):
|
|
normalize_public_base_url(raw)
|
|
|
|
|
|
def test_configure_public_url_updates_only_public_security_settings(tmp_path: Path):
|
|
env_file = tmp_path / ".env"
|
|
env_file.write_text(
|
|
"DJANGO_SECRET_KEY=keep-this-secret\n"
|
|
"POSTGRES_PASSWORD=keep-this-password\n"
|
|
"DJANGO_ALLOWED_HOSTS=vacatureradar.local,localhost\n"
|
|
"DJANGO_CSRF_TRUSTED_ORIGINS=http://vacatureradar.local:1226\n",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
changed = configure_env(
|
|
env_file,
|
|
"https://vacatureradar.itworx.tech/",
|
|
hsts_seconds=300,
|
|
cache_url="redis://127.0.0.1:6379/1",
|
|
trusted_proxy_cidrs=["172.18.0.0/16"],
|
|
)
|
|
content = env_file.read_text(encoding="utf-8")
|
|
|
|
assert "PUBLIC_BASE_URL=https://vacatureradar.itworx.tech" in content
|
|
assert "DJANGO_DEBUG=0" in content
|
|
assert "vacatureradar.itworx.tech" in content
|
|
assert (
|
|
"DJANGO_CSRF_TRUSTED_ORIGINS=http://vacatureradar.local:1226,https://vacatureradar.itworx.tech"
|
|
) in content
|
|
assert "CACHE_URL=redis://127.0.0.1:6379/1" in content
|
|
assert "TRUSTED_PROXY_CIDRS=172.18.0.0/16" in content
|
|
assert "DJANGO_SECRET_KEY=keep-this-secret" in content
|
|
assert "POSTGRES_PASSWORD=keep-this-password" in content
|
|
if os.name != "nt":
|
|
assert env_file.stat().st_mode & 0o777 == 0o600
|
|
assert "DJANGO_SECRET_KEY" not in changed
|
|
|
|
|
|
def test_configure_public_url_rejects_plain_http(tmp_path: Path):
|
|
with pytest.raises(ConfigurationError, match="HTTPS"):
|
|
configure_env(tmp_path / ".env", "http://vacatureradar.example.be")
|
|
|
|
|
|
def test_public_base_url_populates_django_host_and_csrf_settings():
|
|
environment = os.environ.copy()
|
|
environment.update(
|
|
{
|
|
"DJANGO_SECRET_KEY": "aB3!" * 16,
|
|
"DJANGO_DEBUG": "0",
|
|
"PUBLIC_BASE_URL": "https://vacatureradar.itworx.tech",
|
|
"DEMO_MODE_ENABLED": "0",
|
|
"SECURE_HSTS_SECONDS": "300",
|
|
}
|
|
)
|
|
result = subprocess.run( # noqa: S603 - fixed interpreter and static assertion program
|
|
[
|
|
sys.executable,
|
|
"-c",
|
|
(
|
|
"import config.settings as settings; "
|
|
"assert 'vacatureradar.itworx.tech' in settings.ALLOWED_HOSTS; "
|
|
"assert 'https://vacatureradar.itworx.tech' "
|
|
"in settings.CSRF_TRUSTED_ORIGINS; "
|
|
"assert settings.DEBUG is False; "
|
|
"assert settings.SESSION_COOKIE_SECURE is True; "
|
|
"assert settings.CSRF_COOKIE_SECURE is True; "
|
|
"assert settings.SECURE_SSL_REDIRECT is True"
|
|
),
|
|
],
|
|
cwd=Path(__file__).resolve().parents[2],
|
|
env=environment,
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
assert result.returncode == 0, result.stderr
|
|
|
|
|
|
def test_configure_public_url_is_idempotent(tmp_path: Path):
|
|
env_file = tmp_path / ".env"
|
|
env_file.write_text("DJANGO_ALLOWED_HOSTS=localhost\n", encoding="utf-8")
|
|
|
|
for _ in range(2):
|
|
configure_env(env_file, "https://vacatureradar.example.be")
|
|
|
|
content = env_file.read_text(encoding="utf-8")
|
|
assert content.count("PUBLIC_BASE_URL=") == 1
|
|
assert content.count("vacatureradar.example.be") == 3
|