wip: description, fix total_seconds
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
		| @ -33,10 +33,10 @@ def _set_prom_info(): | ||||
|     ) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Update latest version info")) | ||||
| def update_latest_version(): | ||||
|     """Update latest version info""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     raise RuntimeError("whatever") | ||||
|     if CONFIG.get_bool("disable_update_check"): | ||||
|         cache.set(VERSION_CACHE_KEY, VERSION_NULL, VERSION_CACHE_TIMEOUT) | ||||
|         self.info("Version check disabled.") | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| """v1 blueprints tasks""" | ||||
|  | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from dataclasses import asdict, dataclass, field | ||||
| from hashlib import sha512 | ||||
| from pathlib import Path | ||||
| @ -106,10 +108,10 @@ class BlueprintEventHandler(FileSystemEventHandler): | ||||
|  | ||||
|  | ||||
| @actor( | ||||
|     description=_("Find blueprints as `blueprints_find` does, but return a safe dict"), | ||||
|     throws=(DatabaseError, ProgrammingError, InternalError), | ||||
| ) | ||||
| def blueprints_find_dict(): | ||||
|     """Find blueprints as `blueprints_find` does, but return a safe dict""" | ||||
|     blueprints = [] | ||||
|     for blueprint in blueprints_find(): | ||||
|         blueprints.append(sanitize_dict(asdict(blueprint))) | ||||
| @ -145,9 +147,11 @@ def blueprints_find() -> list[BlueprintFile]: | ||||
|     return blueprints | ||||
|  | ||||
|  | ||||
| @actor(throws=(DatabaseError, ProgrammingError, InternalError)) | ||||
| @actor( | ||||
|     description=_("Find blueprints and check if they need to be created in the database"), | ||||
|     throws=(DatabaseError, ProgrammingError, InternalError), | ||||
| ) | ||||
| def blueprints_discovery(path: str | None = None): | ||||
|     """Find blueprints and check if they need to be created in the database""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     count = 0 | ||||
|     for blueprint in blueprints_find(): | ||||
| @ -185,9 +189,8 @@ def check_blueprint_v1_file(blueprint: BlueprintFile): | ||||
|         apply_blueprint.send_with_options(args=(instance.pk,), rel_obj=instance) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Apply single blueprint")) | ||||
| def apply_blueprint(instance_pk: UUID): | ||||
|     """Apply single blueprint""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     self.set_uid(str(instance_pk)) | ||||
|     instance: BlueprintInstance | None = None | ||||
| @ -237,9 +240,8 @@ def apply_blueprint(instance_pk: UUID): | ||||
|             instance.save() | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Remove blueprints which couldn't be fetched")) | ||||
| def clear_failed_blueprints(): | ||||
|     """Remove blueprints which couldn't be fetched""" | ||||
|     # Exclude OCI blueprints as those might be temporarily unavailable | ||||
|     for blueprint in BlueprintInstance.objects.exclude(path__startswith=OCI_PREFIX): | ||||
|         try: | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| """authentik core tasks""" | ||||
|  | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from datetime import datetime, timedelta | ||||
|  | ||||
| from django.utils.timezone import now | ||||
| @ -18,9 +20,8 @@ from authentik.tasks.models import Task | ||||
| LOGGER = get_logger() | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Remove expired objects")) | ||||
| def clean_expired_models(): | ||||
|     """Remove expired objects""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     for cls in ExpiringModel.__subclasses__(): | ||||
|         cls: ExpiringModel | ||||
| @ -34,9 +35,8 @@ def clean_expired_models(): | ||||
|         self.info(f"Expired {amount} {cls._meta.verbose_name_plural}") | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Remove temporary users created by SAML Sources")) | ||||
| def clean_temporary_users(): | ||||
|     """Remove temporary users created by SAML Sources""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     _now = datetime.now() | ||||
|     deleted_users = 0 | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| """Crypto tasks""" | ||||
|  | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from glob import glob | ||||
| from pathlib import Path | ||||
|  | ||||
| @ -35,9 +37,8 @@ def ensure_certificate_valid(body: str): | ||||
|     return body | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Discover, import and update certificates from the filesystem")) | ||||
| def certificate_discovery(): | ||||
|     """Discover, import and update certificates from the filesystem""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     certs = {} | ||||
|     private_keys = {} | ||||
|  | ||||
| @ -2,6 +2,7 @@ from django.db.models.aggregates import Count | ||||
| from django_dramatiq_postgres.middleware import CurrentTask | ||||
| from dramatiq.actor import actor | ||||
| from structlog import get_logger | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from authentik.enterprise.policies.unique_password.models import ( | ||||
|     UniquePasswordPolicy, | ||||
| @ -12,11 +13,12 @@ from authentik.tasks.models import Task | ||||
| LOGGER = get_logger() | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor( | ||||
|     description=_( | ||||
|         "Check if any UniquePasswordPolicy exists, and if not, purge the password history table." | ||||
|     ) | ||||
| ) | ||||
| def check_and_purge_password_history(): | ||||
|     """Check if any UniquePasswordPolicy exists, and if not, purge the password history table. | ||||
|     This is run on a schedule instead of being triggered by policy binding deletion. | ||||
|     """ | ||||
|     self: Task = CurrentTask.get_task() | ||||
|  | ||||
|     if not UniquePasswordPolicy.objects.exists(): | ||||
| @ -28,10 +30,8 @@ def check_and_purge_password_history(): | ||||
|     self.info("Not purging password histories, a unique password policy exists") | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Remove user password history that are too old.")) | ||||
| def trim_password_histories(): | ||||
|     self: Task = CurrentTask.get_task() | ||||
|  | ||||
|     """Removes rows from UserPasswordHistory older than | ||||
|     the `n` most recent entries. | ||||
|  | ||||
| @ -39,6 +39,8 @@ def trim_password_histories(): | ||||
|     UniquePasswordPolicy policies. | ||||
|     """ | ||||
|  | ||||
|     self: Task = CurrentTask.get_task() | ||||
|  | ||||
|     # No policy, we'll let the cleanup above do its thing | ||||
|     if not UniquePasswordPolicy.objects.exists(): | ||||
|         return | ||||
|  | ||||
| @ -4,26 +4,27 @@ from dramatiq.actor import actor | ||||
|  | ||||
| from authentik.enterprise.providers.google_workspace.models import GoogleWorkspaceProvider | ||||
| from authentik.lib.sync.outgoing.tasks import SyncTasks | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| sync_tasks = SyncTasks(GoogleWorkspaceProvider) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync Google Workspace provider objects.")) | ||||
| def google_workspace_sync_objects(*args, **kwargs): | ||||
|     return sync_tasks.sync_objects(*args, **kwargs) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Full sync for Google Workspace provider.")) | ||||
| def google_workspace_sync(provider_pk: int, *args, **kwargs): | ||||
|     """Run full sync for Google Workspace provider""" | ||||
|     return sync_tasks.sync(provider_pk, google_workspace_sync_objects) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync a direct object (user, group) for Google Workspace provider.")) | ||||
| def google_workspace_sync_direct(*args, **kwargs): | ||||
|     return sync_tasks.sync_signal_direct(*args, **kwargs) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync a related object (memberships) for Google Workspace provider.")) | ||||
| def google_workspace_sync_m2m(*args, **kwargs): | ||||
|     return sync_tasks.sync_signal_m2m(*args, **kwargs) | ||||
|  | ||||
| @ -4,26 +4,27 @@ from dramatiq.actor import actor | ||||
|  | ||||
| from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProvider | ||||
| from authentik.lib.sync.outgoing.tasks import SyncTasks | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| sync_tasks = SyncTasks(MicrosoftEntraProvider) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync Microsoft Entra provider objects.")) | ||||
| def microsoft_entra_sync_objects(*args, **kwargs): | ||||
|     return sync_tasks.sync_objects(*args, **kwargs) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Full sync for Microsoft Entra provider.")) | ||||
| def microsoft_entra_sync(provider_pk: int, *args, **kwargs): | ||||
|     """Run full sync for Microsoft Entra provider""" | ||||
|     return sync_tasks.sync(provider_pk, microsoft_entra_sync_objects) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync a direct object (user, group) for Microsoft Entra provider.")) | ||||
| def microsoft_entra_sync_direct(*args, **kwargs): | ||||
|     return sync_tasks.sync_signal_direct(*args, **kwargs) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync a related object (memberships) for Microsoft Entra provider.")) | ||||
| def microsoft_entra_sync_m2m(*args, **kwargs): | ||||
|     return sync_tasks.sync_signal_m2m(*args, **kwargs) | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| from typing import Any | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from uuid import UUID | ||||
|  | ||||
| from django.http import HttpRequest | ||||
| @ -61,7 +62,7 @@ def _check_app_access(stream: Stream, event_data: dict) -> bool: | ||||
|     return engine.passing | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Send an SSF event")) | ||||
| def _send_ssf_event(stream_uuid: UUID, event_data: dict[str, Any]): | ||||
|     self: Task = CurrentTask.get_task() | ||||
|  | ||||
|  | ||||
| @ -1,11 +1,12 @@ | ||||
| """Enterprise tasks""" | ||||
|  | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from dramatiq.actor import actor | ||||
|  | ||||
| from authentik.enterprise.license import LicenseKey | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Update enterprise license status.")) | ||||
| def enterprise_update_usage(): | ||||
|     """Update enterprise license status""" | ||||
|     LicenseKey.get_total().record_usage() | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
|  | ||||
| from uuid import UUID | ||||
|  | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from django.db.models.query_utils import Q | ||||
| from django_dramatiq_postgres.middleware import CurrentTask | ||||
| from dramatiq.actor import actor | ||||
| @ -22,7 +23,7 @@ from authentik.tasks.models import Task | ||||
| LOGGER = get_logger() | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Check if policies attached to NotificationRule match event")) | ||||
| def event_trigger_handler(event_uuid: UUID, trigger_name: str): | ||||
|     """Check if policies attached to NotificationRule match event""" | ||||
|     event: Event = Event.objects.filter(event_uuid=event_uuid).first() | ||||
| @ -79,7 +80,7 @@ def event_trigger_handler(event_uuid: UUID, trigger_name: str): | ||||
|                 break | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Send notification")) | ||||
| def notification_transport(transport_pk: int, event_pk: str, user_pk: int, trigger_pk: str): | ||||
|     """Send notification over specified transport""" | ||||
|     event = Event.objects.filter(pk=event_pk).first() | ||||
| @ -100,7 +101,7 @@ def notification_transport(transport_pk: int, event_pk: str, user_pk: int, trigg | ||||
|     transport.send(notification) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Cleanup events for GDPR compliance")) | ||||
| def gdpr_cleanup(user_pk: int): | ||||
|     """cleanup events from gdpr_compliance""" | ||||
|     events = Event.objects.filter(user__pk=user_pk) | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| """outpost tasks""" | ||||
|  | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from hashlib import sha256 | ||||
| from os import R_OK, access | ||||
| from pathlib import Path | ||||
| @ -82,7 +84,7 @@ def controller_for_outpost(outpost: Outpost) -> type[BaseController] | None: | ||||
|     return None | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Update cached state of a service connection")) | ||||
| def outpost_service_connection_monitor(connection_pk: Any): | ||||
|     """Update cached state of a service connection""" | ||||
|     connection: OutpostServiceConnection = ( | ||||
| @ -107,7 +109,7 @@ def outpost_service_connection_monitor(connection_pk: Any): | ||||
|     cache.set(connection.state_key, state, timeout=None) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Create/update/monitor/delete the deployment of an Outpost")) | ||||
| def outpost_controller(outpost_pk: str, action: str = "up", from_cache: bool = False): | ||||
|     """Create/update/monitor/delete the deployment of an Outpost""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
| @ -140,7 +142,7 @@ def outpost_controller(outpost_pk: str, action: str = "up", from_cache: bool = F | ||||
|             self.info(log) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Ensure that all Outposts have valid Service Accounts and Tokens")) | ||||
| def outpost_token_ensurer(): | ||||
|     """ | ||||
|     Periodically ensure that all Outposts have valid Service Accounts and Tokens | ||||
| @ -153,7 +155,7 @@ def outpost_token_ensurer(): | ||||
|     self.info(f"Successfully checked {len(all_outposts)} Outposts.") | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("If an Outpost is saved, ensure that token is created/updated")) | ||||
| def outpost_post_save(model_class: str, model_pk: Any): | ||||
|     """If an Outpost is saved, Ensure that token is created/updated | ||||
|  | ||||
| @ -225,7 +227,7 @@ def _outpost_single_update(outpost: Outpost, layer=None): | ||||
|     async_to_sync(layer.group_send)(group, {"type": "event.update"}) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Checks the local environment and create Service connections.")) | ||||
| def outpost_connection_discovery(): | ||||
|     """Checks the local environment and create Service connections.""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
| @ -266,9 +268,8 @@ def outpost_connection_discovery(): | ||||
|             ) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Terminate session on all outposts")) | ||||
| def outpost_session_end(session_id: str): | ||||
|     """Update outpost instances connected to a single outpost""" | ||||
|     layer = get_channel_layer() | ||||
|     hashed_session_id = hash_session_key(session_id) | ||||
|     for outpost in Outpost.objects.all(): | ||||
|  | ||||
| @ -7,11 +7,11 @@ from dramatiq.actor import actor | ||||
| from authentik.outposts.consumer import OUTPOST_GROUP | ||||
| from authentik.outposts.models import Outpost, OutpostType | ||||
| from authentik.providers.oauth2.id_token import hash_session_key | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Terminate session on Proxy outpost")) | ||||
| def proxy_on_logout(session_id: str): | ||||
|     """Update outpost instances connected to a single outpost""" | ||||
|     layer = get_channel_layer() | ||||
|     hashed_session_id = hash_session_key(session_id) | ||||
|     for outpost in Outpost.objects.filter(type=OutpostType.PROXY): | ||||
|  | ||||
| @ -4,26 +4,27 @@ from dramatiq.actor import actor | ||||
|  | ||||
| from authentik.lib.sync.outgoing.tasks import SyncTasks | ||||
| from authentik.providers.scim.models import SCIMProvider | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| sync_tasks = SyncTasks(SCIMProvider) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync SCIM provider objects.")) | ||||
| def scim_sync_objects(*args, **kwargs): | ||||
|     return sync_tasks.sync_objects(*args, **kwargs) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Full sync for SCIM provider.")) | ||||
| def scim_sync(provider_pk: int, *args, **kwargs): | ||||
|     """Run full sync for SCIM provider""" | ||||
|     return sync_tasks.sync(provider_pk, scim_sync_objects) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync a direct object (user, group) for SCIM provider.")) | ||||
| def scim_sync_direct(*args, **kwargs): | ||||
|     return sync_tasks.sync_signal_direct(*args, **kwargs) | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Sync a related object (memberships) for SCIM provider.")) | ||||
| def scim_sync_m2m(*args, **kwargs): | ||||
|     return sync_tasks.sync_signal_m2m(*args, **kwargs) | ||||
|  | ||||
| @ -360,8 +360,8 @@ DRAMATIQ = { | ||||
|     "task_model": "authentik.tasks.models.Task", | ||||
|     "task_purge_interval": timedelta_from_string( | ||||
|         CONFIG.get("worker.task_purge_interval") | ||||
|     ).total_seconds, | ||||
|     "task_expiration": timedelta_from_string(CONFIG.get("worker.task_expiration")).total_seconds, | ||||
|     ).total_seconds(), | ||||
|     "task_expiration": timedelta_from_string(CONFIG.get("worker.task_expiration")).total_seconds(), | ||||
|     "autodiscovery": { | ||||
|         "enabled": True, | ||||
|         "setup_module": "authentik.tasks.setup", | ||||
| @ -372,7 +372,7 @@ DRAMATIQ = { | ||||
|         "threads": CONFIG.get_int("worker.threads", 1), | ||||
|         "consumer_listen_timeout": timedelta_from_string( | ||||
|             CONFIG.get("worker.consumer_listen_timeout") | ||||
|         ), | ||||
|         ).total_seconds(), | ||||
|     }, | ||||
|     "scheduler_class": "authentik.tasks.schedules.scheduler.Scheduler", | ||||
|     "schedule_model": "authentik.tasks.schedules.models.Schedule", | ||||
| @ -400,6 +400,7 @@ DRAMATIQ = { | ||||
|         ("authentik.tasks.middleware.TenantMiddleware", {}), | ||||
|         ("authentik.tasks.middleware.RelObjMiddleware", {}), | ||||
|         ("authentik.tasks.middleware.LoggingMiddleware", {}), | ||||
|         ("authentik.tasks.middleware.DescriptionMiddleware", {}), | ||||
|     ), | ||||
|     "test": TEST, | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,7 @@ from django_dramatiq_postgres.middleware import CurrentTask | ||||
| from dramatiq.actor import actor | ||||
| from structlog.stdlib import get_logger | ||||
|  | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.sync.outgoing.exceptions import StopSync | ||||
| from authentik.lib.utils.errors import exception_to_string | ||||
| @ -16,7 +17,7 @@ LOGGER = get_logger() | ||||
| CACHE_KEY_STATUS = "goauthentik.io/sources/kerberos/status/" | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Check connectivity for Kerberos sources")) | ||||
| def kerberos_connectivity_check(pk: str): | ||||
|     """Check connectivity for Kerberos Sources""" | ||||
|     # 2 hour timeout, this task should run every hour | ||||
| @ -28,9 +29,11 @@ def kerberos_connectivity_check(pk: str): | ||||
|     cache.set(CACHE_KEY_STATUS + source.slug, status, timeout=timeout) | ||||
|  | ||||
|  | ||||
| @actor(time_limit=(60 * 60 * CONFIG.get_int("sources.kerberos.task_timeout_hours")) * 2.5 * 1000) | ||||
| @actor( | ||||
|     time_limit=(60 * 60 * CONFIG.get_int("sources.kerberos.task_timeout_hours")) * 2.5 * 1000, | ||||
|     description=_("Sync Kerberos source"), | ||||
| ) | ||||
| def kerberos_sync(pk: str): | ||||
|     """Sync a single source""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     source: KerberosSource = KerberosSource.objects.filter(enabled=True, pk=pk).first() | ||||
|     if not source: | ||||
|  | ||||
| @ -9,6 +9,7 @@ from dramatiq.composition import group | ||||
| from dramatiq.message import Message | ||||
| from ldap3.core.exceptions import LDAPException | ||||
| from structlog.stdlib import get_logger | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.sync.outgoing.exceptions import StopSync | ||||
| @ -33,7 +34,7 @@ CACHE_KEY_PREFIX = "goauthentik.io/sources/ldap/page/" | ||||
| CACHE_KEY_STATUS = "goauthentik.io/sources/ldap/status/" | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Check connectivity for LDAP sources")) | ||||
| def ldap_connectivity_check(pk: str | None = None): | ||||
|     """Check connectivity for LDAP Sources""" | ||||
|     timeout = 60 * 60 * 2 | ||||
| @ -48,8 +49,8 @@ def ldap_connectivity_check(pk: str | None = None): | ||||
|     # We take the configured hours timeout time by 3.5 as we run user and | ||||
|     # group in parallel and then membership, then deletions, so 3x is to cover the serial tasks, | ||||
|     # and 0.5x on top of that to give some more leeway | ||||
|     time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours") * 1000) | ||||
|     * 3.5, | ||||
|     time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours") * 1000) * 3.5, | ||||
|     description=_("Sync LDAP source"), | ||||
| ) | ||||
| def ldap_sync(source_pk: str): | ||||
|     """Sync a single source""" | ||||
| @ -116,7 +117,10 @@ def ldap_sync_paginator(source: LDAPSource, sync: type[BaseLDAPSynchronizer]) -> | ||||
|     return messages | ||||
|  | ||||
|  | ||||
| @actor(time_limit=60 * 60 * CONFIG.get_int("ldap.task_timeout_hours") * 1000) | ||||
| @actor( | ||||
|     time_limit=60 * 60 * CONFIG.get_int("ldap.task_timeout_hours") * 1000, | ||||
|     description=_("Sync page for LDAP source"), | ||||
| ) | ||||
| def ldap_sync_page(source_pk: str, sync_class: str, page_cache_key: str): | ||||
|     """Synchronization of an LDAP Source""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|  | ||||
| @ -6,6 +6,7 @@ from django_dramatiq_postgres.middleware import CurrentTask | ||||
| from dramatiq.actor import actor | ||||
| from requests import RequestException | ||||
| from structlog.stdlib import get_logger | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from authentik.lib.utils.http import get_http_session | ||||
| from authentik.sources.oauth.models import OAuthSource | ||||
| @ -14,9 +15,12 @@ from authentik.tasks.models import Task | ||||
| LOGGER = get_logger() | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor( | ||||
|     description=_( | ||||
|         "Update OAuth sources' config from well_known, and JWKS info from the configured URL" | ||||
|     ) | ||||
| ) | ||||
| def update_well_known_jwks(): | ||||
|     """Update OAuth sources' config from well_known, and JWKS info from the configured URL""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|     session = get_http_session() | ||||
|     for source in OAuthSource.objects.all().exclude(oidc_well_known_url=""): | ||||
|  | ||||
| @ -9,9 +9,10 @@ from authentik.lib.utils.errors import exception_to_string | ||||
| from authentik.sources.plex.models import PlexSource | ||||
| from authentik.sources.plex.plex import PlexAuth | ||||
| from authentik.tasks.models import Task | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Check the validity of a Plex source")) | ||||
| def check_plex_token(source_pk: str): | ||||
|     """Check the validity of a Plex source.""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|  | ||||
| @ -9,6 +9,7 @@ from django.db.transaction import atomic | ||||
| from django_dramatiq_postgres.middleware import CurrentTask | ||||
| from dramatiq.actor import actor | ||||
| from fido2.mds3 import filter_revoked, parse_blob | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
|  | ||||
| from authentik.stages.authenticator_webauthn.models import ( | ||||
|     UNKNOWN_DEVICE_TYPE_AAGUID, | ||||
| @ -29,7 +30,7 @@ def mds_ca() -> bytes: | ||||
|         return _raw_root.read() | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Background task to import FIDO Alliance MDS blob and AAGUIDs into database")) | ||||
| def webauthn_mds_import(force=False): | ||||
|     """Background task to import FIDO Alliance MDS blob and AAGUIDs into database""" | ||||
|     self: Task = CurrentTask.get_task() | ||||
|  | ||||
| @ -6,6 +6,7 @@ from typing import Any | ||||
| from django.core.mail import EmailMultiAlternatives | ||||
| from django.core.mail.utils import DNS_NAME | ||||
| from django.utils.text import slugify | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from django_dramatiq_postgres.middleware import CurrentTask | ||||
| from dramatiq.actor import actor | ||||
| from dramatiq.composition import group | ||||
| @ -48,7 +49,7 @@ def get_email_body(email: EmailMultiAlternatives) -> str: | ||||
|     return email.body | ||||
|  | ||||
|  | ||||
| @actor | ||||
| @actor(description=_("Send email")) | ||||
| def send_mail( | ||||
|     message: dict[Any, Any], | ||||
|     stage_class_path: str | None = None, | ||||
|  | ||||
| @ -72,3 +72,9 @@ class LoggingMiddleware(Middleware): | ||||
|                 message=f"Task {task.actor_name} encountered an error: " | ||||
|                 "{exception_to_string(exception)}", | ||||
|             ).save() | ||||
|  | ||||
|  | ||||
| class DescriptionMiddleware(Middleware): | ||||
|     @property | ||||
|     def actor_options(self): | ||||
|         return {"description"} | ||||
|  | ||||
| @ -52,9 +52,9 @@ class ScheduleSerializer(ModelSerializer): | ||||
|             actor: Actor = get_broker().get_actor(instance.actor_name) | ||||
|         except ActorNotFound: | ||||
|             return "FIXME this shouldn't happen" | ||||
|         if not actor.fn.__doc__: | ||||
|         if "description" not in actor.options: | ||||
|             return "no doc" | ||||
|         return actor.fn.__doc__.strip() | ||||
|         return actor.options["description"] | ||||
|  | ||||
|  | ||||
| class ScheduleFilter(FilterSet): | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Marc 'risson' Schmitt
					Marc 'risson' Schmitt