core: add limit of 20 to group recursion

closes #3116

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-06-19 21:24:57 +02:00
parent 29d3db5112
commit 0d96e68c1e
4 changed files with 35 additions and 13 deletions

View File

@ -106,7 +106,10 @@ class Group(models.Model):
SELECT authentik_core_group.*, parents.relative_depth - 1 SELECT authentik_core_group.*, parents.relative_depth - 1
FROM authentik_core_group,parents FROM authentik_core_group,parents
WHERE authentik_core_group.parent_id = parents.group_uuid WHERE (
authentik_core_group.parent_id = parents.group_uuid and
parents.relative_depth > -20
)
) )
SELECT group_uuid SELECT group_uuid
FROM parents FROM parents

View File

@ -2,6 +2,7 @@
from django.test.testcases import TestCase from django.test.testcases import TestCase
from authentik.core.models import Group, User from authentik.core.models import Group, User
from authentik.lib.generators import generate_id
class TestGroups(TestCase): class TestGroups(TestCase):
@ -9,32 +10,43 @@ class TestGroups(TestCase):
def test_group_membership_simple(self): def test_group_membership_simple(self):
"""Test simple membership""" """Test simple membership"""
user = User.objects.create(username="user") user = User.objects.create(username=generate_id())
user2 = User.objects.create(username="user2") user2 = User.objects.create(username=generate_id())
group = Group.objects.create(name="group") group = Group.objects.create(name=generate_id())
group.users.add(user) group.users.add(user)
self.assertTrue(group.is_member(user)) self.assertTrue(group.is_member(user))
self.assertFalse(group.is_member(user2)) self.assertFalse(group.is_member(user2))
def test_group_membership_parent(self): def test_group_membership_parent(self):
"""Test parent membership""" """Test parent membership"""
user = User.objects.create(username="user") user = User.objects.create(username=generate_id())
user2 = User.objects.create(username="user2") user2 = User.objects.create(username=generate_id())
first = Group.objects.create(name="first") first = Group.objects.create(name=generate_id())
second = Group.objects.create(name="second", parent=first) second = Group.objects.create(name=generate_id(), parent=first)
second.users.add(user) second.users.add(user)
self.assertTrue(first.is_member(user)) self.assertTrue(first.is_member(user))
self.assertFalse(first.is_member(user2)) self.assertFalse(first.is_member(user2))
def test_group_membership_parent_extra(self): def test_group_membership_parent_extra(self):
"""Test parent membership""" """Test parent membership"""
user = User.objects.create(username="user") user = User.objects.create(username=generate_id())
user2 = User.objects.create(username="user2") user2 = User.objects.create(username=generate_id())
first = Group.objects.create(name="first") first = Group.objects.create(name=generate_id())
second = Group.objects.create(name="second", parent=first) second = Group.objects.create(name=generate_id(), parent=first)
third = Group.objects.create(name="third", parent=second) third = Group.objects.create(name=generate_id(), parent=second)
second.users.add(user) second.users.add(user)
self.assertTrue(first.is_member(user)) self.assertTrue(first.is_member(user))
self.assertFalse(first.is_member(user2)) self.assertFalse(first.is_member(user2))
self.assertFalse(third.is_member(user)) self.assertFalse(third.is_member(user))
self.assertFalse(third.is_member(user2)) self.assertFalse(third.is_member(user2))
def test_group_membership_recursive(self):
"""Test group membership (recursive)"""
user = User.objects.create(username=generate_id())
group = Group.objects.create(name=generate_id())
group2 = Group.objects.create(name=generate_id(), parent=group)
group.users.add(user)
group.parent = group2
group.save()
self.assertTrue(group.is_member(user))
self.assertTrue(group2.is_member(user))

View File

@ -9,6 +9,11 @@ slug: "2022.7"
Instead, create an OAuth Source with the certificate configured as JWKS Data, and enable the source in the provider. Instead, create an OAuth Source with the certificate configured as JWKS Data, and enable the source in the provider.
- Maximum Limit of group recursion
In earlier versions, cyclic group relations can lead to a deadlock when one of groups in the relationship are bound to an application/flow/etc.
This is now limited to 20 levels of recursion.
## New features ## New features
- User paths - User paths

View File

@ -8,6 +8,8 @@ Groups can be children of another group. Members of children groups are effectiv
When you bind a group to an application or flow, any members of any child group of the selected group will have access. When you bind a group to an application or flow, any members of any child group of the selected group will have access.
Recursion is limited to 20 levels to prevent deadlocks.
## Attributes ## Attributes
Attributes of groups are recursively merged, for all groups the user is a _direct_ member of. Attributes of groups are recursively merged, for all groups the user is a _direct_ member of.