o
    &zh'8                     @   s   d dl mZmZmZ d dlmZmZmZ d dlm	Z	 d dl
m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mZ G dd deZG dd dZG dd dZdS )    )AnyDictOptional)ImproperlyConfiguredPermissionDeniedValidationError)HttpResponseget_adapter)valid_email_or_none)get_next_redirect_urlget_request_param)context)app_settings)statekit)AuthProcessc                   @   s   e Zd ZdS )ProviderExceptionN)__name__
__module____qualname__ r   r   h/var/www/html/kangema/venv/lib/python3.10/site-packages/allauth/socialaccount/providers/base/provider.pyr      s    r   c                
   @   s  e Zd ZU eed< eed< dZee ed< dZdZdZ	d:d;dd	Z
defd
dZedefddZd:defddZdefddZdefddZ	d<defddZdd ZdefddZdd ZdefddZdd Zdefd d!Zdefd"d#Zdefd$d%Z	d=d&ee d'ed(edee fd)d*Zd+d, Zed-d. Z 	d>d/d0Z!d1d2 Z"e#defd3d4Z$de%ee&f fd5d6Z'ed7e%ee&f dd fd8d9Z(dS )?ProvidernameidNslugTFreturnc                 C   s&   || _ | jr|d u rtd|| _d S )Nzmissing: app)request	uses_apps
ValueErrorapp)selfr   r    r   r   r   __init__#   s   
zProvider.__init__c                 C   s   | j S N)r   r!   r   r   r   __str__)   s   zProvider.__str__c                 C   s   | j p| jS r#   )r   r   )clsr   r   r   get_slug,   s   zProvider.get_slugc                 K   s   t d| j )zb
        Builds the URL to redirect to when initiating a login for this
        provider.
        zget_login_url() for )NotImplementedErrorr   )r!   r   nextkwargsr   r   r   get_login_url0   s   zProvider.get_login_urlc                 C   s   |  |}| j|fi |S r#   ) get_redirect_from_request_kwargsredirect)r!   r   r*   r   r   r   redirect_from_request7   s   
zProvider.redirect_from_requestc                 C   s.   i }t |}|r||d< t|dtj|d< |S )Nnext_urlprocess)r   r   r   LOGIN)r!   r   r*   r/   r   r   r   r,   ;   s   z)Provider.get_redirect_from_request_kwargsc                 K      t  )z6
        Initiate a redirect to the provider.
        r(   )r!   r   r0   r/   datar*   r   r   r   r-   C   s   zProvider.redirectc                 C   r2   )z
        Verifies the token, returning a `SocialLogin` instance when valid.
        Raises a `ValidationError` otherwise.
        r3   )r!   r   tokenr   r   r   verify_tokenK   s   zProvider.verify_tokenc                 C   s   dS )zT
        Some providers may require extra scripts (e.g. a Facebook connect)
         r   )r!   r   r   r   r   media_jsR   s   zProvider.media_jsc                 C   s
   |  |S r#   )account_classr!   social_accountr   r   r   wrap_accountX      
zProvider.wrap_accountc                 C   s   t j| ji S r#   )r   	PROVIDERSgetr   r$   r   r   r   get_settings[   s   zProvider.get_settingsc              	   C   st  ddl m} ddlm}m} | }| |}t|ts$tdt	| t
|tjkr5tdt
| d|s;td| |}| |}	|||| jd}
| |}| j|	d	|t|	d
d}|ri||	d	< n|	d	d |	d}|rzt jdd|}||	d< W n ty   d}|	d Y nw || |
|||	ddd}||| }|_|  ||||	 |S )a|  
        Instantiates and populates a `SocialLogin` model based on the data
        retrieved in `response`. The method does NOT save the model to the
        DB.

        Data for `SocialLogin` will be extracted from `response` with the
        help of the `.extract_uid()`, `.extract_extra_data()`,
        `.extract_common_fields()`, and `.extract_email_addresses()`
        methods.

        :param request: a Django `HttpRequest` object.
        :param response: object retrieved via the callback response of the
            social auth provider.
        :return: A populated instance of the `SocialLogin` model (unsaved).
        r   r	   )SocialAccountSocialLoginzuid must be a string: z)SOCIALACCOUNT_UID_MAX_LENGTH too small (<)zuid must be a non-empty string)
extra_datauidprovideremailemail_verified)rH   NphoneT)requiredphone_verifiedF)rF   accountemail_addressesrI   rK   )allauth.socialaccount.adapterr
   allauth.socialaccount.modelsrA   rB   extract_uid
isinstancestrr   reprlenr   UID_MAX_LENGTHr   extract_extra_dataextract_common_fieldssub_idextract_email_addressescleanup_email_addressesr?   boolpopget_account_adapterphone_form_fieldcleanr   new_useruserset_unusable_passwordpopulate_user)r!   r   responser
   rA   rB   adapterrE   rD   common_fieldssocialaccountrM   rG   rI   socialloginra   r   r   r   sociallogin_from_response^   sb   







z"Provider.sociallogin_from_responsec                 C   s   t d)z9
        Extracts the unique user ID from `data`
        z6The provider must implement the `extract_uid()` methodr3   r!   r4   r   r   r   rP      s   zProvider.extract_uidc                 C   s   |S )z
        Extracts fields from `data` that will be stored in
        `SocialAccount`'s `extra_data` JSONField, such as email address, first
        name, last name, and phone number.

        :return: any JSON-serializable Python structure.
        r   rj   r   r   r   rV         zProvider.extract_extra_datac                 C   s   i S )a  
        Extracts fields from `data` that will be used to populate the
        `User` model in the `SOCIALACCOUNT_ADAPTER`'s `populate_user()`
        method.

        For example:

            {'first_name': 'John'}

        :return: dictionary of key-value pairs.
        r   rj   r   r   r   rW      s   zProvider.extract_common_fieldsrG   	addressesrH   c                 C   s   ddl m} t|}tt|d d d D ]}|| }t|j|_|js)|| q|rB|dd |D vrB|d||t|dd t	 }|D ]}|
| |jrSd|_qG|jdd	 dd
 |sf|rf|d j}|S )Nr   )EmailAddressc                 S   s   g | ]}|j qS r   )rG   ).0ar   r   r   
<listcomp>   s    z4Provider.cleanup_email_addresses.<locals>.<listcomp>T)rG   verifiedprimaryc                 S   s   | j | j| jfS r#   )rs   rr   rG   )rp   r   r   r   <lambda>   s    z2Provider.cleanup_email_addresses.<locals>.<lambda>)keyreverse)allauth.account.modelsrm   r   rangerT   rG   r\   insertr[   r
   is_email_verifiedrr   sort)r!   rG   rl   rH   rm   idxaddressre   r   r   r   rZ      s,   

z Provider.cleanup_email_addressesc                 C   s   g S )z
        For example:

        [EmailAddress(email='john@example.com',
                      verified=True,
                      primary=True)]
        r   rj   r   r   r   rY      rk   z Provider.extract_email_addressesc                 C   s$   t | dd }|s| jdd }|S )Npackage.r   )getattrr   
rpartition)r&   pkgr   r   r   get_package   s   zProvider.get_packagec                 K   s*   ||d|}|r||d< t j|||dS )z
        Stashes state, returning a (random) state ID using which the state
        can be looked up later. Application specific state is stored separately
        from (core) allauth state such as `process` and `**kwargs`.
        )r0   r4   r)   )state_id)r   stash_state)r!   r   r0   r/   r4   r   r*   stater   r   r   stash_redirect_state   s   zProvider.stash_redirect_statec                 C   s   t ||}|d u rt |S r#   )r   unstash_stater   )r!   r   r   r   r   r   r   unstash_redirect_state  s   zProvider.unstash_redirect_statec                 C   s   | j r| jjp
| jjS | jS r#   )r   r    provider_idrF   r   r$   r   r   r   rX   
  s   zProvider.sub_idc                 C   s    d| j i}| jr| jj|d< |S )Nr   app.client_id)r   r   r    	client_idr!   retr   r   r   	serialize  s   
zProvider.serializer4   c                 C   s   t  jtj|d |ddS )Nr   r   )rF   r   )r
   get_providerr   r   r?   )r&   r4   r   r   r   deserialize  s
   zProvider.deserializer#   )r   N)NN)F)NNN))r   r   r   rR   __annotations__r   r   r   supports_redirectsupports_token_authenticationr"   r%   classmethodr'   r+   r   r.   dictr,   r-   r6   r8   r<   r@   ri   rP   rV   rW   listr[   rZ   rY   r   r   r   propertyrX   r   r   r   r   r   r   r   r   r      s^   
 	
F

"


 r   c                   @   sN   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdee	 fddZ
dd ZdS )ProviderAccountc                 C   s
   || _ d S r#   )rL   r:   r   r   r   r"      r=   zProviderAccount.__init__c                 C      d S r#   r   r$   r   r   r   get_profile_url#     zProviderAccount.get_profile_urlc                 C   r   r#   r   r$   r   r   r   get_avatar_url&  r   zProviderAccount.get_avatar_urlc                 C   s   | j  }t|j|jdS )a7  
        Returns a dict containing an id and name identifying the
        brand. Useful when displaying logos next to accounts in
        templates.

        For most providers, these are identical to the provider. For
        OpenID however, the brand can derived from the OpenID identity
        url.
        )r   r   )rL   r   r   r   r   )r!   rF   r   r   r   	get_brand)  s   

zProviderAccount.get_brandc                 C   s   |   S r#   )to_strr$   r   r   r   r%   6  s   zProviderAccount.__str__r   c                 C   s   | j j}t|tsd}|S )a  Typically, the ``extra_data`` directly contains user related keys.
        For some providers, however, they are nested below a different key. In
        that case, you can override this method so that the base ``__str__()``
        will still be able to find the data.
        N)rL   rD   rQ   r   r   r   r   r   get_user_data9  s   
zProviderAccount.get_user_datac           
      C   s   |   }|rki }dg dfdg dfdg dfdddgfdg dfd	g d
fg}|D ]%\}}|D ]}||}t|trN| }|rJ|sJ|    S |||< q0q*|dpVd}|d	p]d}	|sb|	rk| d|	  S |  d S )a  
        Returns string representation of this social account. This is the
        unique identifier of the account, such as its username or its email
        address. It should be meaningful to human beings, which means a numeric
        ID number is rarely the appropriate representation here.

        Subclasses are meant to override this method.

        Users will see the string representation of their social accounts in
        the page rendered by the allauth.socialaccount.views.connections view.

        The following code did not use to work in the past due to py2
        compatibility:

            class GoogleAccount(ProviderAccount):
                def __str__(self):
                    dflt = super(GoogleAccount, self).__str__()
                    return self.account.extra_data.get('name', dflt)

        So we have this method `to_str` that can be overridden in a conventional
        fashion, without having to worry about it.
        N)usernameuserName	user_nameloginhandle)rG   Emailmailemail_address)r   display_namedisplayNamedisplaynameDisplay_Namenickname	full_namefullName
first_name)r   	firstname	firstName
First_Name
given_name	givenName	last_name)r   lastnamelastName	Last_Namefamily_name
familyNamesurnamer7    r   )r   r?   rQ   rR   stripr   )
r!   	user_datacombi_valuestblstore_asvariantsru   valuer   r   r   r   r   r   D  sB   

4

zProviderAccount.to_strN)r   r   r   r"   r   r   r   r%   r   r   r   r   r   r   r   r   r     s    r   N)typingr   r   r   django.core.exceptionsr   r   r   django.httpr   allauth.account.adapterr
   r]   !allauth.account.internal.emailkitr   allauth.account.utilsr   r   allauth.corer   allauth.socialaccountr   rN   allauth.socialaccount.internalr   .allauth.socialaccount.providers.base.constantsr   	Exceptionr   r   r   r   r   r   r   <module>   s       	