events: triggers -> rules
This commit is contained in:
parent
0b41cb84f0
commit
192dbe05c4
|
@ -4,8 +4,8 @@ from django.urls import path
|
|||
from authentik.admin.views import (
|
||||
applications,
|
||||
certificate_key_pair,
|
||||
events_notifications_rules,
|
||||
events_notifications_transports,
|
||||
events_notifications_triggers,
|
||||
flows,
|
||||
groups,
|
||||
outposts,
|
||||
|
@ -370,20 +370,20 @@ urlpatterns = [
|
|||
events_notifications_transports.NotificationTransportDeleteView.as_view(),
|
||||
name="notification-transport-delete",
|
||||
),
|
||||
# Event Notification Triggers
|
||||
# Event Notification Rules
|
||||
path(
|
||||
"events/triggers/create/",
|
||||
events_notifications_triggers.NotificationTriggerCreateView.as_view(),
|
||||
name="notification-trigger-create",
|
||||
"events/rules/create/",
|
||||
events_notifications_rules.NotificationRuleCreateView.as_view(),
|
||||
name="notification-rule-create",
|
||||
),
|
||||
path(
|
||||
"events/triggers/<uuid:pk>/update/",
|
||||
events_notifications_triggers.NotificationTriggerUpdateView.as_view(),
|
||||
name="notification-trigger-update",
|
||||
"events/rules/<uuid:pk>/update/",
|
||||
events_notifications_rules.NotificationRuleUpdateView.as_view(),
|
||||
name="notification-rule-update",
|
||||
),
|
||||
path(
|
||||
"events/triggers/<uuid:pk>/delete/",
|
||||
events_notifications_triggers.NotificationTriggerDeleteView.as_view(),
|
||||
name="notification-trigger-delete",
|
||||
"events/rules/<uuid:pk>/delete/",
|
||||
events_notifications_rules.NotificationRuleDeleteView.as_view(),
|
||||
name="notification-rule-delete",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""authentik NotificationTrigger administration"""
|
||||
"""authentik NotificationRule administration"""
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.auth.mixins import (
|
||||
PermissionRequiredMixin as DjangoPermissionRequiredMixin,
|
||||
|
@ -10,30 +10,30 @@ from django.views.generic import UpdateView
|
|||
from guardian.mixins import PermissionRequiredMixin
|
||||
|
||||
from authentik.admin.views.utils import BackSuccessUrlMixin, DeleteMessageView
|
||||
from authentik.events.forms import NotificationTriggerForm
|
||||
from authentik.events.models import NotificationTrigger
|
||||
from authentik.events.forms import NotificationRuleForm
|
||||
from authentik.events.models import NotificationRule
|
||||
from authentik.lib.views import CreateAssignPermView
|
||||
|
||||
|
||||
class NotificationTriggerCreateView(
|
||||
class NotificationRuleCreateView(
|
||||
SuccessMessageMixin,
|
||||
BackSuccessUrlMixin,
|
||||
LoginRequiredMixin,
|
||||
DjangoPermissionRequiredMixin,
|
||||
CreateAssignPermView,
|
||||
):
|
||||
"""Create new NotificationTrigger"""
|
||||
"""Create new NotificationRule"""
|
||||
|
||||
model = NotificationTrigger
|
||||
form_class = NotificationTriggerForm
|
||||
permission_required = "authentik_events.add_notificationtrigger"
|
||||
model = NotificationRule
|
||||
form_class = NotificationRuleForm
|
||||
permission_required = "authentik_events.add_NotificationRule"
|
||||
|
||||
template_name = "generic/create.html"
|
||||
success_url = reverse_lazy("authentik_core:shell")
|
||||
success_message = _("Successfully created Notification Trigger")
|
||||
success_message = _("Successfully created Notification Rule")
|
||||
|
||||
|
||||
class NotificationTriggerUpdateView(
|
||||
class NotificationRuleUpdateView(
|
||||
SuccessMessageMixin,
|
||||
BackSuccessUrlMixin,
|
||||
LoginRequiredMixin,
|
||||
|
@ -42,23 +42,23 @@ class NotificationTriggerUpdateView(
|
|||
):
|
||||
"""Update application"""
|
||||
|
||||
model = NotificationTrigger
|
||||
form_class = NotificationTriggerForm
|
||||
permission_required = "authentik_events.change_notificationtrigger"
|
||||
model = NotificationRule
|
||||
form_class = NotificationRuleForm
|
||||
permission_required = "authentik_events.change_NotificationRule"
|
||||
|
||||
template_name = "generic/update.html"
|
||||
success_url = reverse_lazy("authentik_core:shell")
|
||||
success_message = _("Successfully updated Notification Trigger")
|
||||
success_message = _("Successfully updated Notification Rule")
|
||||
|
||||
|
||||
class NotificationTriggerDeleteView(
|
||||
class NotificationRuleDeleteView(
|
||||
LoginRequiredMixin, PermissionRequiredMixin, DeleteMessageView
|
||||
):
|
||||
"""Delete application"""
|
||||
|
||||
model = NotificationTrigger
|
||||
permission_required = "authentik_events.delete_notificationtrigger"
|
||||
model = NotificationRule
|
||||
permission_required = "authentik_events.delete_NotificationRule"
|
||||
|
||||
template_name = "generic/delete.html"
|
||||
success_url = reverse_lazy("authentik_core:shell")
|
||||
success_message = _("Successfully deleted Notification Trigger")
|
||||
success_message = _("Successfully deleted Notification Rule")
|
|
@ -21,8 +21,8 @@ from authentik.core.api.users import UserViewSet
|
|||
from authentik.crypto.api import CertificateKeyPairViewSet
|
||||
from authentik.events.api.event import EventViewSet
|
||||
from authentik.events.api.notification import NotificationViewSet
|
||||
from authentik.events.api.notification_rule import NotificationRuleViewSet
|
||||
from authentik.events.api.notification_transport import NotificationTransportViewSet
|
||||
from authentik.events.api.notification_trigger import NotificationTriggerViewSet
|
||||
from authentik.flows.api import (
|
||||
FlowCacheViewSet,
|
||||
FlowStageBindingViewSet,
|
||||
|
@ -103,7 +103,7 @@ router.register("crypto/certificatekeypairs", CertificateKeyPairViewSet)
|
|||
router.register("events/events", EventViewSet)
|
||||
router.register("events/notifications", NotificationViewSet)
|
||||
router.register("events/transports", NotificationTransportViewSet)
|
||||
router.register("events/triggers", NotificationTriggerViewSet)
|
||||
router.register("events/rules", NotificationRuleViewSet)
|
||||
|
||||
router.register("sources/all", SourceViewSet)
|
||||
router.register("sources/ldap", LDAPSourceViewSet)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
"""NotificationRule API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.events.models import NotificationRule
|
||||
|
||||
|
||||
class NotificationRuleSerializer(ModelSerializer):
|
||||
"""NotificationRule Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = NotificationRule
|
||||
depth = 2
|
||||
fields = [
|
||||
"pk",
|
||||
"name",
|
||||
"transports",
|
||||
"severity",
|
||||
"group",
|
||||
]
|
||||
|
||||
|
||||
class NotificationRuleViewSet(ModelViewSet):
|
||||
"""NotificationRule Viewset"""
|
||||
|
||||
queryset = NotificationRule.objects.all()
|
||||
serializer_class = NotificationRuleSerializer
|
|
@ -1,28 +0,0 @@
|
|||
"""NotificationTrigger API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.events.models import NotificationTrigger
|
||||
|
||||
|
||||
class NotificationTriggerSerializer(ModelSerializer):
|
||||
"""NotificationTrigger Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = NotificationTrigger
|
||||
depth = 2
|
||||
fields = [
|
||||
"pk",
|
||||
"name",
|
||||
"transports",
|
||||
"severity",
|
||||
"group",
|
||||
]
|
||||
|
||||
|
||||
class NotificationTriggerViewSet(ModelViewSet):
|
||||
"""NotificationTrigger Viewset"""
|
||||
|
||||
queryset = NotificationTrigger.objects.all()
|
||||
serializer_class = NotificationTriggerSerializer
|
|
@ -2,7 +2,7 @@
|
|||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from authentik.events.models import NotificationTransport, NotificationTrigger
|
||||
from authentik.events.models import NotificationRule, NotificationTransport
|
||||
|
||||
|
||||
class NotificationTransportForm(forms.ModelForm):
|
||||
|
@ -30,12 +30,12 @@ class NotificationTransportForm(forms.ModelForm):
|
|||
}
|
||||
|
||||
|
||||
class NotificationTriggerForm(forms.ModelForm):
|
||||
"""NotificationTrigger Form"""
|
||||
class NotificationRuleForm(forms.ModelForm):
|
||||
"""NotificationRule Form"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = NotificationTrigger
|
||||
model = NotificationRule
|
||||
fields = [
|
||||
"name",
|
||||
"group",
|
||||
|
|
|
@ -48,7 +48,7 @@ class Migration(migrations.Migration):
|
|||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="NotificationTrigger",
|
||||
name="NotificationRule",
|
||||
fields=[
|
||||
(
|
||||
"policybindingmodel_ptr",
|
||||
|
@ -93,8 +93,8 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Notification Trigger",
|
||||
"verbose_name_plural": "Notification Triggers",
|
||||
"verbose_name": "Notification Rule",
|
||||
"verbose_name_plural": "Notification Rules",
|
||||
},
|
||||
bases=("authentik_policies.policybindingmodel",),
|
||||
),
|
|
@ -14,7 +14,7 @@ def notify_configuration_error(apps: Apps, schema_editor: BaseDatabaseSchemaEdit
|
|||
EventMatcherPolicy = apps.get_model(
|
||||
"authentik_policies_event_matcher", "EventMatcherPolicy"
|
||||
)
|
||||
NotificationTrigger = apps.get_model("authentik_events", "NotificationTrigger")
|
||||
NotificationRule = apps.get_model("authentik_events", "NotificationRule")
|
||||
NotificationTransport = apps.get_model("authentik_events", "NotificationTransport")
|
||||
|
||||
admin_group = (
|
||||
|
@ -27,7 +27,7 @@ def notify_configuration_error(apps: Apps, schema_editor: BaseDatabaseSchemaEdit
|
|||
name="default-match-configuration-error",
|
||||
defaults={"action": EventAction.CONFIGURATION_ERROR},
|
||||
)
|
||||
trigger, _ = NotificationTrigger.objects.using(db_alias).update_or_create(
|
||||
trigger, _ = NotificationRule.objects.using(db_alias).update_or_create(
|
||||
name="default-notify-configuration-error",
|
||||
defaults={"group": admin_group, "severity": NotificationSeverity.ALERT},
|
||||
)
|
||||
|
@ -53,7 +53,7 @@ def notify_update(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
|||
EventMatcherPolicy = apps.get_model(
|
||||
"authentik_policies_event_matcher", "EventMatcherPolicy"
|
||||
)
|
||||
NotificationTrigger = apps.get_model("authentik_events", "NotificationTrigger")
|
||||
NotificationRule = apps.get_model("authentik_events", "NotificationRule")
|
||||
NotificationTransport = apps.get_model("authentik_events", "NotificationTransport")
|
||||
|
||||
admin_group = (
|
||||
|
@ -66,7 +66,7 @@ def notify_update(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
|||
name="default-match-update",
|
||||
defaults={"action": EventAction.UPDATE_AVAILABLE},
|
||||
)
|
||||
trigger, _ = NotificationTrigger.objects.using(db_alias).update_or_create(
|
||||
trigger, _ = NotificationRule.objects.using(db_alias).update_or_create(
|
||||
name="default-notify-update",
|
||||
defaults={"group": admin_group, "severity": NotificationSeverity.ALERT},
|
||||
)
|
||||
|
@ -92,7 +92,7 @@ def notify_exception(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
|||
EventMatcherPolicy = apps.get_model(
|
||||
"authentik_policies_event_matcher", "EventMatcherPolicy"
|
||||
)
|
||||
NotificationTrigger = apps.get_model("authentik_events", "NotificationTrigger")
|
||||
NotificationRule = apps.get_model("authentik_events", "NotificationRule")
|
||||
NotificationTransport = apps.get_model("authentik_events", "NotificationTransport")
|
||||
|
||||
admin_group = (
|
||||
|
@ -109,7 +109,7 @@ def notify_exception(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
|||
name="default-match-property-mapping-exception",
|
||||
defaults={"action": EventAction.PROPERTY_MAPPING_EXCEPTION},
|
||||
)
|
||||
trigger, _ = NotificationTrigger.objects.using(db_alias).update_or_create(
|
||||
trigger, _ = NotificationRule.objects.using(db_alias).update_or_create(
|
||||
name="default-notify-exception",
|
||||
defaults={"group": admin_group, "severity": NotificationSeverity.ALERT},
|
||||
)
|
||||
|
@ -150,7 +150,7 @@ class Migration(migrations.Migration):
|
|||
dependencies = [
|
||||
(
|
||||
"authentik_events",
|
||||
"0010_notification_notificationtransport_notificationtrigger",
|
||||
"0010_notification_notificationtransport_notificationrule",
|
||||
),
|
||||
("authentik_core", "0016_auto_20201202_2234"),
|
||||
("authentik_policies_event_matcher", "0003_auto_20210110_1907"),
|
|
@ -174,7 +174,7 @@ class TransportMode(models.TextChoices):
|
|||
|
||||
|
||||
class NotificationTransport(models.Model):
|
||||
"""Action which is executed when a Trigger matches"""
|
||||
"""Action which is executed when a Rule matches"""
|
||||
|
||||
uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
|
||||
|
||||
|
@ -323,7 +323,7 @@ class Notification(models.Model):
|
|||
verbose_name_plural = _("Notifications")
|
||||
|
||||
|
||||
class NotificationTrigger(PolicyBindingModel):
|
||||
class NotificationRule(PolicyBindingModel):
|
||||
"""Decide when to create a Notification based on policies attached to this object."""
|
||||
|
||||
name = models.TextField(unique=True)
|
||||
|
@ -357,9 +357,9 @@ class NotificationTrigger(PolicyBindingModel):
|
|||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Notification Trigger {self.name}"
|
||||
return f"Notification Rule {self.name}"
|
||||
|
||||
class Meta:
|
||||
|
||||
verbose_name = _("Notification Trigger")
|
||||
verbose_name_plural = _("Notification Triggers")
|
||||
verbose_name = _("Notification Rule")
|
||||
verbose_name_plural = _("Notification Rules")
|
||||
|
|
|
@ -5,9 +5,9 @@ from structlog import get_logger
|
|||
from authentik.events.models import (
|
||||
Event,
|
||||
Notification,
|
||||
NotificationRule,
|
||||
NotificationTransport,
|
||||
NotificationTransportError,
|
||||
NotificationTrigger,
|
||||
)
|
||||
from authentik.lib.tasks import MonitoredTask, TaskResult, TaskResultStatus
|
||||
from authentik.policies.engine import PolicyEngine, PolicyEngineMode
|
||||
|
@ -20,7 +20,7 @@ LOGGER = get_logger()
|
|||
@CELERY_APP.task()
|
||||
def event_notification_handler(event_uuid: str):
|
||||
"""Start task for each trigger definition"""
|
||||
for trigger in NotificationTrigger.objects.all():
|
||||
for trigger in NotificationRule.objects.all():
|
||||
event_trigger_handler.apply_async(
|
||||
args=[event_uuid, trigger.name], queue="authentik_events"
|
||||
)
|
||||
|
@ -28,20 +28,20 @@ def event_notification_handler(event_uuid: str):
|
|||
|
||||
@CELERY_APP.task()
|
||||
def event_trigger_handler(event_uuid: str, trigger_name: str):
|
||||
"""Check if policies attached to NotificationTrigger match event"""
|
||||
"""Check if policies attached to NotificationRule match event"""
|
||||
event: Event = Event.objects.get(event_uuid=event_uuid)
|
||||
trigger: NotificationTrigger = NotificationTrigger.objects.get(name=trigger_name)
|
||||
trigger: NotificationRule = NotificationRule.objects.get(name=trigger_name)
|
||||
|
||||
if "policy_uuid" in event.context:
|
||||
policy_uuid = event.context["policy_uuid"]
|
||||
if PolicyBinding.objects.filter(
|
||||
target__in=NotificationTrigger.objects.all().values_list(
|
||||
target__in=NotificationRule.objects.all().values_list(
|
||||
"pbm_uuid", flat=True
|
||||
),
|
||||
policy=policy_uuid,
|
||||
).exists():
|
||||
# If policy that caused this event to be created is attached
|
||||
# to *any* NotificationTrigger, we return early.
|
||||
# to *any* NotificationRule, we return early.
|
||||
# This is the most effective way to prevent infinite loops.
|
||||
LOGGER.debug(
|
||||
"e(trigger): attempting to prevent infinite loop", trigger=trigger
|
||||
|
|
|
@ -8,8 +8,8 @@ from authentik.core.models import Group, User
|
|||
from authentik.events.models import (
|
||||
Event,
|
||||
EventAction,
|
||||
NotificationRule,
|
||||
NotificationTransport,
|
||||
NotificationTrigger,
|
||||
)
|
||||
from authentik.policies.event_matcher.models import EventMatcherPolicy
|
||||
from authentik.policies.exceptions import PolicyException
|
||||
|
@ -28,7 +28,7 @@ class TestEventsNotifications(TestCase):
|
|||
def test_trigger_empty(self):
|
||||
"""Test trigger without any policies attached"""
|
||||
transport = NotificationTransport.objects.create(name="transport")
|
||||
trigger = NotificationTrigger.objects.create(name="trigger", group=self.group)
|
||||
trigger = NotificationRule.objects.create(name="trigger", group=self.group)
|
||||
trigger.transports.add(transport)
|
||||
trigger.save()
|
||||
|
||||
|
@ -40,7 +40,7 @@ class TestEventsNotifications(TestCase):
|
|||
def test_trigger_single(self):
|
||||
"""Test simple transport triggering"""
|
||||
transport = NotificationTransport.objects.create(name="transport")
|
||||
trigger = NotificationTrigger.objects.create(name="trigger", group=self.group)
|
||||
trigger = NotificationRule.objects.create(name="trigger", group=self.group)
|
||||
trigger.transports.add(transport)
|
||||
trigger.save()
|
||||
matcher = EventMatcherPolicy.objects.create(
|
||||
|
@ -55,7 +55,7 @@ class TestEventsNotifications(TestCase):
|
|||
|
||||
def test_trigger_no_group(self):
|
||||
"""Test trigger without group"""
|
||||
trigger = NotificationTrigger.objects.create(name="trigger")
|
||||
trigger = NotificationRule.objects.create(name="trigger")
|
||||
matcher = EventMatcherPolicy.objects.create(
|
||||
name="matcher", action=EventAction.CUSTOM_PREFIX
|
||||
)
|
||||
|
@ -69,8 +69,8 @@ class TestEventsNotifications(TestCase):
|
|||
def test_policy_error_recursive(self):
|
||||
"""Test Policy error which would cause recursion"""
|
||||
transport = NotificationTransport.objects.create(name="transport")
|
||||
NotificationTrigger.objects.filter(name__startswith="default").delete()
|
||||
trigger = NotificationTrigger.objects.create(name="trigger", group=self.group)
|
||||
NotificationRule.objects.filter(name__startswith="default").delete()
|
||||
trigger = NotificationRule.objects.create(name="trigger", group=self.group)
|
||||
trigger.transports.add(transport)
|
||||
trigger.save()
|
||||
matcher = EventMatcherPolicy.objects.create(
|
||||
|
|
320
swagger.yaml
320
swagger.yaml
|
@ -1090,6 +1090,133 @@ paths:
|
|||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
/events/rules/:
|
||||
get:
|
||||
operationId: events_rules_list
|
||||
description: NotificationRule Viewset
|
||||
parameters:
|
||||
- name: ordering
|
||||
in: query
|
||||
description: Which field to use when ordering the results.
|
||||
required: false
|
||||
type: string
|
||||
- name: search
|
||||
in: query
|
||||
description: A search term.
|
||||
required: false
|
||||
type: string
|
||||
- name: page
|
||||
in: query
|
||||
description: A page number within the paginated result set.
|
||||
required: false
|
||||
type: integer
|
||||
- name: page_size
|
||||
in: query
|
||||
description: Number of results to return per page.
|
||||
required: false
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
required:
|
||||
- count
|
||||
- results
|
||||
type: object
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
next:
|
||||
type: string
|
||||
format: uri
|
||||
x-nullable: true
|
||||
previous:
|
||||
type: string
|
||||
format: uri
|
||||
x-nullable: true
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
tags:
|
||||
- events
|
||||
post:
|
||||
operationId: events_rules_create
|
||||
description: NotificationRule Viewset
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
responses:
|
||||
'201':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
tags:
|
||||
- events
|
||||
parameters: []
|
||||
/events/rules/{pbm_uuid}/:
|
||||
get:
|
||||
operationId: events_rules_read
|
||||
description: NotificationRule Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
tags:
|
||||
- events
|
||||
put:
|
||||
operationId: events_rules_update
|
||||
description: NotificationRule Viewset
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
tags:
|
||||
- events
|
||||
patch:
|
||||
operationId: events_rules_partial_update
|
||||
description: NotificationRule Viewset
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationRule'
|
||||
tags:
|
||||
- events
|
||||
delete:
|
||||
operationId: events_rules_delete
|
||||
description: NotificationRule Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'204':
|
||||
description: ''
|
||||
tags:
|
||||
- events
|
||||
parameters:
|
||||
- name: pbm_uuid
|
||||
in: path
|
||||
description: A UUID string identifying this Notification Rule.
|
||||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
/events/transports/:
|
||||
get:
|
||||
operationId: events_transports_list
|
||||
|
@ -1243,133 +1370,6 @@ paths:
|
|||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
/events/triggers/:
|
||||
get:
|
||||
operationId: events_triggers_list
|
||||
description: NotificationTrigger Viewset
|
||||
parameters:
|
||||
- name: ordering
|
||||
in: query
|
||||
description: Which field to use when ordering the results.
|
||||
required: false
|
||||
type: string
|
||||
- name: search
|
||||
in: query
|
||||
description: A search term.
|
||||
required: false
|
||||
type: string
|
||||
- name: page
|
||||
in: query
|
||||
description: A page number within the paginated result set.
|
||||
required: false
|
||||
type: integer
|
||||
- name: page_size
|
||||
in: query
|
||||
description: Number of results to return per page.
|
||||
required: false
|
||||
type: integer
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
required:
|
||||
- count
|
||||
- results
|
||||
type: object
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
next:
|
||||
type: string
|
||||
format: uri
|
||||
x-nullable: true
|
||||
previous:
|
||||
type: string
|
||||
format: uri
|
||||
x-nullable: true
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
tags:
|
||||
- events
|
||||
post:
|
||||
operationId: events_triggers_create
|
||||
description: NotificationTrigger Viewset
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
responses:
|
||||
'201':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
tags:
|
||||
- events
|
||||
parameters: []
|
||||
/events/triggers/{pbm_uuid}/:
|
||||
get:
|
||||
operationId: events_triggers_read
|
||||
description: NotificationTrigger Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
tags:
|
||||
- events
|
||||
put:
|
||||
operationId: events_triggers_update
|
||||
description: NotificationTrigger Viewset
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
tags:
|
||||
- events
|
||||
patch:
|
||||
operationId: events_triggers_partial_update
|
||||
description: NotificationTrigger Viewset
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
responses:
|
||||
'200':
|
||||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/NotificationTrigger'
|
||||
tags:
|
||||
- events
|
||||
delete:
|
||||
operationId: events_triggers_delete
|
||||
description: NotificationTrigger Viewset
|
||||
parameters: []
|
||||
responses:
|
||||
'204':
|
||||
description: ''
|
||||
tags:
|
||||
- events
|
||||
parameters:
|
||||
- name: pbm_uuid
|
||||
in: path
|
||||
description: A UUID string identifying this Notification Trigger.
|
||||
required: true
|
||||
type: string
|
||||
format: uuid
|
||||
/flows/bindings/:
|
||||
get:
|
||||
operationId: flows_bindings_list
|
||||
|
@ -7630,38 +7630,8 @@ definitions:
|
|||
seen:
|
||||
title: Seen
|
||||
type: boolean
|
||||
NotificationTransport:
|
||||
description: NotificationTransport Serializer
|
||||
required:
|
||||
- name
|
||||
- mode
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
title: Uuid
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
minLength: 1
|
||||
mode:
|
||||
title: Mode
|
||||
type: string
|
||||
enum:
|
||||
- webhook
|
||||
- webhook_slack
|
||||
- email
|
||||
mode_verbose:
|
||||
title: Mode verbose
|
||||
type: string
|
||||
readOnly: true
|
||||
webhook_url:
|
||||
title: Webhook url
|
||||
type: string
|
||||
NotificationTrigger:
|
||||
description: NotificationTrigger Serializer
|
||||
NotificationRule:
|
||||
description: NotificationRule Serializer
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
|
@ -7679,7 +7649,7 @@ definitions:
|
|||
description: ''
|
||||
type: array
|
||||
items:
|
||||
description: Action which is executed when a Trigger matches
|
||||
description: Action which is executed when a Rule matches
|
||||
required:
|
||||
- name
|
||||
- mode
|
||||
|
@ -7767,6 +7737,36 @@ definitions:
|
|||
format: uuid
|
||||
readOnly: true
|
||||
readOnly: true
|
||||
NotificationTransport:
|
||||
description: NotificationTransport Serializer
|
||||
required:
|
||||
- name
|
||||
- mode
|
||||
type: object
|
||||
properties:
|
||||
pk:
|
||||
title: Uuid
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
minLength: 1
|
||||
mode:
|
||||
title: Mode
|
||||
type: string
|
||||
enum:
|
||||
- webhook
|
||||
- webhook_slack
|
||||
- email
|
||||
mode_verbose:
|
||||
title: Mode verbose
|
||||
type: string
|
||||
readOnly: true
|
||||
webhook_url:
|
||||
title: Webhook url
|
||||
type: string
|
||||
Stage:
|
||||
title: Stage obj
|
||||
description: Stage Serializer
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { DefaultClient, QueryArguments, PBResponse } from "./Client";
|
||||
import { Group } from "./Groups";
|
||||
|
||||
export class Rule {
|
||||
pk: string;
|
||||
name: string;
|
||||
transports: string[];
|
||||
severity: string;
|
||||
group?: Group;
|
||||
|
||||
constructor() {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
static get(pk: string): Promise<Rule> {
|
||||
return DefaultClient.fetch<Rule>(["events", "rules", pk]);
|
||||
}
|
||||
|
||||
static list(filter?: QueryArguments): Promise<PBResponse<Rule>> {
|
||||
return DefaultClient.fetch<PBResponse<Rule>>(["events", "rules"], filter);
|
||||
}
|
||||
|
||||
static adminUrl(rest: string): string {
|
||||
return `/administration/events/rules/${rest}`;
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import { DefaultClient, QueryArguments, PBResponse } from "./Client";
|
||||
import { Group } from "./Groups";
|
||||
|
||||
export class Trigger {
|
||||
pk: string;
|
||||
name: string;
|
||||
transports: string[];
|
||||
severity: string;
|
||||
group?: Group;
|
||||
|
||||
constructor() {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
static get(pk: string): Promise<Trigger> {
|
||||
return DefaultClient.fetch<Trigger>(["events", "triggers", pk]);
|
||||
}
|
||||
|
||||
static list(filter?: QueryArguments): Promise<PBResponse<Trigger>> {
|
||||
return DefaultClient.fetch<PBResponse<Trigger>>(["events", "triggers"], filter);
|
||||
}
|
||||
|
||||
static adminUrl(rest: string): string {
|
||||
return `/administration/events/triggers/${rest}`;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { customElement, html, LitElement, TemplateResult } from "lit-element";
|
||||
|
||||
@customElement("ak-notification-trigger")
|
||||
export class NotificationTrigger extends LitElement {
|
||||
export class NotificationRule extends LitElement {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
|
|
@ -14,7 +14,7 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [
|
|||
}),
|
||||
new SidebarItem("Events").children(
|
||||
new SidebarItem("Log", "/events/log"),
|
||||
new SidebarItem("Notification Triggers", "/events/triggers"),
|
||||
new SidebarItem("Notification Rules", "/events/rules"),
|
||||
new SidebarItem("Notification Transports", "/events/transports"),
|
||||
).when((): Promise<boolean> => {
|
||||
return User.me().then(u => u.is_superuser);
|
||||
|
|
|
@ -7,20 +7,20 @@ import "../../elements/policies/BoundPoliciesList";
|
|||
import "../../elements/buttons/ModalButton";
|
||||
import "../../elements/buttons/SpinnerButton";
|
||||
import { TableColumn } from "../../elements/table/Table";
|
||||
import { Trigger } from "../../api/EventTriggers";
|
||||
import { Rule } from "../../api/EventRules";
|
||||
|
||||
@customElement("ak-event-trigger-list")
|
||||
export class TriggerListPage extends TablePage<Trigger> {
|
||||
@customElement("ak-event-rule-list")
|
||||
export class RuleListPage extends TablePage<Rule> {
|
||||
expandable = true;
|
||||
|
||||
searchEnabled(): boolean {
|
||||
return true;
|
||||
}
|
||||
pageTitle(): string {
|
||||
return gettext("Notification Triggers");
|
||||
return gettext("Notification Rules");
|
||||
}
|
||||
pageDescription(): string {
|
||||
return gettext("Send notifications on whenever a specific Event is created and matched by policies.");
|
||||
return gettext("Send notifications whenever a specific Event is created and matched by policies.");
|
||||
}
|
||||
pageIcon(): string {
|
||||
return gettext("pf-icon pf-icon-attention-bell");
|
||||
|
@ -29,8 +29,8 @@ export class TriggerListPage extends TablePage<Trigger> {
|
|||
@property()
|
||||
order = "name";
|
||||
|
||||
apiEndpoint(page: number): Promise<PBResponse<Trigger>> {
|
||||
return Trigger.list({
|
||||
apiEndpoint(page: number): Promise<PBResponse<Rule>> {
|
||||
return Rule.list({
|
||||
ordering: this.order,
|
||||
page: page,
|
||||
search: this.search || "",
|
||||
|
@ -46,19 +46,19 @@ export class TriggerListPage extends TablePage<Trigger> {
|
|||
];
|
||||
}
|
||||
|
||||
row(item: Trigger): TemplateResult[] {
|
||||
row(item: Rule): TemplateResult[] {
|
||||
return [
|
||||
html`${item.name}`,
|
||||
html`${item.severity}`,
|
||||
html`${item.group?.name || gettext("None (trigger disabled)")}`,
|
||||
html`${item.group?.name || gettext("None (rule disabled)")}`,
|
||||
html`
|
||||
<ak-modal-button href="${Trigger.adminUrl(`${item.pk}/update/`)}">
|
||||
<ak-modal-button href="${Rule.adminUrl(`${item.pk}/update/`)}">
|
||||
<ak-spinner-button slot="trigger" class="pf-m-secondary">
|
||||
${gettext("Edit")}
|
||||
</ak-spinner-button>
|
||||
<div slot="modal"></div>
|
||||
</ak-modal-button>
|
||||
<ak-modal-button href="${Trigger.adminUrl(`${item.pk}/delete/`)}">
|
||||
<ak-modal-button href="${Rule.adminUrl(`${item.pk}/delete/`)}">
|
||||
<ak-spinner-button slot="trigger" class="pf-m-danger">
|
||||
${gettext("Delete")}
|
||||
</ak-spinner-button>
|
||||
|
@ -70,7 +70,7 @@ export class TriggerListPage extends TablePage<Trigger> {
|
|||
|
||||
renderToolbar(): TemplateResult {
|
||||
return html`
|
||||
<ak-modal-button href=${Trigger.adminUrl("create/")}>
|
||||
<ak-modal-button href=${Rule.adminUrl("create/")}>
|
||||
<ak-spinner-button slot="trigger" class="pf-m-primary">
|
||||
${gettext("Create")}
|
||||
</ak-spinner-button>
|
||||
|
@ -80,7 +80,7 @@ export class TriggerListPage extends TablePage<Trigger> {
|
|||
`;
|
||||
}
|
||||
|
||||
renderExpanded(item: Trigger): TemplateResult {
|
||||
renderExpanded(item: Rule): TemplateResult {
|
||||
return html`
|
||||
<td role="cell" colspan="4">
|
||||
<div class="pf-c-table__expandable-row-content">
|
|
@ -9,7 +9,7 @@ import "./pages/sources/SourceViewPage";
|
|||
import "./pages/flows/FlowViewPage";
|
||||
import "./pages/events/EventListPage";
|
||||
import "./pages/events/TransportListPage";
|
||||
import "./pages/events/TriggerListPage";
|
||||
import "./pages/events/RuleListPage";
|
||||
|
||||
export const ROUTES: Route[] = [
|
||||
// Prevent infinite Shell loops
|
||||
|
@ -29,5 +29,5 @@ export const ROUTES: Route[] = [
|
|||
}),
|
||||
new Route(new RegExp("^/events/log$"), html`<ak-event-list></ak-event-list>`),
|
||||
new Route(new RegExp("^/events/transports$"), html`<ak-event-transport-list></ak-event-transport-list>`),
|
||||
new Route(new RegExp("^/events/triggers$"), html`<ak-event-trigger-list></ak-event-trigger-list>`),
|
||||
new Route(new RegExp("^/events/rules$"), html`<ak-event-rule-list></ak-event-rule-list>`),
|
||||
];
|
||||
|
|
|
@ -3,18 +3,18 @@ title: Notifications
|
|||
---
|
||||
|
||||
:::note
|
||||
To prevent infinite loops (events created by policies which are attached to a Notification rule), **any events created by a policy which is attached to any Notification Trigger do not trigger notifications.**
|
||||
To prevent infinite loops (events created by policies which are attached to a Notification rule), **any events created by a policy which is attached to any Notification Rules do not trigger notifications.**
|
||||
:::
|
||||
|
||||
## Filtering Events
|
||||
|
||||
Starting with authentik 0.15, you can create notification triggers, which can alert you based on the creation of certain events.
|
||||
Starting with authentik 0.15, you can create notification rules, which can alert you based on the creation of certain events.
|
||||
|
||||
Filtering is done by using the Policy Engine. You can do simple filtering using the "Event Matcher Policy" type.
|
||||
|
||||
![](./event_matcher.png)
|
||||
|
||||
An event has to match all configured fields, otherwise the trigger will not activate.
|
||||
An event has to match all configured fields, otherwise the rule will not trigger.
|
||||
|
||||
To match events with an "Expression Policy", you can write code like so:
|
||||
|
||||
|
@ -27,9 +27,9 @@ return ip_address(request.context["evnet"].client_ip) in ip_network('192.0.2.0/2
|
|||
|
||||
## Selecting who gets notified
|
||||
|
||||
After you've created the policies to match the events you want, create a "Notification Trigger".
|
||||
After you've created the policies to match the events you want, create a "Notification Rule".
|
||||
|
||||
You have to select which group the generated notification should be sent to. If left empty, the trigger will be disabled.
|
||||
You have to select which group the generated notification should be sent to. If left empty, the rule will be disabled.
|
||||
|
||||
You also have to select which transports should be used to send the notification.
|
||||
A transport with the name "default-email-transport" is created by default. This transport will use the [global email configuration](../installation/docker-compose#email-configuration-optional-but-recommended).
|
||||
|
|
Reference in New Issue