@ -1,12 +1,13 @@
|
|||||||
"""authentik API AppConfig"""
|
"""authentik API AppConfig"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikAPIConfig(AppConfig):
|
class AuthentikAPIConfig(ManagedAppConfig):
|
||||||
"""authentik API Config"""
|
"""authentik API Config"""
|
||||||
|
|
||||||
name = "authentik.api"
|
name = "authentik.api"
|
||||||
label = "authentik_api"
|
label = "authentik_api"
|
||||||
mountpoint = "api/"
|
|
||||||
verbose_name = "authentik API"
|
verbose_name = "authentik API"
|
||||||
|
default = True
|
||||||
|
mountpoint = "api/"
|
||||||
|
@ -6,6 +6,7 @@ from inspect import ismethod
|
|||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.db import DatabaseError, InternalError, ProgrammingError
|
from django.db import DatabaseError, InternalError, ProgrammingError
|
||||||
|
from dramatiq.broker import get_broker
|
||||||
from structlog.stdlib import BoundLogger, get_logger
|
from structlog.stdlib import BoundLogger, get_logger
|
||||||
|
|
||||||
from authentik.lib.utils.time import fqdn_rand
|
from authentik.lib.utils.time import fqdn_rand
|
||||||
@ -92,10 +93,6 @@ class ManagedAppConfig(AppConfig):
|
|||||||
"""Get a list of schedule specs that must exist in the default tenant"""
|
"""Get a list of schedule specs that must exist in the default tenant"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def _reconcile_schedules(self, schedules: list[ScheduleSpec]):
|
|
||||||
for schedule in schedules:
|
|
||||||
schedule.update_or_create()
|
|
||||||
|
|
||||||
def _reconcile_tenant(self) -> None:
|
def _reconcile_tenant(self) -> None:
|
||||||
"""reconcile ourselves for tenanted methods"""
|
"""reconcile ourselves for tenanted methods"""
|
||||||
from authentik.tenants.models import Tenant
|
from authentik.tenants.models import Tenant
|
||||||
@ -108,7 +105,6 @@ class ManagedAppConfig(AppConfig):
|
|||||||
for tenant in tenants:
|
for tenant in tenants:
|
||||||
with tenant:
|
with tenant:
|
||||||
self._reconcile(self.RECONCILE_TENANT_CATEGORY)
|
self._reconcile(self.RECONCILE_TENANT_CATEGORY)
|
||||||
self._reconcile_schedules(self.tenant_schedule_specs)
|
|
||||||
|
|
||||||
def _reconcile_global(self) -> None:
|
def _reconcile_global(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -119,7 +115,6 @@ class ManagedAppConfig(AppConfig):
|
|||||||
|
|
||||||
with schema_context(get_public_schema_name()):
|
with schema_context(get_public_schema_name()):
|
||||||
self._reconcile(self.RECONCILE_GLOBAL_CATEGORY)
|
self._reconcile(self.RECONCILE_GLOBAL_CATEGORY)
|
||||||
self._reconcile_schedules(self.global_schedule_specs)
|
|
||||||
|
|
||||||
|
|
||||||
class AuthentikBlueprintsConfig(ManagedAppConfig):
|
class AuthentikBlueprintsConfig(ManagedAppConfig):
|
||||||
@ -131,9 +126,15 @@ class AuthentikBlueprintsConfig(ManagedAppConfig):
|
|||||||
default = True
|
default = True
|
||||||
|
|
||||||
@ManagedAppConfig.reconcile_global
|
@ManagedAppConfig.reconcile_global
|
||||||
def load_blueprints_v1_tasks(self):
|
def tasks_middlewares(self):
|
||||||
"""Load v1 tasks"""
|
from authentik.blueprints.v1.tasks import BlueprintWatcherMiddleware
|
||||||
self.import_module("authentik.blueprints.v1.tasks")
|
|
||||||
|
get_broker().add_middleware(BlueprintWatcherMiddleware())
|
||||||
|
|
||||||
|
# @ManagedAppConfig.reconcile_global
|
||||||
|
# def load_blueprints_v1_tasks(self):
|
||||||
|
# """Load v1 tasks"""
|
||||||
|
# self.import_module("authentik.blueprints.v1.tasks")
|
||||||
|
|
||||||
@ManagedAppConfig.reconcile_tenant
|
@ManagedAppConfig.reconcile_tenant
|
||||||
def blueprints_discovery(self):
|
def blueprints_discovery(self):
|
||||||
|
2
authentik/blueprints/tasks.py
Normal file
2
authentik/blueprints/tasks.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Import all v1 tasks for auto task discovery
|
||||||
|
from authentik.blueprints.v1.tasks import * # noqa: F403
|
@ -65,7 +65,7 @@ class BlueprintWatcherMiddleware(Middleware):
|
|||||||
)
|
)
|
||||||
observer.start()
|
observer.start()
|
||||||
|
|
||||||
def before_worker_boot(self, broker, worker):
|
def after_worker_boot(self, broker, worker):
|
||||||
self.start_blueprint_watcher()
|
self.start_blueprint_watcher()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
"""authentik brands app"""
|
"""authentik brands app"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikBrandsConfig(AppConfig):
|
class AuthentikBrandsConfig(ManagedAppConfig):
|
||||||
"""authentik Brand app"""
|
"""authentik Brand app"""
|
||||||
|
|
||||||
name = "authentik.brands"
|
name = "authentik.brands"
|
||||||
label = "authentik_brands"
|
label = "authentik_brands"
|
||||||
verbose_name = "authentik Brands"
|
verbose_name = "authentik Brands"
|
||||||
|
default = True
|
||||||
mountpoints = {
|
mountpoints = {
|
||||||
"authentik.brands.urls_root": "",
|
"authentik.brands.urls_root": "",
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ class Outpost(ScheduledModel, SerializerModel, ManagedModel):
|
|||||||
ScheduleSpec(
|
ScheduleSpec(
|
||||||
actor_name="authentik.outposts.tasks.outpost_controller",
|
actor_name="authentik.outposts.tasks.outpost_controller",
|
||||||
uid=self.pk,
|
uid=self.pk,
|
||||||
args=(self.pk, "up"),
|
args=(self.pk,),
|
||||||
kwargs={"action": "up", "from_cache": False},
|
kwargs={"action": "up", "from_cache": False},
|
||||||
crontab=f"{fqdn_rand('outpost_controller')} */4 * * *",
|
crontab=f"{fqdn_rand('outpost_controller')} */4 * * *",
|
||||||
description=_(
|
description=_(
|
||||||
|
@ -134,8 +134,9 @@ def outpost_controller(outpost_pk: str, action: str = "up", from_cache: bool = F
|
|||||||
|
|
||||||
@actor
|
@actor
|
||||||
def outpost_token_ensurer():
|
def outpost_token_ensurer():
|
||||||
"""Periodically ensure that all Outposts have valid Service Accounts
|
"""
|
||||||
and Tokens"""
|
Periodically ensure that all Outposts have valid Service Accounts and Tokens
|
||||||
|
"""
|
||||||
self: Task = CurrentTask.get_task()
|
self: Task = CurrentTask.get_task()
|
||||||
all_outposts = Outpost.objects.all()
|
all_outposts = Outpost.objects.all()
|
||||||
for outpost in all_outposts:
|
for outpost in all_outposts:
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""Authentik policy dummy app config"""
|
"""Authentik policy dummy app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikPolicyDummyConfig(AppConfig):
|
class AuthentikPolicyDummyConfig(ManagedAppConfig):
|
||||||
"""Authentik policy_dummy app config"""
|
"""Authentik policy_dummy app config"""
|
||||||
|
|
||||||
name = "authentik.policies.dummy"
|
name = "authentik.policies.dummy"
|
||||||
label = "authentik_policies_dummy"
|
label = "authentik_policies_dummy"
|
||||||
verbose_name = "authentik Policies.Dummy"
|
verbose_name = "authentik Policies.Dummy"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik Event Matcher policy app config"""
|
"""authentik Event Matcher policy app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikPoliciesEventMatcherConfig(AppConfig):
|
class AuthentikPoliciesEventMatcherConfig(ManagedAppConfig):
|
||||||
"""authentik Event Matcher policy app config"""
|
"""authentik Event Matcher policy app config"""
|
||||||
|
|
||||||
name = "authentik.policies.event_matcher"
|
name = "authentik.policies.event_matcher"
|
||||||
label = "authentik_policies_event_matcher"
|
label = "authentik_policies_event_matcher"
|
||||||
verbose_name = "authentik Policies.Event Matcher"
|
verbose_name = "authentik Policies.Event Matcher"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""Authentik policy_expiry app config"""
|
"""Authentik policy_expiry app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikPolicyExpiryConfig(AppConfig):
|
class AuthentikPolicyExpiryConfig(ManagedAppConfig):
|
||||||
"""Authentik policy_expiry app config"""
|
"""Authentik policy_expiry app config"""
|
||||||
|
|
||||||
name = "authentik.policies.expiry"
|
name = "authentik.policies.expiry"
|
||||||
label = "authentik_policies_expiry"
|
label = "authentik_policies_expiry"
|
||||||
verbose_name = "authentik Policies.Expiry"
|
verbose_name = "authentik Policies.Expiry"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""Authentik policy_expression app config"""
|
"""Authentik policy_expression app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikPolicyExpressionConfig(AppConfig):
|
class AuthentikPolicyExpressionConfig(ManagedAppConfig):
|
||||||
"""Authentik policy_expression app config"""
|
"""Authentik policy_expression app config"""
|
||||||
|
|
||||||
name = "authentik.policies.expression"
|
name = "authentik.policies.expression"
|
||||||
label = "authentik_policies_expression"
|
label = "authentik_policies_expression"
|
||||||
verbose_name = "authentik Policies.Expression"
|
verbose_name = "authentik Policies.Expression"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""Authentik policy geoip app config"""
|
"""Authentik policy geoip app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikPolicyGeoIPConfig(AppConfig):
|
class AuthentikPolicyGeoIPConfig(ManagedAppConfig):
|
||||||
"""Authentik policy_geoip app config"""
|
"""Authentik policy_geoip app config"""
|
||||||
|
|
||||||
name = "authentik.policies.geoip"
|
name = "authentik.policies.geoip"
|
||||||
label = "authentik_policies_geoip"
|
label = "authentik_policies_geoip"
|
||||||
verbose_name = "authentik Policies.GeoIP"
|
verbose_name = "authentik Policies.GeoIP"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik Password policy app config"""
|
"""authentik Password policy app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikPoliciesPasswordConfig(AppConfig):
|
class AuthentikPoliciesPasswordConfig(ManagedAppConfig):
|
||||||
"""authentik Password policy app config"""
|
"""authentik Password policy app config"""
|
||||||
|
|
||||||
name = "authentik.policies.password"
|
name = "authentik.policies.password"
|
||||||
label = "authentik_policies_password"
|
label = "authentik_policies_password"
|
||||||
verbose_name = "authentik Policies.Password"
|
verbose_name = "authentik Policies.Password"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik ldap provider app config"""
|
"""authentik ldap provider app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikProviderLDAPConfig(AppConfig):
|
class AuthentikProviderLDAPConfig(ManagedAppConfig):
|
||||||
"""authentik ldap provider app config"""
|
"""authentik ldap provider app config"""
|
||||||
|
|
||||||
name = "authentik.providers.ldap"
|
name = "authentik.providers.ldap"
|
||||||
label = "authentik_providers_ldap"
|
label = "authentik_providers_ldap"
|
||||||
verbose_name = "authentik Providers.LDAP"
|
verbose_name = "authentik Providers.LDAP"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik radius provider app config"""
|
"""authentik radius provider app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikProviderRadiusConfig(AppConfig):
|
class AuthentikProviderRadiusConfig(ManagedAppConfig):
|
||||||
"""authentik radius provider app config"""
|
"""authentik radius provider app config"""
|
||||||
|
|
||||||
name = "authentik.providers.radius"
|
name = "authentik.providers.radius"
|
||||||
label = "authentik_providers_radius"
|
label = "authentik_providers_radius"
|
||||||
verbose_name = "authentik Providers.Radius"
|
verbose_name = "authentik Providers.Radius"
|
||||||
|
default = True
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
"""authentik SAML IdP app config"""
|
"""authentik SAML IdP app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikProviderSAMLConfig(AppConfig):
|
class AuthentikProviderSAMLConfig(ManagedAppConfig):
|
||||||
"""authentik SAML IdP app config"""
|
"""authentik SAML IdP app config"""
|
||||||
|
|
||||||
name = "authentik.providers.saml"
|
name = "authentik.providers.saml"
|
||||||
label = "authentik_providers_saml"
|
label = "authentik_providers_saml"
|
||||||
verbose_name = "authentik Providers.SAML"
|
verbose_name = "authentik Providers.SAML"
|
||||||
mountpoint = "application/saml/"
|
mountpoint = "application/saml/"
|
||||||
|
default = True
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
"""authentik Recovery app config"""
|
"""authentik Recovery app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikRecoveryConfig(AppConfig):
|
class AuthentikRecoveryConfig(ManagedAppConfig):
|
||||||
"""authentik Recovery app config"""
|
"""authentik Recovery app config"""
|
||||||
|
|
||||||
name = "authentik.recovery"
|
name = "authentik.recovery"
|
||||||
label = "authentik_recovery"
|
label = "authentik_recovery"
|
||||||
verbose_name = "authentik Recovery"
|
verbose_name = "authentik Recovery"
|
||||||
mountpoint = "recovery/"
|
mountpoint = "recovery/"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik plex config"""
|
"""authentik plex config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikSourcePlexConfig(AppConfig):
|
class AuthentikSourcePlexConfig(ManagedAppConfig):
|
||||||
"""authentik source plex config"""
|
"""authentik source plex config"""
|
||||||
|
|
||||||
name = "authentik.sources.plex"
|
name = "authentik.sources.plex"
|
||||||
label = "authentik_sources_plex"
|
label = "authentik_sources_plex"
|
||||||
verbose_name = "authentik Sources.Plex"
|
verbose_name = "authentik Sources.Plex"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""Authenticator"""
|
"""Authenticator"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageAuthenticatorConfig(AppConfig):
|
class AuthentikStageAuthenticatorConfig(ManagedAppConfig):
|
||||||
"""Authenticator App config"""
|
"""Authenticator App config"""
|
||||||
|
|
||||||
name = "authentik.stages.authenticator"
|
name = "authentik.stages.authenticator"
|
||||||
label = "authentik_stages_authenticator"
|
label = "authentik_stages_authenticator"
|
||||||
verbose_name = "authentik Stages.Authenticator"
|
verbose_name = "authentik Stages.Authenticator"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""SMS"""
|
"""SMS"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageAuthenticatorSMSConfig(AppConfig):
|
class AuthentikStageAuthenticatorSMSConfig(ManagedAppConfig):
|
||||||
"""SMS App config"""
|
"""SMS App config"""
|
||||||
|
|
||||||
name = "authentik.stages.authenticator_sms"
|
name = "authentik.stages.authenticator_sms"
|
||||||
label = "authentik_stages_authenticator_sms"
|
label = "authentik_stages_authenticator_sms"
|
||||||
verbose_name = "authentik Stages.Authenticator.SMS"
|
verbose_name = "authentik Stages.Authenticator.SMS"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""TOTP"""
|
"""TOTP"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageAuthenticatorTOTPConfig(AppConfig):
|
class AuthentikStageAuthenticatorTOTPConfig(ManagedAppConfig):
|
||||||
"""TOTP App config"""
|
"""TOTP App config"""
|
||||||
|
|
||||||
name = "authentik.stages.authenticator_totp"
|
name = "authentik.stages.authenticator_totp"
|
||||||
label = "authentik_stages_authenticator_totp"
|
label = "authentik_stages_authenticator_totp"
|
||||||
verbose_name = "authentik Stages.Authenticator.TOTP"
|
verbose_name = "authentik Stages.Authenticator.TOTP"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""Authenticator Validation Stage"""
|
"""Authenticator Validation Stage"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageAuthenticatorValidateConfig(AppConfig):
|
class AuthentikStageAuthenticatorValidateConfig(ManagedAppConfig):
|
||||||
"""Authenticator Validation Stage"""
|
"""Authenticator Validation Stage"""
|
||||||
|
|
||||||
name = "authentik.stages.authenticator_validate"
|
name = "authentik.stages.authenticator_validate"
|
||||||
label = "authentik_stages_authenticator_validate"
|
label = "authentik_stages_authenticator_validate"
|
||||||
verbose_name = "authentik Stages.Authenticator.Validate"
|
verbose_name = "authentik Stages.Authenticator.Validate"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik captcha app"""
|
"""authentik captcha app"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageCaptchaConfig(AppConfig):
|
class AuthentikStageCaptchaConfig(ManagedAppConfig):
|
||||||
"""authentik captcha app"""
|
"""authentik captcha app"""
|
||||||
|
|
||||||
name = "authentik.stages.captcha"
|
name = "authentik.stages.captcha"
|
||||||
label = "authentik_stages_captcha"
|
label = "authentik_stages_captcha"
|
||||||
verbose_name = "authentik Stages.Captcha"
|
verbose_name = "authentik Stages.Captcha"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik consent app"""
|
"""authentik consent app"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageConsentConfig(AppConfig):
|
class AuthentikStageConsentConfig(ManagedAppConfig):
|
||||||
"""authentik consent app"""
|
"""authentik consent app"""
|
||||||
|
|
||||||
name = "authentik.stages.consent"
|
name = "authentik.stages.consent"
|
||||||
label = "authentik_stages_consent"
|
label = "authentik_stages_consent"
|
||||||
verbose_name = "authentik Stages.Consent"
|
verbose_name = "authentik Stages.Consent"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik deny stage app config"""
|
"""authentik deny stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageDenyConfig(AppConfig):
|
class AuthentikStageDenyConfig(ManagedAppConfig):
|
||||||
"""authentik deny stage config"""
|
"""authentik deny stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.deny"
|
name = "authentik.stages.deny"
|
||||||
label = "authentik_stages_deny"
|
label = "authentik_stages_deny"
|
||||||
verbose_name = "authentik Stages.Deny"
|
verbose_name = "authentik Stages.Deny"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik dummy stage config"""
|
"""authentik dummy stage config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageDummyConfig(AppConfig):
|
class AuthentikStageDummyConfig(ManagedAppConfig):
|
||||||
"""authentik dummy stage config"""
|
"""authentik dummy stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.dummy"
|
name = "authentik.stages.dummy"
|
||||||
label = "authentik_stages_dummy"
|
label = "authentik_stages_dummy"
|
||||||
verbose_name = "authentik Stages.Dummy"
|
verbose_name = "authentik Stages.Dummy"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik identification stage app config"""
|
"""authentik identification stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageIdentificationConfig(AppConfig):
|
class AuthentikStageIdentificationConfig(ManagedAppConfig):
|
||||||
"""authentik identification stage config"""
|
"""authentik identification stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.identification"
|
name = "authentik.stages.identification"
|
||||||
label = "authentik_stages_identification"
|
label = "authentik_stages_identification"
|
||||||
verbose_name = "authentik Stages.Identification"
|
verbose_name = "authentik Stages.Identification"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik invitation stage app config"""
|
"""authentik invitation stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageInvitationConfig(AppConfig):
|
class AuthentikStageInvitationConfig(ManagedAppConfig):
|
||||||
"""authentik invitation stage config"""
|
"""authentik invitation stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.invitation"
|
name = "authentik.stages.invitation"
|
||||||
label = "authentik_stages_invitation"
|
label = "authentik_stages_invitation"
|
||||||
verbose_name = "authentik Stages.Invitation"
|
verbose_name = "authentik Stages.Invitation"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik core app config"""
|
"""authentik core app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStagePasswordConfig(AppConfig):
|
class AuthentikStagePasswordConfig(ManagedAppConfig):
|
||||||
"""authentik password stage config"""
|
"""authentik password stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.password"
|
name = "authentik.stages.password"
|
||||||
label = "authentik_stages_password"
|
label = "authentik_stages_password"
|
||||||
verbose_name = "authentik Stages.Password"
|
verbose_name = "authentik Stages.Password"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik prompt stage app config"""
|
"""authentik prompt stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStagePromptConfig(AppConfig):
|
class AuthentikStagePromptConfig(ManagedAppConfig):
|
||||||
"""authentik prompt stage config"""
|
"""authentik prompt stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.prompt"
|
name = "authentik.stages.prompt"
|
||||||
label = "authentik_stages_prompt"
|
label = "authentik_stages_prompt"
|
||||||
verbose_name = "authentik Stages.Prompt"
|
verbose_name = "authentik Stages.Prompt"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik redirect app"""
|
"""authentik redirect app"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageRedirectConfig(AppConfig):
|
class AuthentikStageRedirectConfig(ManagedAppConfig):
|
||||||
"""authentik redirect app"""
|
"""authentik redirect app"""
|
||||||
|
|
||||||
name = "authentik.stages.redirect"
|
name = "authentik.stages.redirect"
|
||||||
label = "authentik_stages_redirect"
|
label = "authentik_stages_redirect"
|
||||||
verbose_name = "authentik Stages.Redirect"
|
verbose_name = "authentik Stages.Redirect"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik delete stage app config"""
|
"""authentik delete stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageUserDeleteConfig(AppConfig):
|
class AuthentikStageUserDeleteConfig(ManagedAppConfig):
|
||||||
"""authentik delete stage config"""
|
"""authentik delete stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.user_delete"
|
name = "authentik.stages.user_delete"
|
||||||
label = "authentik_stages_user_delete"
|
label = "authentik_stages_user_delete"
|
||||||
verbose_name = "authentik Stages.User Delete"
|
verbose_name = "authentik Stages.User Delete"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik login stage app config"""
|
"""authentik login stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageUserLoginConfig(AppConfig):
|
class AuthentikStageUserLoginConfig(ManagedAppConfig):
|
||||||
"""authentik login stage config"""
|
"""authentik login stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.user_login"
|
name = "authentik.stages.user_login"
|
||||||
label = "authentik_stages_user_login"
|
label = "authentik_stages_user_login"
|
||||||
verbose_name = "authentik Stages.User Login"
|
verbose_name = "authentik Stages.User Login"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik logout stage app config"""
|
"""authentik logout stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageUserLogoutConfig(AppConfig):
|
class AuthentikStageUserLogoutConfig(ManagedAppConfig):
|
||||||
"""authentik logout stage config"""
|
"""authentik logout stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.user_logout"
|
name = "authentik.stages.user_logout"
|
||||||
label = "authentik_stages_user_logout"
|
label = "authentik_stages_user_logout"
|
||||||
verbose_name = "authentik Stages.User Logout"
|
verbose_name = "authentik Stages.User Logout"
|
||||||
|
default = True
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
"""authentik write stage app config"""
|
"""authentik write stage app config"""
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
|
||||||
|
|
||||||
class AuthentikStageUserWriteConfig(AppConfig):
|
class AuthentikStageUserWriteConfig(ManagedAppConfig):
|
||||||
"""authentik write stage config"""
|
"""authentik write stage config"""
|
||||||
|
|
||||||
name = "authentik.stages.user_write"
|
name = "authentik.stages.user_write"
|
||||||
label = "authentik_stages_user_write"
|
label = "authentik_stages_user_write"
|
||||||
verbose_name = "authentik Stages.User Write"
|
verbose_name = "authentik Stages.User Write"
|
||||||
|
default = True
|
||||||
|
@ -35,6 +35,7 @@ class AuthentikTasksConfig(ManagedAppConfig):
|
|||||||
broker.add_middleware(Pipelines())
|
broker.add_middleware(Pipelines())
|
||||||
broker.add_middleware(Retries(max_retries=max_retries))
|
broker.add_middleware(Retries(max_retries=max_retries))
|
||||||
broker.add_middleware(Results(backend=PostgresBackend(), store_results=True))
|
broker.add_middleware(Results(backend=PostgresBackend(), store_results=True))
|
||||||
|
|
||||||
broker.add_middleware(FullyQualifiedActorName())
|
broker.add_middleware(FullyQualifiedActorName())
|
||||||
broker.add_middleware(CurrentTask())
|
broker.add_middleware(CurrentTask())
|
||||||
|
|
||||||
|
@ -319,20 +319,29 @@ class _PostgresConsumer(Consumer):
|
|||||||
|
|
||||||
@raise_connection_error
|
@raise_connection_error
|
||||||
def requeue(self, messages: Iterable[Message]):
|
def requeue(self, messages: Iterable[Message]):
|
||||||
|
for message in messages:
|
||||||
|
self.unlock_queue.put_nowait(message)
|
||||||
self.query_set.filter(
|
self.query_set.filter(
|
||||||
message_id__in=[message.message_id for message in messages],
|
message_id__in=[message.message_id for message in messages],
|
||||||
).update(
|
).update(
|
||||||
state=TaskState.QUEUED,
|
state=TaskState.QUEUED,
|
||||||
)
|
)
|
||||||
# We don't care about locks, requeue occurs on worker stop
|
for message in messages:
|
||||||
# TODO: this is not true, we need to handle them
|
self.in_processing.remove(message.message_id)
|
||||||
|
self._purge_locks()
|
||||||
|
|
||||||
def _fetch_pending_notifies(self) -> list[Notify]:
|
def _fetch_pending_notifies(self) -> list[Notify]:
|
||||||
self.logger.debug(f"Polling for lost messages in {self.queue_name}")
|
self.logger.debug(f"Polling for lost messages in {self.queue_name}")
|
||||||
notifies = self.query_set.filter(
|
notifies = (
|
||||||
state__in=(TaskState.QUEUED, TaskState.CONSUMED),
|
self.query_set.filter(
|
||||||
queue_name=self.queue_name,
|
state__in=(TaskState.QUEUED, TaskState.CONSUMED),
|
||||||
).values_list("message_id", flat=True)
|
queue_name=self.queue_name,
|
||||||
|
)
|
||||||
|
.exclude(
|
||||||
|
message_id__in=self.in_processing,
|
||||||
|
)
|
||||||
|
.values_list("message_id", flat=True)
|
||||||
|
)
|
||||||
channel = channel_name(self.queue_name, ChannelIdentifier.ENQUEUE)
|
channel = channel_name(self.queue_name, ChannelIdentifier.ENQUEUE)
|
||||||
return [Notify(pid=0, channel=channel, payload=item) for item in notifies]
|
return [Notify(pid=0, channel=channel, payload=item) for item in notifies]
|
||||||
|
|
||||||
@ -383,7 +392,7 @@ class _PostgresConsumer(Consumer):
|
|||||||
|
|
||||||
processing = len(self.in_processing)
|
processing = len(self.in_processing)
|
||||||
if processing >= self.prefetch:
|
if processing >= self.prefetch:
|
||||||
# Wait and don't consume the message, other worker will be fast
|
# Wait and don't consume the message, other worker will be faster
|
||||||
self.misses, backoff_ms = compute_backoff(self.misses, max_backoff=1000)
|
self.misses, backoff_ms = compute_backoff(self.misses, max_backoff=1000)
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
f"Too many messages in processing: {processing}. Sleeping {backoff_ms} ms"
|
f"Too many messages in processing: {processing}. Sleeping {backoff_ms} ms"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils.module_loading import module_has_submodule
|
from django.utils.module_loading import module_has_submodule
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ class Command(BaseCommand):
|
|||||||
):
|
):
|
||||||
executable_name = "dramatiq-gevent" if use_gevent else "dramatiq"
|
executable_name = "dramatiq-gevent" if use_gevent else "dramatiq"
|
||||||
executable_path = self._resolve_executable(executable_name)
|
executable_path = self._resolve_executable(executable_name)
|
||||||
watch_args = ["--watch", "."] if use_watcher else []
|
watch_args = ["--watch", "."] if use_watcher or settings.DEBUG else []
|
||||||
if watch_args and use_polling_watcher:
|
if watch_args and use_polling_watcher:
|
||||||
watch_args.append("--watch-use-polling")
|
watch_args.append("--watch-use-polling")
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ class ScheduleSerializer(ModelSerializer):
|
|||||||
try:
|
try:
|
||||||
actor: Actor = get_broker().get_actor(instance.actor_name)
|
actor: Actor = get_broker().get_actor(instance.actor_name)
|
||||||
except ActorNotFound:
|
except ActorNotFound:
|
||||||
return None
|
return "FIXME this shouldn't happen"
|
||||||
return actor.fn.__doc__
|
return actor.fn.__doc__.strip()
|
||||||
|
|
||||||
|
|
||||||
class ScheduleViewSet(
|
class ScheduleViewSet(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from authentik.blueprints.apps import ManagedAppConfig
|
from authentik.blueprints.apps import ManagedAppConfig
|
||||||
|
from authentik.lib.utils.reflection import get_apps
|
||||||
from authentik.tasks.schedules.lib import ScheduleSpec
|
from authentik.tasks.schedules.lib import ScheduleSpec
|
||||||
|
|
||||||
|
|
||||||
@ -21,3 +22,26 @@ class AuthentikTasksSchedulesConfig(ManagedAppConfig):
|
|||||||
spec.rel_obj = obj
|
spec.rel_obj = obj
|
||||||
schedules.append(spec)
|
schedules.append(spec)
|
||||||
return schedules
|
return schedules
|
||||||
|
|
||||||
|
def _reconcile_schedules(self, specs: list[ScheduleSpec]):
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
from authentik.tasks.schedules.models import Schedule
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
|
pks_to_keep = []
|
||||||
|
for spec in specs:
|
||||||
|
schedule = spec.update_or_create()
|
||||||
|
pks_to_keep.append(schedule.pk)
|
||||||
|
Schedule.objects.exclude(pk__in=pks_to_keep).delete()
|
||||||
|
|
||||||
|
@ManagedAppConfig.reconcile_tenant
|
||||||
|
def reconcile_tenant_schedules(self):
|
||||||
|
from authentik.tenants.utils import get_current_tenant, get_public_schema_name
|
||||||
|
|
||||||
|
schedule_specs = []
|
||||||
|
for app in get_apps():
|
||||||
|
schedule_specs.extend(app.tenant_schedule_specs)
|
||||||
|
if get_current_tenant().schema_name == get_public_schema_name():
|
||||||
|
schedule_specs.extend(app.global_schedule_specs)
|
||||||
|
self._reconcile_schedules(schedule_specs)
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from cryptography.hazmat.backends.openssl.backend import backend
|
from cryptography.hazmat.backends.openssl.backend import backend
|
||||||
from defusedxml import defuse_stdlib
|
from defusedxml import defuse_stdlib
|
||||||
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
|
|
||||||
|
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
from lifecycle.migrate import run_migrations
|
|
||||||
from lifecycle.wait_for_db import wait_for_db
|
|
||||||
|
|
||||||
warnings.filterwarnings("ignore", "SelectableGroups dict interface")
|
warnings.filterwarnings("ignore", "SelectableGroups dict interface")
|
||||||
warnings.filterwarnings(
|
warnings.filterwarnings(
|
||||||
@ -25,21 +21,15 @@ defuse_stdlib()
|
|||||||
if CONFIG.get_bool("compliance.fips.enabled", False):
|
if CONFIG.get_bool("compliance.fips.enabled", False):
|
||||||
backend._enable_fips()
|
backend._enable_fips()
|
||||||
|
|
||||||
|
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
|
||||||
wait_for_db()
|
|
||||||
print(sys.argv)
|
|
||||||
if (
|
|
||||||
len(sys.argv) > 1
|
|
||||||
# Explicitly only run migrate for server and worker
|
|
||||||
# `bootstrap_tasks` is a special case as that command might be triggered by the `ak`
|
|
||||||
# script to pre-run certain tasks for an automated install
|
|
||||||
and sys.argv[1] in ["dev_server", "worker", "bootstrap_tasks"]
|
|
||||||
# and don't run if this is the child process of a dev_server
|
|
||||||
and os.environ.get(DJANGO_AUTORELOAD_ENV, None) is None
|
|
||||||
):
|
|
||||||
run_migrations()
|
|
||||||
|
|
||||||
import django # noqa: E402
|
import django # noqa: E402
|
||||||
|
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
||||||
|
from authentik.root.signals import post_startup, pre_startup, startup # noqa: E402
|
||||||
|
|
||||||
|
_startup_sender = type("WorkerStartup", (object,), {})
|
||||||
|
pre_startup.send(sender=_startup_sender)
|
||||||
|
startup.send(sender=_startup_sender)
|
||||||
|
post_startup.send(sender=_startup_sender)
|
||||||
|
@ -108,6 +108,7 @@ func NewWebServer() *WebServer {
|
|||||||
func (ws *WebServer) Start() {
|
func (ws *WebServer) Start() {
|
||||||
go ws.runMetricsServer()
|
go ws.runMetricsServer()
|
||||||
go ws.attemptStartBackend()
|
go ws.attemptStartBackend()
|
||||||
|
go ws.attemptStartWorker()
|
||||||
go ws.listenPlain()
|
go ws.listenPlain()
|
||||||
go ws.listenTLS()
|
go ws.listenTLS()
|
||||||
}
|
}
|
||||||
@ -137,6 +138,12 @@ func (ws *WebServer) attemptStartBackend() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ws *WebServer) attemptStartWorker() {
|
||||||
|
if ws.worker == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (ws *WebServer) Core() *gounicorn.GoUnicorn {
|
func (ws *WebServer) Core() *gounicorn.GoUnicorn {
|
||||||
return ws.g
|
return ws.g
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ type Worker struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func New(healthcheck func() bool) *Worker {
|
func New(healthcheck func() bool) *Worker {
|
||||||
logger := log.WithField("logger", "authentik.router.unicorn")
|
logger := log.WithField("logger", "authentik.router.worker")
|
||||||
w := &Worker{
|
w := &Worker{
|
||||||
Healthcheck: healthcheck,
|
Healthcheck: healthcheck,
|
||||||
log: logger,
|
log: logger,
|
||||||
|
Reference in New Issue
Block a user