prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Fixed light/dark theme setting
  Hello, is it possible to set the dark and light theme fixed? With the OS autodetection I have otherwise problems with my different logos that I use in my Tenants settings. Light logos are not visible to users on light platforms, dark logos are not visible to users on dark platforms.
  Thanks in advanced
  pupazze
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `authentik/tenants/api.py`
  Content:
  ```
  1 """Serializer for tenant models"""
  2 from typing import Any
  3 
  4 from drf_spectacular.utils import extend_schema
  5 from rest_framework.decorators import action
  6 from rest_framework.exceptions import ValidationError
  7 from rest_framework.fields import CharField, ListField
  8 from rest_framework.filters import OrderingFilter, SearchFilter
  9 from rest_framework.permissions import AllowAny
  10 from rest_framework.request import Request
  11 from rest_framework.response import Response
  12 from rest_framework.serializers import ModelSerializer
  13 from rest_framework.viewsets import ModelViewSet
  14 
  15 from authentik.api.authorization import SecretKeyFilter
  16 from authentik.core.api.used_by import UsedByMixin
  17 from authentik.core.api.utils import PassiveSerializer
  18 from authentik.lib.config import CONFIG
  19 from authentik.tenants.models import Tenant
  20 
  21 
  22 class FooterLinkSerializer(PassiveSerializer):
  23     """Links returned in Config API"""
  24 
  25     href = CharField(read_only=True)
  26     name = CharField(read_only=True)
  27 
  28 
  29 class TenantSerializer(ModelSerializer):
  30     """Tenant Serializer"""
  31 
  32     def validate(self, attrs: dict[str, Any]) -> dict[str, Any]:
  33         if attrs.get("default", False):
  34             tenants = Tenant.objects.filter(default=True)
  35             if self.instance:
  36                 tenants = tenants.exclude(pk=self.instance.pk)
  37             if tenants.exists():
  38                 raise ValidationError("Only a single Tenant can be set as default.")
  39         return super().validate(attrs)
  40 
  41     class Meta:
  42         model = Tenant
  43         fields = [
  44             "tenant_uuid",
  45             "domain",
  46             "default",
  47             "branding_title",
  48             "branding_logo",
  49             "branding_favicon",
  50             "flow_authentication",
  51             "flow_invalidation",
  52             "flow_recovery",
  53             "flow_unenrollment",
  54             "flow_user_settings",
  55             "flow_device_code",
  56             "event_retention",
  57             "web_certificate",
  58             "attributes",
  59         ]
  60 
  61 
  62 class CurrentTenantSerializer(PassiveSerializer):
  63     """Partial tenant information for styling"""
  64 
  65     matched_domain = CharField(source="domain")
  66     branding_title = CharField()
  67     branding_logo = CharField()
  68     branding_favicon = CharField()
  69     ui_footer_links = ListField(
  70         child=FooterLinkSerializer(),
  71         read_only=True,
  72         default=CONFIG.y("footer_links", []),
  73     )
  74 
  75     flow_authentication = CharField(source="flow_authentication.slug", required=False)
  76     flow_invalidation = CharField(source="flow_invalidation.slug", required=False)
  77     flow_recovery = CharField(source="flow_recovery.slug", required=False)
  78     flow_unenrollment = CharField(source="flow_unenrollment.slug", required=False)
  79     flow_user_settings = CharField(source="flow_user_settings.slug", required=False)
  80     flow_device_code = CharField(source="flow_device_code.slug", required=False)
  81 
  82     default_locale = CharField(read_only=True)
  83 
  84 
  85 class TenantViewSet(UsedByMixin, ModelViewSet):
  86     """Tenant Viewset"""
  87 
  88     queryset = Tenant.objects.all()
  89     serializer_class = TenantSerializer
  90     search_fields = [
  91         "domain",
  92         "branding_title",
  93         "web_certificate__name",
  94     ]
  95     filterset_fields = [
  96         "tenant_uuid",
  97         "domain",
  98         "default",
  99         "branding_title",
  100         "branding_logo",
  101         "branding_favicon",
  102         "flow_authentication",
  103         "flow_invalidation",
  104         "flow_recovery",
  105         "flow_unenrollment",
  106         "flow_user_settings",
  107         "flow_device_code",
  108         "event_retention",
  109         "web_certificate",
  110     ]
  111     ordering = ["domain"]
  112 
  113     filter_backends = [SecretKeyFilter, OrderingFilter, SearchFilter]
  114 
  115     @extend_schema(
  116         responses=CurrentTenantSerializer(many=False),
  117     )
  118     @action(methods=["GET"], detail=False, permission_classes=[AllowAny])
  119     def current(self, request: Request) -> Response:
  120         """Get current tenant"""
  121         tenant: Tenant = request._request.tenant
  122         return Response(CurrentTenantSerializer(tenant).data)
  123
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/authentik/tenants/api.py b/authentik/tenants/api.py
  --- a/authentik/tenants/api.py
  +++ b/authentik/tenants/api.py
  @@ -1,10 +1,11 @@
   """Serializer for tenant models"""
   from typing import Any
   
  +from django.db import models
   from drf_spectacular.utils import extend_schema
   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, ChoiceField, ListField
   from rest_framework.filters import OrderingFilter, SearchFilter
   from rest_framework.permissions import AllowAny
   from rest_framework.request import Request
  @@ -59,6 +60,14 @@
           ]
   
   
  +class Themes(models.TextChoices):
  +    """Themes"""
  +
  +    AUTOMATIC = "automatic"
  +    LIGHT = "light"
  +    DARK = "dark"
  +
  +
   class CurrentTenantSerializer(PassiveSerializer):
       """Partial tenant information for styling"""
   
  @@ -71,6 +80,12 @@
           read_only=True,
           default=CONFIG.y("footer_links", []),
       )
  +    ui_theme = ChoiceField(
  +        choices=Themes.choices,
  +        source="attributes.settings.theme.base",
  +        default=Themes.AUTOMATIC,
  +        read_only=True,
  +    )
   
       flow_authentication = CharField(source="flow_authentication.slug", required=False)
       flow_invalidation = CharField(source="flow_invalidation.slug", required=False)
  
verification_info: {"golden_diff": "diff --git a/authentik/tenants/api.py b/authentik/tenants/api.py\n--- a/authentik/tenants/api.py\n+++ b/authentik/tenants/api.py\n@@ -1,10 +1,11 @@\n \"\"\"Serializer for tenant models\"\"\"\n from typing import Any\n \n+from django.db import models\n from drf_spectacular.utils import extend_schema\n from rest_framework.decorators import action\n from rest_framework.exceptions import ValidationError\n-from rest_framework.fields import CharField, ListField\n+from rest_framework.fields import CharField, ChoiceField, ListField\n from rest_framework.filters import OrderingFilter, SearchFilter\n from rest_framework.permissions import AllowAny\n from rest_framework.request import Request\n@@ -59,6 +60,14 @@\n         ]\n \n \n+class Themes(models.TextChoices):\n+    \"\"\"Themes\"\"\"\n+\n+    AUTOMATIC = \"automatic\"\n+    LIGHT = \"light\"\n+    DARK = \"dark\"\n+\n+\n class CurrentTenantSerializer(PassiveSerializer):\n     \"\"\"Partial tenant information for styling\"\"\"\n \n@@ -71,6 +80,12 @@\n         read_only=True,\n         default=CONFIG.y(\"footer_links\", []),\n     )\n+    ui_theme = ChoiceField(\n+        choices=Themes.choices,\n+        source=\"attributes.settings.theme.base\",\n+        default=Themes.AUTOMATIC,\n+        read_only=True,\n+    )\n \n     flow_authentication = CharField(source=\"flow_authentication.slug\", required=False)\n     flow_invalidation = CharField(source=\"flow_invalidation.slug\", required=False)\n", "issue": "Fixed light/dark theme setting\nHello, is it possible to set the dark and light theme fixed? With the OS autodetection I have otherwise problems with my different logos that I use in my Tenants settings. Light logos are not visible to users on light platforms, dark logos are not visible to users on dark platforms.\r\nThanks in advanced\r\npupazze\n", "before_files": [{"content": "\"\"\"Serializer for tenant models\"\"\"\nfrom typing import Any\n\nfrom drf_spectacular.utils import extend_schema\nfrom rest_framework.decorators import action\nfrom rest_framework.exceptions import ValidationError\nfrom rest_framework.fields import CharField, ListField\nfrom rest_framework.filters import OrderingFilter, SearchFilter\nfrom rest_framework.permissions import AllowAny\nfrom rest_framework.request import Request\nfrom rest_framework.response import Response\nfrom rest_framework.serializers import ModelSerializer\nfrom rest_framework.viewsets import ModelViewSet\n\nfrom authentik.api.authorization import SecretKeyFilter\nfrom authentik.core.api.used_by import UsedByMixin\nfrom authentik.core.api.utils import PassiveSerializer\nfrom authentik.lib.config import CONFIG\nfrom authentik.tenants.models import Tenant\n\n\nclass FooterLinkSerializer(PassiveSerializer):\n    \"\"\"Links returned in Config API\"\"\"\n\n    href = CharField(read_only=True)\n    name = CharField(read_only=True)\n\n\nclass TenantSerializer(ModelSerializer):\n    \"\"\"Tenant Serializer\"\"\"\n\n    def validate(self, attrs: dict[str, Any]) -> dict[str, Any]:\n        if attrs.get(\"default\", False):\n            tenants = Tenant.objects.filter(default=True)\n            if self.instance:\n                tenants = tenants.exclude(pk=self.instance.pk)\n            if tenants.exists():\n                raise ValidationError(\"Only a single Tenant can be set as default.\")\n        return super().validate(attrs)\n\n    class Meta:\n        model = Tenant\n        fields = [\n            \"tenant_uuid\",\n            \"domain\",\n            \"default\",\n            \"branding_title\",\n            \"branding_logo\",\n            \"branding_favicon\",\n            \"flow_authentication\",\n            \"flow_invalidation\",\n            \"flow_recovery\",\n            \"flow_unenrollment\",\n            \"flow_user_settings\",\n            \"flow_device_code\",\n            \"event_retention\",\n            \"web_certificate\",\n            \"attributes\",\n        ]\n\n\nclass CurrentTenantSerializer(PassiveSerializer):\n    \"\"\"Partial tenant information for styling\"\"\"\n\n    matched_domain = CharField(source=\"domain\")\n    branding_title = CharField()\n    branding_logo = CharField()\n    branding_favicon = CharField()\n    ui_footer_links = ListField(\n        child=FooterLinkSerializer(),\n        read_only=True,\n        default=CONFIG.y(\"footer_links\", []),\n    )\n\n    flow_authentication = CharField(source=\"flow_authentication.slug\", required=False)\n    flow_invalidation = CharField(source=\"flow_invalidation.slug\", required=False)\n    flow_recovery = CharField(source=\"flow_recovery.slug\", required=False)\n    flow_unenrollment = CharField(source=\"flow_unenrollment.slug\", required=False)\n    flow_user_settings = CharField(source=\"flow_user_settings.slug\", required=False)\n    flow_device_code = CharField(source=\"flow_device_code.slug\", required=False)\n\n    default_locale = CharField(read_only=True)\n\n\nclass TenantViewSet(UsedByMixin, ModelViewSet):\n    \"\"\"Tenant Viewset\"\"\"\n\n    queryset = Tenant.objects.all()\n    serializer_class = TenantSerializer\n    search_fields = [\n        \"domain\",\n        \"branding_title\",\n        \"web_certificate__name\",\n    ]\n    filterset_fields = [\n        \"tenant_uuid\",\n        \"domain\",\n        \"default\",\n        \"branding_title\",\n        \"branding_logo\",\n        \"branding_favicon\",\n        \"flow_authentication\",\n        \"flow_invalidation\",\n        \"flow_recovery\",\n        \"flow_unenrollment\",\n        \"flow_user_settings\",\n        \"flow_device_code\",\n        \"event_retention\",\n        \"web_certificate\",\n    ]\n    ordering = [\"domain\"]\n\n    filter_backends = [SecretKeyFilter, OrderingFilter, SearchFilter]\n\n    @extend_schema(\n        responses=CurrentTenantSerializer(many=False),\n    )\n    @action(methods=[\"GET\"], detail=False, permission_classes=[AllowAny])\n    def current(self, request: Request) -> Response:\n        \"\"\"Get current tenant\"\"\"\n        tenant: Tenant = request._request.tenant\n        return Response(CurrentTenantSerializer(tenant).data)\n", "path": "authentik/tenants/api.py"}], "after_files": [{"content": "\"\"\"Serializer for tenant models\"\"\"\nfrom typing import Any\n\nfrom django.db import models\nfrom drf_spectacular.utils import extend_schema\nfrom rest_framework.decorators import action\nfrom rest_framework.exceptions import ValidationError\nfrom rest_framework.fields import CharField, ChoiceField, ListField\nfrom rest_framework.filters import OrderingFilter, SearchFilter\nfrom rest_framework.permissions import AllowAny\nfrom rest_framework.request import Request\nfrom rest_framework.response import Response\nfrom rest_framework.serializers import ModelSerializer\nfrom rest_framework.viewsets import ModelViewSet\n\nfrom authentik.api.authorization import SecretKeyFilter\nfrom authentik.core.api.used_by import UsedByMixin\nfrom authentik.core.api.utils import PassiveSerializer\nfrom authentik.lib.config import CONFIG\nfrom authentik.tenants.models import Tenant\n\n\nclass FooterLinkSerializer(PassiveSerializer):\n    \"\"\"Links returned in Config API\"\"\"\n\n    href = CharField(read_only=True)\n    name = CharField(read_only=True)\n\n\nclass TenantSerializer(ModelSerializer):\n    \"\"\"Tenant Serializer\"\"\"\n\n    def validate(self, attrs: dict[str, Any]) -> dict[str, Any]:\n        if attrs.get(\"default\", False):\n            tenants = Tenant.objects.filter(default=True)\n            if self.instance:\n                tenants = tenants.exclude(pk=self.instance.pk)\n            if tenants.exists():\n                raise ValidationError(\"Only a single Tenant can be set as default.\")\n        return super().validate(attrs)\n\n    class Meta:\n        model = Tenant\n        fields = [\n            \"tenant_uuid\",\n            \"domain\",\n            \"default\",\n            \"branding_title\",\n            \"branding_logo\",\n            \"branding_favicon\",\n            \"flow_authentication\",\n            \"flow_invalidation\",\n            \"flow_recovery\",\n            \"flow_unenrollment\",\n            \"flow_user_settings\",\n            \"flow_device_code\",\n            \"event_retention\",\n            \"web_certificate\",\n            \"attributes\",\n        ]\n\n\nclass Themes(models.TextChoices):\n    \"\"\"Themes\"\"\"\n\n    AUTOMATIC = \"automatic\"\n    LIGHT = \"light\"\n    DARK = \"dark\"\n\n\nclass CurrentTenantSerializer(PassiveSerializer):\n    \"\"\"Partial tenant information for styling\"\"\"\n\n    matched_domain = CharField(source=\"domain\")\n    branding_title = CharField()\n    branding_logo = CharField()\n    branding_favicon = CharField()\n    ui_footer_links = ListField(\n        child=FooterLinkSerializer(),\n        read_only=True,\n        default=CONFIG.y(\"footer_links\", []),\n    )\n    ui_theme = ChoiceField(\n        choices=Themes.choices,\n        source=\"attributes.settings.theme.base\",\n        default=Themes.AUTOMATIC,\n        read_only=True,\n    )\n\n    flow_authentication = CharField(source=\"flow_authentication.slug\", required=False)\n    flow_invalidation = CharField(source=\"flow_invalidation.slug\", required=False)\n    flow_recovery = CharField(source=\"flow_recovery.slug\", required=False)\n    flow_unenrollment = CharField(source=\"flow_unenrollment.slug\", required=False)\n    flow_user_settings = CharField(source=\"flow_user_settings.slug\", required=False)\n    flow_device_code = CharField(source=\"flow_device_code.slug\", required=False)\n\n    default_locale = CharField(read_only=True)\n\n\nclass TenantViewSet(UsedByMixin, ModelViewSet):\n    \"\"\"Tenant Viewset\"\"\"\n\n    queryset = Tenant.objects.all()\n    serializer_class = TenantSerializer\n    search_fields = [\n        \"domain\",\n        \"branding_title\",\n        \"web_certificate__name\",\n    ]\n    filterset_fields = [\n        \"tenant_uuid\",\n        \"domain\",\n        \"default\",\n        \"branding_title\",\n        \"branding_logo\",\n        \"branding_favicon\",\n        \"flow_authentication\",\n        \"flow_invalidation\",\n        \"flow_recovery\",\n        \"flow_unenrollment\",\n        \"flow_user_settings\",\n        \"flow_device_code\",\n        \"event_retention\",\n        \"web_certificate\",\n    ]\n    ordering = [\"domain\"]\n\n    filter_backends = [SecretKeyFilter, OrderingFilter, SearchFilter]\n\n    @extend_schema(\n        responses=CurrentTenantSerializer(many=False),\n    )\n    @action(methods=[\"GET\"], detail=False, permission_classes=[AllowAny])\n    def current(self, request: Request) -> Response:\n        \"\"\"Get current tenant\"\"\"\n        tenant: Tenant = request._request.tenant\n        return Response(CurrentTenantSerializer(tenant).data)\n", "path": "authentik/tenants/api.py"}]}