feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
53
tests/test_security_audit.py
Normal file
53
tests/test_security_audit.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from codexpi.config import load_or_create_secret
|
||||
from codexpi.security import LoginLimiter
|
||||
|
||||
|
||||
def test_progressive_login_delay_is_capped():
|
||||
limiter = LoginLimiter(attempts=20)
|
||||
delays = []
|
||||
for _ in range(8):
|
||||
assert limiter.allow("100.64.0.10")
|
||||
delays.append(limiter.penalty("100.64.0.10"))
|
||||
assert delays[:5] == [0.25, 0.5, 1.0, 2.0, 4.0]
|
||||
assert delays[-1] == 4.0
|
||||
|
||||
|
||||
def test_login_security_log_contains_no_credentials(logged_in):
|
||||
_, app, *_ = logged_in
|
||||
records = [json.loads(line) for line in (app.state.settings.data_dir / "security.log").read_text(encoding="utf-8").splitlines()]
|
||||
assert [row["event"] for row in records[:2]] == ["auth.login_succeeded", "session.created"]
|
||||
rendered = json.dumps(records)
|
||||
assert "a-very-long-test-password" not in rendered
|
||||
assert "csrf" not in rendered.lower()
|
||||
assert "cookie" not in rendered.lower()
|
||||
|
||||
|
||||
def test_full_access_change_is_audited(logged_in):
|
||||
client, app, projects, _, headers = logged_in
|
||||
root = projects / "full-access"
|
||||
root.mkdir()
|
||||
project = client.post("/api/projects", headers=headers, json={"name": "Full", "path": str(root)}).json()
|
||||
response = client.put(
|
||||
f"/api/projects/{project['id']}/full-access",
|
||||
headers=headers,
|
||||
json={"enabled": True, "acknowledged": True},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
log = (app.state.settings.data_dir / "security.log").read_text(encoding="utf-8")
|
||||
assert '"event":"security.full_access_changed"' in log
|
||||
assert '"outcome":"enabled"' in log
|
||||
|
||||
|
||||
def test_application_secret_can_come_from_external_file(tmp_path: Path, monkeypatch):
|
||||
external = tmp_path / "mounted-secret"
|
||||
external.write_text("x" * 48, encoding="utf-8")
|
||||
generated_data = tmp_path / "data"
|
||||
generated_data.mkdir()
|
||||
monkeypatch.setenv("CODEXPI_SECRET_KEY_FILE", str(external))
|
||||
assert load_or_create_secret(generated_data) == "x" * 48
|
||||
assert not (generated_data / "secret_key").exists()
|
||||
Reference in New Issue
Block a user