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:
Jens L 2023-06-12 22:11:11 +02:00 committed by GitHub
parent e5576d486b
commit 05d73f688c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 698 additions and 29 deletions

View File

@ -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)

View File

@ -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"""

View File

@ -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(),

View File

@ -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",
]

View File

@ -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.",
),
),
]

View File

@ -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")

View File

@ -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())

View File

@ -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": []

View File

@ -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

View File

@ -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}
>
${app.label}
</option>`;
})}
</select>
<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}
>
</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>`;