Skip to content

Commit c47fb26

Browse files
jorhettrisssonBeryJu
authored
providers/scim: add compatibility mode for AWS & Slack (#13342)
* providers/scim: override AWS patch support AWS /ServiceProviderConfig query responds that it supports patch, but they only support patching a single group property. resolves #12321 * introduce compatibility mode for scim provider instead of hack Signed-off-by: Marc 'risson' Schmitt <[email protected]> * add option for slack Signed-off-by: Jens Langhammer <[email protected]> --------- Signed-off-by: Marc 'risson' Schmitt <[email protected]> Signed-off-by: Jens Langhammer <[email protected]> Co-authored-by: Marc 'risson' Schmitt <[email protected]> Co-authored-by: Jens Langhammer <[email protected]>
1 parent 23c0d90 commit c47fb26

File tree

7 files changed

+109
-2
lines changed

7 files changed

+109
-2
lines changed

authentik/providers/scim/api/providers.py

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Meta:
2828
"url",
2929
"verify_certificates",
3030
"token",
31+
"compatibility_mode",
3132
"exclude_users_service_account",
3233
"filter_group",
3334
"dry_run",

authentik/providers/scim/clients/base.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from authentik.lib.utils.http import get_http_session
2323
from authentik.providers.scim.clients.exceptions import SCIMRequestException
2424
from authentik.providers.scim.clients.schema import ServiceProviderConfiguration
25-
from authentik.providers.scim.models import SCIMProvider
25+
from authentik.providers.scim.models import SCIMCompatibilityMode, SCIMProvider
2626

2727
if TYPE_CHECKING:
2828
from django.db.models import Model
@@ -90,9 +90,14 @@ def get_service_provider_config(self):
9090
"""Get Service provider config"""
9191
default_config = ServiceProviderConfiguration.default()
9292
try:
93-
return ServiceProviderConfiguration.model_validate(
93+
config = ServiceProviderConfiguration.model_validate(
9494
self._request("GET", "/ServiceProviderConfig")
9595
)
96+
if self.provider.compatibility_mode == SCIMCompatibilityMode.AWS:
97+
config.patch.supported = False
98+
if self.provider.compatibility_mode == SCIMCompatibilityMode.SLACK:
99+
config.filter.supported = True
100+
return config
96101
except (ValidationError, SCIMRequestException, NotFoundSyncException) as exc:
97102
self.logger.warning("failed to get ServiceProviderConfig", exc=exc)
98103
return default_config
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Generated by Django 5.0.12 on 2025-03-07 23:35
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="scimprovider",
15+
name="compatibility_mode",
16+
field=models.CharField(
17+
choices=[("default", "Default"), ("aws", "AWS"), ("slack", "Slack")],
18+
default="default",
19+
help_text="Alter authentik behavior for vendor-specific SCIM implementations.",
20+
max_length=30,
21+
verbose_name="SCIM Compatibility Mode",
22+
),
23+
),
24+
]

authentik/providers/scim/models.py

+16
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ def __str__(self) -> str:
5757
return f"SCIM Provider Group {self.group_id} to {self.provider_id}"
5858

5959

60+
class SCIMCompatibilityMode(models.TextChoices):
61+
"""SCIM compatibility mode"""
62+
63+
DEFAULT = "default", _("Default")
64+
AWS = "aws", _("AWS")
65+
SLACK = "slack", _("Slack")
66+
67+
6068
class SCIMProvider(OutgoingSyncProvider, BackchannelProvider):
6169
"""SCIM 2.0 provider to create users and groups in external applications"""
6270

@@ -77,6 +85,14 @@ class SCIMProvider(OutgoingSyncProvider, BackchannelProvider):
7785
help_text=_("Property mappings used for group creation/updating."),
7886
)
7987

88+
compatibility_mode = models.CharField(
89+
max_length=30,
90+
choices=SCIMCompatibilityMode.choices,
91+
default=SCIMCompatibilityMode.DEFAULT,
92+
verbose_name=_("SCIM Compatibility Mode"),
93+
help_text=_("Alter authentik behavior for vendor-specific SCIM implementations."),
94+
)
95+
8096
@property
8197
def icon_url(self) -> str | None:
8298
return static("authentik/sources/scim.png")

blueprints/schema.json

+10
Original file line numberDiff line numberDiff line change
@@ -6661,6 +6661,16 @@
66616661
"title": "Token",
66626662
"description": "Authentication token"
66636663
},
6664+
"compatibility_mode": {
6665+
"type": "string",
6666+
"enum": [
6667+
"default",
6668+
"aws",
6669+
"slack"
6670+
],
6671+
"title": "SCIM Compatibility Mode",
6672+
"description": "Alter authentik behavior for vendor-specific SCIM implementations."
6673+
},
66646674
"exclude_users_service_account": {
66656675
"type": "boolean",
66666676
"title": "Exclude users service account"

schema.yml

+21
Original file line numberDiff line numberDiff line change
@@ -41582,6 +41582,12 @@ components:
4158241582
- confidential
4158341583
- public
4158441584
type: string
41585+
CompatibilityModeEnum:
41586+
enum:
41587+
- default
41588+
- aws
41589+
- slack
41590+
type: string
4158541591
Config:
4158641592
type: object
4158741593
description: Serialize authentik Config into DRF Object
@@ -52441,6 +52447,11 @@ components:
5244152447
type: string
5244252448
minLength: 1
5244352449
description: Authentication token
52450+
compatibility_mode:
52451+
allOf:
52452+
- $ref: '#/components/schemas/CompatibilityModeEnum'
52453+
title: SCIM Compatibility Mode
52454+
description: Alter authentik behavior for vendor-specific SCIM implementations.
5244452455
exclude_users_service_account:
5244552456
type: boolean
5244652457
filter_group:
@@ -55841,6 +55852,11 @@ components:
5584155852
token:
5584255853
type: string
5584355854
description: Authentication token
55855+
compatibility_mode:
55856+
allOf:
55857+
- $ref: '#/components/schemas/CompatibilityModeEnum'
55858+
title: SCIM Compatibility Mode
55859+
description: Alter authentik behavior for vendor-specific SCIM implementations.
5584455860
exclude_users_service_account:
5584555861
type: boolean
5584655862
filter_group:
@@ -55931,6 +55947,11 @@ components:
5593155947
type: string
5593255948
minLength: 1
5593355949
description: Authentication token
55950+
compatibility_mode:
55951+
allOf:
55952+
- $ref: '#/components/schemas/CompatibilityModeEnum'
55953+
title: SCIM Compatibility Mode
55954+
description: Alter authentik behavior for vendor-specific SCIM implementations.
5593455955
exclude_users_service_account:
5593555956
type: boolean
5593655957
filter_group:

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

+30
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { html } from "lit";
1111
import { ifDefined } from "lit/directives/if-defined.js";
1212

1313
import {
14+
CompatibilityModeEnum,
1415
CoreApi,
1516
CoreGroupsListRequest,
1617
Group,
@@ -61,6 +62,35 @@ export function renderForm(provider?: Partial<SCIMProvider>, errors: ValidationE
6162
)}
6263
inputHint="code"
6364
></ak-text-input>
65+
<ak-radio-input
66+
name="compatibilityMode"
67+
label=${msg("Compatibility Mode")}
68+
.value=${provider?.compatibilityMode}
69+
required
70+
.options=${[
71+
{
72+
label: msg("Default"),
73+
value: CompatibilityModeEnum.Default,
74+
default: true,
75+
description: html`${msg("Default behavior.")}`,
76+
},
77+
{
78+
label: msg("AWS"),
79+
value: CompatibilityModeEnum.Aws,
80+
description: html`${msg(
81+
"Altered behavior for usage with Amazon Web Services.",
82+
)}`,
83+
},
84+
{
85+
label: msg("Slack"),
86+
value: CompatibilityModeEnum.Slack,
87+
description: html`${msg("Altered behavior for usage with Slack.")}`,
88+
},
89+
]}
90+
help=${msg(
91+
"Alter authentik's behavior for vendor-specific SCIM implementations.",
92+
)}
93+
></ak-radio-input>
6494
<ak-form-element-horizontal name="dryRun">
6595
<label class="pf-c-switch">
6696
<input

0 commit comments

Comments
 (0)