diff --git a/authentik/core/api/propertymappings.py b/authentik/core/api/propertymappings.py index b3970f832..cc2542483 100644 --- a/authentik/core/api/propertymappings.py +++ b/authentik/core/api/propertymappings.py @@ -7,7 +7,7 @@ from guardian.shortcuts import get_objects_for_user from rest_framework import mixins from rest_framework.decorators import action from rest_framework.exceptions import PermissionDenied -from rest_framework.fields import CharField +from rest_framework.fields import BooleanField, CharField from rest_framework.request import Request from rest_framework.response import Response from rest_framework.serializers import ModelSerializer, SerializerMethodField @@ -29,6 +29,7 @@ class PropertyMappingTestResultSerializer(PassiveSerializer): """Result of a Property-mapping test""" result = CharField(read_only=True) + successful = BooleanField(read_only=True) class PropertyMappingSerializer(ModelSerializer, MetaNameSerializer): @@ -115,7 +116,9 @@ class PropertyMappingViewSet( if not users.exists(): raise PermissionDenied() - response_data = {} + response_data = { + "successful": True + } try: result = mapping.evaluate( users.first(), @@ -125,5 +128,6 @@ class PropertyMappingViewSet( response_data["result"] = dumps(result) except Exception as exc: # pylint: disable=broad-except response_data["result"] = str(exc) + response_data["successful"] = False response = PropertyMappingTestResultSerializer(response_data) return Response(response.data) diff --git a/swagger.yaml b/swagger.yaml index b7a05f9e3..c0f1a20c5 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -16888,6 +16888,10 @@ definitions: type: string readOnly: true minLength: 1 + successful: + title: Successful + type: boolean + readOnly: true LDAPPropertyMapping: required: - name diff --git a/web/src/elements/forms/ModalForm.ts b/web/src/elements/forms/ModalForm.ts index b3d21bb5e..2590c3485 100644 --- a/web/src/elements/forms/ModalForm.ts +++ b/web/src/elements/forms/ModalForm.ts @@ -1,5 +1,5 @@ import { gettext } from "django"; -import { customElement, html, TemplateResult } from "lit-element"; +import { customElement, html, property, TemplateResult } from "lit-element"; import { EVENT_REFRESH } from "../../constants"; import { ModalButton } from "../buttons/ModalButton"; import { Form } from "./Form"; @@ -7,6 +7,9 @@ import { Form } from "./Form"; @customElement("ak-forms-modal") export class ModalForm extends ModalButton { + @property({ type: Boolean }) + closeAfterSuccessfulSubmit = true; + confirm(): void { this.querySelectorAll>("[slot=form]").forEach(form => { const formPromise = form.submit(new Event("submit")); @@ -14,8 +17,10 @@ export class ModalForm extends ModalButton { return; } formPromise.then(() => { - this.open = false; - form.reset(); + if (this.closeAfterSuccessfulSubmit) { + this.open = false; + form.reset(); + } this.dispatchEvent( new CustomEvent(EVENT_REFRESH, { bubbles: true, diff --git a/web/src/pages/outposts/OutpostListPage.ts b/web/src/pages/outposts/OutpostListPage.ts index c39018c1c..ca5dce387 100644 --- a/web/src/pages/outposts/OutpostListPage.ts +++ b/web/src/pages/outposts/OutpostListPage.ts @@ -10,6 +10,7 @@ import "./OutpostForm"; import "../../elements/buttons/SpinnerButton"; import "../../elements/buttons/TokenCopyButton"; import "../../elements/forms/DeleteForm"; +import "../../elements/forms/ModalForm"; import { PAGE_SIZE } from "../../constants"; import { Outpost, OutpostsApi } from "authentik-api"; import { DEFAULT_CONFIG } from "../../api/Config"; diff --git a/web/src/pages/policies/PolicyListPage.ts b/web/src/pages/policies/PolicyListPage.ts index 609fe37c5..cf6464ea7 100644 --- a/web/src/pages/policies/PolicyListPage.ts +++ b/web/src/pages/policies/PolicyListPage.ts @@ -7,6 +7,8 @@ import "../../elements/buttons/ModalButton"; import "../../elements/buttons/Dropdown"; import "../../elements/buttons/SpinnerButton"; import "../../elements/forms/DeleteForm"; +import "../../elements/forms/ModalForm"; +import "./PolicyTestForm"; import { TableColumn } from "../../elements/table/Table"; import { until } from "lit-html/directives/until"; import { PAGE_SIZE } from "../../constants"; @@ -69,12 +71,19 @@ export class PolicyListPage extends TablePage {
- - + + ${gettext("Test")} - -
-
+ + + ${gettext("Test Policy")} + + + + + { + + @property({attribute: false}) + policy?: Policy; + + @property({ attribute: false}) + result?: PolicyTestResult; + + getSuccessMessage(): string { + return gettext("Successfully sent test-request."); + } + + send = (data: PolicyTest): Promise => { + return new PoliciesApi(DEFAULT_CONFIG).policiesAllTest({ + policyUuid: this.policy?.pk || "", + data: data + }).then(result => this.result = result); + }; + + renderResult(): TemplateResult { + return html` + +
+
+ ${this.result?.passing ? gettext("Yes") : gettext("No")} +
+
+
+ +
+
+
    + ${(this.result?.messages || []).length > 0 ? + this.result?.messages?.map(m => { + return html`
  • ${m}
  • `; + }) : + html`
  • -
  • `} +
+
+
+
`; + } + + renderForm(): TemplateResult { + return html`
+ + + + + + + + ${this.result ? this.renderResult(): html``} +
`; + } + +}