securite: #87 T6-T8 fin dette — deps qualifiées, semgrep, Secure auto, CORS
This commit is contained in:
+80
-1
@@ -402,4 +402,83 @@ class TestAvatar:
|
||||
"username": "admin", "password": "chab30",
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["user"]["avatar"] == TINY_PNG
|
||||
assert resp.json()["user"]["avatar"] == TINY_PNG
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Secure cookies (#87 T8)
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
class TestSecureCookies:
|
||||
"""`Secure` auto par défaut : https → flag, http → pas de flag
|
||||
(les navigateurs jettent les cookies Secure sur http)."""
|
||||
|
||||
@staticmethod
|
||||
def _req(scheme="http", forwarded_proto=None):
|
||||
from types import SimpleNamespace
|
||||
headers = {}
|
||||
if forwarded_proto is not None:
|
||||
headers["x-forwarded-proto"] = forwarded_proto
|
||||
return SimpleNamespace(
|
||||
url=SimpleNamespace(scheme=scheme),
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
def test_forced_true(self, monkeypatch):
|
||||
from backend.auth.router import is_secure_cookies
|
||||
monkeypatch.setenv("OBSIGATE_SECURE_COOKIES", "true")
|
||||
assert is_secure_cookies(self._req("http")) is True
|
||||
|
||||
def test_forced_false(self, monkeypatch):
|
||||
from backend.auth.router import is_secure_cookies
|
||||
monkeypatch.setenv("OBSIGATE_SECURE_COOKIES", "false")
|
||||
assert is_secure_cookies(self._req("https")) is False
|
||||
|
||||
def test_auto_http(self, monkeypatch):
|
||||
from backend.auth.router import is_secure_cookies
|
||||
monkeypatch.delenv("OBSIGATE_SECURE_COOKIES", raising=False)
|
||||
assert is_secure_cookies(self._req("http")) is False
|
||||
|
||||
def test_auto_https(self, monkeypatch):
|
||||
from backend.auth.router import is_secure_cookies
|
||||
monkeypatch.delenv("OBSIGATE_SECURE_COOKIES", raising=False)
|
||||
assert is_secure_cookies(self._req("https")) is True
|
||||
|
||||
def test_auto_forwarded_proto_trusted(self, monkeypatch):
|
||||
from backend.auth.router import is_secure_cookies
|
||||
monkeypatch.delenv("OBSIGATE_SECURE_COOKIES", raising=False)
|
||||
monkeypatch.setenv("OBSIGATE_TRUST_PROXY", "true")
|
||||
assert is_secure_cookies(self._req("http", "https")) is True
|
||||
|
||||
def test_auto_forwarded_proto_untrusted(self, monkeypatch):
|
||||
from backend.auth.router import is_secure_cookies
|
||||
monkeypatch.delenv("OBSIGATE_SECURE_COOKIES", raising=False)
|
||||
monkeypatch.delenv("OBSIGATE_TRUST_PROXY", raising=False)
|
||||
assert is_secure_cookies(self._req("http", "https")) is False
|
||||
|
||||
def test_login_http_sets_cookie_without_secure(self, auth_client, monkeypatch):
|
||||
monkeypatch.delenv("OBSIGATE_SECURE_COOKIES", raising=False)
|
||||
resp = auth_client.post("/api/auth/login", json={
|
||||
"username": "admin", "password": "chab30",
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
set_cookie = resp.headers.get("set-cookie", "")
|
||||
assert "access_token" in set_cookie
|
||||
assert "secure" not in set_cookie.lower()
|
||||
|
||||
def test_login_https_sets_secure_cookie(self, auth_client, monkeypatch):
|
||||
"""Même app servie en https → flag Secure présent."""
|
||||
from backend.main import app
|
||||
from fastapi.testclient import TestClient
|
||||
monkeypatch.delenv("OBSIGATE_SECURE_COOKIES", raising=False)
|
||||
https_client = TestClient(app, base_url="https://testserver",
|
||||
raise_server_exceptions=False)
|
||||
try:
|
||||
resp = https_client.post("/api/auth/login", json={
|
||||
"username": "admin", "password": "chab30",
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
assert "secure" in resp.headers.get("set-cookie", "").lower()
|
||||
finally:
|
||||
if hasattr(https_client, "close"):
|
||||
https_client.close()
|
||||
Reference in New Issue
Block a user