second commit
This commit is contained in:
67
tests/test_auth_flow.py
Normal file
67
tests/test_auth_flow.py
Normal file
@ -0,0 +1,67 @@
|
||||
"""End-to-End-Test des Login-Flows (Passwort -> TOTP-Enrollment -> Session)
|
||||
gegen die echte FastAPI-App mit einer temporaeren SQLite-DB.
|
||||
|
||||
Die `client`-Fixture liegt in conftest.py (von mehreren Testdateien genutzt,
|
||||
u.a. tests/test_pentest_security.py)."""
|
||||
import pyotp
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_full_login_flow_with_totp_enrollment(client, monkeypatch):
|
||||
from app.db import get_db
|
||||
from app.security.passwords import hash_password
|
||||
|
||||
conn = get_db()
|
||||
await conn.execute(
|
||||
"INSERT INTO users (username, password_hash, must_change_password) VALUES (?, ?, 0)",
|
||||
("alice", hash_password("Correct-Horse-Battery-Staple-1")),
|
||||
)
|
||||
await conn.commit()
|
||||
|
||||
resp = await client.post(
|
||||
"/auth/login", json={"username": "alice", "password": "Correct-Horse-Battery-Staple-1"}
|
||||
)
|
||||
assert resp.status_code == 200, resp.text
|
||||
body = resp.json()
|
||||
assert body["totp_enrolled"] is False
|
||||
pending_token = body["pending_token"]
|
||||
|
||||
resp = await client.post("/auth/totp/enroll/start", json={"pending_token": pending_token})
|
||||
assert resp.status_code == 200, resp.text
|
||||
provisioning_uri = resp.json()["provisioning_uri"]
|
||||
secret = dict(part.split("=") for part in provisioning_uri.split("?", 1)[1].split("&"))["secret"]
|
||||
|
||||
code = pyotp.TOTP(secret).now()
|
||||
resp = await client.post(
|
||||
"/auth/totp/enroll/confirm", json={"pending_token": pending_token, "code": code}
|
||||
)
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert len(resp.json()["recovery_codes"]) == 10
|
||||
assert "jh_session" in resp.cookies
|
||||
|
||||
resp = await client.get("/auth/me")
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert resp.json()["username"] == "alice"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_wrong_password_rejected(client):
|
||||
from app.db import get_db
|
||||
from app.security.passwords import hash_password
|
||||
|
||||
conn = get_db()
|
||||
await conn.execute(
|
||||
"INSERT INTO users (username, password_hash, must_change_password) VALUES (?, ?, 0)",
|
||||
("bob", hash_password("Correct-Horse-Battery-Staple-2")),
|
||||
)
|
||||
await conn.commit()
|
||||
|
||||
resp = await client.post("/auth/login", json={"username": "bob", "password": "wrong"})
|
||||
assert resp.status_code == 401
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_unauthenticated_admin_access_denied(client):
|
||||
resp = await client.get("/admin/users")
|
||||
assert resp.status_code == 401
|
||||
Reference in New Issue
Block a user