|
28 | 28 | SESSION_KEY_IMPERSONATE_USER, |
29 | 29 | ) |
30 | 30 | from authentik.core.models import ExpiringModel, Group, PropertyMapping, User |
| 31 | +from authentik.crypto.models import CertificateKeyPair |
31 | 32 | from authentik.events.context_processors.base import get_context_processors |
32 | 33 | from authentik.events.utils import ( |
33 | 34 | cleanse_dict, |
|
41 | 42 | from authentik.lib.utils.errors import exception_to_dict |
42 | 43 | from authentik.lib.utils.http import get_http_session |
43 | 44 | from authentik.lib.utils.time import timedelta_from_string |
| 45 | +from authentik.outposts.docker_tls import DockerInlineTLS |
44 | 46 | from authentik.policies.models import PolicyBindingModel |
45 | 47 | from authentik.root.middleware import ClientIPMiddleware |
46 | 48 | from authentik.root.ws.consumer import build_user_group |
@@ -326,6 +328,16 @@ class NotificationTransport(TasksModel, SerializerModel): |
326 | 328 | email_template = models.TextField(default=EmailTemplates.EVENT_NOTIFICATION) |
327 | 329 |
|
328 | 330 | webhook_url = models.TextField(blank=True, validators=[DomainlessURLValidator()]) |
| 331 | + webhook_ca = models.ForeignKey( |
| 332 | + CertificateKeyPair, |
| 333 | + null=True, |
| 334 | + default=None, |
| 335 | + on_delete=models.SET_DEFAULT, |
| 336 | + help_text=_( |
| 337 | + "When set, the selected ceritifcate is used to " |
| 338 | + "validate the certificate of the webhook server." |
| 339 | + ), |
| 340 | + ) |
329 | 341 | webhook_mapping_body = models.ForeignKey( |
330 | 342 | "NotificationWebhookMapping", |
331 | 343 | on_delete=models.SET_DEFAULT, |
@@ -409,21 +421,29 @@ def send_webhook(self, notification: Notification) -> list[str]: |
409 | 421 | notification=notification, |
410 | 422 | ) |
411 | 423 | ) |
412 | | - try: |
413 | | - response = get_http_session().post( |
414 | | - self.webhook_url, |
415 | | - json=default_body, |
416 | | - headers=headers, |
417 | | - ) |
418 | | - response.raise_for_status() |
419 | | - except RequestException as exc: |
420 | | - raise NotificationTransportError( |
421 | | - exc.response.text if exc.response else str(exc) |
422 | | - ) from exc |
423 | | - return [ |
424 | | - response.status_code, |
425 | | - response.text, |
426 | | - ] |
| 424 | + |
| 425 | + def send(**kwargs): |
| 426 | + try: |
| 427 | + response = get_http_session().post( |
| 428 | + self.webhook_url, |
| 429 | + json=default_body, |
| 430 | + headers=headers, |
| 431 | + **kwargs, |
| 432 | + ) |
| 433 | + response.raise_for_status() |
| 434 | + except RequestException as exc: |
| 435 | + raise NotificationTransportError( |
| 436 | + exc.response.text if exc.response else str(exc) |
| 437 | + ) from exc |
| 438 | + return [ |
| 439 | + response.status_code, |
| 440 | + response.text, |
| 441 | + ] |
| 442 | + |
| 443 | + if self.webhook_ca: |
| 444 | + with DockerInlineTLS(self.webhook_ca) as tls: |
| 445 | + return send(verify=tls.verify) |
| 446 | + return send() |
427 | 447 |
|
428 | 448 | def send_webhook_slack(self, notification: Notification) -> list[str]: |
429 | 449 | """Send notification to slack or slack-compatible endpoints""" |
|
0 commit comments