diff --git a/authentik/sources/scim/api.py b/authentik/sources/scim/api.py index 98d665692..94edc6213 100644 --- a/authentik/sources/scim/api.py +++ b/authentik/sources/scim/api.py @@ -3,12 +3,32 @@ from rest_framework.viewsets import ModelViewSet from authentik.core.api.sources import SourceSerializer from authentik.core.api.used_by import UsedByMixin +from authentik.core.models import USER_ATTRIBUTE_SA, Token, TokenIntents, User from authentik.sources.scim.models import SCIMSource class SCIMSourceSerializer(SourceSerializer): """SCIMSource Serializer""" + def create(self, validated_data): + instance: SCIMSource = super().create(validated_data) + identifier = f"ak-source-scim-{instance.pk}" + user = User.objects.create( + username=identifier, + name=f"SCIM Source {instance.name} Service-Account", + attributes={USER_ATTRIBUTE_SA: True}, + ) + token = Token.objects.create( + user=user, + identifier=identifier, + intent=TokenIntents.INTENT_API, + expiring=False, + managed=f"goauthentik.io/sources/scim/{instance.pk}", + ) + instance.token = token + instance.save() + return instance + class Meta: model = SCIMSource @@ -22,5 +42,5 @@ class SCIMSourceViewSet(UsedByMixin, ModelViewSet): serializer_class = SCIMSourceSerializer lookup_field = "slug" filterset_fields = "__all__" - search_fields = ["name", "slug"] + search_fields = ["name", "slug", "token__identifier", "token__user__username"] ordering = ["name"] diff --git a/authentik/sources/scim/migrations/0001_initial.py b/authentik/sources/scim/migrations/0001_initial.py index caee869d8..4aac65188 100644 --- a/authentik/sources/scim/migrations/0001_initial.py +++ b/authentik/sources/scim/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.9 on 2021-11-15 12:51 +# Generated by Django 4.0.5 on 2022-06-06 21:03 import django.db.models.deletion from django.db import migrations, models @@ -9,7 +9,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("authentik_core", "0018_auto_20210330_1345_squashed_0028_alter_token_intent"), + ("authentik_core", "0020_application_open_in_new_tab"), ] operations = [ @@ -30,7 +30,10 @@ class Migration(migrations.Migration): ( "token", models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="authentik_core.token" + default=None, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="authentik_core.token", ), ), ], diff --git a/authentik/sources/scim/models.py b/authentik/sources/scim/models.py index e487f7298..912aff6b7 100644 --- a/authentik/sources/scim/models.py +++ b/authentik/sources/scim/models.py @@ -1,5 +1,6 @@ """SCIM Source""" from django.db import models +from django.utils.translation import gettext_lazy as _ from rest_framework.serializers import BaseSerializer from authentik.core.models import Source, Token @@ -10,9 +11,10 @@ USER_ATTRIBUTE_SCIM_ENTERPRISE = "goauthentik.io/sources/scim/enterprise" class SCIMSource(Source): - """SCIM Source""" + """System for Cross-domain Identity Management Source, allows for + cross-system user provisioning""" - token = models.ForeignKey(Token, on_delete=models.CASCADE) + token = models.ForeignKey(Token, on_delete=models.CASCADE, null=True, default=None) @property def component(self) -> str: @@ -24,3 +26,11 @@ class SCIMSource(Source): from authentik.sources.scim.api import SCIMSourceSerializer return SCIMSourceSerializer + + def __str__(self) -> str: + return f"SCIM Source {self.name}" + + class Meta: + + verbose_name = _("SCIM Source") + verbose_name_plural = _("SCIM Sources")