From 7c3d60ec3a77f4f35cb3da3c876dace79774935b Mon Sep 17 00:00:00 2001 From: "gcp-cherry-pick-bot[bot]" <98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 19:43:30 +0100 Subject: [PATCH] events: don't update internal service accounts unless needed (cherry-pick #7611) (#7640) events: stop spam (#7611) * events: don't log updates to internal service accounts * dont log reputation updates * don't actually ignore things, stop updating outpost user when not required * prevent updating internal service account users * fix setattr call --------- Signed-off-by: Jens Langhammer Co-authored-by: Jens L --- authentik/core/api/users.py | 5 +++++ authentik/events/middleware.py | 3 +++ authentik/outposts/models.py | 20 +++++++++++++++----- 3 files changed, 23 insertions(+), 5 deletions(-) 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