Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
Marc 'risson' Schmitt
2025-06-11 17:45:05 +02:00
parent 5e2af4a740
commit f2926fa1eb
12 changed files with 22 additions and 55 deletions

View File

@ -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]:

View File

@ -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):

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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()

View File

@ -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 (

View File

@ -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]):

View File

@ -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