From 116be0b3c0e2f6e153f1d8bf970ad4f70ba683d9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 19 Sep 2020 15:25:17 +0200 Subject: [PATCH] sources/ldap: add status display to show last sync --- passbook/lib/sentry.py | 2 +- passbook/sources/ldap/models.py | 17 +++++++++++++++++ passbook/sources/ldap/tasks.py | 8 +++++++- .../ldap/templates/ldap/source_list_status.html | 8 ++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 passbook/sources/ldap/templates/ldap/source_list_status.html diff --git a/passbook/lib/sentry.py b/passbook/lib/sentry.py index d119f8387..dbe24ab18 100644 --- a/passbook/lib/sentry.py +++ b/passbook/lib/sentry.py @@ -5,12 +5,12 @@ from celery.exceptions import CeleryError from django.core.exceptions import DisallowedHost, ValidationError from django.db import InternalError, OperationalError, ProgrammingError from django_redis.exceptions import ConnectionInterrupted +from ldap3.core.exceptions import LDAPException from redis.exceptions import ConnectionError as RedisConnectionError from redis.exceptions import RedisError from rest_framework.exceptions import APIException from structlog import get_logger from websockets.exceptions import WebSocketException -from ldap3.core.exceptions import LDAPException LOGGER = get_logger() diff --git a/passbook/sources/ldap/models.py b/passbook/sources/ldap/models.py index 16cb14691..eb5836641 100644 --- a/passbook/sources/ldap/models.py +++ b/passbook/sources/ldap/models.py @@ -1,6 +1,8 @@ """passbook LDAP Models""" +from datetime import datetime from typing import Optional, Type +from django.core.cache import cache from django.db import models from django.forms import ModelForm from django.utils.translation import gettext_lazy as _ @@ -8,6 +10,7 @@ from ldap3 import Connection, Server from passbook.core.models import Group, PropertyMapping, Source from passbook.lib.models import DomainlessURLValidator +from passbook.lib.utils.template import render_to_string class LDAPSource(Source): @@ -59,6 +62,20 @@ class LDAPSource(Source): return LDAPSourceForm + def state_cache_prefix(self, suffix: str) -> str: + """Key by which the ldap source status is saved""" + return f"source_ldap_{self.pk}_state_{suffix}" + + @property + def ui_additional_info(self) -> str: + last_sync = cache.get(self.state_cache_prefix("last_sync"), None) + if last_sync: + last_sync = datetime.fromtimestamp(last_sync) + + return render_to_string( + "ldap/source_list_status.html", {"source": self, "last_sync": last_sync} + ) + _connection: Optional[Connection] = None @property diff --git a/passbook/sources/ldap/tasks.py b/passbook/sources/ldap/tasks.py index a200258cd..69a18aed3 100644 --- a/passbook/sources/ldap/tasks.py +++ b/passbook/sources/ldap/tasks.py @@ -1,4 +1,8 @@ """LDAP Sync tasks""" +from time import time + +from django.core.cache import cache + from passbook.root.celery import CELERY_APP from passbook.sources.ldap.connector import Connector from passbook.sources.ldap.models import LDAPSource @@ -14,8 +18,10 @@ def sync(): @CELERY_APP.task() def sync_single(source_pk): """Sync a single source""" - source = LDAPSource.objects.get(pk=source_pk) + source: LDAPSource = LDAPSource.objects.get(pk=source_pk) connector = Connector(source) connector.sync_users() connector.sync_groups() connector.sync_membership() + cache_key = source.state_cache_prefix("last_sync") + cache.set(cache_key, time(), timeout=60 * 60) diff --git a/passbook/sources/ldap/templates/ldap/source_list_status.html b/passbook/sources/ldap/templates/ldap/source_list_status.html new file mode 100644 index 000000000..05c187d6a --- /dev/null +++ b/passbook/sources/ldap/templates/ldap/source_list_status.html @@ -0,0 +1,8 @@ +{% load humanize %} +{% load i18n %} + +{% if last_sync %} + {% blocktrans with last_sync=last_sync|naturaltime %}Synced {{ last_sync }}.{% endblocktrans %} +{% else %} + Not synced yet/Sync in Progress +{% endif %}