conftest.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import json
  2. import os
  3. import random
  4. import string
  5. from typing import Optional, Tuple
  6. import pytest
  7. import requests
  8. class DeSECAPIV1Client:
  9. base_url = "https://desec." + os.environ["DESECSTACK_DOMAIN"] + "/api/v1"
  10. headers = {
  11. "Accept": "application/json",
  12. "Content-Type": "application/json",
  13. "User-Agent": "e2e2",
  14. }
  15. @staticmethod
  16. def random_email() -> str:
  17. return (
  18. "".join(random.choice(string.ascii_letters) for _ in range(10))
  19. + "@desec.test"
  20. )
  21. @staticmethod
  22. def random_password() -> str:
  23. return "".join(random.choice(string.ascii_letters) for _ in range(16))
  24. def __init__(self) -> None:
  25. super().__init__()
  26. self.email = None
  27. self.password = None
  28. def _request(self, method: str, *, path: str, data: Optional[dict] = None, **kwargs) -> requests.Response:
  29. if data is not None:
  30. data = json.dumps(data)
  31. return requests.request(
  32. method,
  33. self.base_url + path,
  34. data=data,
  35. headers=self.headers,
  36. verify=f'/autocert/desec.{os.environ["DESECSTACK_DOMAIN"]}.cer',
  37. **kwargs,
  38. )
  39. def get(self, path: str, **kwargs) -> requests.Response:
  40. return self._request("GET", path=path, **kwargs)
  41. def post(self, path: str, data: Optional[dict] = None, **kwargs) -> requests.Response:
  42. return self._request("POST", path=path, data=data, **kwargs)
  43. def register(self, email: str, password: str) -> Tuple[requests.Response, requests.Response]:
  44. self.email = email
  45. self.password = password
  46. captcha = self.post("/captcha/")
  47. return captcha, self.post(
  48. "/auth/",
  49. data={
  50. "email": email,
  51. "password": password,
  52. "captcha": {
  53. "id": captcha.json()["id"],
  54. "solution": captcha.json()[
  55. "content"
  56. ], # available via e2e configuration magic
  57. },
  58. },
  59. )
  60. def login(self, email: str, password: str) -> requests.Response:
  61. token = self.post(
  62. "/auth/login/", data={"email": email, "password": password}
  63. )
  64. self.headers["Authorization"] = f'Token {token.json()["token"]}'
  65. return token
  66. @pytest.fixture
  67. def api_anon() -> DeSECAPIV1Client:
  68. """
  69. Anonymous access to the API.
  70. """
  71. return DeSECAPIV1Client()
  72. @pytest.fixture()
  73. def api_user(api_anon) -> DeSECAPIV1Client:
  74. """
  75. Access to the API with a fresh user account (zero domains, one token). Authorization header
  76. is preconfigured, email address and password are randomly chosen.
  77. """
  78. api = api_anon
  79. email = api.random_email()
  80. password = api.random_password()
  81. api.register(email, password)
  82. api.login(email, password)
  83. return api