Compare commits
	
		
			4 Commits
		
	
	
		
			website/do
			...
			fix/issue_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 13c8cbf03a | |||
| 1776981f29 | |||
| 5a4df95011 | |||
| f2927e5725 | 
| @ -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 = [ | ||||
|  | ||||
| @ -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), | ||||
|  | ||||
| @ -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"], "") | ||||
|  | ||||
| @ -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", | ||||
|  | ||||
							
								
								
									
										142
									
								
								schema.yml
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								schema.yml
									
									
									
									
									
								
							| @ -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 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	