mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
@@ -50,6 +50,7 @@ from authentik.lib.utils.reflection import get_apps
|
||||
from authentik.outposts.models import OutpostServiceConnection
|
||||
from authentik.policies.models import Policy, PolicyBindingModel
|
||||
from authentik.rbac.models import Role
|
||||
from authentik.sources.ldap.models import LDAPSourceSync
|
||||
|
||||
# Context set when the serializer is created in a blueprint context
|
||||
# Update website/docs/customize/blueprints/v1/models.md when used
|
||||
@@ -84,6 +85,7 @@ def excluded_models() -> list[type[Model]]:
|
||||
# Classes that have other dependencies
|
||||
Session,
|
||||
AuthenticatedSession,
|
||||
LDAPSourceSync,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from rest_framework.fields import BooleanField, ChoiceField, DateTimeField, SerializerMethodField
|
||||
from rest_framework.fields import BooleanField, ChoiceField, DateTimeField
|
||||
|
||||
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
|
||||
from authentik.lib.sync.models import Sync
|
||||
@@ -14,16 +14,12 @@ class SyncStatusSerializer(PassiveSerializer):
|
||||
|
||||
|
||||
class SyncSerializer(ModelSerializer):
|
||||
done = SerializerMethodField()
|
||||
|
||||
def get_done(self, obj: Sync) -> bool:
|
||||
return obj.is_done()
|
||||
|
||||
class Meta:
|
||||
model = Sync
|
||||
fields = [
|
||||
"pk",
|
||||
"tasks",
|
||||
"started_at",
|
||||
"done",
|
||||
"finished_at",
|
||||
"status",
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from datetime import datetime
|
||||
from uuid import uuid4
|
||||
|
||||
from django.db import models
|
||||
@@ -6,22 +7,66 @@ from dramatiq.broker import get_broker
|
||||
from dramatiq.message import Message
|
||||
|
||||
from authentik.core.models import ExpiringModel
|
||||
from authentik.tasks.models import Task
|
||||
from authentik.tasks.models import Task, TaskStatus
|
||||
|
||||
|
||||
class SyncStatus(models.TextChoices):
|
||||
RUNNING = TaskStatus.RUNNING
|
||||
ERROR = TaskStatus.ERROR
|
||||
WARNING = TaskStatus.WARNING
|
||||
DONE = TaskStatus.DONE
|
||||
|
||||
|
||||
class Sync(ExpiringModel):
|
||||
uuid = models.UUIDField(default=uuid4)
|
||||
uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
|
||||
|
||||
tasks = models.ManyToManyField(Task, related_name="+")
|
||||
|
||||
started_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def is_done(self) -> bool:
|
||||
return any(
|
||||
@property
|
||||
def done(self) -> bool:
|
||||
return not any(
|
||||
state not in (TaskState.DONE, TaskState.REJECTED)
|
||||
for state in self.tasks.values_list("state", flat=True)
|
||||
)
|
||||
|
||||
@property
|
||||
def finished_at(self) -> datetime | None:
|
||||
last_task = self.tasks.order_by("-mtime").first()
|
||||
if last_task:
|
||||
return last_task.mtime
|
||||
return None
|
||||
|
||||
@property
|
||||
def status(self) -> SyncStatus:
|
||||
states = self.tasks.values_list("aggregated_status", flat=True)
|
||||
if any(
|
||||
state
|
||||
in (
|
||||
TaskStatus.WAITING_FOR_DEPENDENCIES,
|
||||
TaskStatus.QUEUED,
|
||||
TaskStatus.CONSUMED,
|
||||
TaskStatus.PREPROCESS,
|
||||
TaskStatus.RUNNING,
|
||||
TaskStatus.POSTPROCESS,
|
||||
)
|
||||
for state in states
|
||||
):
|
||||
return SyncStatus.RUNNING
|
||||
if any(
|
||||
state
|
||||
in (
|
||||
TaskStatus.REJECTED,
|
||||
TaskStatus.ERROR,
|
||||
)
|
||||
for state in states
|
||||
):
|
||||
return SyncStatus.ERROR
|
||||
if any(state == TaskStatus.WARNING for state in states):
|
||||
return SyncStatus.WARNING
|
||||
return SyncStatus.DONE
|
||||
|
||||
def enqueue(self, messages: list[Message], existing_tasks_as_dependencies: bool = True) -> None:
|
||||
broker = get_broker()
|
||||
if existing_tasks_as_dependencies:
|
||||
|
||||
@@ -16,7 +16,7 @@ from rest_framework.viewsets import ModelViewSet
|
||||
from authentik.core.api.sources import SourceSerializer
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.lib.sync.api import SyncSerializer, SyncStatusSerializer
|
||||
from authentik.lib.sync.api import SyncSerializer
|
||||
from authentik.rbac.filters import ObjectFilter
|
||||
from authentik.sources.ldap.models import LDAPSource, LDAPSourceSync
|
||||
from authentik.sources.ldap.tasks import CACHE_KEY_STATUS, SYNC_CLASSES
|
||||
@@ -163,9 +163,15 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
|
||||
def syncs(self, request: Request, slug: str) -> Response:
|
||||
"""Get provider's sync statuses"""
|
||||
source: LDAPSource = self.get_object()
|
||||
syncs = LDAPSourceSync.objects.filter(source=source)
|
||||
|
||||
return Response(SyncStatusSerializer(syncs, many=True).data)
|
||||
syncs = LDAPSourceSync.objects.filter(source=source).order_by("-started_at")
|
||||
|
||||
page = self.paginate_queryset(syncs)
|
||||
if page is not None:
|
||||
serializer = LDAPSourceSyncSerializer(page, many=True)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
|
||||
return Response(LDAPSourceSyncSerializer(syncs, many=True).data)
|
||||
|
||||
@extend_schema(
|
||||
responses={
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.2.15 on 2026-06-16 12:03
|
||||
# Generated by Django 5.2.15 on 2026-06-16 14:08
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
@@ -16,15 +16,14 @@ class Migration(migrations.Migration):
|
||||
migrations.CreateModel(
|
||||
name="LDAPSourceSync",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
("expires", models.DateTimeField(default=None, null=True)),
|
||||
("expiring", models.BooleanField(default=True)),
|
||||
("uuid", models.UUIDField(default=uuid.uuid4)),
|
||||
(
|
||||
"uuid",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4, editable=False, primary_key=True, serialize=False
|
||||
),
|
||||
),
|
||||
("started_at", models.DateTimeField(auto_now_add=True)),
|
||||
("users_count", models.PositiveBigIntegerField(default=0)),
|
||||
("groups_count", models.PositiveBigIntegerField(default=0)),
|
||||
|
||||
@@ -80,6 +80,7 @@ def ldap_sync(source_pk: str):
|
||||
current_sync = LDAPSourceSync.objects.create(
|
||||
source=source, expires=now() + timedelta(days=60)
|
||||
)
|
||||
current_sync.tasks.add(task)
|
||||
|
||||
# User and group sync can happen at once, they have no dependencies on each other
|
||||
current_sync.enqueue(
|
||||
|
||||
@@ -2,7 +2,7 @@ from typing import cast
|
||||
|
||||
from django.db.models import Count
|
||||
from django_dramatiq_postgres.models import TaskState
|
||||
from django_filters.filters import BooleanFilter, MultipleChoiceFilter
|
||||
from django_filters.filters import BaseInFilter, BooleanFilter, MultipleChoiceFilter, UUIDFilter
|
||||
from django_filters.filterset import FilterSet
|
||||
from dramatiq.actor import Actor
|
||||
from dramatiq.broker import get_broker
|
||||
@@ -17,10 +17,7 @@ from drf_spectacular.utils import (
|
||||
)
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import IntegerField, ReadOnlyField, SerializerMethodField
|
||||
from rest_framework.mixins import (
|
||||
ListModelMixin,
|
||||
RetrieveModelMixin,
|
||||
)
|
||||
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
@@ -94,16 +91,23 @@ class TaskSerializer(ModelSerializer):
|
||||
return actor.options["description"]
|
||||
|
||||
|
||||
class UUIDInFilter(BaseInFilter, UUIDFilter):
|
||||
pass
|
||||
|
||||
|
||||
class TaskFilter(FilterSet):
|
||||
rel_obj_id__isnull = BooleanFilter("rel_obj_id", "isnull")
|
||||
aggregated_status = MultipleChoiceFilter(
|
||||
choices=TaskStatus.choices,
|
||||
field_name="aggregated_status",
|
||||
)
|
||||
message_id__in = UUIDInFilter(field_name="message_id", lookup_expr="in")
|
||||
|
||||
class Meta:
|
||||
model = Task
|
||||
fields = (
|
||||
"message_id",
|
||||
"message_id__in",
|
||||
"queue_name",
|
||||
"actor_name",
|
||||
"state",
|
||||
|
||||
Generated
+12
@@ -64,6 +64,8 @@ export interface TasksSchedulesUpdateRequest {
|
||||
export interface TasksTasksListRequest {
|
||||
actorName?: string;
|
||||
aggregatedStatus?: Array<TaskAggregatedStatusEnum>;
|
||||
messageId?: string;
|
||||
messageIdIn?: Array<string>;
|
||||
ordering?: string;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
@@ -452,6 +454,16 @@ export class TasksApi extends runtime.BaseAPI {
|
||||
queryParameters["aggregated_status"] = requestParameters["aggregatedStatus"];
|
||||
}
|
||||
|
||||
if (requestParameters["messageId"] != null) {
|
||||
queryParameters["message_id"] = requestParameters["messageId"];
|
||||
}
|
||||
|
||||
if (requestParameters["messageIdIn"] != null) {
|
||||
queryParameters["message_id__in"] = requestParameters["messageIdIn"]!.join(
|
||||
runtime.COLLECTION_FORMATS["csv"],
|
||||
);
|
||||
}
|
||||
|
||||
if (requestParameters["ordering"] != null) {
|
||||
queryParameters["ordering"] = requestParameters["ordering"];
|
||||
}
|
||||
|
||||
+18
-7
@@ -12,6 +12,9 @@
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
import type { LDAPSourceSyncStatusEnum } from "./LDAPSourceSyncStatusEnum";
|
||||
import { LDAPSourceSyncStatusEnumFromJSON } from "./LDAPSourceSyncStatusEnum";
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
@@ -20,10 +23,10 @@
|
||||
export interface LDAPSourceSync {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @type {string}
|
||||
* @memberof LDAPSourceSync
|
||||
*/
|
||||
readonly pk: number;
|
||||
readonly pk: string;
|
||||
/**
|
||||
*
|
||||
* @type {Array<string>}
|
||||
@@ -38,10 +41,16 @@ export interface LDAPSourceSync {
|
||||
readonly startedAt: Date;
|
||||
/**
|
||||
*
|
||||
* @type {boolean}
|
||||
* @type {Date}
|
||||
* @memberof LDAPSourceSync
|
||||
*/
|
||||
readonly done: boolean;
|
||||
readonly finishedAt: Date | null;
|
||||
/**
|
||||
*
|
||||
* @type {LDAPSourceSyncStatusEnum}
|
||||
* @memberof LDAPSourceSync
|
||||
*/
|
||||
readonly status: LDAPSourceSyncStatusEnum;
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
@@ -87,7 +96,8 @@ export function instanceOfLDAPSourceSync(value: object): value is LDAPSourceSync
|
||||
if (!("pk" in value) || value["pk"] === undefined) return false;
|
||||
if (!("tasks" in value) || value["tasks"] === undefined) return false;
|
||||
if (!("startedAt" in value) || value["startedAt"] === undefined) return false;
|
||||
if (!("done" in value) || value["done"] === undefined) return false;
|
||||
if (!("finishedAt" in value) || value["finishedAt"] === undefined) return false;
|
||||
if (!("status" in value) || value["status"] === undefined) return false;
|
||||
if (!("source" in value) || value["source"] === undefined) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -107,7 +117,8 @@ export function LDAPSourceSyncFromJSONTyped(
|
||||
pk: json["pk"],
|
||||
tasks: json["tasks"],
|
||||
startedAt: new Date(json["started_at"]),
|
||||
done: json["done"],
|
||||
finishedAt: json["finished_at"] == null ? null : new Date(json["finished_at"]),
|
||||
status: LDAPSourceSyncStatusEnumFromJSON(json["status"]),
|
||||
source: json["source"],
|
||||
usersCount: json["users_count"] == null ? undefined : json["users_count"],
|
||||
groupsCount: json["groups_count"] == null ? undefined : json["groups_count"],
|
||||
@@ -124,7 +135,7 @@ export function LDAPSourceSyncToJSON(json: any): LDAPSourceSync {
|
||||
}
|
||||
|
||||
export function LDAPSourceSyncToJSONTyped(
|
||||
value?: Omit<LDAPSourceSync, "pk" | "started_at" | "done"> | null,
|
||||
value?: Omit<LDAPSourceSync, "pk" | "started_at" | "finished_at" | "status"> | null,
|
||||
ignoreDiscriminator: boolean = false,
|
||||
): any {
|
||||
if (value == null) {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* authentik
|
||||
* Making authentication simple.
|
||||
*
|
||||
* The version of the OpenAPI document: 2026.8.0-rc1
|
||||
* Contact: hello@goauthentik.io
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @export
|
||||
*/
|
||||
export const LDAPSourceSyncStatusEnum = {
|
||||
Running: "running",
|
||||
Error: "error",
|
||||
Warning: "warning",
|
||||
Done: "done",
|
||||
UnknownDefaultOpenApi: "11184809",
|
||||
} as const;
|
||||
export type LDAPSourceSyncStatusEnum =
|
||||
(typeof LDAPSourceSyncStatusEnum)[keyof typeof LDAPSourceSyncStatusEnum];
|
||||
|
||||
export function instanceOfLDAPSourceSyncStatusEnum(value: any): boolean {
|
||||
for (const key in LDAPSourceSyncStatusEnum) {
|
||||
if (Object.prototype.hasOwnProperty.call(LDAPSourceSyncStatusEnum, key)) {
|
||||
if (LDAPSourceSyncStatusEnum[key as keyof typeof LDAPSourceSyncStatusEnum] === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function LDAPSourceSyncStatusEnumFromJSON(json: any): LDAPSourceSyncStatusEnum {
|
||||
return LDAPSourceSyncStatusEnumFromJSONTyped(json, false);
|
||||
}
|
||||
|
||||
export function LDAPSourceSyncStatusEnumFromJSONTyped(
|
||||
json: any,
|
||||
ignoreDiscriminator: boolean,
|
||||
): LDAPSourceSyncStatusEnum {
|
||||
return json as LDAPSourceSyncStatusEnum;
|
||||
}
|
||||
|
||||
export function LDAPSourceSyncStatusEnumToJSON(value?: LDAPSourceSyncStatusEnum | null): any {
|
||||
return value as any;
|
||||
}
|
||||
|
||||
export function LDAPSourceSyncStatusEnumToJSONTyped(
|
||||
value: any,
|
||||
ignoreDiscriminator: boolean,
|
||||
): LDAPSourceSyncStatusEnum {
|
||||
return value as LDAPSourceSyncStatusEnum;
|
||||
}
|
||||
Generated
+1
@@ -280,6 +280,7 @@ export * from "./LDAPSourcePropertyMapping";
|
||||
export * from "./LDAPSourcePropertyMappingRequest";
|
||||
export * from "./LDAPSourceRequest";
|
||||
export * from "./LDAPSourceSync";
|
||||
export * from "./LDAPSourceSyncStatusEnum";
|
||||
export * from "./LangEnum";
|
||||
export * from "./LastTaskStatusEnum";
|
||||
export * from "./License";
|
||||
|
||||
+35
-5
@@ -33358,6 +33358,21 @@ paths:
|
||||
$ref: '#/components/schemas/TaskAggregatedStatusEnum'
|
||||
explode: true
|
||||
style: form
|
||||
- in: query
|
||||
name: message_id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: message_id__in
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
description: Multiple values may be separated by commas.
|
||||
explode: false
|
||||
style: form
|
||||
- $ref: '#/components/parameters/QueryPaginationOrdering'
|
||||
- $ref: '#/components/parameters/QueryPaginationPage'
|
||||
- $ref: '#/components/parameters/QueryPaginationPageSize'
|
||||
@@ -42547,9 +42562,10 @@ components:
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
type: integer
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
title: ID
|
||||
title: Uuid
|
||||
tasks:
|
||||
type: array
|
||||
items:
|
||||
@@ -42559,8 +42575,14 @@ components:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
done:
|
||||
type: boolean
|
||||
finished_at:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
readOnly: true
|
||||
status:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/LDAPSourceSyncStatusEnum'
|
||||
readOnly: true
|
||||
source:
|
||||
type: string
|
||||
@@ -42591,11 +42613,19 @@ components:
|
||||
minimum: 0
|
||||
format: int64
|
||||
required:
|
||||
- done
|
||||
- finished_at
|
||||
- pk
|
||||
- source
|
||||
- started_at
|
||||
- status
|
||||
- tasks
|
||||
LDAPSourceSyncStatusEnum:
|
||||
enum:
|
||||
- running
|
||||
- error
|
||||
- warning
|
||||
- done
|
||||
type: string
|
||||
LangEnum:
|
||||
type: string
|
||||
enum:
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import "#elements/forms/DeleteBulkForm";
|
||||
import "#elements/tasks/TaskList";
|
||||
import "#elements/tasks/TaskStatus";
|
||||
import "#elements/forms/ModalForm";
|
||||
import "#admin/sources/ldap/LDAPSourceUserForm";
|
||||
|
||||
import { aki } from "#common/api/client";
|
||||
|
||||
import { PaginatedResponse, Table, TableColumn, Timestamp } from "#elements/table/Table";
|
||||
import { SlottedTemplateResult } from "#elements/types";
|
||||
|
||||
import { LDAPSource, LDAPSourceSync, SourcesApi } from "@goauthentik/api";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { html, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
@customElement("ak-source-ldap-sync-list")
|
||||
export class LDAPSourceSyncList extends Table<LDAPSourceSync> {
|
||||
@property({ attribute: false })
|
||||
source: LDAPSource;
|
||||
|
||||
expandable = true;
|
||||
clearOnRefresh = true;
|
||||
|
||||
@property()
|
||||
order = "-started_at";
|
||||
|
||||
async apiEndpoint(): Promise<PaginatedResponse<LDAPSourceSync>> {
|
||||
return aki(SourcesApi).sourcesLdapSyncsList({
|
||||
...(await this.defaultEndpointConfig()),
|
||||
slug: this.source?.slug,
|
||||
});
|
||||
}
|
||||
|
||||
protected override rowLabel(item: LDAPSourceSync): string {
|
||||
return item.pk;
|
||||
}
|
||||
|
||||
get columns(): TableColumn[] {
|
||||
return [
|
||||
[msg("Status"), "status"],
|
||||
[msg("Started"), "started_at"],
|
||||
[msg("Finished"), "finished_at"],
|
||||
[msg("User count"), "users_count"],
|
||||
[msg("Group count"), "groups_count"],
|
||||
[msg("Membership count"), "membership_count"],
|
||||
[msg("User deleted count"), "user_deletions_count"],
|
||||
[msg("Group deleted count"), "group_deletions_count"],
|
||||
];
|
||||
}
|
||||
|
||||
row(item: LDAPSourceSync): SlottedTemplateResult[] {
|
||||
return [
|
||||
html`<ak-task-status .status=${item.status}></ak-task-status>`,
|
||||
html`${Timestamp(item.startedAt)}`,
|
||||
html`${Timestamp(item.finishedAt)}`,
|
||||
html`${item.usersCount}`,
|
||||
html`${item.groupsCount}`,
|
||||
html`${item.membershipCount}`,
|
||||
html`${item.userDeletionsCount}`,
|
||||
html`${item.groupDeletionsCount}`,
|
||||
];
|
||||
}
|
||||
|
||||
renderExpanded(item: LDAPSourceSync): TemplateResult {
|
||||
return html`<div class="pf-c-content">
|
||||
<ak-task-list .taskIds=${item.tasks}></ak-task-list>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-source-ldap-sync-list": LDAPSourceSyncList;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import "#admin/rbac/ak-rbac-object-permission-page";
|
||||
import "#admin/sources/ldap/LDAPSourceConnectivity";
|
||||
import "#admin/sources/ldap/LDAPSourceUserList";
|
||||
import "#admin/sources/ldap/LDAPSourceSyncList";
|
||||
import "#admin/sources/ldap/LDAPSourceGroupList";
|
||||
import "#admin/events/ObjectChangelog";
|
||||
import "#components/sync/SyncStatusCard";
|
||||
import "#elements/CodeMirror";
|
||||
import "#elements/Tabs";
|
||||
import "#elements/buttons/ActionButton/index";
|
||||
@@ -120,17 +120,9 @@ export class LDAPSourceViewPage extends AKElement {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl">
|
||||
<ak-sync-status-card
|
||||
.fetch=${() => {
|
||||
if (!this.source) return Promise.reject();
|
||||
return aki(SourcesApi).sourcesLdapSyncStatusRetrieve({
|
||||
slug: this.source.slug,
|
||||
});
|
||||
}}
|
||||
></ak-sync-status-card>
|
||||
</div>
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div
|
||||
class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl"
|
||||
>
|
||||
<div class="pf-c-card__title">
|
||||
<p>${msg("Connectivity")}</p>
|
||||
</div>
|
||||
@@ -150,6 +142,14 @@ export class LDAPSourceViewPage extends AKElement {
|
||||
.relObjId="${this.source?.pk}"
|
||||
></ak-schedule-list>
|
||||
</div>
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__title">
|
||||
<p>${msg("Previous synchronisations")}</p>
|
||||
</div>
|
||||
<ak-source-ldap-sync-list
|
||||
.source=${this.source}
|
||||
></ak-source-ldap-sync-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section
|
||||
|
||||
@@ -42,6 +42,8 @@ export class TaskList extends Table<Task> {
|
||||
expandable = true;
|
||||
clearOnRefresh = true;
|
||||
|
||||
@property()
|
||||
taskIds?: string[];
|
||||
@property()
|
||||
relObjAppLabel?: string;
|
||||
@property()
|
||||
@@ -68,11 +70,13 @@ export class TaskList extends Table<Task> {
|
||||
|
||||
async apiEndpoint(): Promise<PaginatedResponse<Task>> {
|
||||
const relObjIdIsnull =
|
||||
typeof this.relObjId !== "undefined"
|
||||
typeof this.taskIds !== "undefined"
|
||||
? undefined
|
||||
: this.showOnlyStandalone
|
||||
? true
|
||||
: undefined;
|
||||
: typeof this.relObjId !== "undefined"
|
||||
? undefined
|
||||
: this.showOnlyStandalone
|
||||
? true
|
||||
: undefined;
|
||||
const aggregatedStatus = this.excludeSuccessful
|
||||
? [
|
||||
TaskAggregatedStatusEnum.WaitingForDependencies,
|
||||
@@ -91,6 +95,7 @@ export class TaskList extends Table<Task> {
|
||||
}
|
||||
return aki(TasksApi).tasksTasksList({
|
||||
...(await this.defaultEndpointConfig()),
|
||||
messageIdIn: this.taskIds,
|
||||
relObjContentTypeAppLabel: this.relObjAppLabel,
|
||||
relObjContentTypeModel: this.relObjModel,
|
||||
relObjId: this.relObjId ? this.relObjId.toString() : undefined,
|
||||
@@ -135,7 +140,7 @@ export class TaskList extends Table<Task> {
|
||||
return html`<div class="pf-c-toolbar__group pf-m-filter-group">
|
||||
<div class="pf-c-toolbar__item pf-m-search-filter">
|
||||
<div class="pf-c-input-group">
|
||||
${this.relObjId === undefined
|
||||
${this.relObjId === undefined && this.taskIds === undefined
|
||||
? html` <label class="pf-c-switch">
|
||||
<input
|
||||
class="pf-c-switch__input"
|
||||
|
||||
@@ -3,7 +3,11 @@ import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
import { AKElement } from "#elements/Base";
|
||||
import { PFColor } from "#elements/Label";
|
||||
|
||||
import { LastTaskStatusEnum, TaskAggregatedStatusEnum } from "@goauthentik/api";
|
||||
import {
|
||||
LastTaskStatusEnum,
|
||||
LDAPSourceSyncStatusEnum,
|
||||
TaskAggregatedStatusEnum,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, html, TemplateResult } from "lit";
|
||||
@@ -16,7 +20,7 @@ export class TaskStatus extends AKElement {
|
||||
public static styles: CSSResult[] = [PFButton];
|
||||
|
||||
@property()
|
||||
status?: TaskAggregatedStatusEnum | TaskAggregatedStatusEnum | LastTaskStatusEnum;
|
||||
status?: TaskAggregatedStatusEnum | LastTaskStatusEnum | LDAPSourceSyncStatusEnum;
|
||||
|
||||
render(): TemplateResult {
|
||||
switch (this.status) {
|
||||
@@ -36,6 +40,7 @@ export class TaskStatus extends AKElement {
|
||||
return html`<ak-label color=${PFColor.Blue}>${msg("Pre-processing")}</ak-label>`;
|
||||
case TaskAggregatedStatusEnum.Running:
|
||||
case LastTaskStatusEnum.Running:
|
||||
case LDAPSourceSyncStatusEnum.Running:
|
||||
return html`<ak-label color=${PFColor.Blue}>${msg("Running")}</ak-label>`;
|
||||
case TaskAggregatedStatusEnum.Postprocess:
|
||||
case LastTaskStatusEnum.Postprocess:
|
||||
@@ -44,14 +49,17 @@ export class TaskStatus extends AKElement {
|
||||
case LastTaskStatusEnum.Done:
|
||||
case TaskAggregatedStatusEnum.Info:
|
||||
case LastTaskStatusEnum.Info:
|
||||
case LDAPSourceSyncStatusEnum.Done:
|
||||
return html`<ak-label color=${PFColor.Green}>${msg("Successful")}</ak-label>`;
|
||||
case TaskAggregatedStatusEnum.Warning:
|
||||
case LastTaskStatusEnum.Warning:
|
||||
case LDAPSourceSyncStatusEnum.Warning:
|
||||
return html`<ak-label color=${PFColor.Orange}>${msg("Warning")}</ak-label>`;
|
||||
case TaskAggregatedStatusEnum.Rejected:
|
||||
case LastTaskStatusEnum.Rejected:
|
||||
case TaskAggregatedStatusEnum.Error:
|
||||
case LastTaskStatusEnum.Error:
|
||||
case LDAPSourceSyncStatusEnum.Error:
|
||||
return html`<ak-label color=${PFColor.Red}>${msg("Error")}</ak-label>`;
|
||||
default:
|
||||
return html`<ak-label color=${PFColor.Gray}>${msg("Unknown")}</ak-label>`;
|
||||
|
||||
Reference in New Issue
Block a user