o
    
xi=                     @   s  d dl m Z mZ d dlmZ d dlmZmZmZmZm	Z	m
Z
mZmZ d dlmZ d dl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 d d
lmZmZ d dlmZmZ d dl m!Z! d dl"Z"d dl#Z#d dl$m%Z% d dl&m'Z' d dl(Z(d dl)Z)de*fddZ+d_ddZ,eddgdZ-edgddZ.eddZ/G dd deZ0G dd  d eZ1G d!d" d"eZ2G d#d$ d$eZ3G d%d& d&eZ4G d'd( d(eZ5G d)d* d*eZ6d+d, Z7d-d. Z8d`d/e9d0ee fd1d2Z:ee/eefd3e*d4efd5d6Z;e-j<d7e0d8eefd9e2d4efd:d;Z=e-j<d<e0d8e eefd=ed4efd>d?Z>e-?d@ee;fdAe!fdBdCZ@e-Ad@ee;eefdDe3dAe!d4efdEdFZBe-<dGee;eefdHe4dAe!d4efdIdJZCe-<dKe
dLee;eefdMe	dAe!d4efdNdOZDe-<dPeefdQe5dRed4efdSdTZEe-<dUeefdVe6d4efdWdXZFe-?dYeeee;fd4edAe!fdZd[ZGe-<dYeeee;fd\e9d4edAe!fd]d^ZHdS )a    )datetime	timedelta)Optional)	APIRouterDependsHTTPExceptionstatus
UploadFileFileRequestForm)PathN)OAuth2PasswordBearerOAuth2PasswordRequestForm)JWTErrorjwt)CryptContext)	BaseModel)Sessionselect)settingsget_session)User)MIMEText)MIMEMultipartpasswordc                 C   s|   t | dk rtdddtd| stdddtd| s$tdddtd	| s0tdd
dtd| s<tdddd S )N     z+Password must be at least 8 characters longstatus_codedetailz[A-Z]z3Password must contain at least one uppercase letterz[a-z]z3Password must contain at least one lowercase letterz\dz(Password must contain at least one digitz
[@$!%*?&#]z?Password must contain at least one special character (@$!%*?&#))lenr   researchr    r%   A/var/www/html/Resume-Parser/resume-parser-inhouse/routers/auth.pyvalidate_password   s   r'      c                    s|   t jt j d  	 d fddt| D }tdd |D r=tdd |D r=tdd |D r=td	d |D r=|S q	)
N@$!%*?&#T c                 3   s    | ]}t  V  qd S N)secretschoice).0ialphabetr%   r&   	<genexpr>$   s    z+generate_random_password.<locals>.<genexpr>c                 s       | ]}|  V  qd S r+   )islowerr.   cr%   r%   r&   r2   %       c                 s   r3   r+   )isupperr5   r%   r%   r&   r2   &   r7   c                 s   r3   r+   )isdigitr5   r%   r%   r&   r2   '   r7   c                 s   s    | ]}|d v V  qdS )r)   Nr%   r5   r%   r%   r&   r2   (   r7   )stringascii_lettersdigitsjoinrangeany)lengthr   r%   r0   r&   generate_random_password!   s   rA   z/authauth)prefixtagsbcryptauto)schemes
deprecatedz
auth/login)tokenUrlc                   @   s&   e Zd ZU eed< eed< eed< dS )Tokenaccess_token
token_typeis_adminN)__name__
__module____qualname__str__annotations__boolr%   r%   r%   r&   rJ   0      
 rJ   c                   @   s   e Zd ZU dZee ed< dS )	TokenDataNusername)rN   rO   rP   rV   r   rQ   rR   r%   r%   r%   r&   rU   5   s   
 rU   c                   @   s6   e Zd ZU eed< eed< eed< dZee ed< dS )
UserSignuprV   emailr   N	full_name)rN   rO   rP   rQ   rR   rY   r   r%   r%   r%   r&   rW   8   s
   
 rW   c                   @   sN   e Zd ZU dZee ed< dZee ed< dZee ed< dZ	ee ed< dS )
UserUpdateNrY   rX   r   phone)
rN   rO   rP   rY   r   rQ   rR   rX   r   r[   r%   r%   r%   r&   rZ   >   s
   
 rZ   c                   @   &   e Zd ZU eed< eed< eed< dS )PasswordChangecurrent_passwordnew_passwordconfirm_passwordNrN   rO   rP   rQ   rR   r%   r%   r%   r&   r]   D   rT   r]   c                   @   s   e Zd ZU eed< dS )ForgotPasswordRequestrX   Nra   r%   r%   r%   r&   rb   I   s   
 rb   c                   @   r\   )ResetPasswordRequesttokenr_   r`   Nra   r%   r%   r%   r&   rc   L   rT   rc   c                 C   s   t | |S r+   )pwd_contextverify)plain_passwordhashed_passwordr%   r%   r&   verify_passwordQ   s   ri   c                 C   s
   t | S r+   )re   hashr$   r%   r%   r&   get_password_hashT   s   
rk   dataexpires_deltac                 C   sR   |   }|rt | }n	t tdd }|d|i tj|tjtj	d}|S )N   minutesexp)	algorithm)
copyr   utcnowr   updater   encoder   
SECRET_KEY	ALGORITHM)rl   rm   	to_encodeexpireencoded_jwtr%   r%   r&   create_access_tokenW   s   r|   rd   sessionc                    s   t tjdddid}ztj| tjtjgd}|d}|d u r"|t	|d}W n	 t
y1   |w |tttj|jk }|d u rH||S )NzCould not validate credentialsWWW-AuthenticateBearerr   r    headers
algorithmssub)rV   )r   r   HTTP_401_UNAUTHORIZEDr   decoder   rw   rx   getrU   r   execr   r   whererV   first)rd   r}   credentials_exceptionpayloadrV   
token_datauserr%   r%   r&   get_current_usera   s&   
 r   z/signup)response_model	user_datac                    s   | tttj| jktj| jkB  }|rtdddt| j	 t
| j	}t| j| j|| jd}|| |  || ttjd}td|ji|d}|dd	S )
Nr   z$Username or email already registeredr   )rV   rX   rh   rY   ro   r   rl   rm   bearer)rK   rL   )r   r   r   r   rV   rX   r   r   r'   r   rk   rY   addcommitrefreshr   r   ACCESS_TOKEN_EXPIRE_MINUTESr|   )r   r}   existing_user
hashed_pwdr   access_token_expiresrK   r%   r%   r&   signupt   s(   ,





r   z/login	form_datac                    s   | tttj| jktj| jkB  }|r t| j|j	s*t
tjdddidttjd}td|ji|d}|d|jd	S )
Nz Incorrect identifier or passwordr~   r   r   ro   r   r   r   )rK   rL   rM   )r   r   r   r   rV   rX   r   ri   r   rh   r   r   r   r   r   r   r|   rM   )r   r}   r   r   rK   r%   r%   r&   login   s&   
r   z/mecurrent_userc                    s   | S r+   r%   )r   r%   r%   r&   read_users_me   s   r   user_updatec                    sh   | j r| j |_ | jr| j|_| jr| j|_| jr$t| j t| j|_|| |  |	| |S r+   )
rY   rX   r[   r   r'   rk   rh   r   r   r   )r   r   r}   r%   r%   r&   update_user   s   


r   z/change-passwordpwdc                    sd   t | j|jstddd| j| jkrtdddt| j t| j|_|| |	  ddiS )Nr   zIncorrect current passwordr   Passwords do not matchmessagezPassword updated successfully)
ri   r^   rh   r   r_   r`   r'   rk   r   r   )r   r   r}   r%   r%   r&   change_password_endpoint   s   

r   z/avatar.filec           	         s   t d}|jddd t | jj }|dvrtddddd	d
 | jD }d|j d| }|| }t|d}t	
| j| W d    n1 sMw   Y  d| |_|| |  || d|jiS )Nzuploads/avatarsT)parentsexist_ok)z.jpgz.jpegz.pdfr   zMOnly JPEG (.jpg, .jpeg) or PDF (.pdf) formats are allowed for profile photos.r   r*   c                 S   s(   g | ]}|  s| s|d v r|qS )z._-)isalphar9   r5   r%   r%   r&   
<listcomp>   s   ( z!upload_avatar.<locals>.<listcomp>user__wbz/uploads/avatars/	photo_url)r   mkdirfilenamesuffixlowerr   r=   idopenshutilcopyfileobjr   profile_photor   r   r   )	r   r   r}   
upload_dirext	safe_namer   	dest_pathbufferr%   r%   r&   upload_avatar   s"   


r   z/forgot-passwordreq_datarequestc              
      s  | tttj| jk }|sddiS tdd}t|jdd|d}t	|j
d}| d	| }tjr;tjsJtd
|j d|  ddiS zWt }tj|d< |j|d< d|d< d| d}	|t|	d tjdkrxttjtj}
nttjtj}
|
  |
tjtj | }|
tj|j| |
  W ddiS  ty } ztd|  dddW  Y d }~S d }~ww )Nr   z;If this email is registered, you will receive a reset link.rn   ro   reset)r   typer   /z/login?reset_token=z+DEBUG: SMTP not configured. Reset Link for : z/Reset link generated (Dev Mode). Check console.FromToz&Password Reset Request - Resume ParserSubjectzUHello,

You requested a password reset. Click the link below to set a new password:

z^

This link will expire in 15 minutes.

If you did not request this, please ignore this email.plain  Failed to send email: z3Failed to send reset email. Please try again later.error)r   r   zCIf your email is registered, you will receive a reset link shortly.)r   r   r   r   rX   r   r   r|   rV   rQ   base_urlrstripr   	SMTP_USERSMTP_PASSWORDprintr   attachr   	SMTP_PORTsmtplibSMTP_SSLSMTP_SERVERSMTPstarttlsr   	as_stringsendmailquit	Exception)r   r   r}   r   expiresrd   r   
reset_linkmsgbodyservertexter%   r%   r&   forgot_password   s@    




r   z/reset-passwordreqc                    s   | j | jkrtdddz&tj| jtjtjgd}|	d}|	d}|d u s,|dkr2tdddW n t
y@   tdd	dw |tttj|k }|sXtd
ddt| j  t| j |_|| |  ddiS )Nr   r   r   r   r   r   r   zInvalid tokenzInvalid or expired tokeni  zUser not foundr   z/Password reset successfully. You can now login.)r_   r`   r   r   r   rd   r   rw   rx   r   r   r   r   r   r   rV   r   r'   rk   rh   r   r   )r   r}   r   rV   rL   r   r%   r%   r&   reset_password_endpoint  s*   



r   z/dashboard/usersc                    s`   |j s
tddd| tt }g }|D ]}||j|j|j	|j
|j|j |jd q|S )N  &Not authorized. Admin access required.r   )r   rV   rX   rY   	is_activerM   
created_at)rM   r   r   r   r   allappendr   rV   rX   rY   r   r   )r}   r   usersresultsur%   r%   r&   
list_users-  s    
	r   r   c              
      s  |j s
tddd| d}| d}| dd}|r|s$tdd	d|}|tttj|ktj|kB 	 }|rBtdd
dt
 }t|}	t||||	d|d}
||
 |  ||
 tjrtjrz[t }tj|d< ||d< d|d< d| d| d| d}|t|d tjdkrttjtj}nttjtj}|  |tjtj | }|tj|| |  W ddiS  ty } zt d|  d|dW  Y d }~S d }~ww t d| d|  d|dS )Nr   r   r   rX   rY   rM   Fr   zName and Email are requiredz#User with this email already existsT)rV   rX   rY   rh   r   rM   r   r   z(Your Account Credentials - Resume Parserr   z
            Hello z,

            An account has been created for you on the Resume Parser Dashboard.
            
            Your login credentials are:
            Email/Username: z
            Password: z

            You can login at: http://localhost:8000/login

            Please change your password after logging in for security.
            r   r   r   z3User created, but failed to send credentials email.)r   r   z)DEBUG: SMTP not configured. Password for r   z-User created (Dev Mode). SMTP not configured.r   z8User created successfully and credentials sent to email.)!rM   r   r   r   r   r   r   rV   rX   r   rA   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r}   r   rX   rY   rM   rV   r   r   rh   r   r   r   r   r   r   r%   r%   r&   add_user_from_dashboardE  s~   


	



	
r   )r(   r+   )Ir   r   typingr   fastapir   r   r   r   r	   r
   r   r   pathlibr   r   fastapi.securityr   r   joser   r   passlib.contextr   pydanticr   sqlmodelr   r   databaser   r   modelsr   r"   r   email.mime.textr   email.mime.multipartr   r,   r:   rQ   r'   rA   routerre   oauth2_schemerJ   rU   rW   rZ   r]   rb   rc   ri   rk   dictr|   r   postr   r   r   r   putr   r   r   r   r   r   r   r%   r%   r%   r&   <module>   s    (


 
 & +