authentik.rbac.models

RBAC models

  1"""RBAC models"""
  2
  3from uuid import uuid4
  4
  5from django.contrib.auth.management import _get_all_permissions
  6from django.contrib.auth.models import Permission
  7from django.db import models
  8from django.db.transaction import atomic
  9from django.utils.translation import gettext_lazy as _
 10from guardian.shortcuts import assign_perm, remove_perm
 11from rest_framework.serializers import BaseSerializer
 12
 13from authentik.blueprints.models import ManagedModel
 14from authentik.lib.models import SerializerModel
 15from authentik.lib.utils.reflection import get_apps
 16
 17
 18def get_permission_choices():
 19    all_perms = []
 20    for app in get_apps():
 21        for model in app.get_models():
 22            for perm, _desc in _get_all_permissions(model._meta):
 23                all_perms.append((model, perm))
 24    return sorted(
 25        [
 26            (
 27                f"{model._meta.app_label}.{perm}",
 28                f"{model._meta.app_label}.{perm}",
 29            )
 30            for model, perm in all_perms
 31        ]
 32    )
 33
 34
 35class Role(SerializerModel, ManagedModel):
 36    """RBAC role, which can have different permissions (both global and per-object) attached
 37    to it."""
 38
 39    uuid = models.UUIDField(default=uuid4, editable=False, unique=True, primary_key=True)
 40    name = models.TextField(unique=True)
 41
 42    @property
 43    def serializer(self) -> type[BaseSerializer]:
 44        from authentik.rbac.api.roles import RoleSerializer
 45
 46        return RoleSerializer
 47
 48    def __str__(self) -> str:
 49        return f"Role {self.name}"
 50
 51    class Meta:
 52        verbose_name = _("Role")
 53        verbose_name_plural = _("Roles")
 54        permissions = [
 55            ("assign_role_permissions", _("Can assign permissions to roles")),
 56            ("unassign_role_permissions", _("Can unassign permissions from roles")),
 57        ]
 58
 59    def assign_perms(
 60        self,
 61        perms: str | list[str] | Permission | list[Permission],
 62        obj: models.Model | None = None,
 63    ):
 64        """Assign permission to role, can handle multiple permissions,
 65        but when assigning multiple permissions to an object the permissions
 66        must all belong to the object given"""
 67        if not isinstance(perms, list):
 68            perms = [perms]
 69        with atomic():
 70            for perm in perms:
 71                assign_perm(perm, self, obj)
 72
 73    def remove_perms(
 74        self,
 75        perms: str | list[str] | Permission | list[Permission],
 76        obj: models.Model | None = None,
 77    ):
 78        """Assign permission to role, can handle multiple permissions,
 79        but when assigning multiple permissions to an object the permissions
 80        must all belong to the object given"""
 81        if isinstance(perms, str):
 82            perms = [perms]
 83        with atomic():
 84            for perm in perms:
 85                remove_perm(perm, self, obj)
 86
 87
 88class InitialPermissions(SerializerModel):
 89    """Assigns permissions for newly created objects."""
 90
 91    name = models.TextField(max_length=150, unique=True)
 92    role = models.ForeignKey(Role, on_delete=models.CASCADE)
 93    permissions = models.ManyToManyField(Permission, blank=True)
 94
 95    @property
 96    def serializer(self) -> type[BaseSerializer]:
 97        from authentik.rbac.api.initial_permissions import InitialPermissionsSerializer
 98
 99        return InitialPermissionsSerializer
100
101    def __str__(self) -> str:
102        return f"Initial Permissions for Role #{self.role_id}."
103
104    class Meta:
105        verbose_name = _("Initial Permissions")
106        verbose_name_plural = _("Initial Permissions")
107
108
109class SystemPermission(models.Model):
110    """System-wide permissions that are not related to any direct
111    database model"""
112
113    class Meta:
114        managed = False
115        default_permissions = ()
116        verbose_name = _("System permission")
117        verbose_name_plural = _("System permissions")
118        permissions = [
119            ("view_system_info", _("Can view system info")),
120            ("access_admin_interface", _("Can access admin interface")),
121            ("view_system_settings", _("Can view system settings")),
122            ("edit_system_settings", _("Can edit system settings")),
123            ("view_media_files", _("Can view media files")),
124            ("manage_media_files", _("Can manage media files")),
125        ]
126
127    def __str__(self) -> str:
128        return "System Permission"
def get_permission_choices():
19def get_permission_choices():
20    all_perms = []
21    for app in get_apps():
22        for model in app.get_models():
23            for perm, _desc in _get_all_permissions(model._meta):
24                all_perms.append((model, perm))
25    return sorted(
26        [
27            (
28                f"{model._meta.app_label}.{perm}",
29                f"{model._meta.app_label}.{perm}",
30            )
31            for model, perm in all_perms
32        ]
33    )
36class Role(SerializerModel, ManagedModel):
37    """RBAC role, which can have different permissions (both global and per-object) attached
38    to it."""
39
40    uuid = models.UUIDField(default=uuid4, editable=False, unique=True, primary_key=True)
41    name = models.TextField(unique=True)
42
43    @property
44    def serializer(self) -> type[BaseSerializer]:
45        from authentik.rbac.api.roles import RoleSerializer
46
47        return RoleSerializer
48
49    def __str__(self) -> str:
50        return f"Role {self.name}"
51
52    class Meta:
53        verbose_name = _("Role")
54        verbose_name_plural = _("Roles")
55        permissions = [
56            ("assign_role_permissions", _("Can assign permissions to roles")),
57            ("unassign_role_permissions", _("Can unassign permissions from roles")),
58        ]
59
60    def assign_perms(
61        self,
62        perms: str | list[str] | Permission | list[Permission],
63        obj: models.Model | None = None,
64    ):
65        """Assign permission to role, can handle multiple permissions,
66        but when assigning multiple permissions to an object the permissions
67        must all belong to the object given"""
68        if not isinstance(perms, list):
69            perms = [perms]
70        with atomic():
71            for perm in perms:
72                assign_perm(perm, self, obj)
73
74    def remove_perms(
75        self,
76        perms: str | list[str] | Permission | list[Permission],
77        obj: models.Model | None = None,
78    ):
79        """Assign permission to role, can handle multiple permissions,
80        but when assigning multiple permissions to an object the permissions
81        must all belong to the object given"""
82        if isinstance(perms, str):
83            perms = [perms]
84        with atomic():
85            for perm in perms:
86                remove_perm(perm, self, obj)

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

def uuid(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

serializer: type[rest_framework.serializers.BaseSerializer]
43    @property
44    def serializer(self) -> type[BaseSerializer]:
45        from authentik.rbac.api.roles import RoleSerializer
46
47        return RoleSerializer

Get serializer for this model

def assign_perms( self, perms: str | list[str] | django.contrib.auth.models.Permission | list[django.contrib.auth.models.Permission], obj: django.db.models.base.Model | None = None):
60    def assign_perms(
61        self,
62        perms: str | list[str] | Permission | list[Permission],
63        obj: models.Model | None = None,
64    ):
65        """Assign permission to role, can handle multiple permissions,
66        but when assigning multiple permissions to an object the permissions
67        must all belong to the object given"""
68        if not isinstance(perms, list):
69            perms = [perms]
70        with atomic():
71            for perm in perms:
72                assign_perm(perm, self, obj)

Assign permission to role, can handle multiple permissions, but when assigning multiple permissions to an object the permissions must all belong to the object given

def remove_perms( self, perms: str | list[str] | django.contrib.auth.models.Permission | list[django.contrib.auth.models.Permission], obj: django.db.models.base.Model | None = None):
74    def remove_perms(
75        self,
76        perms: str | list[str] | Permission | list[Permission],
77        obj: models.Model | None = None,
78    ):
79        """Assign permission to role, can handle multiple permissions,
80        but when assigning multiple permissions to an object the permissions
81        must all belong to the object given"""
82        if isinstance(perms, str):
83            perms = [perms]
84        with atomic():
85            for perm in perms:
86                remove_perm(perm, self, obj)

Assign permission to role, can handle multiple permissions, but when assigning multiple permissions to an object the permissions must all belong to the object given

def managed(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):

The type of the None singleton.

roleobjectpermission_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

rolemodelpermission_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

initialpermissions_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

groups

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example::

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

users

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example::

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

class Role.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class Role.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

class InitialPermissions(authentik.lib.models.SerializerModel):
 89class InitialPermissions(SerializerModel):
 90    """Assigns permissions for newly created objects."""
 91
 92    name = models.TextField(max_length=150, unique=True)
 93    role = models.ForeignKey(Role, on_delete=models.CASCADE)
 94    permissions = models.ManyToManyField(Permission, blank=True)
 95
 96    @property
 97    def serializer(self) -> type[BaseSerializer]:
 98        from authentik.rbac.api.initial_permissions import InitialPermissionsSerializer
 99
100        return InitialPermissionsSerializer
101
102    def __str__(self) -> str:
103        return f"Initial Permissions for Role #{self.role_id}."
104
105    class Meta:
106        verbose_name = _("Initial Permissions")
107        verbose_name_plural = _("Initial Permissions")

Assigns permissions for newly created objects.

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

role

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

permissions

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example::

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

serializer: type[rest_framework.serializers.BaseSerializer]
 96    @property
 97    def serializer(self) -> type[BaseSerializer]:
 98        from authentik.rbac.api.initial_permissions import InitialPermissionsSerializer
 99
100        return InitialPermissionsSerializer

Get serializer for this model

role_id
def id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):

The type of the None singleton.

class InitialPermissions.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class InitialPermissions.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

class SystemPermission(django.db.models.base.Model):
110class SystemPermission(models.Model):
111    """System-wide permissions that are not related to any direct
112    database model"""
113
114    class Meta:
115        managed = False
116        default_permissions = ()
117        verbose_name = _("System permission")
118        verbose_name_plural = _("System permissions")
119        permissions = [
120            ("view_system_info", _("Can view system info")),
121            ("access_admin_interface", _("Can access admin interface")),
122            ("view_system_settings", _("Can view system settings")),
123            ("edit_system_settings", _("Can edit system settings")),
124            ("view_media_files", _("Can view media files")),
125            ("manage_media_files", _("Can manage media files")),
126        ]
127
128    def __str__(self) -> str:
129        return "System Permission"

System-wide permissions that are not related to any direct database model

def id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):

The type of the None singleton.

class SystemPermission.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class SystemPermission.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.