Compare commits

...

4 Commits

Author SHA1 Message Date
13c8cbf03a fix rac tests 2025-03-28 12:55:14 -03:00
1776981f29 Add schema.yml 2025-03-27 18:18:28 -03:00
5a4df95011 Fix tests, add more tests 2025-03-27 18:17:28 -03:00
f2927e5725 first approach 2025-03-27 18:03:25 -03:00
5 changed files with 205 additions and 40 deletions

View File

@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
from django_filters.filters import BooleanFilter
from django_filters.filterset import FilterSet
from rest_framework import mixins
from rest_framework.fields import ReadOnlyField, SerializerMethodField
from rest_framework.fields import SerializerMethodField
from rest_framework.viewsets import GenericViewSet
from authentik.core.api.object_types import TypesMixin
@ -18,10 +18,10 @@ from authentik.core.models import Provider
class ProviderSerializer(ModelSerializer, MetaNameSerializer):
"""Provider Serializer"""
assigned_application_slug = ReadOnlyField(source="application.slug")
assigned_application_name = ReadOnlyField(source="application.name")
assigned_backchannel_application_slug = ReadOnlyField(source="backchannel_application.slug")
assigned_backchannel_application_name = ReadOnlyField(source="backchannel_application.name")
assigned_application_slug = SerializerMethodField()
assigned_application_name = SerializerMethodField()
assigned_backchannel_application_slug = SerializerMethodField()
assigned_backchannel_application_name = SerializerMethodField()
component = SerializerMethodField()
@ -31,6 +31,38 @@ class ProviderSerializer(ModelSerializer, MetaNameSerializer):
return ""
return obj.component
def get_assigned_application_slug(self, obj: Provider) -> str:
"""Get application slug, return empty string if no application exists"""
try:
return obj.application.slug
except Provider.application.RelatedObjectDoesNotExist:
return ""
def get_assigned_application_name(self, obj: Provider) -> str:
"""Get application name, return empty string if no application exists"""
try:
return obj.application.name
except Provider.application.RelatedObjectDoesNotExist:
return ""
def get_assigned_backchannel_application_slug(self, obj: Provider) -> str:
"""Get backchannel application slug.
Returns an empty string if no backchannel application exists.
"""
if not obj.backchannel_application:
return ""
return obj.backchannel_application.slug or ""
def get_assigned_backchannel_application_name(self, obj: Provider) -> str:
"""Get backchannel application name.
Returns an empty string if no backchannel application exists.
"""
if not obj.backchannel_application:
return ""
return obj.backchannel_application.name or ""
class Meta:
model = Provider
fields = [

View File

@ -133,6 +133,8 @@ class TestApplicationsAPI(APITestCase):
"provider_obj": {
"assigned_application_name": "allowed",
"assigned_application_slug": "allowed",
"assigned_backchannel_application_name": "",
"assigned_backchannel_application_slug": "",
"authentication_flow": None,
"invalidation_flow": None,
"authorization_flow": str(self.provider.authorization_flow.pk),
@ -186,6 +188,8 @@ class TestApplicationsAPI(APITestCase):
"provider_obj": {
"assigned_application_name": "allowed",
"assigned_application_slug": "allowed",
"assigned_backchannel_application_name": "",
"assigned_backchannel_application_slug": "",
"authentication_flow": None,
"invalidation_flow": None,
"authorization_flow": str(self.provider.authorization_flow.pk),

View File

@ -3,7 +3,8 @@
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import PropertyMapping
from authentik.core.api.providers import ProviderSerializer
from authentik.core.models import Application, PropertyMapping, Provider
from authentik.core.tests.utils import create_test_admin_user
@ -24,3 +25,51 @@ class TestProvidersAPI(APITestCase):
reverse("authentik_api:provider-types"),
)
self.assertEqual(response.status_code, 200)
def test_provider_serializer_without_application(self):
"""Test that Provider serializer handles missing application gracefully"""
# Create a provider without an application
provider = Provider.objects.create(name="test-provider")
serializer = ProviderSerializer(instance=provider)
serialized_data = serializer.data
# Check that fields return empty strings when no application exists
self.assertEqual(serialized_data["assigned_application_slug"], "")
self.assertEqual(serialized_data["assigned_application_name"], "")
self.assertEqual(serialized_data["assigned_backchannel_application_slug"], "")
self.assertEqual(serialized_data["assigned_backchannel_application_name"], "")
def test_provider_serializer_with_application(self):
"""Test that Provider serializer correctly includes application data"""
# Create an application
app = Application.objects.create(name="Test App", slug="test-app")
# Create a provider with an application
provider = Provider.objects.create(name="test-provider-with-app")
app.provider = provider
app.save()
serializer = ProviderSerializer(instance=provider)
serialized_data = serializer.data
# Check that fields return correct values when application exists
self.assertEqual(serialized_data["assigned_application_slug"], "test-app")
self.assertEqual(serialized_data["assigned_application_name"], "Test App")
self.assertEqual(serialized_data["assigned_backchannel_application_slug"], "")
self.assertEqual(serialized_data["assigned_backchannel_application_name"], "")
def test_provider_api_response(self):
"""Test that the API response includes empty strings for missing applications"""
# Create a provider without an application
provider = Provider.objects.create(name="test-provider-api")
response = self.client.get(
reverse("authentik_api:provider-detail", kwargs={"pk": provider.pk}),
)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["assigned_application_slug"], "")
self.assertEqual(response.data["assigned_application_name"], "")
self.assertEqual(response.data["assigned_backchannel_application_slug"], "")
self.assertEqual(response.data["assigned_backchannel_application_name"], "")

View File

@ -74,6 +74,8 @@ class TestEndpointsAPI(APITestCase):
"component": "ak-provider-rac-form",
"assigned_application_slug": self.app.slug,
"assigned_application_name": self.app.name,
"assigned_backchannel_application_slug": "",
"assigned_backchannel_application_name": "",
"verbose_name": "RAC Provider",
"verbose_name_plural": "RAC Providers",
"meta_model_name": "authentik_providers_rac.racprovider",
@ -124,6 +126,8 @@ class TestEndpointsAPI(APITestCase):
"component": "ak-provider-rac-form",
"assigned_application_slug": self.app.slug,
"assigned_application_name": self.app.name,
"assigned_backchannel_application_slug": "",
"assigned_backchannel_application_name": "",
"connection_expiry": "hours=8",
"delete_token_on_disconnect": False,
"verbose_name": "RAC Provider",
@ -153,6 +157,8 @@ class TestEndpointsAPI(APITestCase):
"component": "ak-provider-rac-form",
"assigned_application_slug": self.app.slug,
"assigned_application_name": self.app.name,
"assigned_backchannel_application_slug": "",
"assigned_backchannel_application_name": "",
"connection_expiry": "hours=8",
"delete_token_on_disconnect": False,
"verbose_name": "RAC Provider",

View File

@ -44141,11 +44141,17 @@ components:
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -45675,19 +45681,27 @@ components:
readOnly: true
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
description: Get application slug, return empty string if no application
exists
readOnly: true
assigned_application_name:
type: string
description: Application's display Name.
description: Get application name, return empty string if no application
exists
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -46395,11 +46409,17 @@ components:
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -47022,19 +47042,27 @@ components:
readOnly: true
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
description: Get application slug, return empty string if no application
exists
readOnly: true
assigned_application_name:
type: string
description: Application's display Name.
description: Get application name, return empty string if no application
exists
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -53848,19 +53876,27 @@ components:
readOnly: true
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
description: Get application slug, return empty string if no application
exists
readOnly: true
assigned_application_name:
type: string
description: Application's display Name.
description: Get application name, return empty string if no application
exists
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -54089,19 +54125,27 @@ components:
readOnly: true
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
description: Get application slug, return empty string if no application
exists
readOnly: true
assigned_application_name:
type: string
description: Application's display Name.
description: Get application name, return empty string if no application
exists
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -54408,19 +54452,27 @@ components:
readOnly: true
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
description: Get application slug, return empty string if no application
exists
readOnly: true
assigned_application_name:
type: string
description: Application's display Name.
description: Get application name, return empty string if no application
exists
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -54573,19 +54625,27 @@ components:
readOnly: true
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
description: Get application slug, return empty string if no application
exists
readOnly: true
assigned_application_name:
type: string
description: Application's display Name.
description: Get application name, return empty string if no application
exists
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -55185,19 +55245,27 @@ components:
readOnly: true
assigned_application_slug:
type: string
description: Internal application name, used in URLs.
description: Get application slug, return empty string if no application
exists
readOnly: true
assigned_application_name:
type: string
description: Application's display Name.
description: Get application name, return empty string if no application
exists
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string
@ -55900,11 +55968,17 @@ components:
readOnly: true
assigned_backchannel_application_slug:
type: string
description: Internal application name, used in URLs.
description: |-
Get backchannel application slug.
Returns an empty string if no backchannel application exists.
readOnly: true
assigned_backchannel_application_name:
type: string
description: Application's display Name.
description: |-
Get backchannel application name.
Returns an empty string if no backchannel application exists.
readOnly: true
verbose_name:
type: string