Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions authentik/admin/api/version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""authentik administration overview"""

from django.core.cache import cache
from django_tenants.utils import get_public_schema_name
from drf_spectacular.utils import extend_schema
from packaging.version import parse
from rest_framework.fields import SerializerMethodField
Expand All @@ -13,6 +14,7 @@
from authentik.admin.tasks import VERSION_CACHE_KEY, VERSION_NULL, update_latest_version
from authentik.core.api.utils import PassiveSerializer
from authentik.outposts.models import Outpost
from authentik.tenants.utils import get_current_tenant


class VersionSerializer(PassiveSerializer):
Expand All @@ -35,6 +37,8 @@ def get_version_current(self, _) -> str:

def get_version_latest(self, _) -> str:
"""Get latest version from cache"""
if get_current_tenant().schema_name == get_public_schema_name():
return __version__
version_in_cache = cache.get(VERSION_CACHE_KEY)
if not version_in_cache: # pragma: no cover
update_latest_version.delay()
Expand Down
16 changes: 16 additions & 0 deletions authentik/admin/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,19 @@ class AuthentikAdminConfig(ManagedAppConfig):
label = "authentik_admin"
verbose_name = "authentik Admin"
default = True

@ManagedAppConfig.reconcile_global
def clear_update_notifications(self):
"""Clear update notifications on startup if the notification was for the version
we're running now."""
from packaging.version import parse

from authentik.admin.tasks import LOCAL_VERSION
from authentik.events.models import EventAction, Notification

for notification in Notification.objects.filter(event__action=EventAction.UPDATE_AVAILABLE):
if "new_version" not in notification.event.context:
continue
notification_version = notification.event.context["new_version"]
if LOCAL_VERSION >= parse(notification_version):
notification.delete()
2 changes: 2 additions & 0 deletions authentik/admin/settings.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
"""authentik admin settings"""

from celery.schedules import crontab
from django_tenants.utils import get_public_schema_name

from authentik.lib.utils.time import fqdn_rand

CELERY_BEAT_SCHEDULE = {
"admin_latest_version": {
"task": "authentik.admin.tasks.update_latest_version",
"schedule": crontab(minute=fqdn_rand("admin_latest_version"), hour="*"),
"tenant_schemas": [get_public_schema_name()],
"options": {"queue": "authentik_scheduled"},
}
}
17 changes: 1 addition & 16 deletions authentik/admin/tasks.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
"""authentik admin tasks"""

from django.core.cache import cache
from django.db import DatabaseError, InternalError, ProgrammingError
from django.utils.translation import gettext_lazy as _
from packaging.version import parse
from requests import RequestException
from structlog.stdlib import get_logger

from authentik import __version__, get_build_hash
from authentik.admin.apps import PROM_INFO
from authentik.events.models import Event, EventAction, Notification
from authentik.events.models import Event, EventAction
from authentik.events.system_tasks import SystemTask, TaskStatus, prefill_task
from authentik.lib.config import CONFIG
from authentik.lib.utils.http import get_http_session
Expand All @@ -33,20 +32,6 @@ def _set_prom_info():
)


@CELERY_APP.task(
throws=(DatabaseError, ProgrammingError, InternalError),
)
def clear_update_notifications():
"""Clear update notifications on startup if the notification was for the version
we're running now."""
for notification in Notification.objects.filter(event__action=EventAction.UPDATE_AVAILABLE):
if "new_version" not in notification.event.context:
continue
notification_version = notification.event.context["new_version"]
if LOCAL_VERSION >= parse(notification_version):
notification.delete()


@CELERY_APP.task(bind=True, base=SystemTask)
@prefill_task
def update_latest_version(self: SystemTask):
Expand Down
5 changes: 3 additions & 2 deletions authentik/admin/tests/test_tasks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""test admin tasks"""

from django.apps import apps
from django.core.cache import cache
from django.test import TestCase
from requests_mock import Mocker

from authentik.admin.tasks import (
VERSION_CACHE_KEY,
clear_update_notifications,
update_latest_version,
)
from authentik.events.models import Event, EventAction
Expand Down Expand Up @@ -72,12 +72,13 @@ def test_version_disabled(self):

def test_clear_update_notifications(self):
"""Test clear of previous notification"""
admin_config = apps.get_app_config("authentik_admin")
Event.objects.create(
action=EventAction.UPDATE_AVAILABLE, context={"new_version": "99999999.9999999.9999999"}
)
Event.objects.create(action=EventAction.UPDATE_AVAILABLE, context={"new_version": "1.1.1"})
Event.objects.create(action=EventAction.UPDATE_AVAILABLE, context={})
clear_update_notifications()
admin_config.clear_update_notifications()
self.assertFalse(
Event.objects.filter(
action=EventAction.UPDATE_AVAILABLE, context__new_version="1.1"
Expand Down
6 changes: 1 addition & 5 deletions authentik/root/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,7 @@

def _get_startup_tasks_all_tenants() -> list[Callable]:
"""Get all tasks to be run on startup for all tenants"""
from authentik.admin.tasks import clear_update_notifications

return [
clear_update_notifications,
]
return []

Check warning on line 101 in authentik/root/celery.py

View check run for this annotation

Codecov / codecov/patch

authentik/root/celery.py#L101

Added line #L101 was not covered by tests


@worker_ready.connect
Expand Down
Loading