U
    )`0                     @   s  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mZ d dlmZ d	ejkrd d
lmZ d dlmZ nd d
lmZ d dlmZ zd dlmZ W n  ek
r   d dlmZ Y nX ddlm Z  ddl!m"Z" e Z#G dd dej$Z%G dd dej&Z'G dd dej&Z(G dd dej$Z)G dd de)Z*G dd dej$Z+G dd dej$Z,G dd  d ej$Z-d!S )"    )settings)authenticateget_user_model)SetPasswordForm)
exceptions)	force_str)import_string)r   serializers)ValidationErrorallauth)default_token_generator)url_str_to_user_pk)urlsafe_base64_decode)gettext_lazy   )PasswordResetForm)
TokenModelc                   @   s   e Zd ZejdddZejdddZejddidZdd Z	d	d
 Z
dd Zdd Zdd Zdd Zdd Zedd Zedd Zdd ZdS )LoginSerializerFT)requiredallow_blank
input_typepassword)stylec                 K   s   t | jd f|S )Nrequest)r   context)selfkwargs r   @/Users/michael/Projects/dj-rest-auth/dj_rest_auth/serializers.pyr   !   s    zLoginSerializer.authenticatec                 C   s2   d }|r|r| j ||d}ntd}t||S )Nemailr   z$Must include "email" and "password".r   _r   r
   )r   r    r   usermsgr   r   r   _validate_email$   s    
zLoginSerializer._validate_emailc                 C   s.   |r|r| j ||d}ntd}t||S )Nusernamer   z'Must include "username" and "password".r!   )r   r'   r   r#   r$   r   r   r   _validate_username/   s
    
z"LoginSerializer._validate_usernamec                 C   sF   |r|r| j ||d}n*|r0|r0| j ||d}ntd}t||S )Nr   r&   z9Must include either "username" or "email" and "password".r!   )r   r'   r    r   r#   r$   r   r   r   _validate_username_email8   s    
z(LoginSerializer._validate_username_emailc                 C   sN   ddl m} |j|jjkr&| ||S |j|jjkr@| ||S | |||S )Nr   app_settings)	allauth.accountr+   AUTHENTICATION_METHODAuthenticationMethodEMAILr%   USERNAMEr(   r)   )r   r'   r    r   r+   r   r   r   get_auth_user_using_allauthC   s    z+LoginSerializer.get_auth_user_using_allauthc                 C   sH   |r2zt jj|d }W n t jk
r0   Y nX |rD| |d|S d S )N)email__iexact )	UserModelobjectsgetget_usernameDoesNotExistr)   )r   r'   r    r   r   r   r   get_auth_user_using_ormQ   s    z'LoginSerializer.get_auth_user_using_ormc                 C   sR   dt jkrDz| |||W S  tjk
rB   td}t|Y nX | |||S )z
        Retrieve the auth user from given POST payload by using
        either `allauth` auth scheme or bare Django auth scheme.

        Returns the authenticated user instance if credentials are correct,
        else `None` will be returned
        r   +Unable to log in with provided credentials.)	r   INSTALLED_APPSr1   url_exceptionsNoReverseMatchr"   r   r
   r9   )r   r'   r    r   r$   r   r   r   get_auth_user]   s    
zLoginSerializer.get_auth_userc                 C   s   | j std}t|d S )NzUser account is disabled.)	is_activer"   r   r
   )r#   r$   r   r   r   validate_auth_user_statusp   s    z)LoginSerializer.validate_auth_user_statusc                 C   sB   ddl m} |j|jjkr>| jj| jd}|js>t	
tdd S )Nr   r*   r    zE-mail is not verified.)r,   r+   EMAIL_VERIFICATIONEmailVerificationMethod	MANDATORYemailaddress_setr6   r    verifiedr	   r
   r"   )r#   r+   email_addressr   r   r   "validate_email_verification_statusv   s
    z2LoginSerializer.validate_email_verification_statusc                 C   sl   | d}| d}| d}| |||}|sBtd}t|| | dtjkr`| | ||d< |S )Nr'   r    r   r:   zdj_rest_auth.registrationr#   )	r6   r>   r"   r   r
   r@   r   r;   rH   )r   attrsr'   r    r   r#   r$   r   r   r   validate~   s    






zLoginSerializer.validateN)__name__
__module____qualname__r	   	CharFieldr'   
EmailFieldr    r   r   r%   r(   r)   r1   r9   r>   staticmethodr@   rH   rJ   r   r   r   r   r      s   	

r   c                   @   s   e Zd ZdZG dd dZdS )TokenSerializerz%
    Serializer for Token model.
    c                   @   s   e Zd ZeZdZdS )zTokenSerializer.Meta)keyN)rK   rL   rM   r   modelfieldsr   r   r   r   Meta   s   rU   N)rK   rL   rM   __doc__rU   r   r   r   r   rQ      s   rQ   c                   @   s*   e Zd ZdZedd ZG dd dZdS )UserDetailsSerializerz!
    User model w/o password
    c                 C   s*   dt jkr| S ddlm} | | } | S )Nzallauth.accountr   )get_adapter)r   r;   allauth.account.adapterrX   clean_username)r'   rX   r   r   r   validate_username   s
    
z'UserDetailsSerializer.validate_usernamec                   @   st   e Zd Zg Zeedr"eej eedr8eej eedrLed eedr`ed eZ	deZ
dZdS )	zUserDetailsSerializer.MetaUSERNAME_FIELDEMAIL_FIELD
first_name	last_namepkrA   N)r`   )rK   rL   rM   extra_fieldshasattrr4   appendr\   r]   rS   rT   read_only_fieldsr   r   r   r   rU      s   





rU   N)rK   rL   rM   rV   rP   r[   rU   r   r   r   r   rW      s   

rW   c                   @   s0   e Zd ZdZe Ze Ze Z	dd Z
dS )JWTSerializerz,
    Serializer for JWT authentication.
    c                 C   s4   t tdi }t|dd}||d | jdj}|S )z
        Required to allow using custom USER_DETAILS_SERIALIZER in
        JWTSerializer. Defining it here to avoid circular imports
        REST_AUTH_SERIALIZERSUSER_DETAILS_SERIALIZERz.dj_rest_auth.serializers.UserDetailsSerializerr#   )r   )getattrr   r   r6   r   data)r   objrest_auth_serializersZJWTUserDetailsSerializerZ	user_datar   r   r   get_user   s    zJWTSerializer.get_userN)rK   rL   rM   rV   r	   rN   access_tokenrefresh_tokenSerializerMethodFieldr#   rl   r   r   r   r   re      s
   re   c                   @   s    e Zd ZdZe Ze ZdS )JWTSerializerWithExpirationzB
    Serializer for JWT authentication with expiration times.
    N)rK   rL   rM   rV   r	   DateTimeFieldaccess_token_expirationrefresh_token_expirationr   r   r   r   rp      s   rp   c                   @   s8   e Zd ZdZe ZeZdZ	dd Z
dd Zdd ZdS )	PasswordResetSerializerz<
    Serializer for requesting a password reset e-mail.
    Nc                 C   s   i S )z5Override this method to change default e-mail optionsr   r   r   r   r   get_email_options   s    z)PasswordResetSerializer.get_email_optionsc                 C   s,   | j | jd| _| j s(t| jj|S )N)ri   )password_reset_form_classinitial_data
reset_formis_validr	   r
   errors)r   valuer   r   r   validate_email   s    
z&PasswordResetSerializer.validate_emailc                 C   sD   | j d}| ttd|td}||   | jj	f | d S )Nr   DEFAULT_FROM_EMAIL)	use_https
from_emailr   token_generator)
r   r6   	is_securerh   r   r   updaterv   ry   save)r   r   optsr   r   r   r      s    zPasswordResetSerializer.save)rK   rL   rM   rV   r	   rO   r    r   rw   ry   rv   r}   r   r   r   r   r   rt      s   rt   c                   @   s`   e Zd ZdZejddZejddZe Ze Z	e
Zi ZdZdZdd Zdd Zd	d
 ZdS )PasswordResetConfirmSerializerz=
    Serializer for confirming a password reset attempt.
       
max_lengthNc                 C   s   d S Nr   r   rI   r   r   r   custom_validation  s    z0PasswordResetConfirmSerializer.custom_validationc                 C   s   z$t t|d }tjj|d| _W n, ttttj	fk
rP   t
ddgiY nX t| j|d srt
ddgi| | | j| j|d| _| j st
| jj|S )Nuid)r`   zInvalid valuetokenr#   ri   )r   uid_decoderr4   _default_managerr6   r#   	TypeError
ValueErrorOverflowErrorr8   r
   r   check_tokenr   set_password_form_classset_password_formrz   r	   r{   )r   rI   r   r   r   r   rJ     s    
 
z'PasswordResetConfirmSerializer.validatec                 C   s
   | j  S r   )r   r   ru   r   r   r   r   .  s    z#PasswordResetConfirmSerializer.save)rK   rL   rM   rV   r	   rN   new_password1new_password2r   r   r   r   _errorsr#   r   r   rJ   r   r   r   r   r   r     s   r   c                       s`   e Zd ZejddZejddZejddZeZ	dZ
 fddZdd Zdd	 Zd
d Z  ZS )PasswordChangeSerializerr   r   Nc                    s^   t tdd| _t tdd| _t j|| | js<| jd | j	d| _
t | j
dd | _d S )NOLD_PASSWORD_FIELD_ENABLEDFLOGOUT_ON_PASSWORD_CHANGEold_passwordr   r#   )rh   r   old_password_field_enabledlogout_on_password_changesuper__init__rT   popr   r6   r   r#   )r   argsr   	__class__r   r   r   ;  s        z!PasswordChangeSerializer.__init__c                 C   s6   | j | j| j| f}t|r2td}t||S )NzAYour old password was entered incorrectly. Please enter it again.)r   r#   check_passwordallr"   r	   r
   )r   r|   Zinvalid_password_conditionserr_msgr   r   r   validate_old_passwordJ  s    
z.PasswordChangeSerializer.validate_old_passwordc                 C   s.   | j | j|d| _| j s*t| jj|S )Nr   )r   r#   r   rz   r	   r
   r{   r   r   r   r   rJ   V  s     
z!PasswordChangeSerializer.validatec                 C   s.   | j   | js*ddlm} || j| j d S )Nr   )update_session_auth_hash)r   r   r   django.contrib.authr   r   r#   )r   r   r   r   r   r   _  s    
zPasswordChangeSerializer.save)rK   rL   rM   r	   rN   r   r   r   r   r   r   r   r   rJ   r   __classcell__r   r   r   r   r   2  s   	r   N).django.confr   r   r   r   django.contrib.auth.formsr   django.urlsr   r<   django.utils.encodingr   django.utils.module_loadingr   rest_frameworkr	   rest_framework.exceptionsr
   r;   allauth.account.formsr   allauth.account.utilsr   r   django.contrib.auth.tokensdjango.utils.httpr   django.utils.translationr   r"   ImportErrorformsr   modelsr   r4   
Serializerr   ModelSerializerrQ   rW   re   rp   rt   r   r   r   r   r   r   <module>   s6   
w
#$,