tenants: forbid creation of multiple default tenants
closes #2059 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
41d5bff9d3
commit
9d6f79558f
|
@ -1,6 +1,9 @@
|
||||||
"""Serializer for tenant models"""
|
"""Serializer for tenant models"""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from drf_spectacular.utils import extend_schema
|
from drf_spectacular.utils import 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
|
from rest_framework.fields import CharField, ListField
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
|
@ -24,6 +27,15 @@ class FooterLinkSerializer(PassiveSerializer):
|
||||||
class TenantSerializer(ModelSerializer):
|
class TenantSerializer(ModelSerializer):
|
||||||
"""Tenant Serializer"""
|
"""Tenant Serializer"""
|
||||||
|
|
||||||
|
def validate(self, attrs: dict[str, Any]) -> dict[str, Any]:
|
||||||
|
if attrs.get("default", False):
|
||||||
|
tenants = Tenant.objects.filter(default=True)
|
||||||
|
if self.instance:
|
||||||
|
tenants = tenants.exclude(pk=self.instance.pk)
|
||||||
|
if tenants.exists():
|
||||||
|
raise ValidationError("Only a single Tenant can be set as default.")
|
||||||
|
return super().validate(attrs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
model = Tenant
|
model = Tenant
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
"""Test tenants"""
|
"""Test tenants"""
|
||||||
from django.test import TestCase
|
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.tests.utils import create_test_tenant
|
from authentik.core.tests.utils import create_test_admin_user, create_test_tenant
|
||||||
from authentik.events.models import Event, EventAction
|
from authentik.events.models import Event, EventAction
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
from authentik.lib.utils.time import timedelta_from_string
|
from authentik.lib.utils.time import timedelta_from_string
|
||||||
from authentik.tenants.models import Tenant
|
from authentik.tenants.models import Tenant
|
||||||
|
|
||||||
|
|
||||||
class TestTenants(TestCase):
|
class TestTenants(APITestCase):
|
||||||
"""Test tenants"""
|
"""Test tenants"""
|
||||||
|
|
||||||
def test_current_tenant(self):
|
def test_current_tenant(self):
|
||||||
|
@ -78,3 +78,18 @@ class TestTenants(TestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.expires.year, (event.created + timedelta_from_string("weeks=3")).year
|
event.expires.year, (event.created + timedelta_from_string("weeks=3")).year
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_create_default_multiple(self):
|
||||||
|
"""Test attempted creation of multiple default tenants"""
|
||||||
|
Tenant.objects.create(
|
||||||
|
domain="foo",
|
||||||
|
default=True,
|
||||||
|
branding_title="custom",
|
||||||
|
event_retention="weeks=3",
|
||||||
|
)
|
||||||
|
user = create_test_admin_user()
|
||||||
|
self.client.force_login(user)
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("authentik_api:tenant-list"), data={"domain": "bar", "default": True}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
|
Reference in New Issue