core: show users and groups when user has overall user permissions

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-05-05 01:02:47 +02:00
parent 32934fcd38
commit 1a02049104
4 changed files with 42 additions and 4 deletions

View File

@ -1,7 +1,9 @@
"""Groups API Viewset""" """Groups API Viewset"""
from django.db.models.query import QuerySet
from rest_framework.fields import JSONField from rest_framework.fields import JSONField
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework_guardian.filters import ObjectPermissionsFilter
from authentik.core.api.utils import is_dict from authentik.core.api.utils import is_dict
from authentik.core.models import Group from authentik.core.models import Group
@ -26,3 +28,16 @@ class GroupViewSet(ModelViewSet):
search_fields = ["name", "is_superuser"] search_fields = ["name", "is_superuser"]
filterset_fields = ["name", "is_superuser"] filterset_fields = ["name", "is_superuser"]
ordering = ["name"] ordering = ["name"]
def _filter_queryset_for_list(self, queryset: QuerySet) -> QuerySet:
"""Custom filter_queryset method which ignores guardian, but still supports sorting"""
for backend in list(self.filter_backends):
if backend == ObjectPermissionsFilter:
continue
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
def filter_queryset(self, queryset):
if self.request.user.has_perm("authentik_core.view_group"):
return self._filter_queryset_for_list(queryset)
return super().filter_queryset(queryset)

View File

@ -1,6 +1,7 @@
"""User API Views""" """User API Views"""
from json import loads from json import loads
from django.db.models.query import QuerySet
from django.http.response import Http404 from django.http.response import Http404
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.http import urlencode from django.utils.http import urlencode
@ -19,6 +20,7 @@ from rest_framework.serializers import (
ValidationError, ValidationError,
) )
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework_guardian.filters import ObjectPermissionsFilter
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
from authentik.api.decorators import permission_required from authentik.api.decorators import permission_required
@ -185,3 +187,16 @@ class UserViewSet(ModelViewSet):
reverse_lazy("authentik_flows:default-recovery") + f"?{querystring}" reverse_lazy("authentik_flows:default-recovery") + f"?{querystring}"
) )
return Response({"link": link}) return Response({"link": link})
def _filter_queryset_for_list(self, queryset: QuerySet) -> QuerySet:
"""Custom filter_queryset method which ignores guardian, but still supports sorting"""
for backend in list(self.filter_backends):
if backend == ObjectPermissionsFilter:
continue
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
def filter_queryset(self, queryset):
if self.request.user.has_perm("authentik_core.view_group"):
return self._filter_queryset_for_list(queryset)
return super().filter_queryset(queryset)

View File

@ -87,7 +87,7 @@ class ConfigLoader:
if url.scheme == "env": if url.scheme == "env":
value = os.getenv(url.netloc, url.query) value = os.getenv(url.netloc, url.query)
if url.scheme == "file": if url.scheme == "file":
with open(url.netloc, 'r') as _file: with open(url.netloc, "r") as _file:
value = _file.read() value = _file.read()
return value return value

View File

@ -1,7 +1,7 @@
"""Outpost models""" """Outpost models"""
from dataclasses import asdict, dataclass, field from dataclasses import asdict, dataclass, field
from datetime import datetime from datetime import datetime
from typing import Any, Iterable, Optional, Union from typing import Iterable, Optional, Union
from uuid import uuid4 from uuid import uuid4
from dacite import from_dict from dacite import from_dict
@ -336,7 +336,7 @@ class Outpost(models.Model):
# the ones the user needs # the ones the user needs
with transaction.atomic(): with transaction.atomic():
UserObjectPermission.objects.filter(user=user).delete() UserObjectPermission.objects.filter(user=user).delete()
Permission.objects.filter(user=user).delete() user.user_permissions.clear()
for model_or_perm in self.get_required_objects(): for model_or_perm in self.get_required_objects():
if isinstance(model_or_perm, models.Model): if isinstance(model_or_perm, models.Model):
model_or_perm: models.Model model_or_perm: models.Model
@ -346,7 +346,15 @@ class Outpost(models.Model):
) )
assign_perm(code_name, user, model_or_perm) assign_perm(code_name, user, model_or_perm)
else: else:
assign_perm(model_or_perm, user) app_label, perm = model_or_perm.split(".")
permission = Permission.objects.filter(
codename=perm,
content_type__app_label=app_label,
)
if not permission.exists():
LOGGER.warning("permission doesn't exist", perm=model_or_perm)
continue
user.user_permissions.add(permission.first())
LOGGER.debug("Updated service account's permissions") LOGGER.debug("Updated service account's permissions")
return user return user