Skip to content

Commit bb20576

Browse files
authored
providers/scim: save attributes returned from remote system like google workspace and entra ID (#13459)
providers/scim: save attributes returned from remote system like google workspace and entra Signed-off-by: Jens Langhammer <[email protected]>
1 parent 5f315bd commit bb20576

File tree

9 files changed

+60
-4
lines changed

9 files changed

+60
-4
lines changed

authentik/providers/scim/api/groups.py

+2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ class Meta:
2424
"group",
2525
"group_obj",
2626
"provider",
27+
"attributes",
2728
]
29+
extra_kwargs = {"attributes": {"read_only": True}}
2830

2931

3032
class SCIMProviderGroupViewSet(

authentik/providers/scim/api/users.py

+2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ class Meta:
2424
"user",
2525
"user_obj",
2626
"provider",
27+
"attributes",
2728
]
29+
extra_kwargs = {"attributes": {"read_only": True}}
2830

2931

3032
class SCIMProviderUserViewSet(

authentik/providers/scim/clients/groups.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def create(self, group: Group):
102102
if not scim_id or scim_id == "":
103103
raise StopSync("SCIM Response with missing or invalid `id`")
104104
connection = SCIMProviderGroup.objects.create(
105-
provider=self.provider, group=group, scim_id=scim_id
105+
provider=self.provider, group=group, scim_id=scim_id, attributes=response
106106
)
107107
users = list(group.users.order_by("id").values_list("id", flat=True))
108108
self._patch_add_users(connection, users)

authentik/providers/scim/clients/users.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -77,25 +77,30 @@ def create(self, user: User):
7777
if len(users_res) < 1:
7878
raise exc
7979
return SCIMProviderUser.objects.create(
80-
provider=self.provider, user=user, scim_id=users_res[0]["id"]
80+
provider=self.provider,
81+
user=user,
82+
scim_id=users_res[0]["id"],
83+
attributes=users_res[0],
8184
)
8285
else:
8386
scim_id = response.get("id")
8487
if not scim_id or scim_id == "":
8588
raise StopSync("SCIM Response with missing or invalid `id`")
8689
return SCIMProviderUser.objects.create(
87-
provider=self.provider, user=user, scim_id=scim_id
90+
provider=self.provider, user=user, scim_id=scim_id, attributes=response
8891
)
8992

9093
def update(self, user: User, connection: SCIMProviderUser):
9194
"""Update existing user"""
9295
scim_user = self.to_schema(user, connection)
9396
scim_user.id = connection.scim_id
94-
self._request(
97+
response = self._request(
9598
"PUT",
9699
f"/Users/{connection.scim_id}",
97100
json=scim_user.model_dump(
98101
mode="json",
99102
exclude_unset=True,
100103
),
101104
)
105+
connection.attributes = response
106+
connection.save()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 5.0.12 on 2025-03-11 13:51
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("authentik_providers_scim", "0011_scimprovider_dry_run"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="scimprovidergroup",
15+
name="attributes",
16+
field=models.JSONField(default=dict),
17+
),
18+
migrations.AddField(
19+
model_name="scimprovideruser",
20+
name="attributes",
21+
field=models.JSONField(default=dict),
22+
),
23+
]

authentik/providers/scim/models.py

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class SCIMProviderUser(SerializerModel):
2222
scim_id = models.TextField()
2323
user = models.ForeignKey(User, on_delete=models.CASCADE)
2424
provider = models.ForeignKey("SCIMProvider", on_delete=models.CASCADE)
25+
attributes = models.JSONField(default=dict)
2526

2627
@property
2728
def serializer(self) -> type[Serializer]:
@@ -43,6 +44,7 @@ class SCIMProviderGroup(SerializerModel):
4344
scim_id = models.TextField()
4445
group = models.ForeignKey(Group, on_delete=models.CASCADE)
4546
provider = models.ForeignKey("SCIMProvider", on_delete=models.CASCADE)
47+
attributes = models.JSONField(default=dict)
4648

4749
@property
4850
def serializer(self) -> type[Serializer]:

schema.yml

+6
Original file line numberDiff line numberDiff line change
@@ -55897,7 +55897,10 @@ components:
5589755897
readOnly: true
5589855898
provider:
5589955899
type: integer
55900+
attributes:
55901+
readOnly: true
5590055902
required:
55903+
- attributes
5590155904
- group
5590255905
- group_obj
5590355906
- id
@@ -55984,7 +55987,10 @@ components:
5598455987
readOnly: true
5598555988
provider:
5598655989
type: integer
55990+
attributes:
55991+
readOnly: true
5598755992
required:
55993+
- attributes
5598855994
- id
5598955995
- provider
5599055996
- scim_id

web/src/admin/providers/scim/SCIMProviderGroupList.ts

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class SCIMProviderGroupList extends Table<SCIMProviderGroup> {
2424
return true;
2525
}
2626

27+
expandable = true;
2728
checkbox = true;
2829
clearOnRefresh = true;
2930

@@ -81,6 +82,13 @@ export class SCIMProviderGroupList extends Table<SCIMProviderGroup> {
8182
html`${item.id}`,
8283
];
8384
}
85+
renderExpanded(item: SCIMProviderGroup): TemplateResult {
86+
return html`<td role="cell" colspan="4">
87+
<div class="pf-c-table__expandable-row-content">
88+
<pre>${JSON.stringify(item.attributes, null, 4)}</pre>
89+
</div>
90+
</td>`;
91+
}
8492
}
8593

8694
declare global {

web/src/admin/providers/scim/SCIMProviderUserList.ts

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class SCIMProviderUserList extends Table<SCIMProviderUser> {
2424
return true;
2525
}
2626

27+
expandable = true;
2728
checkbox = true;
2829
clearOnRefresh = true;
2930

@@ -82,6 +83,13 @@ export class SCIMProviderUserList extends Table<SCIMProviderUser> {
8283
html`${item.id}`,
8384
];
8485
}
86+
renderExpanded(item: SCIMProviderUser): TemplateResult {
87+
return html`<td role="cell" colspan="4">
88+
<div class="pf-c-table__expandable-row-content">
89+
<pre>${JSON.stringify(item.attributes, null, 4)}</pre>
90+
</div>
91+
</td>`;
92+
}
8593
}
8694

8795
declare global {

0 commit comments

Comments
 (0)