Repository: goauthentik/authentik

Issue:
Can't login with Apple OAuth after update to 2024.4.0
**Describe the bug**
After updating to 2024.4.0 there is no login fields shown as the page immediately renders to the "Something went wrong! Please try again later." error message.

**To Reproduce**
Steps to reproduce the behavior:
1. Have Apple OAuth source enabled in default-authentication-identification
2. Go to URL (local or via reverse proxy address) for Authentik site
3. See error
4. Disable Apple OAuth source in default-authentication-identification
5. Error is gone (Google OAuth remains enabled and works)

**Expected behavior**
To see the usual login screen for Authentik

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Logs**
<details>
    <summary>Stacktrace from authentik</summary>

```
Traceback (most recent call last):
  File "/authentik/flows/views/executor.py", line 290, in get
    stage_response = self.current_stage_view.dispatch(request)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/ak-root/venv/lib/python3.12/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/flows/stage.py", line 95, in get
    challenge = self._get_challenge(*args, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/flows/stage.py", line 172, in _get_challenge
    challenge = self.get_challenge(*args, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/authentik/stages/identification/stage.py", line 243, in get_challenge
    source_challenge.is_valid()
  File "/ak-root/venv/lib/python3.12/site-packages/rest_framework/serializers.py", line 220, in is_valid
    assert hasattr(self, 'initial_data'), (
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
builtins.AssertionError: Cannot call `.is_valid()` as no `data=` keyword argument was passed when instantiating the serializer instance.
```
</details>


**Version and Deployment (please complete the following information):**
- authentik version: 2024.4.0
- Deployment: [docker-compose (MacOS Docker Desktop)]

**Additional context**
Add any other context about the problem here.
        


Discussion:

Resolving patch:
diff --git a/authentik/sources/oauth/types/apple.py b/authentik/sources/oauth/types/apple.py
--- a/authentik/sources/oauth/types/apple.py
+++ b/authentik/sources/oauth/types/apple.py
@@ -125,7 +125,7 @@ def login_challenge(self, source: OAuthSource, request: HttpRequest) -> Challeng
         )
         args = apple_client.get_redirect_args()
         return AppleLoginChallenge(
-            instance={
+            data={
                 "client_id": apple_client.get_client_id(),
                 "scope": "name email",
                 "redirect_uri": args["redirect_uri"],
diff --git a/authentik/sources/plex/models.py b/authentik/sources/plex/models.py
--- a/authentik/sources/plex/models.py
+++ b/authentik/sources/plex/models.py
@@ -66,7 +66,7 @@ def ui_login_button(self, request: HttpRequest) -> UILoginButton:
             icon = static("authentik/sources/plex.svg")
         return UILoginButton(
             challenge=PlexAuthenticationChallenge(
-                {
+                data={
                     "type": ChallengeTypes.NATIVE.value,
                     "component": "ak-source-plex",
                     "client_id": self.client_id,
diff --git a/authentik/stages/identification/stage.py b/authentik/stages/identification/stage.py
--- a/authentik/stages/identification/stage.py
+++ b/authentik/stages/identification/stage.py
@@ -237,6 +237,8 @@ def get_challenge(self) -> Challenge:
         )
         for source in sources:
             ui_login_button = source.ui_login_button(self.request)
+            if source.component == "":
+                continue
             if ui_login_button:
                 button = asdict(ui_login_button)
                 source_challenge = ui_login_button.challenge


Test patch:
diff --git a/authentik/sources/oauth/tests/test_type_apple.py b/authentik/sources/oauth/tests/test_type_apple.py
new file mode 100644
--- /dev/null
+++ b/authentik/sources/oauth/tests/test_type_apple.py
@@ -0,0 +1,37 @@
+"""Apple Type tests"""
+
+from django.test import RequestFactory, TestCase
+from guardian.shortcuts import get_anonymous_user
+
+from authentik.lib.generators import generate_id
+from authentik.lib.tests.utils import dummy_get_response
+from authentik.root.middleware import SessionMiddleware
+from authentik.sources.oauth.models import OAuthSource
+from authentik.sources.oauth.types.registry import registry
+
+
+class TestTypeApple(TestCase):
+    """OAuth Source tests"""
+
+    def setUp(self):
+        self.source = OAuthSource.objects.create(
+            name="test",
+            slug="test",
+            provider_type="apple",
+            authorization_url="",
+            profile_url="",
+            consumer_key=generate_id(),
+        )
+        self.factory = RequestFactory()
+
+    def test_login_challenge(self):
+        """Test login_challenge"""
+        request = self.factory.get("/")
+        request.user = get_anonymous_user()
+
+        middleware = SessionMiddleware(dummy_get_response)
+        middleware.process_request(request)
+        request.session.save()
+        oauth_type = registry.find_type("apple")
+        challenge = oauth_type().login_challenge(self.source, request)
+        self.assertTrue(challenge.is_valid(raise_exception=True))
diff --git a/authentik/sources/plex/tests.py b/authentik/sources/plex/tests.py
--- a/authentik/sources/plex/tests.py
+++ b/authentik/sources/plex/tests.py
@@ -40,6 +40,11 @@ def setUp(self):
             slug="test",
         )
 
+    def test_login_challenge(self):
+        """Test login_challenge"""
+        ui_login_button = self.source.ui_login_button(None)
+        self.assertTrue(ui_login_button.challenge.is_valid(raise_exception=True))
+
     def test_get_user_info(self):
         """Test get_user_info"""
         token = generate_key()