Skip to content

Commit

Permalink
fix lint and such
Browse files Browse the repository at this point in the history
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
  • Loading branch information
BeryJu committed Oct 10, 2023
1 parent 25ebdad commit 47ce8a3
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 27 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ lint-fix: ## Lint and automatically fix errors in the python source code. Repor
codespell -w $(CODESPELL_ARGS)

lint: ## Lint the python and golang sources
pylint $(PY_SOURCES)
bandit -r $(PY_SOURCES) -x node_modules
./web/node_modules/.bin/pyright $(PY_SOURCES)
pylint $(PY_SOURCES)
golangci-lint run -v

migrate: ## Run the Authentik Django server's migrations
Expand Down
8 changes: 4 additions & 4 deletions authentik/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@ def is_member(self, user: "User") -> bool:
"""Recursively check if `user` is member of us, or any parent."""
return user.all_groups().filter(group_uuid=self.group_uuid).exists()

def children_recursive(groups: Self | QuerySet["Group"]) -> QuerySet["Group"]:
def children_recursive(self: Self | QuerySet["Group"]) -> QuerySet["Group"]:
"""Recursively get all groups that have this as parent or are indirectly related"""
direct_groups = []
if isinstance(groups, QuerySet):
direct_groups = list(x for x in groups.all().values_list("pk", flat=True).iterator())
if isinstance(self, QuerySet):
direct_groups = list(x for x in self.all().values_list("pk", flat=True).iterator())
else:
direct_groups = [groups.pk]
direct_groups = [self.pk]
if len(direct_groups) < 1:
return Group.objects.none()
query = """
Expand Down
15 changes: 0 additions & 15 deletions authentik/core/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from django.contrib.sessions.backends.cache import KEY_PREFIX
from django.core.cache import cache
from django.db.transaction import atomic
from django.utils.timezone import now
from structlog.stdlib import get_logger

Expand All @@ -12,8 +11,6 @@
USER_ATTRIBUTE_GENERATED,
AuthenticatedSession,
ExpiringModel,
Group,
Role,
User,
)
from authentik.events.monitored_tasks import (
Expand Down Expand Up @@ -79,15 +76,3 @@ def clean_temporary_users(self: MonitoredTask):
deleted_users += 1
messages.append(f"Successfully deleted {deleted_users} users.")
self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, messages))


@CELERY_APP.task()
def sync_roles():
"""Sync users into roles"""
with atomic():
for ak_group in Group.objects.filter(roles__isnull=False).prefetch_related("roles"):
group_users = ak_group.children_recursive().values_list("users", flat=True)
for role in ak_group.roles.all():
role: Role
role.group.user_set.set(group_users)
LOGGER.debug("Updated users in group", group=ak_group)
2 changes: 1 addition & 1 deletion authentik/rbac/api/rbac.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class PermissionAssignSerializer(PassiveSerializer):
def validate(self, attrs: dict) -> dict:
if attrs.get("model"):
return attrs
permissions = attrs.get("permissions")
permissions = attrs.get("permissions", [])
if not all("." in perm for perm in permissions):
raise ValidationError(

Check warning on line 144 in authentik/rbac/api/rbac.py

View check run for this annotation

Codecov / codecov/patch

authentik/rbac/api/rbac.py#L140-L144

Added lines #L140 - L144 were not covered by tests
{
Expand Down
10 changes: 8 additions & 2 deletions authentik/rbac/api/rbac_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@


class RoleAssignedObjectPermissionSerializer(PassiveSerializer):
"""Roles assigned object permission serializer"""

name = CharField(source="group.name", read_only=True)
permissions = RoleObjectPermissionSerializer(
many=True, source="group.groupobjectpermission_set"
Expand All @@ -30,11 +32,14 @@ class Meta:
fields = ["name", "permissions"]


class AssignedPermissionFilter(FilterSet):
class RoleAssignedPermissionFilter(FilterSet):
"""Role Assigned permission filter"""

model = ChoiceFilter(choices=model_choices(), method="filter_model", required=True)
object_pk = CharFilter(method="filter_object_pk")

def filter_model(self, queryset: QuerySet, name, value: str) -> QuerySet:
"""Filter by object type"""
app, _, model = value.partition(".")
return queryset.filter(

Check warning on line 44 in authentik/rbac/api/rbac_roles.py

View check run for this annotation

Codecov / codecov/patch

authentik/rbac/api/rbac_roles.py#L43-L44

Added lines #L43 - L44 were not covered by tests
Q(
Expand All @@ -48,6 +53,7 @@ def filter_model(self, queryset: QuerySet, name, value: str) -> QuerySet:
)

def filter_object_pk(self, queryset: QuerySet, name, value: str) -> QuerySet:
"""Filter by object primary key"""
return queryset.filter(Q(group__groupobjectpermission__object_pk=value))

Check warning on line 57 in authentik/rbac/api/rbac_roles.py

View check run for this annotation

Codecov / codecov/patch

authentik/rbac/api/rbac_roles.py#L57

Added line #L57 was not covered by tests


Expand All @@ -58,7 +64,7 @@ class RoleAssignedPermissionViewSet(ListModelMixin, GenericViewSet):
# The filtering is done in the filterset,
# which has a required filter that does the heavy lifting
queryset = Role.objects.all()
filterset_class = AssignedPermissionFilter
filterset_class = RoleAssignedPermissionFilter

@extend_schema(
request=PermissionAssignSerializer(),
Expand Down
10 changes: 8 additions & 2 deletions authentik/rbac/api/rbac_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@


class UserAssignedObjectPermissionSerializer(GroupMemberSerializer):
"""Users assigned object permission serializer"""

permissions = UserObjectPermissionSerializer(many=True, source="userobjectpermission_set")
is_superuser = BooleanField()

Expand All @@ -28,11 +30,14 @@ class Meta:
fields = GroupMemberSerializer.Meta.fields + ["permissions", "is_superuser"]


class AssignedPermissionFilter(FilterSet):
class UserAssignedPermissionFilter(FilterSet):
"""Assigned permission filter"""

model = ChoiceFilter(choices=model_choices(), method="filter_model", required=True)
object_pk = CharFilter(method="filter_object_pk")

def filter_model(self, queryset: QuerySet, name, value: str) -> QuerySet:
"""Filter by object type"""
app, _, model = value.partition(".")
return queryset.filter(

Check warning on line 42 in authentik/rbac/api/rbac_users.py

View check run for this annotation

Codecov / codecov/patch

authentik/rbac/api/rbac_users.py#L41-L42

Added lines #L41 - L42 were not covered by tests
Q(
Expand All @@ -47,6 +52,7 @@ def filter_model(self, queryset: QuerySet, name, value: str) -> QuerySet:
).distinct()

def filter_object_pk(self, queryset: QuerySet, name, value: str) -> QuerySet:
"""Filter by object primary key"""
return queryset.filter(

Check warning on line 56 in authentik/rbac/api/rbac_users.py

View check run for this annotation

Codecov / codecov/patch

authentik/rbac/api/rbac_users.py#L56

Added line #L56 was not covered by tests
Q(userobjectpermission__object_pk=value) | Q(ak_groups__is_superuser=True),
).distinct()
Expand All @@ -59,7 +65,7 @@ class UserAssignedPermissionViewSet(CreateModelMixin, ListModelMixin, GenericVie
# The filtering is done in the filterset,
# which has a required filter that does the heavy lifting
queryset = User.objects.all()
filterset_class = AssignedPermissionFilter
filterset_class = UserAssignedPermissionFilter

@extend_schema(
request=PermissionAssignSerializer(),
Expand Down
12 changes: 11 additions & 1 deletion authentik/rbac/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"""RBAC models"""
from uuid import uuid4

from django.db import models
from django.utils.translation import gettext_lazy as _
from rest_framework.serializers import BaseSerializer

from authentik.lib.models import SerializerModel

class Role(models.Model):

class Role(SerializerModel):
"""RBAC role, which can have different permissions (both global and per-object) attached
to it."""

Expand All @@ -23,6 +27,12 @@ class Role(models.Model):
# name field has the same constraints as the group model
name = models.TextField(max_length=150, unique=True)

@property
def serializer(self) -> type[BaseSerializer]:
from authentik.rbac.api.roles import RoleSerializer

return RoleSerializer

def __str__(self) -> str:
return f"Role {self.name}"

Expand Down
2 changes: 2 additions & 0 deletions authentik/rbac/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ def rbac_group_role_m2m(sender: type[Group], action: str, instance: Group, rever
LOGGER.debug("Updated users in group", group=instance)

Check warning on line 39 in authentik/rbac/signals.py

View check run for this annotation

Codecov / codecov/patch

authentik/rbac/signals.py#L38-L39

Added lines #L38 - L39 were not covered by tests


# pylint: disable=no-member
@receiver(m2m_changed, sender=Group.users.through)
def rbac_group_users_m2m(
sender: type[Group], action: str, instance: Group, pk_set: set, reverse: bool, **_
):
"""Handle Group/User m2m and mirror it to roles"""
if action not in ["post_add", "post_remove"]:
return
# reverse: instance is a Group, pk_set is a list of user pks
Expand Down
8 changes: 7 additions & 1 deletion authentik/rbac/tests/test_roles.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""RBAC role tests"""
from guardian.shortcuts import assign_perm
from rest_framework.test import APITestCase

from authentik.core.models import Group, Role
from authentik.core.models import Group
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.generators import generate_id
from authentik.rbac.models import Role


class TestRoles(APITestCase):
Expand All @@ -14,17 +16,21 @@ def test_role_create(self):
user = create_test_admin_user()
group = Group.objects.create(name=generate_id())
role = Role.objects.create(name=generate_id())
assign_perm("authentik_core.view_application", role.group)
group.roles.add(role)
group.users.add(user)
self.assertEqual(list(role.group.user_set.all()), [user])
self.assertTrue(user.has_perm("authentik_core.view_application"))

def test_role_create_remove(self):
"""Test creation and remove"""
user = create_test_admin_user()
group = Group.objects.create(name=generate_id())
role = Role.objects.create(name=generate_id())
assign_perm("authentik_core.view_application", role.group)
group.roles.add(role)
group.users.add(user)
self.assertEqual(list(role.group.user_set.all()), [user])
self.assertTrue(user.has_perm("authentik_core.view_application"))
user.delete()
self.assertEqual(list(role.group.user_set.all()), [])
1 change: 1 addition & 0 deletions authentik/rbac/urls.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""RBAC API urls"""
from authentik.rbac.api.rbac import RBACPermissionViewSet
from authentik.rbac.api.rbac_roles import RoleAssignedPermissionViewSet
from authentik.rbac.api.rbac_users import UserAssignedPermissionViewSet
Expand Down

0 comments on commit 47ce8a3

Please sign in to comment.