sources/scim: fix duplicate service account users and changing token (#10735)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L.
2024-08-02 13:50:14 +02:00
committed by GitHub
parent 81493c66b1
commit 3541ec467c
2 changed files with 24 additions and 24 deletions

View File

@ -1,7 +1,6 @@
"""SCIM Source"""
from typing import Any
from uuid import uuid4
from django.db import models
from django.templatetags.static import static
@ -20,8 +19,6 @@ class SCIMSource(Source):
@property
def service_account_identifier(self) -> str:
if not self.pk:
self.pk = uuid4()
return f"ak-source-scim-{self.pk}"
@property

View File

@ -1,41 +1,44 @@
from django.db.models import Model
from django.db.models.signals import pre_delete, pre_save
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver
from authentik.core.models import USER_PATH_SYSTEM_PREFIX, Token, TokenIntents, User, UserTypes
from authentik.events.middleware import audit_ignore
from authentik.sources.scim.models import SCIMSource
USER_PATH_SOURCE_SCIM = USER_PATH_SYSTEM_PREFIX + "/sources/scim"
@receiver(pre_save, sender=SCIMSource)
def scim_source_pre_save(sender: type[Model], instance: SCIMSource, **_):
@receiver(post_save, sender=SCIMSource)
def scim_source_post_save(sender: type[Model], instance: SCIMSource, created: bool, **_):
"""Create service account before source is saved"""
# .service_account_identifier will auto-assign a primary key uuid to the source
# if none is set yet, just so we can get the identifier before we save
identifier = instance.service_account_identifier
user = User.objects.create(
user, _ = User.objects.update_or_create(
username=identifier,
name=f"SCIM Source {instance.name} Service-Account",
type=UserTypes.INTERNAL_SERVICE_ACCOUNT,
path=USER_PATH_SOURCE_SCIM,
defaults={
"name": f"SCIM Source {instance.name} Service-Account",
"type": UserTypes.INTERNAL_SERVICE_ACCOUNT,
"path": USER_PATH_SOURCE_SCIM,
},
)
token = Token.objects.create(
user=user,
token, token_created = Token.objects.update_or_create(
identifier=identifier,
intent=TokenIntents.INTENT_API,
expiring=False,
managed=f"goauthentik.io/sources/scim/{instance.pk}",
defaults={
"user": user,
"intent": TokenIntents.INTENT_API,
"expiring": False,
"managed": f"goauthentik.io/sources/scim/{instance.pk}",
},
)
instance.token = token
if created or token_created:
with audit_ignore():
instance.token = token
instance.save()
@receiver(pre_delete, sender=SCIMSource)
def scim_source_pre_delete(sender: type[Model], instance: SCIMSource, **_):
"""Delete SCIM Source service account before deleting source"""
Token.objects.filter(
identifier=instance.service_account_identifier, intent=TokenIntents.INTENT_API
).delete()
@receiver(post_delete, sender=SCIMSource)
def scim_source_post_delete(sender: type[Model], instance: SCIMSource, **_):
"""Delete SCIM Source service account after deleting source"""
User.objects.filter(
username=instance.service_account_identifier, type=UserTypes.INTERNAL_SERVICE_ACCOUNT
).delete()