test_auth.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import pytest
  2. from auth import is_allowed, safe_next
  3. from conftest import login_static
  4. # ---------- pure helpers ----------
  5. def test_is_allowed_exact_and_casefold():
  6. users = [{"email": "Alice@Example.com", "role": "admin"}]
  7. assert is_allowed("alice@example.com", users) == (True, "admin")
  8. assert is_allowed("ALICE@EXAMPLE.COM", users) == (True, "admin")
  9. def test_is_allowed_unknown():
  10. assert is_allowed("nobody@x.com", [{"email": "a@b.c", "role": "user"}]) == (False, None)
  11. assert is_allowed("", []) == (False, None)
  12. @pytest.mark.parametrize("target,expected", [
  13. ("//evil.com", "/"),
  14. ("https://evil.com", "/"),
  15. ("/\\evil.com", "/"),
  16. ("http:/evil", "/"),
  17. (None, "/"),
  18. ("", "/"),
  19. ("/", "/"),
  20. ("/admin", "/admin"),
  21. ("/api/messages?folder=x", "/api/messages?folder=x"),
  22. ])
  23. def test_safe_next(target, expected):
  24. assert safe_next(target) == expected
  25. # ---------- integration (static mode) ----------
  26. def test_static_login_and_session(app_client):
  27. csrf = login_static(app_client)
  28. assert csrf
  29. cfg = app_client.get("/api/config").get_json()
  30. assert cfg["is_admin"] is True
  31. def test_api_requires_auth(app_client):
  32. assert app_client.get("/api/config").status_code == 401
  33. assert app_client.get("/api/messages").status_code == 401
  34. def test_admin_gate(app_client):
  35. # not logged in -> 401 for api admin
  36. assert app_client.get("/api/admin/config").status_code == 401
  37. login_static(app_client) # dev is admin
  38. assert app_client.get("/api/admin/config").status_code == 200
  39. def test_csrf_required_on_post(app_client):
  40. csrf = login_static(app_client)
  41. # no token -> 400
  42. r = app_client.put("/api/prefs", json={"default_limit": 50})
  43. assert r.status_code == 400
  44. # with token -> ok
  45. r = app_client.put("/api/prefs", json={"default_limit": 50}, headers={"X-CSRF-Token": csrf})
  46. assert r.status_code == 200
  47. def test_denied_user_static_forced_admin(app_client):
  48. # static mode forces admin regardless of users list, so login always succeeds.
  49. r = app_client.post("/login", data={"username": "dev", "password": "devpass"})
  50. assert r.status_code == 302 # redirect, not denied
  51. def test_bad_static_credentials(app_client):
  52. r = app_client.post("/login", data={"username": "dev", "password": "wrong"})
  53. assert b"Invalid credentials" in r.data