o
    ˷ev                     @   s  d dl Z d dlZd dlmZ d dlmZmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ d dlZd dlmZ d d	lmZ d d
lmZ d dlmZmZmZ d dlmZmZ ddlmZmZ ddl m!Z! ddl"m#Z# G dd deZ$edddZ%e&e$Z'e%Z(e&e$Z)dS )    N)	timedelta)HttpResponseNotAllowedHttpResponseRedirect)reverse)timezone)	urlencode)csrf_exempt)get_adapter)SocialToken)OAuth2Error)OAuth2AdapterOAuth2CallbackViewOAuth2LoginView)build_absolute_uriget_request_param   )add_apple_sessionpersist_apple_session)AppleOAuth2Client)AppleProviderc                   @   sb   e Zd ZeZejZdZdZ	dZ
dd Zdd Zdd	 Zd
d Zdd Zdd Zdd Zdd ZdS )AppleOAuth2Adapterz$https://appleid.apple.com/auth/tokenz(https://appleid.apple.com/auth/authorizez#https://appleid.apple.com/auth/keysc              
   C   sl   t | j}|  z| }W n tjy" } ztd|d }~ww |d D ]}|d |kr3|  S q'd S )Nz"Error retrieving apple public key.keyskid)requestsgetpublic_key_urlraise_for_statusjsonJSONDecodeErrorr   )selfr   responsedataed r$   b/var/www/ideatree/venv/lib/python3.10/site-packages/allauth/socialaccount/providers/apple/views.py_get_apple_public_key#   s   
z(AppleOAuth2Adapter._get_apple_public_keyc                 C   s2   t |d }| j|d}t jjt|}|S )zT
        Get the public key which matches the `kid` in the id_token header.
        r   )r   )jwtget_unverified_headerr&   
algorithmsRSAAlgorithmfrom_jwkr   dumps)r   id_tokenr   apple_public_key
public_keyr$   r$   r%   get_public_key/   s   z!AppleOAuth2Adapter.get_public_keyc                 C   s(   t  jd | jd}dd |jdD S )N)requestproviderc                 S   s   g | ]}|  qS r$   )strip).0audr$   r$   r%   
<listcomp>;   s    z4AppleOAuth2Adapter.get_client_id.<locals>.<listcomp>,)r	   get_appprovider_id	client_idsplit)r   r2   appr$   r$   r%   get_client_id9   s   z AppleOAuth2Adapter.get_client_idc              
   C   s^   |   }| |}z| |}tj||dg|dd}|W S  tjy. } ztd|d }~ww )NRS256zhttps://appleid.apple.com)r)   audienceissuerzInvalid id_token)get_providerr=   r0   r'   decode
PyJWTErrorr   )r   r-   r2   allowed_audsr/   identity_datar"   r$   r$   r%   get_verified_identity_data=   s    


z-AppleOAuth2Adapter.get_verified_identity_datac                 C   sd   t |d d}|dd|_|| j}|r"t tt|d |_| 	|d }i |||_
|S )Naccess_token)tokenrefresh_token )secondsr-   )r
   r   token_secretexpires_in_keyr   nowr   int
expires_atrF   	user_data)r   r!   rH   
expires_inrE   r$   r$   r%   parse_tokenO   s   zAppleOAuth2Adapter.parse_tokenc                 K   s:   |j }|  j||d}|j |jd< t| |j  |S )N)r1   r    r-   )rQ   rA   sociallogin_from_responsestater   apple_login_sessiondelete)r   r1   r<   rH   kwargs
extra_dataloginr$   r$   r%   complete_login`   s   
z!AppleOAuth2Adapter.complete_loginc                 C   s4   |j dd}zt|W S  tjy   i  Y S w )NuserrJ   )rV   r   r   loadsr   )r   r1   user_scope_datar$   r$   r%   get_user_scope_datan   s   z&AppleOAuth2Adapter.get_user_scope_datac                 C   s>   t | t|d}||}i || |d|jdiS )z8We need to gather the info from the apple specific logincoder-   )r   r   get_access_tokenr_   rV   r   )r   r1   r<   clientr`   access_token_datar$   r$   r%   get_access_token_dataw   s   

z(AppleOAuth2Adapter.get_access_token_dataN)__name__
__module____qualname__r   client_classr   idr9   access_token_urlauthorize_urlr   r&   r0   r=   rF   rS   r[   r_   rd   r$   r$   r$   r%   r      s    
	r   apple_finish_callbackc           	      C   s   | j dkr
tdgt|  g d}i }|D ]}t| |d}|r$|||< qddg}|D ]}t| |d| j|< q+t| t|}tdj|t	|d}t
| | |S )a  
    Apple uses a `form_post` response type, which due to
    CORS/Samesite-cookie rules means this request cannot access
    the request since the session cookie is unavailable.

    We work around this by storing the apple response in a
    separate, temporary session and redirecting to a more normal
    oauth flow.

    args:
        finish_endpoint_name (str): The name of a defined URL, which can be
            overridden in your url configuration if you have more than one
            callback endpoint.
    POST)r`   rU   errorrJ   r\   r-   z{url}?{query})urlquery)methodr   r   r   rV   r   r   r   formatr   r   )	r1   finish_endpoint_namekeys_to_put_in_url
url_paramskeyvaluekeys_to_save_to_sessionro   r    r$   r$   r%   apple_post_callback   s&   


ry   )rl   )*r   r   datetimer   django.httpr   r   django.urlsr   django.utilsr   django.utils.httpr   django.views.decorators.csrfr   r'   allauth.socialaccount.adapterr	   allauth.socialaccount.modelsr
   -allauth.socialaccount.providers.oauth2.clientr   ,allauth.socialaccount.providers.oauth2.viewsr   r   r   allauth.utilsr   r   apple_sessionr   r   rb   r   r2   r   r   ry   adapter_viewoauth2_loginoauth2_callbackoauth2_finish_loginr$   r$   r$   r%   <module>   s.    j
(