sources/scim: fix duplicate service account users and changing token (#10735) Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens L. <jens@goauthentik.io>
This commit is contained in:
committed by
GitHub
parent
fe7662f80d
commit
fb9aa9d7f7
@ -1,7 +1,5 @@
|
|||||||
"""SCIM Source"""
|
"""SCIM Source"""
|
||||||
|
|
||||||
from uuid import uuid4
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.templatetags.static import static
|
from django.templatetags.static import static
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
@ -19,8 +17,6 @@ class SCIMSource(Source):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def service_account_identifier(self) -> str:
|
def service_account_identifier(self) -> str:
|
||||||
if not self.pk:
|
|
||||||
self.pk = uuid4()
|
|
||||||
return f"ak-source-scim-{self.pk}"
|
return f"ak-source-scim-{self.pk}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@ -1,41 +1,44 @@
|
|||||||
from django.db.models import Model
|
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 django.dispatch import receiver
|
||||||
|
|
||||||
from authentik.core.models import USER_PATH_SYSTEM_PREFIX, Token, TokenIntents, User, UserTypes
|
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
|
from authentik.sources.scim.models import SCIMSource
|
||||||
|
|
||||||
USER_PATH_SOURCE_SCIM = USER_PATH_SYSTEM_PREFIX + "/sources/scim"
|
USER_PATH_SOURCE_SCIM = USER_PATH_SYSTEM_PREFIX + "/sources/scim"
|
||||||
|
|
||||||
|
|
||||||
@receiver(pre_save, sender=SCIMSource)
|
@receiver(post_save, sender=SCIMSource)
|
||||||
def scim_source_pre_save(sender: type[Model], instance: SCIMSource, **_):
|
def scim_source_post_save(sender: type[Model], instance: SCIMSource, created: bool, **_):
|
||||||
"""Create service account before source is saved"""
|
"""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
|
identifier = instance.service_account_identifier
|
||||||
user = User.objects.create(
|
user, _ = User.objects.update_or_create(
|
||||||
username=identifier,
|
username=identifier,
|
||||||
name=f"SCIM Source {instance.name} Service-Account",
|
defaults={
|
||||||
type=UserTypes.INTERNAL_SERVICE_ACCOUNT,
|
"name": f"SCIM Source {instance.name} Service-Account",
|
||||||
path=USER_PATH_SOURCE_SCIM,
|
"type": UserTypes.INTERNAL_SERVICE_ACCOUNT,
|
||||||
|
"path": USER_PATH_SOURCE_SCIM,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
token = Token.objects.create(
|
token, token_created = Token.objects.update_or_create(
|
||||||
user=user,
|
|
||||||
identifier=identifier,
|
identifier=identifier,
|
||||||
intent=TokenIntents.INTENT_API,
|
defaults={
|
||||||
expiring=False,
|
"user": user,
|
||||||
managed=f"goauthentik.io/sources/scim/{instance.pk}",
|
"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)
|
@receiver(post_delete, sender=SCIMSource)
|
||||||
def scim_source_pre_delete(sender: type[Model], instance: SCIMSource, **_):
|
def scim_source_post_delete(sender: type[Model], instance: SCIMSource, **_):
|
||||||
"""Delete SCIM Source service account before deleting source"""
|
"""Delete SCIM Source service account after deleting source"""
|
||||||
Token.objects.filter(
|
|
||||||
identifier=instance.service_account_identifier, intent=TokenIntents.INTENT_API
|
|
||||||
).delete()
|
|
||||||
User.objects.filter(
|
User.objects.filter(
|
||||||
username=instance.service_account_identifier, type=UserTypes.INTERNAL_SERVICE_ACCOUNT
|
username=instance.service_account_identifier, type=UserTypes.INTERNAL_SERVICE_ACCOUNT
|
||||||
).delete()
|
).delete()
|
||||||
|
|||||||
Reference in New Issue
Block a user