feat(auth): Add OAuth2 authentication

This commit is contained in:
Björn Benouarets
2026-01-27 16:35:46 +01:00
commit 50c85e9b7f
36 changed files with 1599 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
from __future__ import annotations
from datetime import datetime
from typing import Any, Optional
class Application:
def __init__(self, id: str, name: str, secret: str, tenant_id: str, expires_at: datetime | str | None, created_at: datetime | str, updated_at: datetime | str, deleted_at: datetime | str | None) -> None:
self.id = id
self.name = name
self.secret = secret
self.tenant_id = tenant_id
self.expires_at = expires_at
self.created_at = self._parse_datetime(created_at)
self.updated_at = self._parse_datetime(updated_at)
self.deleted_at = self._parse_datetime(deleted_at) if deleted_at is not None else None
def __str__(self) -> str:
return f"{self.name} - {self.id} - {self.secret} - {self.tenant_id} - {self.expires_at} - {self.created_at} - {self.updated_at} - {self.deleted_at}"
@staticmethod
def _parse_datetime(value: Any) -> Any:
if isinstance(value, datetime):
return value
if isinstance(value, str):
try:
return datetime.fromisoformat(value)
except ValueError:
return value

33
secnex/kit/models/key.py Normal file
View File

@@ -0,0 +1,33 @@
from __future__ import annotations
from datetime import datetime
from typing import Any, Optional
class ApiKey:
def __init__(self,
id: str,
key: str,
enabled: bool,
created_at: datetime | str | None,
updated_at: datetime | str | None,
deleted_at: datetime | str | None,
) -> None:
self.id = id
self.key = key
self.enabled = enabled
self.created_at = self._parse_datetime(created_at)
self.updated_at = self._parse_datetime(updated_at)
self.deleted_at = self._parse_datetime(deleted_at) if deleted_at is not None else None
def __str__(self) -> str:
return f"{self.id} - {self.key} - {self.enabled} - {self.created_at} - {self.updated_at} - {self.deleted_at}"
@staticmethod
def _parse_datetime(value: Any) -> Any:
if isinstance(value, datetime):
return value
if isinstance(value, str):
try:
return datetime.fromisoformat(value)
except ValueError:
return value

View File

@@ -0,0 +1,39 @@
from __future__ import annotations
from datetime import datetime
from typing import Any, Optional
class Tenant:
def __init__(
self,
id: str,
name: str,
enabled: bool,
allow_self_registration: bool,
allow_self_registration_domains: Optional[list[str]],
created_at: datetime | str,
updated_at: datetime | str,
deleted_at: datetime | str | None,
) -> None:
self.id = id
self.name = name
self.enabled = enabled
self.allow_self_registration = allow_self_registration
self.allow_self_registration_domains = allow_self_registration_domains or []
self.created_at = self._parse_datetime(created_at)
self.updated_at = self._parse_datetime(updated_at)
self.deleted_at = self._parse_datetime(deleted_at) if deleted_at is not None else None
def __str__(self) -> str:
return f"{self.name} - {self.id} - {self.enabled} - {self.allow_self_registration} - {self.allow_self_registration_domains} - {self.created_at} - {self.updated_at} - {self.deleted_at}"
@staticmethod
def _parse_datetime(value: Any) -> Any:
if isinstance(value, datetime):
return value
if isinstance(value, str):
try:
return datetime.fromisoformat(value)
except ValueError:
return value
return value

47
secnex/kit/models/user.py Normal file
View File

@@ -0,0 +1,47 @@
from __future__ import annotations
from datetime import datetime
from typing import Any, Optional
class User:
def __init__(
self,
id: str,
first_name: str,
last_name: str,
username: str,
email: str,
password: str,
verified: bool,
external_id: Optional[str],
tenant_id: Optional[str],
created_at: datetime | str,
updated_at: datetime | str,
deleted_at: datetime | str | None,
) -> None:
self.id = id
self.first_name = first_name
self.last_name = last_name
self.username = username
self.email = email
self.password = password
self.verified = verified
self.external_id = external_id
self.tenant_id = tenant_id
self.created_at = self._parse_datetime(created_at)
self.updated_at = self._parse_datetime(updated_at)
self.deleted_at = self._parse_datetime(deleted_at) if deleted_at is not None else None
def __str__(self) -> str:
return f"{self.first_name} {self.last_name} - {self.email} - {self.id} - {self.tenant_id} - {self.created_at} - {self.updated_at} - {self.deleted_at}"
@staticmethod
def _parse_datetime(value: Any) -> Any:
if isinstance(value, datetime):
return value
if isinstance(value, str):
try:
return datetime.fromisoformat(value)
except ValueError:
return value
return value