events: allow setting a mapping for webhook transport to customise request payloads
closes #1383 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
c779ad2e3b
commit
9a7fa39de4
|
@ -24,6 +24,7 @@ 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_mapping import NotificationWebhookMappingViewSet
|
||||
from authentik.events.api.notification_rule import NotificationRuleViewSet
|
||||
from authentik.events.api.notification_transport import NotificationTransportViewSet
|
||||
from authentik.flows.api.bindings import FlowStageBindingViewSet
|
||||
|
@ -159,6 +160,7 @@ router.register("propertymappings/all", PropertyMappingViewSet)
|
|||
router.register("propertymappings/ldap", LDAPPropertyMappingViewSet)
|
||||
router.register("propertymappings/saml", SAMLPropertyMappingViewSet)
|
||||
router.register("propertymappings/scope", ScopeMappingViewSet)
|
||||
router.register("propertymappings/notification", NotificationWebhookMappingViewSet)
|
||||
|
||||
router.register("authenticators/duo", DuoDeviceViewSet)
|
||||
router.register("authenticators/static", StaticDeviceViewSet)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
"""NotificationWebhookMapping API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.events.models import NotificationWebhookMapping
|
||||
|
||||
|
||||
class NotificationWebhookMappingSerializer(ModelSerializer):
|
||||
"""NotificationWebhookMapping Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = NotificationWebhookMapping
|
||||
fields = [
|
||||
"pk",
|
||||
"name",
|
||||
"expression",
|
||||
]
|
||||
|
||||
|
||||
class NotificationWebhookMappingViewSet(UsedByMixin, ModelViewSet):
|
||||
"""NotificationWebhookMapping Viewset"""
|
||||
|
||||
queryset = NotificationWebhookMapping.objects.all()
|
||||
serializer_class = NotificationWebhookMappingSerializer
|
||||
filterset_fields = ["name"]
|
||||
ordering = ["name"]
|
|
@ -38,6 +38,7 @@ class NotificationTransportSerializer(ModelSerializer):
|
|||
"mode",
|
||||
"mode_verbose",
|
||||
"webhook_url",
|
||||
"webhook_mapping",
|
||||
"send_once",
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# Generated by Django 3.2.6 on 2021-09-11 22:17
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_core", "0028_alter_token_intent"),
|
||||
("authentik_events", "0017_alter_event_action"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="NotificationWebhookMapping",
|
||||
fields=[
|
||||
(
|
||||
"propertymapping_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="authentik_core.propertymapping",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Notification Webhook Mapping",
|
||||
"verbose_name_plural": "Notification Webhook Mappings",
|
||||
},
|
||||
bases=("authentik_core.propertymapping",),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="notificationtransport",
|
||||
name="webhook_mapping",
|
||||
field=models.ForeignKey(
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_DEFAULT,
|
||||
to="authentik_events.notificationwebhookmapping",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -2,7 +2,7 @@
|
|||
from datetime import timedelta
|
||||
from inspect import getmodule, stack
|
||||
from smtplib import SMTPException
|
||||
from typing import Optional, Union
|
||||
from typing import TYPE_CHECKING, Optional, Type, Union
|
||||
from uuid import uuid4
|
||||
|
||||
from django.conf import settings
|
||||
|
@ -15,7 +15,7 @@ from structlog.stdlib import get_logger
|
|||
|
||||
from authentik import __version__
|
||||
from authentik.core.middleware import SESSION_IMPERSONATE_ORIGINAL_USER, SESSION_IMPERSONATE_USER
|
||||
from authentik.core.models import ExpiringModel, Group, User
|
||||
from authentik.core.models import ExpiringModel, Group, PropertyMapping, User
|
||||
from authentik.events.geo import GEOIP_READER
|
||||
from authentik.events.utils import cleanse_dict, get_user, model_to_dict, sanitize_dict
|
||||
from authentik.lib.sentry import SentryIgnoredException
|
||||
|
@ -27,6 +27,8 @@ from authentik.tenants.models import Tenant
|
|||
from authentik.tenants.utils import DEFAULT_TENANT
|
||||
|
||||
LOGGER = get_logger("authentik.events")
|
||||
if TYPE_CHECKING:
|
||||
from rest_framework.serializers import Serializer
|
||||
|
||||
|
||||
def default_event_duration():
|
||||
|
@ -220,6 +222,9 @@ class NotificationTransport(models.Model):
|
|||
mode = models.TextField(choices=TransportMode.choices)
|
||||
|
||||
webhook_url = models.TextField(blank=True)
|
||||
webhook_mapping = models.ForeignKey(
|
||||
"NotificationWebhookMapping", on_delete=models.SET_DEFAULT, null=True, default=None
|
||||
)
|
||||
send_once = models.BooleanField(
|
||||
default=False,
|
||||
help_text=_(
|
||||
|
@ -239,15 +244,22 @@ class NotificationTransport(models.Model):
|
|||
|
||||
def send_webhook(self, notification: "Notification") -> list[str]:
|
||||
"""Send notification to generic webhook"""
|
||||
default_body = {
|
||||
"body": notification.body,
|
||||
"severity": notification.severity,
|
||||
"user_email": notification.user.email,
|
||||
"user_username": notification.user.username,
|
||||
}
|
||||
if self.webhook_mapping:
|
||||
default_body = self.webhook_mapping.evaluate(
|
||||
user=notification.user,
|
||||
request=None,
|
||||
notification=notification,
|
||||
)
|
||||
try:
|
||||
response = get_http_session().post(
|
||||
self.webhook_url,
|
||||
json={
|
||||
"body": notification.body,
|
||||
"severity": notification.severity,
|
||||
"user_email": notification.user.email,
|
||||
"user_username": notification.user.username,
|
||||
},
|
||||
json=default_body,
|
||||
)
|
||||
response.raise_for_status()
|
||||
except RequestException as exc:
|
||||
|
@ -414,3 +426,25 @@ class NotificationRule(PolicyBindingModel):
|
|||
|
||||
verbose_name = _("Notification Rule")
|
||||
verbose_name_plural = _("Notification Rules")
|
||||
|
||||
|
||||
class NotificationWebhookMapping(PropertyMapping):
|
||||
"""Modify the schema and layout of the webhook being sent"""
|
||||
|
||||
@property
|
||||
def component(self) -> str:
|
||||
return "ak-property-mapping-notification-form"
|
||||
|
||||
@property
|
||||
def serializer(self) -> Type["Serializer"]:
|
||||
from authentik.events.api.notification_mapping import NotificationWebhookMappingSerializer
|
||||
|
||||
return NotificationWebhookMappingSerializer
|
||||
|
||||
def __str__(self):
|
||||
return f"Notification Webhook Mapping {self.name}"
|
||||
|
||||
class Meta:
|
||||
|
||||
verbose_name = _("Notification Webhook Mapping")
|
||||
verbose_name_plural = _("Notification Webhook Mappings")
|
||||
|
|
296
schema.yml
296
schema.yml
|
@ -9388,6 +9388,219 @@ paths:
|
|||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/propertymappings/notification/:
|
||||
get:
|
||||
operationId: propertymappings_notification_list
|
||||
description: NotificationWebhookMapping Viewset
|
||||
parameters:
|
||||
- in: query
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
- name: ordering
|
||||
required: false
|
||||
in: query
|
||||
description: Which field to use when ordering the results.
|
||||
schema:
|
||||
type: string
|
||||
- name: page
|
||||
required: false
|
||||
in: query
|
||||
description: A page number within the paginated result set.
|
||||
schema:
|
||||
type: integer
|
||||
- name: page_size
|
||||
required: false
|
||||
in: query
|
||||
description: Number of results to return per page.
|
||||
schema:
|
||||
type: integer
|
||||
- name: search
|
||||
required: false
|
||||
in: query
|
||||
description: A search term.
|
||||
schema:
|
||||
type: string
|
||||
tags:
|
||||
- propertymappings
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedNotificationWebhookMappingList'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
post:
|
||||
operationId: propertymappings_notification_create
|
||||
description: NotificationWebhookMapping Viewset
|
||||
tags:
|
||||
- propertymappings
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationWebhookMappingRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationWebhookMapping'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/propertymappings/notification/{pm_uuid}/:
|
||||
get:
|
||||
operationId: propertymappings_notification_retrieve
|
||||
description: NotificationWebhookMapping Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: pm_uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this Notification Webhook Mapping.
|
||||
required: true
|
||||
tags:
|
||||
- propertymappings
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationWebhookMapping'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
put:
|
||||
operationId: propertymappings_notification_update
|
||||
description: NotificationWebhookMapping Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: pm_uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this Notification Webhook Mapping.
|
||||
required: true
|
||||
tags:
|
||||
- propertymappings
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationWebhookMappingRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationWebhookMapping'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
patch:
|
||||
operationId: propertymappings_notification_partial_update
|
||||
description: NotificationWebhookMapping Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: pm_uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this Notification Webhook Mapping.
|
||||
required: true
|
||||
tags:
|
||||
- propertymappings
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedNotificationWebhookMappingRequest'
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationWebhookMapping'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
delete:
|
||||
operationId: propertymappings_notification_destroy
|
||||
description: NotificationWebhookMapping Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: pm_uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this Notification Webhook Mapping.
|
||||
required: true
|
||||
tags:
|
||||
- propertymappings
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'204':
|
||||
description: No response body
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/propertymappings/notification/{pm_uuid}/used_by/:
|
||||
get:
|
||||
operationId: propertymappings_notification_used_by_list
|
||||
description: Get a list of all objects that use this object
|
||||
parameters:
|
||||
- in: path
|
||||
name: pm_uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this Notification Webhook Mapping.
|
||||
required: true
|
||||
tags:
|
||||
- propertymappings
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/UsedBy'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/propertymappings/saml/:
|
||||
get:
|
||||
operationId: propertymappings_saml_list
|
||||
|
@ -21368,6 +21581,10 @@ components:
|
|||
readOnly: true
|
||||
webhook_url:
|
||||
type: string
|
||||
webhook_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
send_once:
|
||||
type: boolean
|
||||
description: Only send notification once, for example when sending a webhook
|
||||
|
@ -21393,6 +21610,10 @@ components:
|
|||
$ref: '#/components/schemas/NotificationTransportModeEnum'
|
||||
webhook_url:
|
||||
type: string
|
||||
webhook_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
send_once:
|
||||
type: boolean
|
||||
description: Only send notification once, for example when sending a webhook
|
||||
|
@ -21410,6 +21631,34 @@ components:
|
|||
type: string
|
||||
required:
|
||||
- messages
|
||||
NotificationWebhookMapping:
|
||||
type: object
|
||||
description: NotificationWebhookMapping Serializer
|
||||
properties:
|
||||
pk:
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
title: Pm uuid
|
||||
name:
|
||||
type: string
|
||||
expression:
|
||||
type: string
|
||||
required:
|
||||
- expression
|
||||
- name
|
||||
- pk
|
||||
NotificationWebhookMappingRequest:
|
||||
type: object
|
||||
description: NotificationWebhookMapping Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
expression:
|
||||
type: string
|
||||
required:
|
||||
- expression
|
||||
- name
|
||||
OAuth2Provider:
|
||||
type: object
|
||||
description: OAuth2Provider Serializer
|
||||
|
@ -23183,6 +23432,41 @@ components:
|
|||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedNotificationWebhookMappingList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
type: object
|
||||
properties:
|
||||
next:
|
||||
type: number
|
||||
previous:
|
||||
type: number
|
||||
count:
|
||||
type: number
|
||||
current:
|
||||
type: number
|
||||
total_pages:
|
||||
type: number
|
||||
start_index:
|
||||
type: number
|
||||
end_index:
|
||||
type: number
|
||||
required:
|
||||
- next
|
||||
- previous
|
||||
- count
|
||||
- current
|
||||
- total_pages
|
||||
- start_index
|
||||
- end_index
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/NotificationWebhookMapping'
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedOAuth2ProviderList:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -25525,10 +25809,22 @@ components:
|
|||
$ref: '#/components/schemas/NotificationTransportModeEnum'
|
||||
webhook_url:
|
||||
type: string
|
||||
webhook_mapping:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
send_once:
|
||||
type: boolean
|
||||
description: Only send notification once, for example when sending a webhook
|
||||
into a chat channel.
|
||||
PatchedNotificationWebhookMappingRequest:
|
||||
type: object
|
||||
description: NotificationWebhookMapping Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
expression:
|
||||
type: string
|
||||
PatchedOAuth2ProviderRequest:
|
||||
type: object
|
||||
description: OAuth2Provider Serializer
|
||||
|
|
|
@ -15,9 +15,9 @@ import AKGlobal from "../../authentik.css";
|
|||
|
||||
import { configureSentry } from "../../api/Sentry";
|
||||
import { CurrentTenant } from "@goauthentik/api";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { EVENT_SIDEBAR_TOGGLE } from "../../constants";
|
||||
import { tenant } from "../../api/Config";
|
||||
import { first } from "../../utils";
|
||||
|
||||
// If the viewport is wider than MIN_WIDTH, the sidebar
|
||||
// is shown besides the content, and not overlayed.
|
||||
|
@ -99,7 +99,7 @@ export class SidebarBrand extends LitElement {
|
|||
<a href="#/" class="pf-c-page__header-brand-link">
|
||||
<div class="pf-c-brand ak-brand">
|
||||
<img
|
||||
src="${ifDefined(this.tenant.brandingLogo)}"
|
||||
src="${first(this.tenant.brandingLogo, DefaultTenant.brandingLogo)}"
|
||||
alt="authentik icon"
|
||||
loading="lazy"
|
||||
/>
|
||||
|
|
|
@ -45,11 +45,12 @@ import {
|
|||
ShellChallenge,
|
||||
} from "@goauthentik/api";
|
||||
import { DEFAULT_CONFIG, tenant } from "../api/Config";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { TITLE_DEFAULT } from "../constants";
|
||||
import { configureSentry } from "../api/Sentry";
|
||||
import { WebsocketClient } from "../common/ws";
|
||||
import { first } from "../utils";
|
||||
import { DefaultTenant } from "../elements/sidebar/SidebarBrand";
|
||||
|
||||
@customElement("ak-flow-executor")
|
||||
export class FlowExecutor extends LitElement implements StageHost {
|
||||
|
@ -342,7 +343,10 @@ export class FlowExecutor extends LitElement implements StageHost {
|
|||
<header class="pf-c-login__header">
|
||||
<div class="pf-c-brand ak-brand">
|
||||
<img
|
||||
src="${ifDefined(this.tenant?.brandingLogo)}"
|
||||
src="${first(
|
||||
this.tenant?.brandingLogo,
|
||||
DefaultTenant.brandingLogo,
|
||||
)}"
|
||||
alt="authentik icon"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1646,6 +1646,7 @@ msgstr "Export flow"
|
|||
#: src/pages/events/EventInfo.ts
|
||||
#: src/pages/policies/expression/ExpressionPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Expression"
|
||||
|
@ -1653,6 +1654,7 @@ msgstr "Expression"
|
|||
|
||||
#: src/pages/policies/expression/ExpressionPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Expression using Python."
|
||||
|
@ -2316,6 +2318,7 @@ msgstr "Loading"
|
|||
#: src/pages/applications/ApplicationForm.ts
|
||||
#: src/pages/events/RuleForm.ts
|
||||
#: src/pages/events/RuleForm.ts
|
||||
#: src/pages/events/TransportForm.ts
|
||||
#: src/pages/flows/StageBindingForm.ts
|
||||
#: src/pages/flows/StageBindingForm.ts
|
||||
#: src/pages/groups/GroupForm.ts
|
||||
|
@ -2564,6 +2567,7 @@ msgstr "My Applications"
|
|||
#: src/pages/policies/reputation/ReputationPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingListPage.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
#: src/pages/providers/ProviderListPage.ts
|
||||
|
@ -3530,6 +3534,7 @@ msgstr "Secret:"
|
|||
|
||||
#: src/pages/policies/expression/ExpressionPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "See documentation for a list of all variables."
|
||||
|
@ -3968,6 +3973,7 @@ msgid "Successfully created invitation."
|
|||
msgstr "Successfully created invitation."
|
||||
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Successfully created mapping."
|
||||
|
@ -4124,6 +4130,7 @@ msgid "Successfully updated invitation."
|
|||
msgstr "Successfully updated invitation."
|
||||
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Successfully updated mapping."
|
||||
|
@ -5071,6 +5078,10 @@ msgstr "Webhook (Slack/Discord)"
|
|||
msgid "Webhook (generic)"
|
||||
msgstr "Webhook (generic)"
|
||||
|
||||
#: src/pages/events/TransportForm.ts
|
||||
msgid "Webhook Mapping"
|
||||
msgstr "Webhook Mapping"
|
||||
|
||||
#: src/pages/events/TransportForm.ts
|
||||
msgid "Webhook URL"
|
||||
msgstr "Webhook URL"
|
||||
|
|
|
@ -1638,6 +1638,7 @@ msgstr ""
|
|||
#: src/pages/events/EventInfo.ts
|
||||
#: src/pages/policies/expression/ExpressionPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Expression"
|
||||
|
@ -1645,6 +1646,7 @@ msgstr ""
|
|||
|
||||
#: src/pages/policies/expression/ExpressionPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Expression using Python."
|
||||
|
@ -2308,6 +2310,7 @@ msgstr ""
|
|||
#: src/pages/applications/ApplicationForm.ts
|
||||
#: src/pages/events/RuleForm.ts
|
||||
#: src/pages/events/RuleForm.ts
|
||||
#: src/pages/events/TransportForm.ts
|
||||
#: src/pages/flows/StageBindingForm.ts
|
||||
#: src/pages/flows/StageBindingForm.ts
|
||||
#: src/pages/groups/GroupForm.ts
|
||||
|
@ -2556,6 +2559,7 @@ msgstr ""
|
|||
#: src/pages/policies/reputation/ReputationPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingListPage.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
#: src/pages/providers/ProviderListPage.ts
|
||||
|
@ -3522,6 +3526,7 @@ msgstr ""
|
|||
|
||||
#: src/pages/policies/expression/ExpressionPolicyForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "See documentation for a list of all variables."
|
||||
|
@ -3960,6 +3965,7 @@ msgid "Successfully created invitation."
|
|||
msgstr ""
|
||||
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Successfully created mapping."
|
||||
|
@ -4116,6 +4122,7 @@ msgid "Successfully updated invitation."
|
|||
msgstr ""
|
||||
|
||||
#: src/pages/property-mappings/PropertyMappingLDAPForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingNotification.ts
|
||||
#: src/pages/property-mappings/PropertyMappingSAMLForm.ts
|
||||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
msgid "Successfully updated mapping."
|
||||
|
@ -5056,6 +5063,10 @@ msgstr ""
|
|||
msgid "Webhook (generic)"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/events/TransportForm.ts
|
||||
msgid "Webhook Mapping"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/events/TransportForm.ts
|
||||
msgid "Webhook URL"
|
||||
msgstr ""
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { EventsApi, NotificationTransport, NotificationTransportModeEnum } from "@goauthentik/api";
|
||||
import {
|
||||
EventsApi,
|
||||
NotificationTransport,
|
||||
NotificationTransportModeEnum,
|
||||
PropertymappingsApi,
|
||||
} from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { customElement, property } from "lit-element";
|
||||
import { html, TemplateResult } from "lit-html";
|
||||
|
@ -7,6 +12,7 @@ import { ifDefined } from "lit-html/directives/if-defined";
|
|||
import "../../elements/forms/HorizontalFormElement";
|
||||
import { first } from "../../utils";
|
||||
import { ModelForm } from "../../elements/forms/ModelForm";
|
||||
import { until } from "lit-html/directives/until";
|
||||
|
||||
@customElement("ak-event-transport-form")
|
||||
export class TransportForm extends ModelForm<NotificationTransport, string> {
|
||||
|
@ -112,6 +118,32 @@ export class TransportForm extends ModelForm<NotificationTransport, string> {
|
|||
class="pf-c-form-control"
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
?hidden=${!this.showWebhook}
|
||||
label=${t`Webhook Mapping`}
|
||||
name="webhookMapping"
|
||||
>
|
||||
<select class="pf-c-form-control">
|
||||
<option value="" ?selected=${this.instance?.webhookMapping === undefined}>
|
||||
---------
|
||||
</option>
|
||||
${until(
|
||||
new PropertymappingsApi(DEFAULT_CONFIG)
|
||||
.propertymappingsNotificationList({})
|
||||
.then((mappings) => {
|
||||
return mappings.results.map((mapping) => {
|
||||
return html`<option
|
||||
value=${ifDefined(mapping.pk)}
|
||||
?selected=${this.instance?.webhookMapping === mapping.pk}
|
||||
>
|
||||
${mapping.name}
|
||||
</option>`;
|
||||
});
|
||||
}),
|
||||
html`<option>${t`Loading...`}</option>`,
|
||||
)}
|
||||
</select>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="sendOnce">
|
||||
<div class="pf-c-check">
|
||||
<input
|
||||
|
|
|
@ -12,6 +12,7 @@ import "./PropertyMappingTestForm";
|
|||
import "./PropertyMappingScopeForm";
|
||||
import "./PropertyMappingLDAPForm";
|
||||
import "./PropertyMappingSAMLForm";
|
||||
import "./PropertyMappingNotification";
|
||||
import { TableColumn } from "../../elements/table/Table";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { PAGE_SIZE } from "../../constants";
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
import { NotificationWebhookMapping, PropertymappingsApi } from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { customElement } from "lit-element";
|
||||
import { html, TemplateResult } from "lit-html";
|
||||
import { DEFAULT_CONFIG } from "../../api/Config";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import "../../elements/forms/HorizontalFormElement";
|
||||
import "../../elements/CodeMirror";
|
||||
import { ModelForm } from "../../elements/forms/ModelForm";
|
||||
|
||||
@customElement("ak-property-mapping-notification-form")
|
||||
export class PropertyMappingNotification extends ModelForm<NotificationWebhookMapping, string> {
|
||||
loadInstance(pk: string): Promise<NotificationWebhookMapping> {
|
||||
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsNotificationRetrieveRaw({
|
||||
pmUuid: pk,
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance) {
|
||||
return t`Successfully updated mapping.`;
|
||||
} else {
|
||||
return t`Successfully created mapping.`;
|
||||
}
|
||||
}
|
||||
|
||||
send = (data: NotificationWebhookMapping): Promise<NotificationWebhookMapping> => {
|
||||
if (this.instance) {
|
||||
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsNotificationUpdate({
|
||||
pmUuid: this.instance.pk || "",
|
||||
notificationWebhookMappingRequest: data,
|
||||
});
|
||||
} else {
|
||||
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsNotificationCreate({
|
||||
notificationWebhookMappingRequest: data,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${t`Expression`} ?required=${true} name="expression">
|
||||
<ak-codemirror mode="python" value="${ifDefined(this.instance?.expression)}">
|
||||
</ak-codemirror>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${t`Expression using Python.`}
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://goauthentik.io/docs/property-mappings/expression/"
|
||||
>
|
||||
${t`See documentation for a list of all variables.`}
|
||||
</a>
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</form>`;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,14 @@ This will send a POST request to the given URL with the following contents:
|
|||
|
||||
The `Content-Type` header is set to `text/json`.
|
||||
|
||||
Starting in 2021.10, you can also select a Notification mapping. This allows you to freely configure the request's payload. For example:
|
||||
|
||||
```python
|
||||
return {
|
||||
"foo": context['notification'].body,
|
||||
}
|
||||
```
|
||||
|
||||
## Slack Webhook
|
||||
|
||||
This sends a request using the Slack-specific format. This is also compatible with Discord's webhooks by appending `/slack` to the Discord webhook URL.
|
||||
|
|
Reference in New Issue