Skip to content

Commit

Permalink
feat(apple): Authentication by token
Browse files Browse the repository at this point in the history
  • Loading branch information
pennersr committed Apr 4, 2024
1 parent e7f82a3 commit 3d48b08
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
25 changes: 25 additions & 0 deletions allauth/socialaccount/providers/apple/provider.py
@@ -1,7 +1,11 @@
import requests

from allauth.account.models import EmailAddress
from allauth.socialaccount.adapter import get_adapter
from allauth.socialaccount.app_settings import QUERY_EMAIL
from allauth.socialaccount.providers.apple.views import AppleOAuth2Adapter
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.client import OAuth2Error
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider


Expand All @@ -10,6 +14,7 @@ class AppleProvider(OAuth2Provider):
name = "Apple"
account_class = ProviderAccount
oauth2_adapter_class = AppleOAuth2Adapter
supports_token_authentication = True

def extract_uid(self, data):
return str(data["sub"])
Expand Down Expand Up @@ -47,5 +52,25 @@ def get_default_scope(self):
scopes.append("email")
return scopes

def verify_token(self, request, token):
from allauth.socialaccount.providers.apple.views import (
AppleOAuth2Adapter,
)

id_token = token.get("id_token")
if not id_token:
raise get_adapter().validation_error("invalid_token")
try:
identity_data = AppleOAuth2Adapter.get_verified_identity_data(
self, id_token
)
except (OAuth2Error, requests.RequestException) as e:
raise get_adapter().validation_error("invalid_token") from e
login = self.sociallogin_from_response(request, identity_data)
return login

def get_auds(self):
return [aud.strip() for aud in self.app.client_id.split(",")]


provider_classes = [AppleProvider]
6 changes: 6 additions & 0 deletions allauth/socialaccount/providers/apple/tests.py
Expand Up @@ -137,6 +137,12 @@ def get_apple_id_token_payload(self):
"auth_time": 1234345345, # not converted automatically by pyjwt
}

def test_verify_token(self):
id_token = sign_id_token(self.get_apple_id_token_payload())
with mocked_response(self.get_mocked_response()):
sociallogin = self.provider.verify_token(None, {"id_token": id_token})
assert sociallogin.user.email == "test@privaterelay.appleid.com"

def get_login_response_json(self, with_refresh_token=True):
"""
`with_refresh_token` is not optional for apple, so it's ignored.
Expand Down
18 changes: 7 additions & 11 deletions allauth/socialaccount/providers/apple/views.py
Expand Up @@ -7,7 +7,6 @@
from django.utils.http import urlencode
from django.views.decorators.csrf import csrf_exempt

from allauth.socialaccount.adapter import get_adapter
from allauth.socialaccount.internal import jwtkit
from allauth.socialaccount.models import SocialToken
from allauth.socialaccount.providers.oauth2.views import (
Expand All @@ -28,18 +27,13 @@ class AppleOAuth2Adapter(OAuth2Adapter):
authorize_url = "https://appleid.apple.com/auth/authorize"
public_key_url = "https://appleid.apple.com/auth/keys"

def get_client_id(self, provider):
app = get_adapter().get_app(request=None, provider=self.provider_id)
return [aud.strip() for aud in app.client_id.split(",")]

def get_verified_identity_data(self, id_token):
provider = self.get_provider()
allowed_auds = self.get_client_id(provider)
@classmethod
def get_verified_identity_data(cls, provider, id_token):
data = jwtkit.verify_and_decode(
credential=id_token,
keys_url=self.public_key_url,
keys_url=cls.public_key_url,
issuer="https://appleid.apple.com",
audience=allowed_auds,
audience=provider.get_auds(),
lookup_kid=jwtkit.lookup_kid_jwk,
)
return data
Expand All @@ -56,7 +50,9 @@ def parse_token(self, data):

# `user_data` is a big flat dictionary with the parsed JWT claims
# access_tokens, and user info from the apple post.
identity_data = self.get_verified_identity_data(data["id_token"])
identity_data = AppleOAuth2Adapter.get_verified_identity_data(
self.get_provider(), data["id_token"]
)
token.user_data = {**data, **identity_data}

return token
Expand Down

0 comments on commit 3d48b08

Please sign in to comment.