mirror of
https://github.com/goauthentik/authentik.git
synced 2026-08-30 18:51:39 -07:00
providers/scim: fix scim changed detection for nested attributes (#24332)
fix scim changed detection for nested attributes Co-authored-by: Jens L. <jens@goauthentik.io>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
"""Group client"""
|
||||
|
||||
from copy import deepcopy
|
||||
from itertools import batched
|
||||
from typing import Any
|
||||
|
||||
@@ -135,12 +136,11 @@ class SCIMGroupClient(SCIMClient[Group, SCIMProviderGroup, SCIMGroupSchema]):
|
||||
self._patch_add_users(connection, users)
|
||||
return connection
|
||||
|
||||
def diff(self, local_created: dict[str, Any], connection: SCIMProviderUser):
|
||||
def diff(self, local_created: dict[str, Any], connection: SCIMProviderGroup):
|
||||
"""Check if a group is different than what we last wrote to the remote system.
|
||||
Returns true if there is a difference in data."""
|
||||
local_known = connection.attributes
|
||||
local_updated = {}
|
||||
MERGE_LIST_UNIQUE.merge(local_updated, local_known)
|
||||
local_updated = deepcopy(local_known)
|
||||
MERGE_LIST_UNIQUE.merge(local_updated, local_created)
|
||||
return self._json_encoder.encode(local_updated) != self._json_encoder.encode(local_known)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""User client"""
|
||||
|
||||
from copy import deepcopy
|
||||
from typing import Any
|
||||
|
||||
from django.db import transaction
|
||||
@@ -95,8 +96,7 @@ class SCIMUserClient(SCIMClient[User, SCIMProviderUser, SCIMUserSchema]):
|
||||
"""Check if a user is different than what we last wrote to the remote system.
|
||||
Returns true if there is a difference in data."""
|
||||
local_known = connection.attributes
|
||||
local_updated = {}
|
||||
MERGE_LIST_UNIQUE.merge(local_updated, local_known)
|
||||
local_updated = deepcopy(local_known)
|
||||
MERGE_LIST_UNIQUE.merge(local_updated, local_created)
|
||||
return self._json_encoder.encode(local_updated) != self._json_encoder.encode(local_known)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from requests_mock import Mocker
|
||||
from authentik.blueprints.tests import apply_blueprint
|
||||
from authentik.core.models import Application, Group, User
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.scim.clients.groups import SCIMGroupClient
|
||||
from authentik.providers.scim.models import SCIMMapping, SCIMProvider, SCIMProviderGroup
|
||||
from authentik.providers.scim.tasks import scim_sync
|
||||
|
||||
@@ -209,6 +210,20 @@ class SCIMGroupTests(TestCase):
|
||||
self.assertEqual(mock.request_history[2].method, "GET")
|
||||
self.assertNotIn("PUT", [req.method for req in mock.request_history])
|
||||
|
||||
@Mocker()
|
||||
def test_group_diff_nested_attribute(self, mock: Mocker):
|
||||
"""Test nested attribute changes are detected without mutating cached data"""
|
||||
mock.get("https://localhost/ServiceProviderConfig", json={})
|
||||
connection = SCIMProviderGroup(attributes={"custom": {"value": "old"}})
|
||||
|
||||
self.assertTrue(
|
||||
SCIMGroupClient(self.provider).diff(
|
||||
{"custom": {"value": "new"}},
|
||||
connection,
|
||||
)
|
||||
)
|
||||
self.assertEqual(connection.attributes["custom"]["value"], "old")
|
||||
|
||||
@Mocker()
|
||||
def test_discover(self, mock: Mocker):
|
||||
group = Group.objects.create(name="acl_admins")
|
||||
|
||||
@@ -12,6 +12,7 @@ from authentik.core.models import Application, Group, User, UserTypes
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.lib.sync.outgoing.base import SAFE_METHODS
|
||||
from authentik.lib.sync.outgoing.exceptions import TransientSyncException
|
||||
from authentik.providers.scim.clients.users import SCIMUserClient
|
||||
from authentik.providers.scim.models import SCIMMapping, SCIMProvider, SCIMProviderUser
|
||||
from authentik.providers.scim.tasks import scim_sync, scim_sync_objects, sync_tasks
|
||||
from authentik.tasks.models import Task
|
||||
@@ -540,6 +541,35 @@ class SCIMUserTests(TestCase):
|
||||
self.assertEqual(mock.request_history[0].method, "GET")
|
||||
self.assertEqual(mock.request_history[1].method, "POST")
|
||||
|
||||
@Mocker()
|
||||
def test_user_diff_nested_attribute(self, mock: Mocker):
|
||||
"""Test nested attribute changes are detected without mutating cached data"""
|
||||
mock.get("https://localhost/ServiceProviderConfig", json={})
|
||||
connection = SCIMProviderUser(
|
||||
attributes={
|
||||
"urn:ietf:params:scim:schemas:extension:example:2.0:User": {
|
||||
"birthDate": "1990-01-31"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
self.assertTrue(
|
||||
SCIMUserClient(self.provider).diff(
|
||||
{
|
||||
"urn:ietf:params:scim:schemas:extension:example:2.0:User": {
|
||||
"birthDate": "1991-02-01"
|
||||
}
|
||||
},
|
||||
connection,
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
connection.attributes["urn:ietf:params:scim:schemas:extension:example:2.0:User"][
|
||||
"birthDate"
|
||||
],
|
||||
"1990-01-31",
|
||||
)
|
||||
|
||||
@Mocker()
|
||||
def test_discover(self, mock: Mocker):
|
||||
user = User.objects.create(username="admin@goauthentik.io")
|
||||
|
||||
Reference in New Issue
Block a user