o
    &zh 9                     @   s   d dl Z d dl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 d dlmZ d d	lmZmZmZ d d
l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 dddZdS )    N)ImproperlyConfiguredMultipleObjectsReturned)Qreverse)get_random_string)gettext_lazy)get_adapter)valid_email_or_none)
user_email
user_fielduser_username)BaseAdapter)deserialize_instanceserialize_instance)import_attribute   )app_settingsc                   @   s   e Zd ZdZededededededdZd	d
 Z			d6ddZdd Zd7ddZ	dd Z
dd Zd8ddZdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd7d%d&Zd9d'd(Zd7d)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3edefd4d5ZdS ):DefaultSocialAccountAdapteraV  The adapter class allows you to override various functionality of the
    ``allauth.socialaccount`` app.  To do so, point ``settings.SOCIALACCOUNT_ADAPTER`` to
    your own class that derives from ``DefaultSocialAccountAdapter`` and override the
    behavior by altering the implementation of the methods according to your own
    needs.
    zvAn account already exists with this email address. Please sign in to that account first, then connect your %s account.zInvalid token.z$Your account has no password set up.z+Your account has no verified email address.z>You cannot disconnect your last remaining third-party account.zDThe third-party account is already connected to a different account.)email_takeninvalid_tokenno_passwordno_verified_emaildisconnect_lastconnected_otherc                 C      dS )a	  
        Invoked just after a user successfully authenticates via a
        social provider, but before the login is actually processed
        (and before the pre_social_login signal is emitted).

        You can use this hook to intervene, e.g. abort the login by
        raising an ImmediateHttpResponse

        Why both an adapter hook and the signal? Intervening in
        e.g. the flow from within a signal handler is bad -- multiple
        handlers may be active and are executed in undetermined order.
        N selfrequestsocialloginr   r   X/var/www/html/kangema/venv/lib/python3.10/site-packages/allauth/socialaccount/adapter.pypre_social_login-   s   z,DefaultSocialAccountAdapter.pre_social_loginNc                 C   s2   t | drtd | j||j|||d dS dS )a  
        Invoked when there is an error in the authentication cycle. In this
        case, pre_social_login will not be reached.

        You can use this hook to intervene, e.g. redirect to an
        educational flow by raising an ImmediateHttpResponse.
        authentication_errorzSadapter.authentication_error() is deprecated, use adapter.on_authentication_error())error	exceptionextra_contextN)hasattrwarningswarnr#   id)r   r   providerr$   r%   r&   r   r   r!   on_authentication_error<   s   

z3DefaultSocialAccountAdapter.on_authentication_errorc                 C   s   t  |S )z3
        Instantiates a new User instance.
        )get_account_adapternew_userr   r   r   r!   r.   X   s   z$DefaultSocialAccountAdapter.new_userc                 C   sB   |j }|  t }|r|||| n||| || |S )zy
        Saves a newly signed up social login. In case of auto-signup,
        the signup form is not available.
        )userset_unusable_passwordr-   	save_userpopulate_usernamesave)r   r   r    formuaccount_adapterr   r   r!   r1   ^   s   
z%DefaultSocialAccountAdapter.save_userc                 C   s   | d}| d}| d}| d}| d}|j}	t|	|p!d t|	t|p*d |p/dd}
t|	d|p;|
d  t|	d|pE|
d	  |	S )
a  
        Hook that can be used to further populate the user instance.

        For convenience, we populate several common fields.

        Note that the user instance being populated represents a
        suggested User instance that represents the social user that is
        in the process of being logged in.

        The User instance need not be completely valid and conflict
        free. For example, verifying whether or not the username
        already exists, is not a responsibility.
        username
first_name	last_nameemailname  r      )getr/   r   r   r
   	partitionr   )r   r   r    datar7   r8   r9   r:   r;   r/   
name_partsr   r   r!   populate_userm   s   




z)DefaultSocialAccountAdapter.populate_userc                 C   s   t d}|S )zp
        Returns the default URL to redirect to after successfully
        connecting a social account.
        socialaccount_connectionsr   )r   r   socialaccounturlr   r   r!   get_connect_redirect_url   s   z4DefaultSocialAccountAdapter.get_connect_redirect_urlreturnc                 C   r   )zg
        Validate whether or not the socialaccount account can be
        safely disconnected.
        Nr   )r   accountaccountsr   r   r!   validate_disconnect   s   z/DefaultSocialAccountAdapter.validate_disconnectc                 C   s
   t j}|S N)r   AUTO_SIGNUP)r   r   r    auto_signupr   r   r!   is_auto_signup_allowed   s   z2DefaultSocialAccountAdapter.is_auto_signup_allowedc                 C   s   t ||S )z
        Checks whether or not the site is open for signups.

        Next to simply returning True/False you can also intervene the
        regular flow by raising an ImmediateHttpResponse
        )r-   is_open_for_signupr   r   r   r!   rP      s   z.DefaultSocialAccountAdapter.is_open_for_signupc                 C   s^   |j }t|}|st|jdkr|jd j}|pdt|pdt|dp$dt|dp*dd}|S )Nr   r<   r8   r9   )r:   r7   r8   r9   )r/   r   lenemail_addressesr:   r   r   )r   r    r/   r:   initialr   r   r!   get_signup_form_initial_data   s   
z8DefaultSocialAccountAdapter.get_signup_form_initial_datac                 C   s
   t ||S rL   )r   )r   modelrA   r   r   r!   r      s   
z0DefaultSocialAccountAdapter.deserialize_instancec                 C   s   t |S rL   )r   )r   instancer   r   r!   r      s   z.DefaultSocialAccountAdapter.serialize_instancec                 C   s   ddl m} g }| }| |}i }|D ]}||jg | q|D ]"}||jg }	|	s6|j	r3q$d g}	|	D ]}|||d}
||
 q8q$|S )Nr   registry)r   app)
allauth.socialaccount.providersrX   get_class_list	list_apps
setdefaultr+   appendr?   r*   	uses_apps)r   r   rX   retprovider_classesappsapps_maprY   provider_classprovider_appsr+   r   r   r!   list_providers   s$   
z*DefaultSocialAccountAdapter.list_providersc                 C   s   ddl m} ||}|du s|jr2| j|||d}|s"||j}|s,td|j |||dS |r?|jr9J ||ddS td| )z_Looks up a `provider`, supporting subproviders by looking up by
        `provider_id`.
        r   rW   Nr+   	client_idzunknown provider: )rY   )rZ   rX   	get_classr_   get_appr+   r   )r   r   r+   rh   rX   rd   rY   r   r   r!   get_provider   s   

z(DefaultSocialAccountAdapter.get_providerc                 C   sr  ddl m} i }|r|j|}n|j }|r%|t|dt|dB }|r-|j|d}|D ]}||jg }|	| q/t
j D ]e\}	}
|
d}|du r]|
d}|du rZqC|g}||	g }|D ]B}||	d}d	D ]}||v r|t||||  qnd
|v rtd |d
 |jd
< |r|j|krqe|r|j|kr|j|krqe|	| qeqCg }| D ]}|| q|S )zSocialApp's can be setup in the database, or, via
        `settings.SOCIALACCOUNT_PROVIDERS`.  This methods returns a uniform list
        of all known apps matching the specified criteria, and blends both
        (db/settings) sources of data.
        r   	SocialApp)r+   )provider_id)rh   APPSNAPP)r;   rn   rh   secretkeysettingscertificate_keyz3'certificate_key' should be moved into app.settings)allauth.socialaccount.modelsrm   objectson_siteallfilterr   r]   r+   r^   r   	PROVIDERSitemsr?   setattrr(   r)   rs   rh   rn   valuesextend)r   r   r+   rh   rm   provider_to_appsdb_appsrY   rb   ppcfgapp_configs
app_configconfigfieldre   r   r   r!   r\      sT   






z%DefaultSocialAccountAdapter.list_appsc                 C   sn   ddl m} | j|||d}t|dkr)dd |D }t|dkr#t|}|d S t|dkr3| |d S )Nr   rl   rg   r   c                 S   s   g | ]
}|j d s|qS )hidden)rs   r?   ).0rY   r   r   r!   
<listcomp>)  s    z7DefaultSocialAccountAdapter.get_app.<locals>.<listcomp>)ru   rm   r\   rQ   r   DoesNotExist)r   r   r+   rh   rm   rb   visible_appsr   r   r!   rj   $  s   z#DefaultSocialAccountAdapter.get_appc                 O   s   t  j|i |S rL   )r-   send_notification_mail)r   argskwargsr   r   r!   r   1  s   z2DefaultSocialAccountAdapter.send_notification_mailc                 C   s(   dd l }| }tj|jtjd|_|S )Nr   )timeout)requestsSession	functoolspartialr   r   REQUESTS_TIMEOUT)r   r   sessionr   r   r!   get_requests_session4  s   z0DefaultSocialAccountAdapter.get_requests_sessionc                 C   s   d}|j r|j jd}|du r| }|dd}t|tr"	 |S t|tr=|dd  }dd |D }||v }|S t	d	)
a  
        Returns ``True`` iff the given email encountered during a social
        login for the given provider is to be assumed verified.

        This can be configured with a ``"verified_email"`` key in the provider
        app settings, or a ``"VERIFIED_EMAIL"`` in the global provider settings
        (``SOCIALACCOUNT_PROVIDERS``).  Both can be set to ``False`` or
        ``True``, or, a list of domains to match email addresses against.
        Nverified_emailVERIFIED_EMAILF@r>   c                 S   s   g | ]}|  qS r   )lower)r   dr   r   r!   r   Q  s    zADefaultSocialAccountAdapter.is_email_verified.<locals>.<listcomp>z!verified_email wrongly configured)
rY   rs   r?   get_settings
isinstanceboollistr@   r   r   )r   r+   r:   r   rs   email_domainverified_domainsr   r   r!   is_email_verified=  s   


z-DefaultSocialAccountAdapter.is_email_verifiedc                 C   s@   d}|j }|jr|jjd}|du rtjp| dd}|S )a,  
        Returns ``True`` iff  authentication by email is active for this login/email.

        This can be configured with a ``"email_authentication"`` key in the provider
        app settings, or a ``"VERIFIED_EMAIL"`` in the global provider settings
        (``SOCIALACCOUNT_PROVIDERS``).
        Nemail_authenticationEMAIL_AUTHENTICATIONF)r+   rY   rs   r?   r   r   r   )r   loginr:   r`   r+   r   r   r!   can_authenticate_by_emailW  s   z5DefaultSocialAccountAdapter.can_authenticate_by_emailstatec                 C   s   ddl m} t|S )a  
        To preserve certain state before the handshake with the provider
        takes place, and be able to verify/use that state later on, a `state`
        parameter is typically passed to the provider. By default, a random
        string sufficies as the state parameter value is actually just a
        reference/pointer to the actual state. You can use this adapter method
        to alter the generation of the `state` parameter.
        r   )STATE_ID_LENGTH)'allauth.socialaccount.internal.statekitr   r   )r   r   r   r   r   r!   generate_state_parami  s   	z0DefaultSocialAccountAdapter.generate_state_param)NNNrL   )rH   N)NN)__name__
__module____qualname____doc___error_messagesr"   r,   r.   r1   rC   rG   rK   rO   rP   rT   r   r   rf   rk   r\   rj   r   r   r   r   dictstrr   r   r   r   r!   r      sN    


	


B	r   c                 C   s   t tj| S rL   )r   r   ADAPTER)r   r   r   r!   r	   w  s   r	   rL   )!r   r(   django.core.exceptionsr   r   django.db.modelsr   django.urlsr   django.utils.cryptor   django.utils.translationr   r   allauth.account.adapterr	   r-   !allauth.account.internal.emailkitr
   allauth.account.utilsr   r   r   allauth.core.internal.adapterr   allauth.core.internal.modelkitr   r   allauth.utilsr   r<   r   r   r   r   r   r!   <module>   s$      e