From 192dbe05c469bcf270845b8c90e91612a0502eda Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 15 Jan 2021 16:23:27 +0100 Subject: [PATCH] events: triggers -> rules --- authentik/admin/urls.py | 22 +- ...ggers.py => events_notifications_rules.py} | 36 +- authentik/api/v2/urls.py | 4 +- authentik/events/api/notification_rule.py | 28 ++ authentik/events/api/notification_trigger.py | 28 -- authentik/events/forms.py | 8 +- ...notificationtransport_notificationrule.py} | 6 +- ... => 0011_notification_rules_default_v1.py} | 14 +- authentik/events/models.py | 10 +- authentik/events/tasks.py | 12 +- authentik/events/tests/test_notifications.py | 12 +- swagger.yaml | 320 +++++++++--------- web/src/api/EventRules.ts | 26 ++ web/src/api/EventTriggers.ts | 26 -- .../notifications/NotificationTrigger.ts | 2 +- web/src/interfaces/AdminInterface.ts | 2 +- .../{TriggerListPage.ts => RuleListPage.ts} | 26 +- web/src/routes.ts | 4 +- website/docs/events/notifications.md | 10 +- 19 files changed, 298 insertions(+), 298 deletions(-) rename authentik/admin/views/{events_notifications_triggers.py => events_notifications_rules.py} (57%) create mode 100644 authentik/events/api/notification_rule.py delete mode 100644 authentik/events/api/notification_trigger.py rename authentik/events/migrations/{0010_notification_notificationtransport_notificationtrigger.py => 0010_notification_notificationtransport_notificationrule.py} (97%) rename authentik/events/migrations/{0011_notification_trigger_default_v1.py => 0011_notification_rules_default_v1.py} (91%) create mode 100644 web/src/api/EventRules.ts delete mode 100644 web/src/api/EventTriggers.ts rename web/src/pages/events/{TriggerListPage.ts => RuleListPage.ts} (74%) diff --git a/authentik/admin/urls.py b/authentik/admin/urls.py index 04bf1c8de..680f30f5c 100644 --- a/authentik/admin/urls.py +++ b/authentik/admin/urls.py @@ -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//update/", - events_notifications_triggers.NotificationTriggerUpdateView.as_view(), - name="notification-trigger-update", + "events/rules//update/", + events_notifications_rules.NotificationRuleUpdateView.as_view(), + name="notification-rule-update", ), path( - "events/triggers//delete/", - events_notifications_triggers.NotificationTriggerDeleteView.as_view(), - name="notification-trigger-delete", + "events/rules//delete/", + events_notifications_rules.NotificationRuleDeleteView.as_view(), + name="notification-rule-delete", ), ] diff --git a/authentik/admin/views/events_notifications_triggers.py b/authentik/admin/views/events_notifications_rules.py similarity index 57% rename from authentik/admin/views/events_notifications_triggers.py rename to authentik/admin/views/events_notifications_rules.py index 9fc7981c0..cf7b70a73 100644 --- a/authentik/admin/views/events_notifications_triggers.py +++ b/authentik/admin/views/events_notifications_rules.py @@ -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") diff --git a/authentik/api/v2/urls.py b/authentik/api/v2/urls.py index 0078b2b99..34eb63470 100644 --- a/authentik/api/v2/urls.py +++ b/authentik/api/v2/urls.py @@ -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) diff --git a/authentik/events/api/notification_rule.py b/authentik/events/api/notification_rule.py new file mode 100644 index 000000000..996216e2a --- /dev/null +++ b/authentik/events/api/notification_rule.py @@ -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 diff --git a/authentik/events/api/notification_trigger.py b/authentik/events/api/notification_trigger.py deleted file mode 100644 index d8f666d02..000000000 --- a/authentik/events/api/notification_trigger.py +++ /dev/null @@ -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 diff --git a/authentik/events/forms.py b/authentik/events/forms.py index 3343b99d2..7243e01c9 100644 --- a/authentik/events/forms.py +++ b/authentik/events/forms.py @@ -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", diff --git a/authentik/events/migrations/0010_notification_notificationtransport_notificationtrigger.py b/authentik/events/migrations/0010_notification_notificationtransport_notificationrule.py similarity index 97% rename from authentik/events/migrations/0010_notification_notificationtransport_notificationtrigger.py rename to authentik/events/migrations/0010_notification_notificationtransport_notificationrule.py index 395159039..d46d04063 100644 --- a/authentik/events/migrations/0010_notification_notificationtransport_notificationtrigger.py +++ b/authentik/events/migrations/0010_notification_notificationtransport_notificationrule.py @@ -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",), ), diff --git a/authentik/events/migrations/0011_notification_trigger_default_v1.py b/authentik/events/migrations/0011_notification_rules_default_v1.py similarity index 91% rename from authentik/events/migrations/0011_notification_trigger_default_v1.py rename to authentik/events/migrations/0011_notification_rules_default_v1.py index 1653cb5ba..70289bbf8 100644 --- a/authentik/events/migrations/0011_notification_trigger_default_v1.py +++ b/authentik/events/migrations/0011_notification_rules_default_v1.py @@ -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"), diff --git a/authentik/events/models.py b/authentik/events/models.py index 17a621634..8fcfe3b3a 100644 --- a/authentik/events/models.py +++ b/authentik/events/models.py @@ -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") diff --git a/authentik/events/tasks.py b/authentik/events/tasks.py index 0f66eb2bb..ad13c610b 100644 --- a/authentik/events/tasks.py +++ b/authentik/events/tasks.py @@ -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 diff --git a/authentik/events/tests/test_notifications.py b/authentik/events/tests/test_notifications.py index 7b648aa57..eccf3e182 100644 --- a/authentik/events/tests/test_notifications.py +++ b/authentik/events/tests/test_notifications.py @@ -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( diff --git a/swagger.yaml b/swagger.yaml index 044141ba4..6cb69babd 100755 --- a/swagger.yaml +++ b/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 diff --git a/web/src/api/EventRules.ts b/web/src/api/EventRules.ts new file mode 100644 index 000000000..221ea34f5 --- /dev/null +++ b/web/src/api/EventRules.ts @@ -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 { + return DefaultClient.fetch(["events", "rules", pk]); + } + + static list(filter?: QueryArguments): Promise> { + return DefaultClient.fetch>(["events", "rules"], filter); + } + + static adminUrl(rest: string): string { + return `/administration/events/rules/${rest}`; + } +} diff --git a/web/src/api/EventTriggers.ts b/web/src/api/EventTriggers.ts deleted file mode 100644 index a80f74fad..000000000 --- a/web/src/api/EventTriggers.ts +++ /dev/null @@ -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 { - return DefaultClient.fetch(["events", "triggers", pk]); - } - - static list(filter?: QueryArguments): Promise> { - return DefaultClient.fetch>(["events", "triggers"], filter); - } - - static adminUrl(rest: string): string { - return `/administration/events/triggers/${rest}`; - } -} diff --git a/web/src/elements/notifications/NotificationTrigger.ts b/web/src/elements/notifications/NotificationTrigger.ts index 1acb54fca..db7f581e0 100644 --- a/web/src/elements/notifications/NotificationTrigger.ts +++ b/web/src/elements/notifications/NotificationTrigger.ts @@ -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(); diff --git a/web/src/interfaces/AdminInterface.ts b/web/src/interfaces/AdminInterface.ts index 9c98b9f25..d709b7773 100644 --- a/web/src/interfaces/AdminInterface.ts +++ b/web/src/interfaces/AdminInterface.ts @@ -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 => { return User.me().then(u => u.is_superuser); diff --git a/web/src/pages/events/TriggerListPage.ts b/web/src/pages/events/RuleListPage.ts similarity index 74% rename from web/src/pages/events/TriggerListPage.ts rename to web/src/pages/events/RuleListPage.ts index 1bad8b87e..75850bce2 100644 --- a/web/src/pages/events/TriggerListPage.ts +++ b/web/src/pages/events/RuleListPage.ts @@ -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 { +@customElement("ak-event-rule-list") +export class RuleListPage extends TablePage { 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 { @property() order = "name"; - apiEndpoint(page: number): Promise> { - return Trigger.list({ + apiEndpoint(page: number): Promise> { + return Rule.list({ ordering: this.order, page: page, search: this.search || "", @@ -46,19 +46,19 @@ export class TriggerListPage extends TablePage { ]; } - 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` - + ${gettext("Edit")}
  - + ${gettext("Delete")} @@ -70,7 +70,7 @@ export class TriggerListPage extends TablePage { renderToolbar(): TemplateResult { return html` - + ${gettext("Create")} @@ -80,7 +80,7 @@ export class TriggerListPage extends TablePage { `; } - renderExpanded(item: Trigger): TemplateResult { + renderExpanded(item: Rule): TemplateResult { return html`
diff --git a/web/src/routes.ts b/web/src/routes.ts index 70549305b..7d3764a14 100644 --- a/web/src/routes.ts +++ b/web/src/routes.ts @@ -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``), new Route(new RegExp("^/events/transports$"), html``), - new Route(new RegExp("^/events/triggers$"), html``), + new Route(new RegExp("^/events/rules$"), html``), ]; diff --git a/website/docs/events/notifications.md b/website/docs/events/notifications.md index be370143a..b885a8165 100644 --- a/website/docs/events/notifications.md +++ b/website/docs/events/notifications.md @@ -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).