diff --git a/authentik/enterprise/providers/google_workspace/models.py b/authentik/enterprise/providers/google_workspace/models.py index 0bffe3eb6e..e3fde7de74 100644 --- a/authentik/enterprise/providers/google_workspace/models.py +++ b/authentik/enterprise/providers/google_workspace/models.py @@ -21,7 +21,6 @@ from authentik.core.models import ( from authentik.lib.models import SerializerModel from authentik.lib.sync.outgoing.base import BaseOutgoingSyncClient from authentik.lib.sync.outgoing.models import OutgoingSyncDeleteAction, OutgoingSyncProvider -from authentik.tasks.schedules.models import ScheduledModel def default_scopes() -> list[str]: diff --git a/authentik/enterprise/providers/microsoft_entra/models.py b/authentik/enterprise/providers/microsoft_entra/models.py index 3438ef6ad0..37c6512d58 100644 --- a/authentik/enterprise/providers/microsoft_entra/models.py +++ b/authentik/enterprise/providers/microsoft_entra/models.py @@ -21,7 +21,6 @@ from authentik.core.models import ( from authentik.lib.models import SerializerModel from authentik.lib.sync.outgoing.base import BaseOutgoingSyncClient from authentik.lib.sync.outgoing.models import OutgoingSyncDeleteAction, OutgoingSyncProvider -from authentik.tasks.schedules.models import ScheduledModel class MicrosoftEntraProviderUser(SerializerModel): diff --git a/authentik/events/models.py b/authentik/events/models.py index 11bfb31fd2..25455a92f6 100644 --- a/authentik/events/models.py +++ b/authentik/events/models.py @@ -9,11 +9,6 @@ from uuid import uuid4 from django.apps import apps from django.db import models -from django.db.models import Count, ExpressionWrapper, F -from django.db.models.fields import DurationField -from django.db.models.functions import Extract -from django.db.models.manager import Manager -from django.db.models.query import QuerySet from django.http import HttpRequest from django.http.request import QueryDict from django.utils.timezone import now @@ -197,21 +192,15 @@ class Event(SerializerModel, ExpiringModel): if hasattr(request, "user"): original_user = None if hasattr(request, "session"): - original_user = request.session.get( - SESSION_KEY_IMPERSONATE_ORIGINAL_USER, None - ) + original_user = request.session.get(SESSION_KEY_IMPERSONATE_ORIGINAL_USER, None) self.user = get_user(request.user, original_user) if user: self.user = get_user(user) # Check if we're currently impersonating, and add that user if hasattr(request, "session"): if SESSION_KEY_IMPERSONATE_ORIGINAL_USER in request.session: - self.user = get_user( - request.session[SESSION_KEY_IMPERSONATE_ORIGINAL_USER] - ) - self.user["on_behalf_of"] = get_user( - request.session[SESSION_KEY_IMPERSONATE_USER] - ) + self.user = get_user(request.session[SESSION_KEY_IMPERSONATE_ORIGINAL_USER]) + self.user["on_behalf_of"] = get_user(request.session[SESSION_KEY_IMPERSONATE_USER]) # User 255.255.255.255 as fallback if IP cannot be determined self.client_ip = ClientIPMiddleware.get_client_ip(request) # Enrich event data @@ -345,12 +334,8 @@ class NotificationTransport(SerializerModel): "user_username": notification.user.username, } if notification.event and notification.event.user: - default_body["event_user_email"] = notification.event.user.get( - "email", None - ) - default_body["event_user_username"] = notification.event.user.get( - "username", None - ) + default_body["event_user_email"] = notification.event.user.get("email", None) + default_body["event_user_username"] = notification.event.user.get("username", None) headers = {} if self.webhook_mapping_body: default_body = sanitize_item( @@ -461,9 +446,7 @@ class NotificationTransport(SerializerModel): "title": "", } if notification.event and notification.event.user: - context["key_value"]["event_user_email"] = notification.event.user.get( - "email", None - ) + context["key_value"]["event_user_email"] = notification.event.user.get("email", None) context["key_value"]["event_user_username"] = notification.event.user.get( "username", None ) @@ -564,9 +547,7 @@ class NotificationRule(SerializerModel, PolicyBindingModel): severity = models.TextField( choices=NotificationSeverity.choices, default=NotificationSeverity.NOTICE, - help_text=_( - "Controls which severity level the created notifications will have." - ), + help_text=_("Controls which severity level the created notifications will have."), ) group = models.ForeignKey( Group, diff --git a/authentik/lib/sync/outgoing/api.py b/authentik/lib/sync/outgoing/api.py index fd9f69b85f..eab32b248d 100644 --- a/authentik/lib/sync/outgoing/api.py +++ b/authentik/lib/sync/outgoing/api.py @@ -1,7 +1,5 @@ -from django.utils.text import slugify from dramatiq.actor import Actor -from drf_spectacular.utils import OpenApiResponse, extend_schema -from guardian.shortcuts import get_objects_for_user +from drf_spectacular.utils import extend_schema from rest_framework.decorators import action from rest_framework.fields import BooleanField, CharField, ChoiceField from rest_framework.request import Request diff --git a/authentik/lib/sync/outgoing/signals.py b/authentik/lib/sync/outgoing/signals.py index f6df70154a..5e8eb221ce 100644 --- a/authentik/lib/sync/outgoing/signals.py +++ b/authentik/lib/sync/outgoing/signals.py @@ -2,7 +2,6 @@ from django.db.models import Model from django.db.models.query import Q from django.db.models.signals import m2m_changed, post_save, pre_delete from dramatiq.actor import Actor -from dramatiq.results.errors import ResultFailure from authentik.core.models import Group, User from authentik.lib.sync.outgoing.base import Direction diff --git a/authentik/outposts/signals.py b/authentik/outposts/signals.py index 32963cd4a3..f75687c26f 100644 --- a/authentik/outposts/signals.py +++ b/authentik/outposts/signals.py @@ -42,9 +42,7 @@ def pre_save_outpost(sender, instance: Outpost, **_): # Name changes the deployment name, need to recreate dirty += old_instance.name != instance.name # namespace requires re-create - dirty += ( - old_instance.config.kubernetes_namespace != instance.config.kubernetes_namespace - ) + dirty += old_instance.config.kubernetes_namespace != instance.config.kubernetes_namespace if bool(dirty): LOGGER.info("Outpost needs re-deployment due to changes", instance=instance) cache.set(CACHE_KEY_OUTPOST_DOWN % instance.pk.hex, old_instance) @@ -105,8 +103,6 @@ def logout_revoke_direct(sender: type[User], request: HttpRequest, **_): @receiver(pre_delete, sender=AuthenticatedSession) -def logout_revoke( - sender: type[AuthenticatedSession], instance: AuthenticatedSession, **_ -): +def logout_revoke(sender: type[AuthenticatedSession], instance: AuthenticatedSession, **_): """Catch logout by expiring sessions being deleted""" outpost_session_end.send(instance.session.session_key) diff --git a/authentik/providers/scim/models.py b/authentik/providers/scim/models.py index c0f7236b4d..4a8f047a34 100644 --- a/authentik/providers/scim/models.py +++ b/authentik/providers/scim/models.py @@ -14,7 +14,6 @@ from authentik.core.models import BackchannelProvider, Group, PropertyMapping, U from authentik.lib.models import SerializerModel from authentik.lib.sync.outgoing.base import BaseOutgoingSyncClient from authentik.lib.sync.outgoing.models import OutgoingSyncProvider -from authentik.tasks.schedules.models import ScheduledModel class SCIMProviderUser(SerializerModel): diff --git a/authentik/sources/kerberos/api/source.py b/authentik/sources/kerberos/api/source.py index f4c1d62af5..49fc7c0bf6 100644 --- a/authentik/sources/kerberos/api/source.py +++ b/authentik/sources/kerberos/api/source.py @@ -2,7 +2,6 @@ from django.core.cache import cache from drf_spectacular.utils import extend_schema -from guardian.shortcuts import get_objects_for_user from rest_framework.decorators import action from rest_framework.fields import BooleanField, SerializerMethodField from rest_framework.request import Request diff --git a/authentik/stages/email/tasks.py b/authentik/stages/email/tasks.py index 6070dc55b7..4dc84fd5f5 100644 --- a/authentik/stages/email/tasks.py +++ b/authentik/stages/email/tasks.py @@ -35,9 +35,7 @@ def send_mails( # Use the class path instead of the class itself for serialization stage_class_path = class_to_path(stage.__class__) for message in messages: - tasks.append( - send_mail.message(message.__dict__, stage_class_path, str(stage.pk)) - ) + tasks.append(send_mail.message(message.__dict__, stage_class_path, str(stage.pk))) return group(tasks).run() diff --git a/authentik/tasks/apps.py b/authentik/tasks/apps.py index a20b905053..a1255cc124 100644 --- a/authentik/tasks/apps.py +++ b/authentik/tasks/apps.py @@ -1,5 +1,4 @@ import dramatiq -from django.conf import settings from dramatiq.broker import Broker, get_broker from dramatiq.encoder import PickleEncoder from dramatiq.middleware import ( diff --git a/authentik/tasks/schedules/apps.py b/authentik/tasks/schedules/apps.py index 0e245388e9..1d62cdb53b 100644 --- a/authentik/tasks/schedules/apps.py +++ b/authentik/tasks/schedules/apps.py @@ -1,4 +1,3 @@ -from django.apps import apps from authentik.blueprints.apps import ManagedAppConfig from authentik.lib.utils.reflection import get_apps @@ -15,21 +14,12 @@ class AuthentikTasksSchedulesConfig(ManagedAppConfig): def tenant_schedule_specs(self) -> list[ScheduleSpec]: from authentik.tasks.schedules.models import ScheduledModel - def is_scheduled_model(klass) -> bool: - if ScheduledModel in klass.__bases__: - return True - return any(is_scheduled_model(klass) for klass in klass.__bases__) - schedules = [] - - for Model in apps.get_models(): - if not is_scheduled_model(Model): - continue + for Model in ScheduledModel.models(): for obj in Model.objects.all(): for spec in obj.schedule_specs: spec.rel_obj = obj schedules.append(spec) - return schedules def _reconcile_schedules(self, specs: list[ScheduleSpec]): diff --git a/authentik/tasks/schedules/models.py b/authentik/tasks/schedules/models.py index 83ef1be82a..e2d4f16d3d 100644 --- a/authentik/tasks/schedules/models.py +++ b/authentik/tasks/schedules/models.py @@ -3,6 +3,7 @@ from uuid import uuid4 import pgtrigger from cron_converter import Cron +from django.apps import apps from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError @@ -109,6 +110,15 @@ class ScheduledModel(models.Model): class Meta: abstract = True + @classmethod + def models(cls) -> list[models.Model]: + def is_scheduled_model(klass) -> bool: + if ScheduledModel in klass.__bases__: + return True + return any(is_scheduled_model(klass) for klass in klass.__bases__) + + return [model for model in apps.get_models() if is_scheduled_model(model)] + @property def schedule_specs(self) -> list[ScheduleSpec]: raise NotImplementedError