U
    `9%                     @   sF  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 d dlmZ 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! W n e"k
r   e"dY nX G dd dej#Z$G dd dej%Z&G dd dZ'G dd de'e&Z(G dd dej%Z)G dd dej%Z*dS )    )get_user_model)ValidationError)HttpRequest)NoReverseMatch)gettext_lazy)	HTTPError)serializers)reverse)app_settings)get_adapter)setup_user_email)complete_social_login)SocialAccount)AuthProcess)email_address_existsget_username_max_lengthz,allauth needs to be added to INSTALLED_APPS.c                   @   s   e Zd ZdZG dd dZdS )SocialAccountSerializerzB
    serialize allauth SocialAccounts for use with a REST API
    c                   @   s   e Zd ZeZdZdS )zSocialAccountSerializer.Meta)idprovideruid
last_logindate_joinedN)__name__
__module____qualname__r   modelfields r   r   M/Users/michael/Projects/dj-rest-auth/dj_rest_auth/registration/serializers.pyMeta   s   r   N)r   r   r   __doc__r   r   r   r   r   r      s   r   c                   @   sV   e Zd ZejdddZejdddZejdddZdd Zdd Z	dd	 Z
d
d ZdS )SocialLoginSerializerFT)requiredallow_blankc                 C   s    | j d}t|ts|j}|S )Nrequest)contextget
isinstancer   _request)selfr$   r   r   r   _get_request+   s    
z"SocialLoginSerializer._get_requestc                 C   s$   |   }|j||||d}||_|S )a  
        :param adapter: allauth.socialaccount Adapter subclass.
            Usually OAuthAdapter or Auth2Adapter
        :param app: `allauth.socialaccount.SocialApp` instance
        :param token: `allauth.socialaccount.SocialToken` instance
        :param response: Provider's response for OAuth1. Not used in the
        :returns: A populated instance of the
            `allauth.socialaccount.SocialLoginView` instance
        )response)r*   Zcomplete_logintoken)r)   adapterappr,   r+   r$   social_loginr   r   r   get_social_login1   s    
z&SocialLoginSerializer.get_social_loginc                 C   sX   t |dd | _| jsTzt|jd |  d| _W n" tk
rR   ttdY nX d S )Ncallback_url	_callback)viewnamer$   zDefine callback_url in view)	getattrr1   r	   provider_idr*   r   r   r   _)r)   viewadapter_classr   r   r   set_callback_url@   s    z&SocialLoginSerializer.set_callback_urlc                 C   s  | j d}|  }|s&ttdt|dd }|sDttd||}| |}|d}|d}|rd|i}	|}
|d}|r||	d< n|rR| j	||d t|d	d | _
| j
sttd
| }||}| j
||j|j|j|j| j||j|j|jd
}||}
|
d }d|i}	dd|jfD ]}||
kr2|
| |	|< q2nttd||	}||_z| ||||
}t|| W n$ tk
r   ttdY nX |jstjrt jj |j!j"d# }|rttd|$  |j%|dd |j&j!|d< |S )Nr7   z2View is not defined, pass it as a context variabler8   zDefine adapter_class in viewaccess_tokencodeid_token)r7   r8   client_classzDefine client_class in view)scope_delimiterheaders
basic_authrefresh_tokenz2Incorrect input. access_token or code is required.zIncorrect value)emailz4User is already registered with this e-mail address.T)connectuser)'r%   r&   r*   r   r   r6   r4   get_providerget_appr9   r=   	get_scope	client_idsecretZaccess_token_methodZaccess_token_urlr1   r>   r?   r@   Zget_access_tokenZexpires_in_keyZparse_tokenr.   r0   r   r   is_existingallauth_settingsUNIQUE_EMAILr   objectsfilterrD   rB   existslookupsaveaccount)r)   attrsr7   r$   r8   r-   r.   r:   r;   Ztokens_to_parser,   r<   r   scopeclientkeyZsocial_tokenloginZaccount_existsr   r   r   validateO   s    








zSocialLoginSerializer.validateN)r   r   r   r   	CharFieldr:   r;   r<   r*   r0   r9   rX   r   r   r   r   r!   &   s   r!   c                       s   e Zd Z fddZ  ZS )SocialConnectMixinc                    s   t  j||}tj|jd< |S )z
        Set the social login process state to connect rather than login
        Refer to the implementation of get_social_login in base class and to the
        allauth.socialaccount.helpers module complete_social_login function.
        process)superr0   r   CONNECTstate)r)   argskwargsr/   	__class__r   r   r0      s    z#SocialConnectMixin.get_social_login)r   r   r   r0   __classcell__r   r   ra   r   rZ      s   rZ   c                   @   s   e Zd ZdS )SocialConnectSerializerN)r   r   r   r   r   r   r   rd      s   rd   c                   @   s   e Zd Zeje ejejdZ	ej
ejdZejddZej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 )RegisterSerializer)
max_length
min_lengthr"   )r"   T)
write_onlyc                 C   s   t  |}|S N)r   clean_username)r)   usernamer   r   r   validate_username   s    z$RegisterSerializer.validate_usernamec                 C   s0   t  |}tjr,|r,t|r,ttd|S )Nz6A user is already registered with this e-mail address.)r   clean_emailrK   rL   r   r   r   r6   )r)   rB   r   r   r   validate_email   s    z!RegisterSerializer.validate_emailc                 C   s   t  |S ri   )r   clean_password)r)   passwordr   r   r   validate_password1   s    z%RegisterSerializer.validate_password1c                 C   s"   |d |d krt td|S )N	password1	password2z%The two password fields didn't match.)r   r   r6   )r)   datar   r   r   rX      s    zRegisterSerializer.validatec                 C   s   d S ri   r   )r)   r$   rD   r   r   r   custom_signup   s    z RegisterSerializer.custom_signupc                 C   s*   | j dd| j dd| j dddS )Nrk    rr   rB   )rk   rr   rB   )validated_datar&   )r)   r   r   r   get_cleaned_data   s    z#RegisterSerializer.get_cleaned_datac              
   C   s   t  }||}|  | _|j||| dd}z|j| jd |d W n4 tk
rx } ztjt	|dW 5 d }~X Y nX |
  | || t||g  |S )NF)commitrr   )rD   )detail)r   new_userrx   cleaned_data	save_userro   DjangoValidationErrorr   r   as_serializer_errorrQ   ru   r   )r)   r$   r-   rD   excr   r   r   rQ      s    

zRegisterSerializer.saveN)r   r   r   r   rY   r   rK   USERNAME_MIN_LENGTHUSERNAME_REQUIREDrk   
EmailFieldEMAIL_REQUIREDrB   rr   rs   rl   rn   rq   rX   ru   rx   rQ   r   r   r   r   re      s   	re   c                   @   s   e Zd Ze ZdS )VerifyEmailSerializerN)r   r   r   r   rY   rV   r   r   r   r   r      s   r   N)+django.contrib.authr   django.core.exceptionsr   r~   django.httpr   Zdjango.urls.exceptionsr   django.utils.translationr   r6   Zrequests.exceptionsr   rest_frameworkr   rest_framework.reverser	   allauth.accountr
   rK   Zallauth.account.adapterr   allauth.account.utilsr   Zallauth.socialaccount.helpersr   allauth.socialaccount.modelsr   $allauth.socialaccount.providers.baser   allauth.utilsr   r   ImportErrorModelSerializerr   
Serializerr!   rZ   rd   re   r   r   r   r   r   <module>   s0    :