authentik.admin.tasks

authentik admin tasks

 1"""authentik admin tasks"""
 2
 3from django.core.cache import cache
 4from django.utils.translation import gettext_lazy as _
 5from dramatiq import actor
 6from packaging.version import parse
 7from requests import RequestException
 8from structlog.stdlib import get_logger
 9
10from authentik import authentik_build_hash, authentik_version
11from authentik.admin.apps import PROM_INFO
12from authentik.events.models import Event, EventAction
13from authentik.lib.config import CONFIG
14from authentik.lib.utils.http import get_http_session
15from authentik.tasks.middleware import CurrentTask
16
17LOGGER = get_logger()
18VERSION_NULL = "0.0.0"
19VERSION_CACHE_KEY = "authentik_latest_version"
20VERSION_CACHE_TIMEOUT = 8 * 60 * 60  # 8 hours
21LOCAL_VERSION = parse(authentik_version())
22
23
24def _set_prom_info():
25    """Set prometheus info for version"""
26    PROM_INFO.info(
27        {
28            "version": authentik_version(),
29            "latest": cache.get(VERSION_CACHE_KEY, ""),
30            "build_hash": authentik_build_hash(),
31        }
32    )
33
34
35@actor(description=_("Update latest version info."))
36def update_latest_version():
37    self = CurrentTask.get_task()
38    if CONFIG.get_bool("disable_update_check"):
39        cache.set(VERSION_CACHE_KEY, VERSION_NULL, VERSION_CACHE_TIMEOUT)
40        self.info("Version check disabled.")
41        return
42    try:
43        response = get_http_session().get(
44            "https://version.goauthentik.io/version.json",
45        )
46        response.raise_for_status()
47        data = response.json()
48        upstream_version = data.get("stable", {}).get("version")
49        cache.set(VERSION_CACHE_KEY, upstream_version, VERSION_CACHE_TIMEOUT)
50        self.info("Successfully updated latest Version")
51        _set_prom_info()
52        # Check if upstream version is newer than what we're running,
53        # and if no event exists yet, create one.
54        if LOCAL_VERSION < parse(upstream_version):
55            # Event has already been created, don't create duplicate
56            if Event.objects.filter(
57                action=EventAction.UPDATE_AVAILABLE,
58                context__new_version=upstream_version,
59            ).exists():
60                return
61            Event.new(
62                EventAction.UPDATE_AVAILABLE,
63                message=_(
64                    "New version {version} available!".format(
65                        version=upstream_version,
66                    )
67                ),
68                new_version=upstream_version,
69                changelog=data.get("stable", {}).get("changelog_url"),
70            ).save()
71    except (RequestException, IndexError) as exc:
72        cache.set(VERSION_CACHE_KEY, VERSION_NULL, VERSION_CACHE_TIMEOUT)
73        raise exc
LOGGER = <BoundLoggerLazyProxy(logger=None, wrapper_class=None, processors=None, context_class=None, initial_values={}, logger_factory_args=())>
VERSION_NULL = '0.0.0'
VERSION_CACHE_KEY = 'authentik_latest_version'
VERSION_CACHE_TIMEOUT = 28800
LOCAL_VERSION = <Version('2026.5.0rc1')>