policies/event_matcher: add model filter (#5802)
* policies/event_matcher: add model filter Signed-off-by: Jens Langhammer <jens@goauthentik.io> * cleanup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * improve logic Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove t`` Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
e5576d486b
commit
05d73f688c
|
@ -8,6 +8,7 @@ from rest_framework.viewsets import ViewSet
|
|||
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.lib.utils.reflection import get_apps
|
||||
from authentik.policies.event_matcher.models import model_choices
|
||||
|
||||
|
||||
class AppSerializer(PassiveSerializer):
|
||||
|
@ -29,3 +30,17 @@ class AppsViewSet(ViewSet):
|
|||
for app in sorted(get_apps(), key=lambda app: app.name):
|
||||
data.append({"name": app.name, "label": app.verbose_name})
|
||||
return Response(AppSerializer(data, many=True).data)
|
||||
|
||||
|
||||
class ModelViewSet(ViewSet):
|
||||
"""Read-only view list all installed models"""
|
||||
|
||||
permission_classes = [IsAdminUser]
|
||||
|
||||
@extend_schema(responses={200: AppSerializer(many=True)})
|
||||
def list(self, request: Request) -> Response:
|
||||
"""Read-only view list all installed models"""
|
||||
data = []
|
||||
for name, label in model_choices():
|
||||
data.append({"name": name, "label": label})
|
||||
return Response(AppSerializer(data, many=True).data)
|
||||
|
|
|
@ -94,6 +94,11 @@ class TestAdminAPI(TestCase):
|
|||
response = self.client.get(reverse("authentik_api:apps-list"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_models(self):
|
||||
"""Test models API"""
|
||||
response = self.client.get(reverse("authentik_api:models-list"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
@reconcile_app("authentik_outposts")
|
||||
def test_system(self):
|
||||
"""Test system API"""
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""API URLs"""
|
||||
from django.urls import path
|
||||
|
||||
from authentik.admin.api.meta import AppsViewSet
|
||||
from authentik.admin.api.meta import AppsViewSet, ModelViewSet
|
||||
from authentik.admin.api.metrics import AdministrationMetricsViewSet
|
||||
from authentik.admin.api.system import SystemView
|
||||
from authentik.admin.api.tasks import TaskViewSet
|
||||
|
@ -11,6 +11,7 @@ from authentik.admin.api.workers import WorkerView
|
|||
api_urlpatterns = [
|
||||
("admin/system_tasks", TaskViewSet, "admin_system_tasks"),
|
||||
("admin/apps", AppsViewSet, "apps"),
|
||||
("admin/models", ModelViewSet, "models"),
|
||||
path(
|
||||
"admin/metrics/",
|
||||
AdministrationMetricsViewSet.as_view(),
|
||||
|
|
|
@ -6,7 +6,7 @@ from rest_framework.viewsets import ModelViewSet
|
|||
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.policies.api.policies import PolicySerializer
|
||||
from authentik.policies.event_matcher.models import EventMatcherPolicy, app_choices
|
||||
from authentik.policies.event_matcher.models import EventMatcherPolicy, app_choices, model_choices
|
||||
|
||||
|
||||
class EventMatcherPolicySerializer(PolicySerializer):
|
||||
|
@ -21,9 +21,24 @@ class EventMatcherPolicySerializer(PolicySerializer):
|
|||
"all applications are matched."
|
||||
),
|
||||
)
|
||||
model = ChoiceField(
|
||||
choices=model_choices(),
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
help_text=_(
|
||||
"Match events created by selected model. "
|
||||
"When left empty, all models are matched. When an app is selected, "
|
||||
"all the application's models are matched."
|
||||
),
|
||||
)
|
||||
|
||||
def validate(self, attrs: dict) -> dict:
|
||||
if attrs["action"] == "" and attrs["client_ip"] == "" and attrs["app"] == "":
|
||||
if (
|
||||
attrs["action"] == ""
|
||||
and attrs["client_ip"] == ""
|
||||
and attrs["app"] == ""
|
||||
and attrs["model"] == ""
|
||||
):
|
||||
raise ValidationError(_("At least one criteria must be set."))
|
||||
return super().validate(attrs)
|
||||
|
||||
|
@ -33,6 +48,7 @@ class EventMatcherPolicySerializer(PolicySerializer):
|
|||
"action",
|
||||
"client_ip",
|
||||
"app",
|
||||
"model",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 4.1.7 on 2023-05-29 15:24
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("authentik_policies_event_matcher", "0021_alter_eventmatcherpolicy_app"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="eventmatcherpolicy",
|
||||
name="model",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text="Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -1,13 +1,19 @@
|
|||
"""Event Matcher models"""
|
||||
from itertools import chain
|
||||
|
||||
from django.apps import apps
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework.serializers import BaseSerializer
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.blueprints.v1.importer import is_model_allowed
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.policies.models import Policy
|
||||
from authentik.policies.types import PolicyRequest, PolicyResult
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
def app_choices() -> list[tuple[str, str]]:
|
||||
"""Get a list of all installed applications that create events.
|
||||
|
@ -19,6 +25,18 @@ def app_choices() -> list[tuple[str, str]]:
|
|||
return choices
|
||||
|
||||
|
||||
def model_choices() -> list[tuple[str, str]]:
|
||||
"""Get a list of all installed models
|
||||
Returns a list of tuples containing (dotted.model.path, name)"""
|
||||
choices = []
|
||||
for model in apps.get_models():
|
||||
if not is_model_allowed(model):
|
||||
continue
|
||||
name = f"{model._meta.app_label}.{model._meta.model_name}"
|
||||
choices.append((name, model._meta.verbose_name))
|
||||
return choices
|
||||
|
||||
|
||||
class EventMatcherPolicy(Policy):
|
||||
"""Passes when Event matches selected criteria."""
|
||||
|
||||
|
@ -38,6 +56,15 @@ class EventMatcherPolicy(Policy):
|
|||
"When left empty, all applications are matched."
|
||||
),
|
||||
)
|
||||
model = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
help_text=_(
|
||||
"Match events created by selected model. "
|
||||
"When left empty, all models are matched. When an app is selected, "
|
||||
"all the application's models are matched."
|
||||
),
|
||||
)
|
||||
client_ip = models.TextField(
|
||||
blank=True,
|
||||
help_text=_(
|
||||
|
@ -60,13 +87,55 @@ class EventMatcherPolicy(Policy):
|
|||
if "event" not in request.context:
|
||||
return PolicyResult(False)
|
||||
event: Event = request.context["event"]
|
||||
if event.action == self.action:
|
||||
return PolicyResult(True, "Action matched.")
|
||||
if event.client_ip == self.client_ip:
|
||||
return PolicyResult(True, "Client IP matched.")
|
||||
if event.app == self.app:
|
||||
return PolicyResult(True, "App matched.")
|
||||
return PolicyResult(False)
|
||||
matches: list[PolicyResult] = []
|
||||
messages = []
|
||||
checks = [
|
||||
self.passes_action,
|
||||
self.passes_client_ip,
|
||||
self.passes_app,
|
||||
self.passes_model,
|
||||
]
|
||||
for checker in checks:
|
||||
result = checker(request, event)
|
||||
if result is None:
|
||||
continue
|
||||
LOGGER.info(
|
||||
"Event matcher check result",
|
||||
checker=checker.__name__,
|
||||
result=result,
|
||||
)
|
||||
matches.append(result)
|
||||
passing = any(x.passing for x in matches)
|
||||
messages = chain(*[x.messages for x in matches])
|
||||
result = PolicyResult(passing, *messages)
|
||||
result.source_results = matches
|
||||
return result
|
||||
|
||||
def passes_action(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
|
||||
"""Check if `self.action` matches"""
|
||||
if self.action == "":
|
||||
return None
|
||||
return PolicyResult(self.action == event.action, "Action matched.")
|
||||
|
||||
def passes_client_ip(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
|
||||
"""Check if `self.client_ip` matches"""
|
||||
if self.client_ip == "":
|
||||
return None
|
||||
return PolicyResult(self.client_ip == event.client_ip, "Client IP matched.")
|
||||
|
||||
def passes_app(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
|
||||
"""Check if `self.app` matches"""
|
||||
if self.app == "":
|
||||
return None
|
||||
return PolicyResult(self.app == event.app, "App matched.")
|
||||
|
||||
def passes_model(self, request: PolicyRequest, event: Event) -> PolicyResult | None:
|
||||
"""Check if `self.model` is set, and pass if it matches the event's model"""
|
||||
if self.model == "":
|
||||
return None
|
||||
event_model_info = event.context.get("model", {})
|
||||
event_model = f"{event_model_info.get('app')}.{event_model_info.get('model_name')}"
|
||||
return PolicyResult(event_model == self.model, "Model matched.")
|
||||
|
||||
class Meta(Policy.PolicyMeta):
|
||||
verbose_name = _("Event Matcher Policy")
|
||||
|
|
|
@ -42,6 +42,22 @@ class TestEventMatcherPolicy(TestCase):
|
|||
self.assertTrue(response.passing)
|
||||
self.assertTupleEqual(response.messages, ("App matched.",))
|
||||
|
||||
def test_match_model(self):
|
||||
"""Test match model"""
|
||||
event = Event.new(EventAction.LOGIN)
|
||||
event.context = {
|
||||
"model": {
|
||||
"app": "foo",
|
||||
"model_name": "bar",
|
||||
}
|
||||
}
|
||||
request = PolicyRequest(get_anonymous_user())
|
||||
request.context["event"] = event
|
||||
policy: EventMatcherPolicy = EventMatcherPolicy.objects.create(model="foo.bar")
|
||||
response = policy.passes(request)
|
||||
self.assertTrue(response.passing)
|
||||
self.assertTupleEqual(response.messages, ("Model matched.",))
|
||||
|
||||
def test_drop(self):
|
||||
"""Test drop event"""
|
||||
event = Event.new(EventAction.LOGIN)
|
||||
|
@ -52,6 +68,19 @@ class TestEventMatcherPolicy(TestCase):
|
|||
response = policy.passes(request)
|
||||
self.assertFalse(response.passing)
|
||||
|
||||
def test_drop_multiple(self):
|
||||
"""Test drop event"""
|
||||
event = Event.new(EventAction.LOGIN)
|
||||
event.app = "foo"
|
||||
event.client_ip = "1.2.3.4"
|
||||
request = PolicyRequest(get_anonymous_user())
|
||||
request.context["event"] = event
|
||||
policy: EventMatcherPolicy = EventMatcherPolicy.objects.create(
|
||||
client_ip="1.2.3.5", app="bar"
|
||||
)
|
||||
response = policy.passes(request)
|
||||
self.assertFalse(response.passing)
|
||||
|
||||
def test_invalid(self):
|
||||
"""Test passing event"""
|
||||
request = PolicyRequest(get_anonymous_user())
|
||||
|
|
|
@ -3249,6 +3249,84 @@
|
|||
],
|
||||
"title": "App",
|
||||
"description": "Match events created by selected application. When left empty, all applications are matched."
|
||||
},
|
||||
"model": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"",
|
||||
"authentik_crypto.certificatekeypair",
|
||||
"authentik_events.event",
|
||||
"authentik_events.notificationtransport",
|
||||
"authentik_events.notification",
|
||||
"authentik_events.notificationrule",
|
||||
"authentik_events.notificationwebhookmapping",
|
||||
"authentik_flows.flow",
|
||||
"authentik_flows.flowstagebinding",
|
||||
"authentik_outposts.dockerserviceconnection",
|
||||
"authentik_outposts.kubernetesserviceconnection",
|
||||
"authentik_outposts.outpost",
|
||||
"authentik_policies_dummy.dummypolicy",
|
||||
"authentik_policies_event_matcher.eventmatcherpolicy",
|
||||
"authentik_policies_expiry.passwordexpirypolicy",
|
||||
"authentik_policies_expression.expressionpolicy",
|
||||
"authentik_policies_password.passwordpolicy",
|
||||
"authentik_policies_reputation.reputationpolicy",
|
||||
"authentik_policies_reputation.reputation",
|
||||
"authentik_policies.policybinding",
|
||||
"authentik_providers_ldap.ldapprovider",
|
||||
"authentik_providers_oauth2.scopemapping",
|
||||
"authentik_providers_oauth2.oauth2provider",
|
||||
"authentik_providers_oauth2.authorizationcode",
|
||||
"authentik_providers_oauth2.accesstoken",
|
||||
"authentik_providers_oauth2.refreshtoken",
|
||||
"authentik_providers_proxy.proxyprovider",
|
||||
"authentik_providers_radius.radiusprovider",
|
||||
"authentik_providers_saml.samlprovider",
|
||||
"authentik_providers_saml.samlpropertymapping",
|
||||
"authentik_providers_scim.scimprovider",
|
||||
"authentik_providers_scim.scimmapping",
|
||||
"authentik_sources_ldap.ldapsource",
|
||||
"authentik_sources_ldap.ldappropertymapping",
|
||||
"authentik_sources_oauth.oauthsource",
|
||||
"authentik_sources_oauth.useroauthsourceconnection",
|
||||
"authentik_sources_plex.plexsource",
|
||||
"authentik_sources_plex.plexsourceconnection",
|
||||
"authentik_sources_saml.samlsource",
|
||||
"authentik_sources_saml.usersamlsourceconnection",
|
||||
"authentik_stages_authenticator_duo.authenticatorduostage",
|
||||
"authentik_stages_authenticator_duo.duodevice",
|
||||
"authentik_stages_authenticator_sms.authenticatorsmsstage",
|
||||
"authentik_stages_authenticator_sms.smsdevice",
|
||||
"authentik_stages_authenticator_static.authenticatorstaticstage",
|
||||
"authentik_stages_authenticator_totp.authenticatortotpstage",
|
||||
"authentik_stages_authenticator_validate.authenticatorvalidatestage",
|
||||
"authentik_stages_authenticator_webauthn.authenticatewebauthnstage",
|
||||
"authentik_stages_authenticator_webauthn.webauthndevice",
|
||||
"authentik_stages_captcha.captchastage",
|
||||
"authentik_stages_consent.consentstage",
|
||||
"authentik_stages_consent.userconsent",
|
||||
"authentik_stages_deny.denystage",
|
||||
"authentik_stages_dummy.dummystage",
|
||||
"authentik_stages_email.emailstage",
|
||||
"authentik_stages_identification.identificationstage",
|
||||
"authentik_stages_invitation.invitationstage",
|
||||
"authentik_stages_invitation.invitation",
|
||||
"authentik_stages_password.passwordstage",
|
||||
"authentik_stages_prompt.prompt",
|
||||
"authentik_stages_prompt.promptstage",
|
||||
"authentik_stages_user_delete.userdeletestage",
|
||||
"authentik_stages_user_login.userloginstage",
|
||||
"authentik_stages_user_logout.userlogoutstage",
|
||||
"authentik_stages_user_write.userwritestage",
|
||||
"authentik_tenants.tenant",
|
||||
"authentik_blueprints.blueprintinstance",
|
||||
"authentik_core.group",
|
||||
"authentik_core.user",
|
||||
"authentik_core.application",
|
||||
"authentik_core.token"
|
||||
],
|
||||
"title": "Model",
|
||||
"description": "Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched."
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
|
405
schema.yml
405
schema.yml
|
@ -65,6 +65,35 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/admin/models/:
|
||||
get:
|
||||
operationId: admin_models_list
|
||||
description: Read-only view list all installed models
|
||||
tags:
|
||||
- admin
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/App'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/admin/system/:
|
||||
get:
|
||||
operationId: admin_system_retrieve
|
||||
|
@ -10973,6 +11002,10 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- in: query
|
||||
name: model
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: name
|
||||
schema:
|
||||
|
@ -29155,6 +29188,82 @@ components:
|
|||
* `authentik.blueprints` - authentik Blueprints
|
||||
* `authentik.core` - authentik Core
|
||||
* `authentik.enterprise` - authentik Enterprise
|
||||
model:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/ModelEnum'
|
||||
description: |-
|
||||
Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
* `authentik_crypto.certificatekeypair` - Certificate-Key Pair
|
||||
* `authentik_events.event` - Event
|
||||
* `authentik_events.notificationtransport` - Notification Transport
|
||||
* `authentik_events.notification` - Notification
|
||||
* `authentik_events.notificationrule` - Notification Rule
|
||||
* `authentik_events.notificationwebhookmapping` - Webhook Mapping
|
||||
* `authentik_flows.flow` - Flow
|
||||
* `authentik_flows.flowstagebinding` - Flow Stage Binding
|
||||
* `authentik_outposts.dockerserviceconnection` - Docker Service-Connection
|
||||
* `authentik_outposts.kubernetesserviceconnection` - Kubernetes Service-Connection
|
||||
* `authentik_outposts.outpost` - outpost
|
||||
* `authentik_policies_dummy.dummypolicy` - Dummy Policy
|
||||
* `authentik_policies_event_matcher.eventmatcherpolicy` - Event Matcher Policy
|
||||
* `authentik_policies_expiry.passwordexpirypolicy` - Password Expiry Policy
|
||||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
* `authentik_providers_oauth2.oauth2provider` - OAuth2/OpenID Provider
|
||||
* `authentik_providers_oauth2.authorizationcode` - Authorization Code
|
||||
* `authentik_providers_oauth2.accesstoken` - OAuth2 Access Token
|
||||
* `authentik_providers_oauth2.refreshtoken` - OAuth2 Refresh Token
|
||||
* `authentik_providers_proxy.proxyprovider` - Proxy Provider
|
||||
* `authentik_providers_radius.radiusprovider` - Radius Provider
|
||||
* `authentik_providers_saml.samlprovider` - SAML Provider
|
||||
* `authentik_providers_saml.samlpropertymapping` - SAML Property Mapping
|
||||
* `authentik_providers_scim.scimprovider` - SCIM Provider
|
||||
* `authentik_providers_scim.scimmapping` - SCIM Mapping
|
||||
* `authentik_sources_ldap.ldapsource` - LDAP Source
|
||||
* `authentik_sources_ldap.ldappropertymapping` - LDAP Property Mapping
|
||||
* `authentik_sources_oauth.oauthsource` - OAuth Source
|
||||
* `authentik_sources_oauth.useroauthsourceconnection` - User OAuth Source Connection
|
||||
* `authentik_sources_plex.plexsource` - Plex Source
|
||||
* `authentik_sources_plex.plexsourceconnection` - User Plex Source Connection
|
||||
* `authentik_sources_saml.samlsource` - SAML Source
|
||||
* `authentik_sources_saml.usersamlsourceconnection` - User SAML Source Connection
|
||||
* `authentik_stages_authenticator_duo.authenticatorduostage` - Duo Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_duo.duodevice` - Duo Device
|
||||
* `authentik_stages_authenticator_sms.authenticatorsmsstage` - SMS Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_sms.smsdevice` - SMS Device
|
||||
* `authentik_stages_authenticator_static.authenticatorstaticstage` - Static Authenticator Stage
|
||||
* `authentik_stages_authenticator_totp.authenticatortotpstage` - TOTP Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_validate.authenticatorvalidatestage` - Authenticator Validation Stage
|
||||
* `authentik_stages_authenticator_webauthn.authenticatewebauthnstage` - WebAuthn Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_webauthn.webauthndevice` - WebAuthn Device
|
||||
* `authentik_stages_captcha.captchastage` - Captcha Stage
|
||||
* `authentik_stages_consent.consentstage` - Consent Stage
|
||||
* `authentik_stages_consent.userconsent` - User Consent
|
||||
* `authentik_stages_deny.denystage` - Deny Stage
|
||||
* `authentik_stages_dummy.dummystage` - Dummy Stage
|
||||
* `authentik_stages_email.emailstage` - Email Stage
|
||||
* `authentik_stages_identification.identificationstage` - Identification Stage
|
||||
* `authentik_stages_invitation.invitationstage` - Invitation Stage
|
||||
* `authentik_stages_invitation.invitation` - Invitation
|
||||
* `authentik_stages_password.passwordstage` - Password Stage
|
||||
* `authentik_stages_prompt.prompt` - Prompt
|
||||
* `authentik_stages_prompt.promptstage` - Prompt Stage
|
||||
* `authentik_stages_user_delete.userdeletestage` - User Delete Stage
|
||||
* `authentik_stages_user_login.userloginstage` - User Login Stage
|
||||
* `authentik_stages_user_logout.userlogoutstage` - User Logout Stage
|
||||
* `authentik_stages_user_write.userwritestage` - User Write Stage
|
||||
* `authentik_tenants.tenant` - Tenant
|
||||
* `authentik_blueprints.blueprintinstance` - Blueprint Instance
|
||||
* `authentik_core.group` - group
|
||||
* `authentik_core.user` - User
|
||||
* `authentik_core.application` - Application
|
||||
* `authentik_core.token` - Token
|
||||
required:
|
||||
- bound_to
|
||||
- component
|
||||
|
@ -29265,6 +29374,82 @@ components:
|
|||
* `authentik.blueprints` - authentik Blueprints
|
||||
* `authentik.core` - authentik Core
|
||||
* `authentik.enterprise` - authentik Enterprise
|
||||
model:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/ModelEnum'
|
||||
description: |-
|
||||
Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
* `authentik_crypto.certificatekeypair` - Certificate-Key Pair
|
||||
* `authentik_events.event` - Event
|
||||
* `authentik_events.notificationtransport` - Notification Transport
|
||||
* `authentik_events.notification` - Notification
|
||||
* `authentik_events.notificationrule` - Notification Rule
|
||||
* `authentik_events.notificationwebhookmapping` - Webhook Mapping
|
||||
* `authentik_flows.flow` - Flow
|
||||
* `authentik_flows.flowstagebinding` - Flow Stage Binding
|
||||
* `authentik_outposts.dockerserviceconnection` - Docker Service-Connection
|
||||
* `authentik_outposts.kubernetesserviceconnection` - Kubernetes Service-Connection
|
||||
* `authentik_outposts.outpost` - outpost
|
||||
* `authentik_policies_dummy.dummypolicy` - Dummy Policy
|
||||
* `authentik_policies_event_matcher.eventmatcherpolicy` - Event Matcher Policy
|
||||
* `authentik_policies_expiry.passwordexpirypolicy` - Password Expiry Policy
|
||||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
* `authentik_providers_oauth2.oauth2provider` - OAuth2/OpenID Provider
|
||||
* `authentik_providers_oauth2.authorizationcode` - Authorization Code
|
||||
* `authentik_providers_oauth2.accesstoken` - OAuth2 Access Token
|
||||
* `authentik_providers_oauth2.refreshtoken` - OAuth2 Refresh Token
|
||||
* `authentik_providers_proxy.proxyprovider` - Proxy Provider
|
||||
* `authentik_providers_radius.radiusprovider` - Radius Provider
|
||||
* `authentik_providers_saml.samlprovider` - SAML Provider
|
||||
* `authentik_providers_saml.samlpropertymapping` - SAML Property Mapping
|
||||
* `authentik_providers_scim.scimprovider` - SCIM Provider
|
||||
* `authentik_providers_scim.scimmapping` - SCIM Mapping
|
||||
* `authentik_sources_ldap.ldapsource` - LDAP Source
|
||||
* `authentik_sources_ldap.ldappropertymapping` - LDAP Property Mapping
|
||||
* `authentik_sources_oauth.oauthsource` - OAuth Source
|
||||
* `authentik_sources_oauth.useroauthsourceconnection` - User OAuth Source Connection
|
||||
* `authentik_sources_plex.plexsource` - Plex Source
|
||||
* `authentik_sources_plex.plexsourceconnection` - User Plex Source Connection
|
||||
* `authentik_sources_saml.samlsource` - SAML Source
|
||||
* `authentik_sources_saml.usersamlsourceconnection` - User SAML Source Connection
|
||||
* `authentik_stages_authenticator_duo.authenticatorduostage` - Duo Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_duo.duodevice` - Duo Device
|
||||
* `authentik_stages_authenticator_sms.authenticatorsmsstage` - SMS Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_sms.smsdevice` - SMS Device
|
||||
* `authentik_stages_authenticator_static.authenticatorstaticstage` - Static Authenticator Stage
|
||||
* `authentik_stages_authenticator_totp.authenticatortotpstage` - TOTP Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_validate.authenticatorvalidatestage` - Authenticator Validation Stage
|
||||
* `authentik_stages_authenticator_webauthn.authenticatewebauthnstage` - WebAuthn Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_webauthn.webauthndevice` - WebAuthn Device
|
||||
* `authentik_stages_captcha.captchastage` - Captcha Stage
|
||||
* `authentik_stages_consent.consentstage` - Consent Stage
|
||||
* `authentik_stages_consent.userconsent` - User Consent
|
||||
* `authentik_stages_deny.denystage` - Deny Stage
|
||||
* `authentik_stages_dummy.dummystage` - Dummy Stage
|
||||
* `authentik_stages_email.emailstage` - Email Stage
|
||||
* `authentik_stages_identification.identificationstage` - Identification Stage
|
||||
* `authentik_stages_invitation.invitationstage` - Invitation Stage
|
||||
* `authentik_stages_invitation.invitation` - Invitation
|
||||
* `authentik_stages_password.passwordstage` - Password Stage
|
||||
* `authentik_stages_prompt.prompt` - Prompt
|
||||
* `authentik_stages_prompt.promptstage` - Prompt Stage
|
||||
* `authentik_stages_user_delete.userdeletestage` - User Delete Stage
|
||||
* `authentik_stages_user_login.userloginstage` - User Login Stage
|
||||
* `authentik_stages_user_logout.userlogoutstage` - User Logout Stage
|
||||
* `authentik_stages_user_write.userwritestage` - User Write Stage
|
||||
* `authentik_tenants.tenant` - Tenant
|
||||
* `authentik_blueprints.blueprintinstance` - Blueprint Instance
|
||||
* `authentik_core.group` - group
|
||||
* `authentik_core.user` - User
|
||||
* `authentik_core.application` - Application
|
||||
* `authentik_core.token` - Token
|
||||
required:
|
||||
- name
|
||||
EventRequest:
|
||||
|
@ -31236,6 +31421,150 @@ components:
|
|||
required:
|
||||
- labels
|
||||
- name
|
||||
ModelEnum:
|
||||
enum:
|
||||
- authentik_crypto.certificatekeypair
|
||||
- authentik_events.event
|
||||
- authentik_events.notificationtransport
|
||||
- authentik_events.notification
|
||||
- authentik_events.notificationrule
|
||||
- authentik_events.notificationwebhookmapping
|
||||
- authentik_flows.flow
|
||||
- authentik_flows.flowstagebinding
|
||||
- authentik_outposts.dockerserviceconnection
|
||||
- authentik_outposts.kubernetesserviceconnection
|
||||
- authentik_outposts.outpost
|
||||
- authentik_policies_dummy.dummypolicy
|
||||
- authentik_policies_event_matcher.eventmatcherpolicy
|
||||
- authentik_policies_expiry.passwordexpirypolicy
|
||||
- authentik_policies_expression.expressionpolicy
|
||||
- authentik_policies_password.passwordpolicy
|
||||
- authentik_policies_reputation.reputationpolicy
|
||||
- authentik_policies_reputation.reputation
|
||||
- authentik_policies.policybinding
|
||||
- authentik_providers_ldap.ldapprovider
|
||||
- authentik_providers_oauth2.scopemapping
|
||||
- authentik_providers_oauth2.oauth2provider
|
||||
- authentik_providers_oauth2.authorizationcode
|
||||
- authentik_providers_oauth2.accesstoken
|
||||
- authentik_providers_oauth2.refreshtoken
|
||||
- authentik_providers_proxy.proxyprovider
|
||||
- authentik_providers_radius.radiusprovider
|
||||
- authentik_providers_saml.samlprovider
|
||||
- authentik_providers_saml.samlpropertymapping
|
||||
- authentik_providers_scim.scimprovider
|
||||
- authentik_providers_scim.scimmapping
|
||||
- authentik_sources_ldap.ldapsource
|
||||
- authentik_sources_ldap.ldappropertymapping
|
||||
- authentik_sources_oauth.oauthsource
|
||||
- authentik_sources_oauth.useroauthsourceconnection
|
||||
- authentik_sources_plex.plexsource
|
||||
- authentik_sources_plex.plexsourceconnection
|
||||
- authentik_sources_saml.samlsource
|
||||
- authentik_sources_saml.usersamlsourceconnection
|
||||
- authentik_stages_authenticator_duo.authenticatorduostage
|
||||
- authentik_stages_authenticator_duo.duodevice
|
||||
- authentik_stages_authenticator_sms.authenticatorsmsstage
|
||||
- authentik_stages_authenticator_sms.smsdevice
|
||||
- authentik_stages_authenticator_static.authenticatorstaticstage
|
||||
- authentik_stages_authenticator_totp.authenticatortotpstage
|
||||
- authentik_stages_authenticator_validate.authenticatorvalidatestage
|
||||
- authentik_stages_authenticator_webauthn.authenticatewebauthnstage
|
||||
- authentik_stages_authenticator_webauthn.webauthndevice
|
||||
- authentik_stages_captcha.captchastage
|
||||
- authentik_stages_consent.consentstage
|
||||
- authentik_stages_consent.userconsent
|
||||
- authentik_stages_deny.denystage
|
||||
- authentik_stages_dummy.dummystage
|
||||
- authentik_stages_email.emailstage
|
||||
- authentik_stages_identification.identificationstage
|
||||
- authentik_stages_invitation.invitationstage
|
||||
- authentik_stages_invitation.invitation
|
||||
- authentik_stages_password.passwordstage
|
||||
- authentik_stages_prompt.prompt
|
||||
- authentik_stages_prompt.promptstage
|
||||
- authentik_stages_user_delete.userdeletestage
|
||||
- authentik_stages_user_login.userloginstage
|
||||
- authentik_stages_user_logout.userlogoutstage
|
||||
- authentik_stages_user_write.userwritestage
|
||||
- authentik_tenants.tenant
|
||||
- authentik_blueprints.blueprintinstance
|
||||
- authentik_core.group
|
||||
- authentik_core.user
|
||||
- authentik_core.application
|
||||
- authentik_core.token
|
||||
type: string
|
||||
description: |-
|
||||
* `authentik_crypto.certificatekeypair` - Certificate-Key Pair
|
||||
* `authentik_events.event` - Event
|
||||
* `authentik_events.notificationtransport` - Notification Transport
|
||||
* `authentik_events.notification` - Notification
|
||||
* `authentik_events.notificationrule` - Notification Rule
|
||||
* `authentik_events.notificationwebhookmapping` - Webhook Mapping
|
||||
* `authentik_flows.flow` - Flow
|
||||
* `authentik_flows.flowstagebinding` - Flow Stage Binding
|
||||
* `authentik_outposts.dockerserviceconnection` - Docker Service-Connection
|
||||
* `authentik_outposts.kubernetesserviceconnection` - Kubernetes Service-Connection
|
||||
* `authentik_outposts.outpost` - outpost
|
||||
* `authentik_policies_dummy.dummypolicy` - Dummy Policy
|
||||
* `authentik_policies_event_matcher.eventmatcherpolicy` - Event Matcher Policy
|
||||
* `authentik_policies_expiry.passwordexpirypolicy` - Password Expiry Policy
|
||||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
* `authentik_providers_oauth2.oauth2provider` - OAuth2/OpenID Provider
|
||||
* `authentik_providers_oauth2.authorizationcode` - Authorization Code
|
||||
* `authentik_providers_oauth2.accesstoken` - OAuth2 Access Token
|
||||
* `authentik_providers_oauth2.refreshtoken` - OAuth2 Refresh Token
|
||||
* `authentik_providers_proxy.proxyprovider` - Proxy Provider
|
||||
* `authentik_providers_radius.radiusprovider` - Radius Provider
|
||||
* `authentik_providers_saml.samlprovider` - SAML Provider
|
||||
* `authentik_providers_saml.samlpropertymapping` - SAML Property Mapping
|
||||
* `authentik_providers_scim.scimprovider` - SCIM Provider
|
||||
* `authentik_providers_scim.scimmapping` - SCIM Mapping
|
||||
* `authentik_sources_ldap.ldapsource` - LDAP Source
|
||||
* `authentik_sources_ldap.ldappropertymapping` - LDAP Property Mapping
|
||||
* `authentik_sources_oauth.oauthsource` - OAuth Source
|
||||
* `authentik_sources_oauth.useroauthsourceconnection` - User OAuth Source Connection
|
||||
* `authentik_sources_plex.plexsource` - Plex Source
|
||||
* `authentik_sources_plex.plexsourceconnection` - User Plex Source Connection
|
||||
* `authentik_sources_saml.samlsource` - SAML Source
|
||||
* `authentik_sources_saml.usersamlsourceconnection` - User SAML Source Connection
|
||||
* `authentik_stages_authenticator_duo.authenticatorduostage` - Duo Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_duo.duodevice` - Duo Device
|
||||
* `authentik_stages_authenticator_sms.authenticatorsmsstage` - SMS Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_sms.smsdevice` - SMS Device
|
||||
* `authentik_stages_authenticator_static.authenticatorstaticstage` - Static Authenticator Stage
|
||||
* `authentik_stages_authenticator_totp.authenticatortotpstage` - TOTP Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_validate.authenticatorvalidatestage` - Authenticator Validation Stage
|
||||
* `authentik_stages_authenticator_webauthn.authenticatewebauthnstage` - WebAuthn Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_webauthn.webauthndevice` - WebAuthn Device
|
||||
* `authentik_stages_captcha.captchastage` - Captcha Stage
|
||||
* `authentik_stages_consent.consentstage` - Consent Stage
|
||||
* `authentik_stages_consent.userconsent` - User Consent
|
||||
* `authentik_stages_deny.denystage` - Deny Stage
|
||||
* `authentik_stages_dummy.dummystage` - Dummy Stage
|
||||
* `authentik_stages_email.emailstage` - Email Stage
|
||||
* `authentik_stages_identification.identificationstage` - Identification Stage
|
||||
* `authentik_stages_invitation.invitationstage` - Invitation Stage
|
||||
* `authentik_stages_invitation.invitation` - Invitation
|
||||
* `authentik_stages_password.passwordstage` - Password Stage
|
||||
* `authentik_stages_prompt.prompt` - Prompt
|
||||
* `authentik_stages_prompt.promptstage` - Prompt Stage
|
||||
* `authentik_stages_user_delete.userdeletestage` - User Delete Stage
|
||||
* `authentik_stages_user_login.userloginstage` - User Login Stage
|
||||
* `authentik_stages_user_logout.userlogoutstage` - User Logout Stage
|
||||
* `authentik_stages_user_write.userwritestage` - User Write Stage
|
||||
* `authentik_tenants.tenant` - Tenant
|
||||
* `authentik_blueprints.blueprintinstance` - Blueprint Instance
|
||||
* `authentik_core.group` - group
|
||||
* `authentik_core.user` - User
|
||||
* `authentik_core.application` - Application
|
||||
* `authentik_core.token` - Token
|
||||
NameIdPolicyEnum:
|
||||
enum:
|
||||
- urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
|
||||
|
@ -35988,6 +36317,82 @@ components:
|
|||
* `authentik.blueprints` - authentik Blueprints
|
||||
* `authentik.core` - authentik Core
|
||||
* `authentik.enterprise` - authentik Enterprise
|
||||
model:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/ModelEnum'
|
||||
description: |-
|
||||
Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
* `authentik_crypto.certificatekeypair` - Certificate-Key Pair
|
||||
* `authentik_events.event` - Event
|
||||
* `authentik_events.notificationtransport` - Notification Transport
|
||||
* `authentik_events.notification` - Notification
|
||||
* `authentik_events.notificationrule` - Notification Rule
|
||||
* `authentik_events.notificationwebhookmapping` - Webhook Mapping
|
||||
* `authentik_flows.flow` - Flow
|
||||
* `authentik_flows.flowstagebinding` - Flow Stage Binding
|
||||
* `authentik_outposts.dockerserviceconnection` - Docker Service-Connection
|
||||
* `authentik_outposts.kubernetesserviceconnection` - Kubernetes Service-Connection
|
||||
* `authentik_outposts.outpost` - outpost
|
||||
* `authentik_policies_dummy.dummypolicy` - Dummy Policy
|
||||
* `authentik_policies_event_matcher.eventmatcherpolicy` - Event Matcher Policy
|
||||
* `authentik_policies_expiry.passwordexpirypolicy` - Password Expiry Policy
|
||||
* `authentik_policies_expression.expressionpolicy` - Expression Policy
|
||||
* `authentik_policies_password.passwordpolicy` - Password Policy
|
||||
* `authentik_policies_reputation.reputationpolicy` - Reputation Policy
|
||||
* `authentik_policies_reputation.reputation` - reputation
|
||||
* `authentik_policies.policybinding` - Policy Binding
|
||||
* `authentik_providers_ldap.ldapprovider` - LDAP Provider
|
||||
* `authentik_providers_oauth2.scopemapping` - Scope Mapping
|
||||
* `authentik_providers_oauth2.oauth2provider` - OAuth2/OpenID Provider
|
||||
* `authentik_providers_oauth2.authorizationcode` - Authorization Code
|
||||
* `authentik_providers_oauth2.accesstoken` - OAuth2 Access Token
|
||||
* `authentik_providers_oauth2.refreshtoken` - OAuth2 Refresh Token
|
||||
* `authentik_providers_proxy.proxyprovider` - Proxy Provider
|
||||
* `authentik_providers_radius.radiusprovider` - Radius Provider
|
||||
* `authentik_providers_saml.samlprovider` - SAML Provider
|
||||
* `authentik_providers_saml.samlpropertymapping` - SAML Property Mapping
|
||||
* `authentik_providers_scim.scimprovider` - SCIM Provider
|
||||
* `authentik_providers_scim.scimmapping` - SCIM Mapping
|
||||
* `authentik_sources_ldap.ldapsource` - LDAP Source
|
||||
* `authentik_sources_ldap.ldappropertymapping` - LDAP Property Mapping
|
||||
* `authentik_sources_oauth.oauthsource` - OAuth Source
|
||||
* `authentik_sources_oauth.useroauthsourceconnection` - User OAuth Source Connection
|
||||
* `authentik_sources_plex.plexsource` - Plex Source
|
||||
* `authentik_sources_plex.plexsourceconnection` - User Plex Source Connection
|
||||
* `authentik_sources_saml.samlsource` - SAML Source
|
||||
* `authentik_sources_saml.usersamlsourceconnection` - User SAML Source Connection
|
||||
* `authentik_stages_authenticator_duo.authenticatorduostage` - Duo Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_duo.duodevice` - Duo Device
|
||||
* `authentik_stages_authenticator_sms.authenticatorsmsstage` - SMS Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_sms.smsdevice` - SMS Device
|
||||
* `authentik_stages_authenticator_static.authenticatorstaticstage` - Static Authenticator Stage
|
||||
* `authentik_stages_authenticator_totp.authenticatortotpstage` - TOTP Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_validate.authenticatorvalidatestage` - Authenticator Validation Stage
|
||||
* `authentik_stages_authenticator_webauthn.authenticatewebauthnstage` - WebAuthn Authenticator Setup Stage
|
||||
* `authentik_stages_authenticator_webauthn.webauthndevice` - WebAuthn Device
|
||||
* `authentik_stages_captcha.captchastage` - Captcha Stage
|
||||
* `authentik_stages_consent.consentstage` - Consent Stage
|
||||
* `authentik_stages_consent.userconsent` - User Consent
|
||||
* `authentik_stages_deny.denystage` - Deny Stage
|
||||
* `authentik_stages_dummy.dummystage` - Dummy Stage
|
||||
* `authentik_stages_email.emailstage` - Email Stage
|
||||
* `authentik_stages_identification.identificationstage` - Identification Stage
|
||||
* `authentik_stages_invitation.invitationstage` - Invitation Stage
|
||||
* `authentik_stages_invitation.invitation` - Invitation
|
||||
* `authentik_stages_password.passwordstage` - Password Stage
|
||||
* `authentik_stages_prompt.prompt` - Prompt
|
||||
* `authentik_stages_prompt.promptstage` - Prompt Stage
|
||||
* `authentik_stages_user_delete.userdeletestage` - User Delete Stage
|
||||
* `authentik_stages_user_login.userloginstage` - User Login Stage
|
||||
* `authentik_stages_user_logout.userlogoutstage` - User Logout Stage
|
||||
* `authentik_stages_user_write.userwritestage` - User Write Stage
|
||||
* `authentik_tenants.tenant` - Tenant
|
||||
* `authentik_blueprints.blueprintinstance` - Blueprint Instance
|
||||
* `authentik_core.group` - group
|
||||
* `authentik_core.user` - User
|
||||
* `authentik_core.application` - Application
|
||||
* `authentik_core.token` - Token
|
||||
PatchedEventRequest:
|
||||
type: object
|
||||
description: Event Serializer
|
||||
|
|
|
@ -27,12 +27,6 @@ export class EventMatcherPolicyForm extends ModelForm<EventMatcherPolicy, string
|
|||
});
|
||||
}
|
||||
|
||||
async load(): Promise<void> {
|
||||
this.apps = await new AdminApi(DEFAULT_CONFIG).adminAppsList();
|
||||
}
|
||||
|
||||
apps?: App[];
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance) {
|
||||
return msg("Successfully updated policy.");
|
||||
|
@ -133,25 +127,61 @@ export class EventMatcherPolicyForm extends ModelForm<EventMatcherPolicy, string
|
|||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${msg("App")} name="app">
|
||||
<select class="pf-c-form-control">
|
||||
<option value="" ?selected=${this.instance?.app === undefined}>
|
||||
---------
|
||||
</option>
|
||||
${this.apps?.map((app) => {
|
||||
return html`<option
|
||||
value=${app.name}
|
||||
?selected=${this.instance?.app === app.name}
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<App[]> => {
|
||||
const items = await new AdminApi(DEFAULT_CONFIG).adminAppsList();
|
||||
return items.filter((item) =>
|
||||
query ? item.name.includes(query) : true,
|
||||
);
|
||||
}}
|
||||
.renderElement=${(item: App): string => {
|
||||
return item.label;
|
||||
}}
|
||||
.value=${(item: App | undefined): string | undefined => {
|
||||
return item?.name;
|
||||
}}
|
||||
.selected=${(item: App): boolean => {
|
||||
return this.instance?.app === item.name;
|
||||
}}
|
||||
?blankable=${true}
|
||||
>
|
||||
${app.label}
|
||||
</option>`;
|
||||
})}
|
||||
</select>
|
||||
</ak-search-select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Match events created by selected application. When left empty, all applications are matched.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${msg("Model")} name="model">
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<App[]> => {
|
||||
const items = await new AdminApi(DEFAULT_CONFIG).adminModelsList();
|
||||
return items
|
||||
.filter((item) => (query ? item.name.includes(query) : true))
|
||||
.sort((a, b) => {
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
}}
|
||||
.renderElement=${(item: App): string => {
|
||||
return `${item.label} (${item.name.split(".")[0]})`;
|
||||
}}
|
||||
.value=${(item: App | undefined): string | undefined => {
|
||||
return item?.name;
|
||||
}}
|
||||
.selected=${(item: App): boolean => {
|
||||
return this.instance?.model === item.name;
|
||||
}}
|
||||
?blankable=${true}
|
||||
>
|
||||
</ak-search-select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Match events created by selected model. When left empty, all models are matched.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
</form>`;
|
||||
|
|
Reference in a new issue