token.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. from typing import Optional
  2. from pydantic import field_validator
  3. from clean_python import Json
  4. from clean_python import Scope
  5. from clean_python import Tenant
  6. from clean_python import User
  7. from clean_python import ValueObject
  8. __all__ = ["Token"]
  9. class Token(ValueObject):
  10. claims: Json
  11. @field_validator("claims")
  12. @classmethod
  13. def validate_claims(cls, v):
  14. if not isinstance(v, dict):
  15. return v
  16. assert v.get("sub"), "missing 'sub' claim"
  17. assert v.get("scope"), "missing 'scope' claim"
  18. assert v.get("username") or v.get(
  19. "client_id"
  20. ), "missing 'username' / 'client_id' claim"
  21. if v.get("tenant"):
  22. assert v.get("tenant_name"), "missing 'tenant_name' claim"
  23. return v
  24. @property
  25. def user(self) -> User:
  26. return User(
  27. id=self.claims["sub"],
  28. name=self.claims.get("username") or self.claims["client_id"],
  29. )
  30. @property
  31. def scope(self) -> Scope:
  32. return frozenset(self.claims["scope"].split(" "))
  33. @property
  34. def tenant(self) -> Optional[Tenant]:
  35. if self.claims.get("tenant"):
  36. return Tenant(id=self.claims["tenant"], name=self.claims["tenant_name"])
  37. else:
  38. return None