feat: api route to get api client infos

This commit is contained in:
imperosol
2025-10-25 21:45:27 +02:00
parent 1f3a483b1b
commit 2a79bf4978
3 changed files with 46 additions and 22 deletions

16
api/api.py Normal file
View File

@@ -0,0 +1,16 @@
from ninja_extra import ControllerBase, api_controller, route
from api.auth import ApiKeyAuth
from api.schemas import ApiClientSchema
@api_controller("/client")
class ApiClientController(ControllerBase):
@route.get(
"/me",
auth=[ApiKeyAuth()],
response=ApiClientSchema,
url_name="api-client-infos",
)
def get_client_info(self):
return self.context.request.auth

View File

@@ -2,6 +2,8 @@ from typing import Iterable
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.db import models from django.db import models
from django.db.models import Q
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.utils.translation import pgettext_lazy from django.utils.translation import pgettext_lazy
@@ -29,8 +31,6 @@ class ApiClient(models.Model):
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True) updated_at = models.DateTimeField(auto_now=True)
_perm_cache: set[str] | None = None
class Meta: class Meta:
verbose_name = _("api client") verbose_name = _("api client")
verbose_name_plural = _("api clients") verbose_name_plural = _("api clients")
@@ -38,29 +38,23 @@ class ApiClient(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
def has_perm(self, perm: str): @cached_property
"""Return True if the client has the specified permission.""" def all_permissions(self) -> set[str]:
permissions = (
if self._perm_cache is None: Permission.objects.filter(
group_permissions = ( Q(group__group__in=self.groups.all()) | Q(clients=self)
Permission.objects.filter(group__group__in=self.groups.all()) )
.values_list("content_type__app_label", "codename") .values_list("content_type__app_label", "codename")
.order_by() .order_by()
) )
client_permissions = self.client_permissions.values_list( return {f"{content_type}.{name}" for content_type, name in permissions}
"content_type__app_label", "codename"
).order_by()
self._perm_cache = {
f"{content_type}.{name}"
for content_type, name in (*group_permissions, *client_permissions)
}
return perm in self._perm_cache
def has_perms(self, perm_list): def has_perm(self, perm: str):
""" """Return True if the client has the specified permission."""
Return True if the client has each of the specified permissions. If return perm in self.all_permissions
object is passed, check if the client has all required perms for it.
""" def has_perms(self, perm_list: Iterable[str]) -> bool:
"""Return True if the client has each of the specified permissions."""
if not isinstance(perm_list, Iterable) or isinstance(perm_list, str): if not isinstance(perm_list, Iterable) or isinstance(perm_list, str):
raise ValueError("perm_list must be an iterable of permissions.") raise ValueError("perm_list must be an iterable of permissions.")
return all(self.has_perm(perm) for perm in perm_list) return all(self.has_perm(perm) for perm in perm_list)

14
api/schemas.py Normal file
View File

@@ -0,0 +1,14 @@
from ninja import ModelSchema
from pydantic import Field
from api.models import ApiClient
from core.schemas import SimpleUserSchema
class ApiClientSchema(ModelSchema):
class Meta:
model = ApiClient
fields = ["id", "name"]
owner: SimpleUserSchema
permissions: list[str] = Field(alias="all_permissions")