diff --git a/authentik/core/api/users.py b/authentik/core/api/users.py index d4adacc97..5ee249729 100644 --- a/authentik/core/api/users.py +++ b/authentik/core/api/users.py @@ -171,6 +171,11 @@ class UserSerializer(ModelSerializer): raise ValidationError("Setting a user to internal service account is not allowed.") return user_type + def validate(self, attrs: dict) -> dict: + if self.instance and self.instance.type == UserTypes.INTERNAL_SERVICE_ACCOUNT: + raise ValidationError("Can't modify internal service account users") + return super().validate(attrs) + class Meta: model = User fields = [ diff --git a/authentik/events/middleware.py b/authentik/events/middleware.py index d482bb21e..7834bae5e 100644 --- a/authentik/events/middleware.py +++ b/authentik/events/middleware.py @@ -27,6 +27,7 @@ from authentik.lib.sentry import before_send from authentik.lib.utils.errors import exception_to_string from authentik.outposts.models import OutpostServiceConnection from authentik.policies.models import Policy, PolicyBindingModel +from authentik.policies.reputation.models import Reputation from authentik.providers.oauth2.models import AccessToken, AuthorizationCode, RefreshToken from authentik.providers.scim.models import SCIMGroup, SCIMUser from authentik.stages.authenticator_static.models import StaticToken @@ -52,11 +53,13 @@ IGNORED_MODELS = ( RefreshToken, SCIMUser, SCIMGroup, + Reputation, ) def should_log_model(model: Model) -> bool: """Return true if operation on `model` should be logged""" + # Check for silk by string so this comparison doesn't fail when silk isn't installed if model.__module__.startswith("silk"): return False return model.__class__ not in IGNORED_MODELS diff --git a/authentik/outposts/models.py b/authentik/outposts/models.py index f876a0cf3..14f896c35 100644 --- a/authentik/outposts/models.py +++ b/authentik/outposts/models.py @@ -344,12 +344,22 @@ class Outpost(SerializerModel, ManagedModel): user_created = False if not user: user: User = User.objects.create(username=self.user_identifier) - user.set_unusable_password() user_created = True - user.type = UserTypes.INTERNAL_SERVICE_ACCOUNT - user.name = f"Outpost {self.name} Service-Account" - user.path = USER_PATH_OUTPOSTS - user.save() + attrs = { + "type": UserTypes.INTERNAL_SERVICE_ACCOUNT, + "name": f"Outpost {self.name} Service-Account", + "path": USER_PATH_OUTPOSTS, + } + dirty = False + for key, value in attrs.items(): + if getattr(user, key) != value: + dirty = True + setattr(user, key, value) + if user.has_usable_password(): + user.set_unusable_password() + dirty = True + if dirty: + user.save() if user_created: self.build_user_permissions(user) return user