sources/ldap: only save sync state in TaskInfo, return TaskInfo in API

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-04-08 23:20:48 +02:00
parent 7b0005ac42
commit d37c33d941
9 changed files with 148 additions and 102 deletions

View file

@ -35,7 +35,9 @@ class TaskViewSet(ViewSet):
permission_classes = [IsAdminUser] permission_classes = [IsAdminUser]
@swagger_auto_schema(responses={200: TaskSerializer(many=False)}) @swagger_auto_schema(
responses={200: TaskSerializer(many=False), 404: "Task not found"}
)
# pylint: disable=invalid-name # pylint: disable=invalid-name
def retrieve(self, request: Request, pk=None) -> Response: def retrieve(self, request: Request, pk=None) -> Response:
"""Get a single system task""" """Get a single system task"""

View file

@ -1,18 +1,16 @@
"""Source API Views""" """Source API Views"""
from datetime import datetime from django.http.response import Http404
from time import time from django.utils.text import slugify
from django.core.cache import cache
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import DateTimeField
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.admin.api.tasks import TaskSerializer
from authentik.core.api.propertymappings import PropertyMappingSerializer from authentik.core.api.propertymappings import PropertyMappingSerializer
from authentik.core.api.sources import SourceSerializer from authentik.core.api.sources import SourceSerializer
from authentik.core.api.utils import PassiveSerializer from authentik.events.monitored_tasks import TaskInfo
from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource
@ -43,12 +41,6 @@ class LDAPSourceSerializer(SourceSerializer):
extra_kwargs = {"bind_password": {"write_only": True}} extra_kwargs = {"bind_password": {"write_only": True}}
class LDAPSourceSyncStatusSerializer(PassiveSerializer):
"""LDAP Sync status"""
last_sync = DateTimeField(read_only=True)
class LDAPSourceViewSet(ModelViewSet): class LDAPSourceViewSet(ModelViewSet):
"""LDAP Source Viewset""" """LDAP Source Viewset"""
@ -56,18 +48,18 @@ class LDAPSourceViewSet(ModelViewSet):
serializer_class = LDAPSourceSerializer serializer_class = LDAPSourceSerializer
lookup_field = "slug" lookup_field = "slug"
@swagger_auto_schema(responses={200: LDAPSourceSyncStatusSerializer(many=False)}) @swagger_auto_schema(
responses={200: TaskSerializer(many=False), 404: "Task not found"}
)
@action(methods=["GET"], detail=True) @action(methods=["GET"], detail=True)
# pylint: disable=unused-argument # pylint: disable=unused-argument
def sync_status(self, request: Request, slug: str) -> Response: def sync_status(self, request: Request, slug: str) -> Response:
"""Get source's sync status""" """Get source's sync status"""
source = self.get_object() source = self.get_object()
last_sync = cache.get(source.state_cache_prefix("last_sync"), time()) task = TaskInfo.by_name(f"ldap_sync_{slugify(source.name)}")
return Response( if not task:
LDAPSourceSyncStatusSerializer( raise Http404
{"last_sync": datetime.fromtimestamp(last_sync)} return Response(TaskSerializer(task, many=False).data)
).data
)
class LDAPPropertyMappingSerializer(PropertyMappingSerializer): class LDAPPropertyMappingSerializer(PropertyMappingSerializer):

View file

@ -81,10 +81,6 @@ class LDAPSource(Source):
return LDAPSourceSerializer return LDAPSourceSerializer
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}"
_connection: Optional[Connection] = None _connection: Optional[Connection] = None
@property @property

View file

@ -1,7 +1,4 @@
"""LDAP Sync tasks""" """LDAP Sync tasks"""
from time import time
from django.core.cache import cache
from django.utils.text import slugify from django.utils.text import slugify
from ldap3.core.exceptions import LDAPException from ldap3.core.exceptions import LDAPException
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
@ -26,6 +23,7 @@ def ldap_sync_all():
@CELERY_APP.task(bind=True, base=MonitoredTask) @CELERY_APP.task(bind=True, base=MonitoredTask)
def ldap_sync(self: MonitoredTask, source_pk: str): def ldap_sync(self: MonitoredTask, source_pk: str):
"""Synchronization of an LDAP Source""" """Synchronization of an LDAP Source"""
self.result_timeout_hours = 2
try: try:
source: LDAPSource = LDAPSource.objects.get(pk=source_pk) source: LDAPSource = LDAPSource.objects.get(pk=source_pk)
except LDAPSource.DoesNotExist: except LDAPSource.DoesNotExist:
@ -43,8 +41,6 @@ def ldap_sync(self: MonitoredTask, source_pk: str):
sync_inst = sync_class(source) sync_inst = sync_class(source)
count = sync_inst.sync() count = sync_inst.sync()
messages.append(f"Synced {count} objects from {sync_class.__name__}") messages.append(f"Synced {count} objects from {sync_class.__name__}")
cache_key = source.state_cache_prefix("last_sync")
cache.set(cache_key, time(), timeout=60 * 60)
self.set_status( self.set_status(
TaskResult( TaskResult(
TaskResultStatus.SUCCESSFUL, TaskResultStatus.SUCCESSFUL,

View file

@ -85,15 +85,15 @@ paths:
description: '' description: ''
schema: schema:
$ref: '#/definitions/Task' $ref: '#/definitions/Task'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404': '404':
description: Object does not exist or caller has insufficient permissions description: Object does not exist or caller has insufficient permissions
to access it. to access it.
schema: schema:
$ref: '#/definitions/APIException' $ref: '#/definitions/APIException'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags: tags:
- admin - admin
parameters: parameters:
@ -9602,16 +9602,16 @@ paths:
'200': '200':
description: '' description: ''
schema: schema:
$ref: '#/definitions/LDAPSourceSyncStatus' $ref: '#/definitions/Task'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404': '404':
description: Object does not exist or caller has insufficient permissions description: Object does not exist or caller has insufficient permissions
to access it. to access it.
schema: schema:
$ref: '#/definitions/APIException' $ref: '#/definitions/APIException'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags: tags:
- sources - sources
parameters: parameters:
@ -17021,14 +17021,6 @@ definitions:
type: string type: string
format: uuid format: uuid
uniqueItems: true uniqueItems: true
LDAPSourceSyncStatus:
type: object
properties:
last_sync:
title: Last sync
type: string
format: date-time
readOnly: true
SourceType: SourceType:
description: Get source's type configuration description: Get source's type configuration
required: required:

View file

@ -150,7 +150,7 @@ msgstr "App"
#: src/elements/user/UserConsentList.ts:29 #: src/elements/user/UserConsentList.ts:29
#: src/pages/admin-overview/TopApplicationsTable.ts:42 #: src/pages/admin-overview/TopApplicationsTable.ts:42
#: src/pages/applications/ApplicationListPage.ts:95 #: src/pages/applications/ApplicationListPage.ts:100
#: src/pages/providers/ProviderListPage.ts:53 #: src/pages/providers/ProviderListPage.ts:53
msgid "Application" msgid "Application"
msgstr "Application" msgstr "Application"
@ -370,6 +370,10 @@ msgstr "Binding Type"
msgid "Build hash: {0}" msgid "Build hash: {0}"
msgstr "Build hash: {0}" msgstr "Build hash: {0}"
#: src/pages/sources/SourcesListPage.ts:62
msgid "Built-in"
msgstr "Built-in"
#: src/pages/outposts/ServiceConnectionDockerForm.ts:89 #: src/pages/outposts/ServiceConnectionDockerForm.ts:89
msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation."
msgstr "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." msgstr "CA which the endpoint's Certificate is verified against. Can be left empty for no validation."
@ -654,8 +658,8 @@ msgid "Copy Key"
msgstr "Copy Key" msgstr "Copy Key"
#: src/pages/applications/ApplicationForm.ts:120 #: src/pages/applications/ApplicationForm.ts:120
#: src/pages/applications/ApplicationListPage.ts:111 #: src/pages/applications/ApplicationListPage.ts:116
#: src/pages/applications/ApplicationListPage.ts:119 #: src/pages/applications/ApplicationListPage.ts:124
#: src/pages/crypto/CertificateKeyPairListPage.ts:122 #: src/pages/crypto/CertificateKeyPairListPage.ts:122
#: src/pages/crypto/CertificateKeyPairListPage.ts:130 #: src/pages/crypto/CertificateKeyPairListPage.ts:130
#: src/pages/events/RuleListPage.ts:91 #: src/pages/events/RuleListPage.ts:91
@ -684,8 +688,8 @@ msgstr "Copy Key"
#: src/pages/providers/ProviderListPage.ts:116 #: src/pages/providers/ProviderListPage.ts:116
#: src/pages/providers/RelatedApplicationButton.ts:27 #: src/pages/providers/RelatedApplicationButton.ts:27
#: src/pages/providers/RelatedApplicationButton.ts:35 #: src/pages/providers/RelatedApplicationButton.ts:35
#: src/pages/sources/SourcesListPage.ts:100 #: src/pages/sources/SourcesListPage.ts:115
#: src/pages/sources/SourcesListPage.ts:109 #: src/pages/sources/SourcesListPage.ts:124
#: src/pages/stages/StageListPage.ts:119 #: src/pages/stages/StageListPage.ts:119
#: src/pages/stages/StageListPage.ts:128 #: src/pages/stages/StageListPage.ts:128
#: src/pages/stages/invitation/InvitationListPage.ts:77 #: src/pages/stages/invitation/InvitationListPage.ts:77
@ -701,7 +705,7 @@ msgstr "Copy Key"
msgid "Create" msgid "Create"
msgstr "Create" msgstr "Create"
#: src/pages/applications/ApplicationListPage.ts:114 #: src/pages/applications/ApplicationListPage.ts:119
#: src/pages/providers/RelatedApplicationButton.ts:30 #: src/pages/providers/RelatedApplicationButton.ts:30
msgid "Create Application" msgid "Create Application"
msgstr "Create Application" msgstr "Create Application"
@ -782,7 +786,7 @@ msgstr "Create provider"
#: src/pages/policies/PolicyListPage.ts:136 #: src/pages/policies/PolicyListPage.ts:136
#: src/pages/property-mappings/PropertyMappingListPage.ts:125 #: src/pages/property-mappings/PropertyMappingListPage.ts:125
#: src/pages/providers/ProviderListPage.ts:119 #: src/pages/providers/ProviderListPage.ts:119
#: src/pages/sources/SourcesListPage.ts:112 #: src/pages/sources/SourcesListPage.ts:127
#: src/pages/stages/StageListPage.ts:131 #: src/pages/stages/StageListPage.ts:131
msgid "Create {0}" msgid "Create {0}"
msgstr "Create {0}" msgstr "Create {0}"
@ -826,7 +830,7 @@ msgid "Define how notifications are sent to users, like Email or Webhook."
msgstr "Define how notifications are sent to users, like Email or Webhook." msgstr "Define how notifications are sent to users, like Email or Webhook."
#: src/elements/forms/DeleteForm.ts:79 #: src/elements/forms/DeleteForm.ts:79
#: src/pages/applications/ApplicationListPage.ts:102 #: src/pages/applications/ApplicationListPage.ts:107
#: src/pages/crypto/CertificateKeyPairListPage.ts:86 #: src/pages/crypto/CertificateKeyPairListPage.ts:86
#: src/pages/events/RuleListPage.ts:82 #: src/pages/events/RuleListPage.ts:82
#: src/pages/events/TransportListPage.ts:86 #: src/pages/events/TransportListPage.ts:86
@ -837,7 +841,7 @@ msgstr "Define how notifications are sent to users, like Email or Webhook."
#: src/pages/policies/PolicyListPage.ts:115 #: src/pages/policies/PolicyListPage.ts:115
#: src/pages/property-mappings/PropertyMappingListPage.ts:104 #: src/pages/property-mappings/PropertyMappingListPage.ts:104
#: src/pages/providers/ProviderListPage.ts:98 #: src/pages/providers/ProviderListPage.ts:98
#: src/pages/sources/SourcesListPage.ts:91 #: src/pages/sources/SourcesListPage.ts:106
#: src/pages/stages/StageListPage.ts:110 #: src/pages/stages/StageListPage.ts:110
#: src/pages/stages/invitation/InvitationListPage.ts:68 #: src/pages/stages/invitation/InvitationListPage.ts:68
#: src/pages/stages/prompt/PromptListPage.ts:87 #: src/pages/stages/prompt/PromptListPage.ts:87
@ -939,7 +943,7 @@ msgstr "Disable Static Tokens"
msgid "Disable Time-based OTP" msgid "Disable Time-based OTP"
msgstr "Disable Time-based OTP" msgstr "Disable Time-based OTP"
#: src/pages/sources/SourcesListPage.ts:60 #: src/pages/sources/SourcesListPage.ts:75
msgid "Disabled" msgid "Disabled"
msgstr "Disabled" msgstr "Disabled"
@ -976,7 +980,7 @@ msgstr "Each provider has a different issuer, based on the application slug."
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:139 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:139
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:138 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:138
#: src/pages/providers/saml/SAMLProviderViewPage.ts:132 #: src/pages/providers/saml/SAMLProviderViewPage.ts:132
#: src/pages/sources/SourcesListPage.ts:79 #: src/pages/sources/SourcesListPage.ts:94
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:116 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:116
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:135 #: src/pages/sources/oauth/OAuthSourceViewPage.ts:135
#: src/pages/sources/saml/SAMLSourceViewPage.ts:122 #: src/pages/sources/saml/SAMLSourceViewPage.ts:122
@ -1592,8 +1596,8 @@ msgstr "Last run"
msgid "Last seen: {0}" msgid "Last seen: {0}"
msgstr "Last seen: {0}" msgstr "Last seen: {0}"
#: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:23 #: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:25
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:150 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:154
msgid "Last sync: {0}" msgid "Last sync: {0}"
msgstr "Last sync: {0}" msgstr "Last sync: {0}"
@ -1950,11 +1954,11 @@ msgstr "Not connected."
msgid "Not found" msgid "Not found"
msgstr "Not found" msgstr "Not found"
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:148 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:165
msgid "Not synced in the last hour, check System tasks." msgid "Not synced yet."
msgstr "Not synced in the last hour, check System tasks." msgstr "Not synced yet."
#: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:32 #: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:40
msgid "Not synced." msgid "Not synced."
msgstr "Not synced." msgstr "Not synced."
@ -2043,6 +2047,10 @@ msgstr "Only fail the policy, don't set user's password."
msgid "Only send notification once, for example when sending a webhook into a chat channel." msgid "Only send notification once, for example when sending a webhook into a chat channel."
msgstr "Only send notification once, for example when sending a webhook into a chat channel." msgstr "Only send notification once, for example when sending a webhook into a chat channel."
#: src/pages/applications/ApplicationListPage.ts:95
msgid "Open application"
msgstr "Open application"
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:172 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:172
msgid "OpenID Configuration Issuer" msgid "OpenID Configuration Issuer"
msgstr "OpenID Configuration Issuer" msgstr "OpenID Configuration Issuer"
@ -2472,7 +2480,7 @@ msgstr "Resources"
msgid "Result" msgid "Result"
msgstr "Result" msgstr "Result"
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:163 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:177
#: src/pages/system-tasks/SystemTaskListPage.ts:107 #: src/pages/system-tasks/SystemTaskListPage.ts:107
msgid "Retry Task" msgid "Retry Task"
msgstr "Retry Task" msgstr "Retry Task"
@ -2589,7 +2597,7 @@ msgstr "See documentation for a list of all variables."
msgid "Select a provider that this application should use. Alternatively, create a new provider." msgid "Select a provider that this application should use. Alternatively, create a new provider."
msgstr "Select a provider that this application should use. Alternatively, create a new provider." msgstr "Select a provider that this application should use. Alternatively, create a new provider."
#: src/elements/table/Table.ts:215 #: src/elements/table/Table.ts:218
msgid "Select all rows" msgid "Select all rows"
msgstr "Select all rows" msgstr "Select all rows"
@ -2726,7 +2734,7 @@ msgid "Something went wrong! Please try again later."
msgstr "Something went wrong! Please try again later." msgstr "Something went wrong! Please try again later."
#: src/pages/providers/ProviderListPage.ts:91 #: src/pages/providers/ProviderListPage.ts:91
#: src/pages/sources/SourcesListPage.ts:84 #: src/pages/sources/SourcesListPage.ts:99
msgid "Source" msgid "Source"
msgstr "Source" msgstr "Source"
@ -3101,6 +3109,10 @@ msgstr "Symbol charset"
msgid "Sync" msgid "Sync"
msgstr "Sync" msgstr "Sync"
#: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:31
msgid "Sync failed."
msgstr "Sync failed."
#: src/pages/sources/ldap/LDAPSourceForm.ts:93 #: src/pages/sources/ldap/LDAPSourceForm.ts:93
msgid "Sync groups" msgid "Sync groups"
msgstr "Sync groups" msgstr "Sync groups"
@ -3142,6 +3154,14 @@ msgstr "TOTP Authenticators"
msgid "Target" msgid "Target"
msgstr "Target" msgstr "Target"
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:151
msgid "Task finished with errors"
msgstr "Task finished with errors"
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:148
msgid "Task finished with warnings"
msgstr "Task finished with warnings"
#: src/pages/stages/email/EmailStageForm.ts:157 #: src/pages/stages/email/EmailStageForm.ts:157
msgid "Template" msgid "Template"
msgstr "Template" msgstr "Template"
@ -3351,7 +3371,7 @@ msgstr "Up-to-date!"
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:129 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:129
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:128 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:128
#: src/pages/providers/saml/SAMLProviderViewPage.ts:122 #: src/pages/providers/saml/SAMLProviderViewPage.ts:122
#: src/pages/sources/SourcesListPage.ts:66 #: src/pages/sources/SourcesListPage.ts:81
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:106 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:106
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:125 #: src/pages/sources/oauth/OAuthSourceViewPage.ts:125
#: src/pages/sources/saml/SAMLSourceViewPage.ts:112 #: src/pages/sources/saml/SAMLSourceViewPage.ts:112
@ -3454,7 +3474,7 @@ msgstr "Update details"
#: src/pages/policies/PolicyListPage.ts:80 #: src/pages/policies/PolicyListPage.ts:80
#: src/pages/property-mappings/PropertyMappingListPage.ts:69 #: src/pages/property-mappings/PropertyMappingListPage.ts:69
#: src/pages/providers/ProviderListPage.ts:76 #: src/pages/providers/ProviderListPage.ts:76
#: src/pages/sources/SourcesListPage.ts:69 #: src/pages/sources/SourcesListPage.ts:84
#: src/pages/stages/StageListPage.ts:88 #: src/pages/stages/StageListPage.ts:88
#: src/pages/users/UserActiveForm.ts:41 #: src/pages/users/UserActiveForm.ts:41
msgid "Update {0}" msgid "Update {0}"
@ -3714,6 +3734,10 @@ msgstr "Yes"
msgid "You're currently impersonating {0}." msgid "You're currently impersonating {0}."
msgstr "You're currently impersonating {0}." msgstr "You're currently impersonating {0}."
#: src/pages/sources/SourcesListPage.ts:61
msgid "authentik Built-in"
msgstr "authentik Built-in"
#: src/pages/stages/password/PasswordStageForm.ts:76 #: src/pages/stages/password/PasswordStageForm.ts:76
msgid "authentik Builtin Database" msgid "authentik Builtin Database"
msgstr "authentik Builtin Database" msgstr "authentik Builtin Database"

View file

@ -150,7 +150,7 @@ msgstr ""
#: src/elements/user/UserConsentList.ts:29 #: src/elements/user/UserConsentList.ts:29
#: src/pages/admin-overview/TopApplicationsTable.ts:42 #: src/pages/admin-overview/TopApplicationsTable.ts:42
#: src/pages/applications/ApplicationListPage.ts:95 #: src/pages/applications/ApplicationListPage.ts:100
#: src/pages/providers/ProviderListPage.ts:53 #: src/pages/providers/ProviderListPage.ts:53
msgid "Application" msgid "Application"
msgstr "" msgstr ""
@ -366,6 +366,10 @@ msgstr ""
msgid "Build hash: {0}" msgid "Build hash: {0}"
msgstr "" msgstr ""
#: src/pages/sources/SourcesListPage.ts:62
msgid "Built-in"
msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts:89 #: src/pages/outposts/ServiceConnectionDockerForm.ts:89
msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation." msgid "CA which the endpoint's Certificate is verified against. Can be left empty for no validation."
msgstr "" msgstr ""
@ -650,8 +654,8 @@ msgid "Copy Key"
msgstr "" msgstr ""
#: src/pages/applications/ApplicationForm.ts:120 #: src/pages/applications/ApplicationForm.ts:120
#: src/pages/applications/ApplicationListPage.ts:111 #: src/pages/applications/ApplicationListPage.ts:116
#: src/pages/applications/ApplicationListPage.ts:119 #: src/pages/applications/ApplicationListPage.ts:124
#: src/pages/crypto/CertificateKeyPairListPage.ts:122 #: src/pages/crypto/CertificateKeyPairListPage.ts:122
#: src/pages/crypto/CertificateKeyPairListPage.ts:130 #: src/pages/crypto/CertificateKeyPairListPage.ts:130
#: src/pages/events/RuleListPage.ts:91 #: src/pages/events/RuleListPage.ts:91
@ -680,8 +684,8 @@ msgstr ""
#: src/pages/providers/ProviderListPage.ts:116 #: src/pages/providers/ProviderListPage.ts:116
#: src/pages/providers/RelatedApplicationButton.ts:27 #: src/pages/providers/RelatedApplicationButton.ts:27
#: src/pages/providers/RelatedApplicationButton.ts:35 #: src/pages/providers/RelatedApplicationButton.ts:35
#: src/pages/sources/SourcesListPage.ts:100 #: src/pages/sources/SourcesListPage.ts:115
#: src/pages/sources/SourcesListPage.ts:109 #: src/pages/sources/SourcesListPage.ts:124
#: src/pages/stages/StageListPage.ts:119 #: src/pages/stages/StageListPage.ts:119
#: src/pages/stages/StageListPage.ts:128 #: src/pages/stages/StageListPage.ts:128
#: src/pages/stages/invitation/InvitationListPage.ts:77 #: src/pages/stages/invitation/InvitationListPage.ts:77
@ -697,7 +701,7 @@ msgstr ""
msgid "Create" msgid "Create"
msgstr "" msgstr ""
#: src/pages/applications/ApplicationListPage.ts:114 #: src/pages/applications/ApplicationListPage.ts:119
#: src/pages/providers/RelatedApplicationButton.ts:30 #: src/pages/providers/RelatedApplicationButton.ts:30
msgid "Create Application" msgid "Create Application"
msgstr "" msgstr ""
@ -778,7 +782,7 @@ msgstr ""
#: src/pages/policies/PolicyListPage.ts:136 #: src/pages/policies/PolicyListPage.ts:136
#: src/pages/property-mappings/PropertyMappingListPage.ts:125 #: src/pages/property-mappings/PropertyMappingListPage.ts:125
#: src/pages/providers/ProviderListPage.ts:119 #: src/pages/providers/ProviderListPage.ts:119
#: src/pages/sources/SourcesListPage.ts:112 #: src/pages/sources/SourcesListPage.ts:127
#: src/pages/stages/StageListPage.ts:131 #: src/pages/stages/StageListPage.ts:131
msgid "Create {0}" msgid "Create {0}"
msgstr "" msgstr ""
@ -822,7 +826,7 @@ msgid "Define how notifications are sent to users, like Email or Webhook."
msgstr "" msgstr ""
#: src/elements/forms/DeleteForm.ts:79 #: src/elements/forms/DeleteForm.ts:79
#: src/pages/applications/ApplicationListPage.ts:102 #: src/pages/applications/ApplicationListPage.ts:107
#: src/pages/crypto/CertificateKeyPairListPage.ts:86 #: src/pages/crypto/CertificateKeyPairListPage.ts:86
#: src/pages/events/RuleListPage.ts:82 #: src/pages/events/RuleListPage.ts:82
#: src/pages/events/TransportListPage.ts:86 #: src/pages/events/TransportListPage.ts:86
@ -833,7 +837,7 @@ msgstr ""
#: src/pages/policies/PolicyListPage.ts:115 #: src/pages/policies/PolicyListPage.ts:115
#: src/pages/property-mappings/PropertyMappingListPage.ts:104 #: src/pages/property-mappings/PropertyMappingListPage.ts:104
#: src/pages/providers/ProviderListPage.ts:98 #: src/pages/providers/ProviderListPage.ts:98
#: src/pages/sources/SourcesListPage.ts:91 #: src/pages/sources/SourcesListPage.ts:106
#: src/pages/stages/StageListPage.ts:110 #: src/pages/stages/StageListPage.ts:110
#: src/pages/stages/invitation/InvitationListPage.ts:68 #: src/pages/stages/invitation/InvitationListPage.ts:68
#: src/pages/stages/prompt/PromptListPage.ts:87 #: src/pages/stages/prompt/PromptListPage.ts:87
@ -935,7 +939,7 @@ msgstr ""
msgid "Disable Time-based OTP" msgid "Disable Time-based OTP"
msgstr "" msgstr ""
#: src/pages/sources/SourcesListPage.ts:60 #: src/pages/sources/SourcesListPage.ts:75
msgid "Disabled" msgid "Disabled"
msgstr "" msgstr ""
@ -972,7 +976,7 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:139 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:139
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:138 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:138
#: src/pages/providers/saml/SAMLProviderViewPage.ts:132 #: src/pages/providers/saml/SAMLProviderViewPage.ts:132
#: src/pages/sources/SourcesListPage.ts:79 #: src/pages/sources/SourcesListPage.ts:94
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:116 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:116
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:135 #: src/pages/sources/oauth/OAuthSourceViewPage.ts:135
#: src/pages/sources/saml/SAMLSourceViewPage.ts:122 #: src/pages/sources/saml/SAMLSourceViewPage.ts:122
@ -1588,8 +1592,8 @@ msgstr ""
msgid "Last seen: {0}" msgid "Last seen: {0}"
msgstr "" msgstr ""
#: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:23 #: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:25
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:150 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:154
msgid "Last sync: {0}" msgid "Last sync: {0}"
msgstr "" msgstr ""
@ -1946,11 +1950,11 @@ msgstr ""
msgid "Not found" msgid "Not found"
msgstr "" msgstr ""
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:148 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:165
msgid "Not synced in the last hour, check System tasks." msgid "Not synced yet."
msgstr "" msgstr ""
#: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:32 #: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:40
msgid "Not synced." msgid "Not synced."
msgstr "" msgstr ""
@ -2039,6 +2043,10 @@ msgstr ""
msgid "Only send notification once, for example when sending a webhook into a chat channel." msgid "Only send notification once, for example when sending a webhook into a chat channel."
msgstr "" msgstr ""
#: src/pages/applications/ApplicationListPage.ts:95
msgid "Open application"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:172 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:172
msgid "OpenID Configuration Issuer" msgid "OpenID Configuration Issuer"
msgstr "" msgstr ""
@ -2468,7 +2476,7 @@ msgstr ""
msgid "Result" msgid "Result"
msgstr "" msgstr ""
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:163 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:177
#: src/pages/system-tasks/SystemTaskListPage.ts:107 #: src/pages/system-tasks/SystemTaskListPage.ts:107
msgid "Retry Task" msgid "Retry Task"
msgstr "" msgstr ""
@ -2585,7 +2593,7 @@ msgstr ""
msgid "Select a provider that this application should use. Alternatively, create a new provider." msgid "Select a provider that this application should use. Alternatively, create a new provider."
msgstr "" msgstr ""
#: src/elements/table/Table.ts:215 #: src/elements/table/Table.ts:218
msgid "Select all rows" msgid "Select all rows"
msgstr "" msgstr ""
@ -2722,7 +2730,7 @@ msgid "Something went wrong! Please try again later."
msgstr "" msgstr ""
#: src/pages/providers/ProviderListPage.ts:91 #: src/pages/providers/ProviderListPage.ts:91
#: src/pages/sources/SourcesListPage.ts:84 #: src/pages/sources/SourcesListPage.ts:99
msgid "Source" msgid "Source"
msgstr "" msgstr ""
@ -3097,6 +3105,10 @@ msgstr ""
msgid "Sync" msgid "Sync"
msgstr "" msgstr ""
#: src/pages/admin-overview/cards/LDAPSyncStatusCard.ts:31
msgid "Sync failed."
msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts:93 #: src/pages/sources/ldap/LDAPSourceForm.ts:93
msgid "Sync groups" msgid "Sync groups"
msgstr "" msgstr ""
@ -3138,6 +3150,14 @@ msgstr ""
msgid "Target" msgid "Target"
msgstr "" msgstr ""
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:151
msgid "Task finished with errors"
msgstr ""
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:148
msgid "Task finished with warnings"
msgstr ""
#: src/pages/stages/email/EmailStageForm.ts:157 #: src/pages/stages/email/EmailStageForm.ts:157
msgid "Template" msgid "Template"
msgstr "" msgstr ""
@ -3345,7 +3365,7 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:129 #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:129
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:128 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:128
#: src/pages/providers/saml/SAMLProviderViewPage.ts:122 #: src/pages/providers/saml/SAMLProviderViewPage.ts:122
#: src/pages/sources/SourcesListPage.ts:66 #: src/pages/sources/SourcesListPage.ts:81
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:106 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:106
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:125 #: src/pages/sources/oauth/OAuthSourceViewPage.ts:125
#: src/pages/sources/saml/SAMLSourceViewPage.ts:112 #: src/pages/sources/saml/SAMLSourceViewPage.ts:112
@ -3448,7 +3468,7 @@ msgstr ""
#: src/pages/policies/PolicyListPage.ts:80 #: src/pages/policies/PolicyListPage.ts:80
#: src/pages/property-mappings/PropertyMappingListPage.ts:69 #: src/pages/property-mappings/PropertyMappingListPage.ts:69
#: src/pages/providers/ProviderListPage.ts:76 #: src/pages/providers/ProviderListPage.ts:76
#: src/pages/sources/SourcesListPage.ts:69 #: src/pages/sources/SourcesListPage.ts:84
#: src/pages/stages/StageListPage.ts:88 #: src/pages/stages/StageListPage.ts:88
#: src/pages/users/UserActiveForm.ts:41 #: src/pages/users/UserActiveForm.ts:41
msgid "Update {0}" msgid "Update {0}"
@ -3708,6 +3728,10 @@ msgstr ""
msgid "You're currently impersonating {0}." msgid "You're currently impersonating {0}."
msgstr "" msgstr ""
#: src/pages/sources/SourcesListPage.ts:61
msgid "authentik Built-in"
msgstr ""
#: src/pages/stages/password/PasswordStageForm.ts:76 #: src/pages/stages/password/PasswordStageForm.ts:76
msgid "authentik Builtin Database" msgid "authentik Builtin Database"
msgstr "" msgstr ""

View file

@ -1,32 +1,40 @@
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { customElement, html, property, TemplateResult } from "lit-element"; import { customElement, html, property, TemplateResult } from "lit-element";
import { AdminStatus, AdminStatusCard } from "./AdminStatusCard"; import { AdminStatus, AdminStatusCard } from "./AdminStatusCard";
import { SourcesApi } from "authentik-api"; import { SourcesApi, Task, TaskStatusEnum } from "authentik-api";
import { DEFAULT_CONFIG } from "../../../api/Config"; import { DEFAULT_CONFIG } from "../../../api/Config";
import "../../../elements/forms/ConfirmationForm"; import "../../../elements/forms/ConfirmationForm";
@customElement("ak-admin-status-card-ldap-sync") @customElement("ak-admin-status-card-ldap-sync")
export class LDAPSyncStatusCard extends AdminStatusCard<Date | undefined> { export class LDAPSyncStatusCard extends AdminStatusCard<Task> {
@property() @property()
slug!: string; slug!: string;
getPrimaryValue(): Promise<Date | undefined> { getPrimaryValue(): Promise<Task> {
return new SourcesApi(DEFAULT_CONFIG).sourcesLdapSyncStatus({ return new SourcesApi(DEFAULT_CONFIG).sourcesLdapSyncStatus({
slug: this.slug slug: this.slug
}).then((value) => { }).then((value) => {
return value.lastSync; return value;
}).catch(() => {
return { status: TaskStatusEnum.Error } as Task;
}); });
} }
renderValue(): TemplateResult { renderValue(): TemplateResult {
return html`${t`Last sync: ${this.value?.toLocaleTimeString()}`}`; return html`${t`Last sync: ${this.value?.taskFinishTimestamp.toLocaleTimeString()}`}`;
} }
getStatus(value: Date | undefined): Promise<AdminStatus> { getStatus(value: Task): Promise<AdminStatus> {
if (value.status !== TaskStatusEnum.Successful) {
return Promise.resolve<AdminStatus>({
icon: "fa fas fa-times-circle pf-m-danger",
message: t`Sync failed.`,
});
}
const now = new Date().getTime(); const now = new Date().getTime();
const maxDelta = 3600000; // 1 hour const maxDelta = 3600000; // 1 hour
if (!value || (now - value.getTime()) > maxDelta) { if (!value || (now - value.taskFinishTimestamp.getTime()) > maxDelta) {
// No sync or last sync was over maxDelta ago // No sync or last sync was over maxDelta ago
return Promise.resolve<AdminStatus>({ return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning", icon: "fa fa-exclamation-triangle pf-m-warning",

View file

@ -22,7 +22,7 @@ import "../../../elements/forms/ModalForm";
import "./LDAPSourceForm"; import "./LDAPSourceForm";
import { Page } from "../../../elements/Page"; import { Page } from "../../../elements/Page";
import { until } from "lit-html/directives/until"; import { until } from "lit-html/directives/until";
import { LDAPSource, SourcesApi } from "authentik-api"; import { LDAPSource, SourcesApi, TaskStatusEnum } from "authentik-api";
import { DEFAULT_CONFIG } from "../../../api/Config"; import { DEFAULT_CONFIG } from "../../../api/Config";
import { EVENT_REFRESH } from "../../../constants"; import { EVENT_REFRESH } from "../../../constants";
@ -143,16 +143,28 @@ export class LDAPSourceViewPage extends Page {
<p>${t`Sync status`}</p> <p>${t`Sync status`}</p>
</div> </div>
<div class="pf-c-card__body"> <div class="pf-c-card__body">
<p>
${until(new SourcesApi(DEFAULT_CONFIG).sourcesLdapSyncStatus({ ${until(new SourcesApi(DEFAULT_CONFIG).sourcesLdapSyncStatus({
slug: this.source.slug slug: this.source.slug
}).then((ls) => { }).then((ls) => {
if (!ls.lastSync) { let header = html``;
return t`Not synced in the last hour, check System tasks.`; if (ls.status === TaskStatusEnum.Warning) {
header = html`<p>${t`Task finished with warnings`}</p>`;
} else if (status === TaskStatusEnum.Error) {
header = html`<p>${t`Task finished with errors`}</p>`;
} else {
header = html`<p>${t`Last sync: ${ls.taskFinishTimestamp.toLocaleString()}`}</p>`;
} }
return t`Last sync: ${ls.lastSync.toLocaleString()}`; return html`
${header}
<ul>
${ls.messages.map(m => {
return html`<li>${m}</li>`;
})}
</ul>
`;
}).catch(() => {
return html`<p>${t`Not synced yet.`}</p>`;
}), "loading")} }), "loading")}
</p>
</div> </div>
<div class="pf-c-card__footer"> <div class="pf-c-card__footer">
<ak-action-button <ak-action-button