events: add additional validation for event transport
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
40a62ac1e5
commit
64b4e851ce
|
@ -1,7 +1,10 @@
|
||||||
"""NotificationTransport API Views"""
|
"""NotificationTransport API Views"""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.types import OpenApiTypes
|
||||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
from rest_framework.fields import CharField, ListField, SerializerMethodField
|
from rest_framework.fields import CharField, ListField, SerializerMethodField
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -29,6 +32,14 @@ class NotificationTransportSerializer(ModelSerializer):
|
||||||
"""Return selected mode with a UI Label"""
|
"""Return selected mode with a UI Label"""
|
||||||
return TransportMode(instance.mode).label
|
return TransportMode(instance.mode).label
|
||||||
|
|
||||||
|
def validate(self, attrs: dict[Any, str]) -> dict[Any, str]:
|
||||||
|
"""Ensure the required fields are set."""
|
||||||
|
mode = attrs.get("mode")
|
||||||
|
if mode in [TransportMode.WEBHOOK, TransportMode.WEBHOOK_SLACK]:
|
||||||
|
if "webhook_url" not in attrs or attrs.get("webhook_url", "") == "":
|
||||||
|
raise ValidationError("Webhook URL may not be empty.")
|
||||||
|
return attrs
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
model = NotificationTransport
|
model = NotificationTransport
|
||||||
|
|
|
@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Optional, Type, Union
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.validators import URLValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.http.request import QueryDict
|
from django.http.request import QueryDict
|
||||||
|
@ -223,7 +224,7 @@ class NotificationTransport(models.Model):
|
||||||
name = models.TextField(unique=True)
|
name = models.TextField(unique=True)
|
||||||
mode = models.TextField(choices=TransportMode.choices)
|
mode = models.TextField(choices=TransportMode.choices)
|
||||||
|
|
||||||
webhook_url = models.TextField(blank=True)
|
webhook_url = models.TextField(blank=True, validators=[URLValidator()])
|
||||||
webhook_mapping = models.ForeignKey(
|
webhook_mapping = models.ForeignKey(
|
||||||
"NotificationWebhookMapping", on_delete=models.SET_DEFAULT, null=True, default=None
|
"NotificationWebhookMapping", on_delete=models.SET_DEFAULT, null=True, default=None
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,13 @@ from django.urls import reverse
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.events.models import Event, EventAction, Notification, NotificationSeverity
|
from authentik.events.models import (
|
||||||
|
Event,
|
||||||
|
EventAction,
|
||||||
|
Notification,
|
||||||
|
NotificationSeverity,
|
||||||
|
TransportMode,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestEventsAPI(APITestCase):
|
class TestEventsAPI(APITestCase):
|
||||||
|
@ -41,3 +47,23 @@ class TestEventsAPI(APITestCase):
|
||||||
)
|
)
|
||||||
notification.refresh_from_db()
|
notification.refresh_from_db()
|
||||||
self.assertTrue(notification.seen)
|
self.assertTrue(notification.seen)
|
||||||
|
|
||||||
|
def test_transport(self):
|
||||||
|
"""Test transport API"""
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("authentik_api:notificationtransport-list"),
|
||||||
|
data={
|
||||||
|
"name": "foo-with",
|
||||||
|
"mode": TransportMode.WEBHOOK,
|
||||||
|
"webhook_url": "http://foo.com",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 201)
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("authentik_api:notificationtransport-list"),
|
||||||
|
data={
|
||||||
|
"name": "foo-without",
|
||||||
|
"mode": TransportMode.WEBHOOK,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
|
Reference in New Issue