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 <marc.schmitt@risson.space> * add option for slack Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space> Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -28,6 +28,7 @@ class SCIMProviderSerializer(ProviderSerializer):
|
||||
"url",
|
||||
"verify_certificates",
|
||||
"token",
|
||||
"compatibility_mode",
|
||||
"exclude_users_service_account",
|
||||
"filter_group",
|
||||
"dry_run",
|
||||
|
@ -22,7 +22,7 @@ from authentik.lib.sync.outgoing.exceptions import (
|
||||
from authentik.lib.utils.http import get_http_session
|
||||
from authentik.providers.scim.clients.exceptions import SCIMRequestException
|
||||
from authentik.providers.scim.clients.schema import ServiceProviderConfiguration
|
||||
from authentik.providers.scim.models import SCIMProvider
|
||||
from authentik.providers.scim.models import SCIMCompatibilityMode, SCIMProvider
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from django.db.models import Model
|
||||
@ -90,9 +90,14 @@ class SCIMClient[TModel: "Model", TConnection: "Model", TSchema: "BaseModel"](
|
||||
"""Get Service provider config"""
|
||||
default_config = ServiceProviderConfiguration.default()
|
||||
try:
|
||||
return ServiceProviderConfiguration.model_validate(
|
||||
config = ServiceProviderConfiguration.model_validate(
|
||||
self._request("GET", "/ServiceProviderConfig")
|
||||
)
|
||||
if self.provider.compatibility_mode == SCIMCompatibilityMode.AWS:
|
||||
config.patch.supported = False
|
||||
if self.provider.compatibility_mode == SCIMCompatibilityMode.SLACK:
|
||||
config.filter.supported = True
|
||||
return config
|
||||
except (ValidationError, SCIMRequestException, NotFoundSyncException) as exc:
|
||||
self.logger.warning("failed to get ServiceProviderConfig", exc=exc)
|
||||
return default_config
|
||||
|
@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.0.12 on 2025-03-07 23:35
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_providers_scim", "0011_scimprovider_dry_run"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="scimprovider",
|
||||
name="compatibility_mode",
|
||||
field=models.CharField(
|
||||
choices=[("default", "Default"), ("aws", "AWS"), ("slack", "Slack")],
|
||||
default="default",
|
||||
help_text="Alter authentik behavior for vendor-specific SCIM implementations.",
|
||||
max_length=30,
|
||||
verbose_name="SCIM Compatibility Mode",
|
||||
),
|
||||
),
|
||||
]
|
@ -57,6 +57,14 @@ class SCIMProviderGroup(SerializerModel):
|
||||
return f"SCIM Provider Group {self.group_id} to {self.provider_id}"
|
||||
|
||||
|
||||
class SCIMCompatibilityMode(models.TextChoices):
|
||||
"""SCIM compatibility mode"""
|
||||
|
||||
DEFAULT = "default", _("Default")
|
||||
AWS = "aws", _("AWS")
|
||||
SLACK = "slack", _("Slack")
|
||||
|
||||
|
||||
class SCIMProvider(OutgoingSyncProvider, BackchannelProvider):
|
||||
"""SCIM 2.0 provider to create users and groups in external applications"""
|
||||
|
||||
@ -77,6 +85,14 @@ class SCIMProvider(OutgoingSyncProvider, BackchannelProvider):
|
||||
help_text=_("Property mappings used for group creation/updating."),
|
||||
)
|
||||
|
||||
compatibility_mode = models.CharField(
|
||||
max_length=30,
|
||||
choices=SCIMCompatibilityMode.choices,
|
||||
default=SCIMCompatibilityMode.DEFAULT,
|
||||
verbose_name=_("SCIM Compatibility Mode"),
|
||||
help_text=_("Alter authentik behavior for vendor-specific SCIM implementations."),
|
||||
)
|
||||
|
||||
@property
|
||||
def icon_url(self) -> str | None:
|
||||
return static("authentik/sources/scim.png")
|
||||
|
@ -6661,6 +6661,16 @@
|
||||
"title": "Token",
|
||||
"description": "Authentication token"
|
||||
},
|
||||
"compatibility_mode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"default",
|
||||
"aws",
|
||||
"slack"
|
||||
],
|
||||
"title": "SCIM Compatibility Mode",
|
||||
"description": "Alter authentik behavior for vendor-specific SCIM implementations."
|
||||
},
|
||||
"exclude_users_service_account": {
|
||||
"type": "boolean",
|
||||
"title": "Exclude users service account"
|
||||
|
21
schema.yml
21
schema.yml
@ -41582,6 +41582,12 @@ components:
|
||||
- confidential
|
||||
- public
|
||||
type: string
|
||||
CompatibilityModeEnum:
|
||||
enum:
|
||||
- default
|
||||
- aws
|
||||
- slack
|
||||
type: string
|
||||
Config:
|
||||
type: object
|
||||
description: Serialize authentik Config into DRF Object
|
||||
@ -52441,6 +52447,11 @@ components:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Authentication token
|
||||
compatibility_mode:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/CompatibilityModeEnum'
|
||||
title: SCIM Compatibility Mode
|
||||
description: Alter authentik behavior for vendor-specific SCIM implementations.
|
||||
exclude_users_service_account:
|
||||
type: boolean
|
||||
filter_group:
|
||||
@ -55841,6 +55852,11 @@ components:
|
||||
token:
|
||||
type: string
|
||||
description: Authentication token
|
||||
compatibility_mode:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/CompatibilityModeEnum'
|
||||
title: SCIM Compatibility Mode
|
||||
description: Alter authentik behavior for vendor-specific SCIM implementations.
|
||||
exclude_users_service_account:
|
||||
type: boolean
|
||||
filter_group:
|
||||
@ -55931,6 +55947,11 @@ components:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Authentication token
|
||||
compatibility_mode:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/CompatibilityModeEnum'
|
||||
title: SCIM Compatibility Mode
|
||||
description: Alter authentik behavior for vendor-specific SCIM implementations.
|
||||
exclude_users_service_account:
|
||||
type: boolean
|
||||
filter_group:
|
||||
|
@ -11,6 +11,7 @@ import { html } from "lit";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import {
|
||||
CompatibilityModeEnum,
|
||||
CoreApi,
|
||||
CoreGroupsListRequest,
|
||||
Group,
|
||||
@ -61,6 +62,35 @@ export function renderForm(provider?: Partial<SCIMProvider>, errors: ValidationE
|
||||
)}
|
||||
inputHint="code"
|
||||
></ak-text-input>
|
||||
<ak-radio-input
|
||||
name="compatibilityMode"
|
||||
label=${msg("Compatibility Mode")}
|
||||
.value=${provider?.compatibilityMode}
|
||||
required
|
||||
.options=${[
|
||||
{
|
||||
label: msg("Default"),
|
||||
value: CompatibilityModeEnum.Default,
|
||||
default: true,
|
||||
description: html`${msg("Default behavior.")}`,
|
||||
},
|
||||
{
|
||||
label: msg("AWS"),
|
||||
value: CompatibilityModeEnum.Aws,
|
||||
description: html`${msg(
|
||||
"Altered behavior for usage with Amazon Web Services.",
|
||||
)}`,
|
||||
},
|
||||
{
|
||||
label: msg("Slack"),
|
||||
value: CompatibilityModeEnum.Slack,
|
||||
description: html`${msg("Altered behavior for usage with Slack.")}`,
|
||||
},
|
||||
]}
|
||||
help=${msg(
|
||||
"Alter authentik's behavior for vendor-specific SCIM implementations.",
|
||||
)}
|
||||
></ak-radio-input>
|
||||
<ak-form-element-horizontal name="dryRun">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
|
Reference in New Issue
Block a user