a
    hy2                  	   @   s8  d dl mZmZmZmZ d dlmZ d dlmZm	Z	 d dl
Z
d dlZd dlZd dlmZmZ d dl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 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% d dl&m'Z' d dlmZm	Z	m(Z( e Z)ee)Z*ej+ej,dd e-e.Z/eddgdZ0eddZ1e!dgdddZ2G dd deZ3d4ddZ4d5d d!Z5d"d# Z6e0j7d$ed%ed&d'd(Z8e0j9d$ed%ed)ed)ed)fee:e:e:d*d+d,Z;e07d-ee<e:d.d/d0Z=e09d-ed)ed)ed)ededfee<e:e:e%e: e%e: d1d2d3Z>dS )6    )	APIRouterFormRequestQuery)Jinja2Templates)	BaseModelfield_validatorN)HTMLResponseRedirectResponse)MIMEText)MIMEMultipart)get_pingconf_vars
open_mysqlget_mysql_creds)contextmanager)CryptContext)	parseaddr)Optional)HTTP_302_FOUND)r   r   model_validatorz)%(asctime)s - %(levelname)s - %(message)s)levelformatz/resetpwZresetpw)prefixtags	templates)	directorybcryptauto2b)schemes
deprecatedZbcrypt__identc                   @   sL   e Zd ZU eed< eed< eed< ededd Zedddd	 Z	d
S )	ResetForm
identifiercaptchacaptcha_codec                 C   s   |r|  std|  S )NzUsername or email is required)strip
ValueError)clsv r)   */wd/v2025.freedom4um.com/routes/resetpw.pyvalidate_identifier,   s    zResetForm.validate_identifierafter)modec                 C   s,   | j   }| j }||kr(td| S )NzIncorrect CAPTCHA input)r#   r%   lowerr$   r&   )selfZcaptcha_normZ	code_normr)   r)   r*   validate_captcha3   s
    
zResetForm.validate_captchaN)
__name__
__module____qualname__str__annotations__r   classmethodr+   r   r0   r)   r)   r)   r*   r!   '   s   
r!      c                    s(   t jt j  d fddt| D S )N c                 3   s   | ]}t  V  qd S Nrandomchoice.0_charsr)   r*   	<genexpr>=       z(generate_captcha_code.<locals>.<genexpr>stringascii_lettersdigitsjoinrangelengthr)   r@   r*   generate_captcha_code;   s    rL      c                    s(   t jt j  d fddt| D S )Nr8   c                 3   s   | ]}t  V  qd S r9   r:   r=   r@   r)   r*   rB   B   rC   z&generate_reset_code.<locals>.<genexpr>rD   rJ   r)   r@   r*   generate_reset_code@   s    rN   c              
   C   sd  dt d  d| d| }dt d  d| d| d	t d  d
	}dt d  d| d| dt d  d	}td}t d  d|d< dt d  |d< | |d< t|d}t|d}	|| ||	 z^tt d d(}
|
|d | g|  W d    n1 s0    Y  t	d|   W n> t
y^ } z$td|  d|   W Y d }~n
d }~0 0 d S )Nzhttps://HomeURLDomainz/resetpw/resetpwconfirm?id=z&code=z-You have requested a password reset for your SiteNamez# account associated with username 'z@'.

Please reset your password by clicking the following link:

zW

If you did not request this reset, please disregard this message.

Best regards,
The z Team
a  <!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"></head>
<body style="font-family: Arial, sans-serif; background-color: #f5f1e9; color: #193048; margin:0; padding:20px;">
  <div style="max-width:600px; margin:auto; padding:20px; background:#fff; border:3px solid #C6BBA3; border-radius:8px;">
    <h1 style="color:#7ed957;">Password Reset Request</h1>
    <p>You have requested a password reset for your <strong>z3</strong> account associated with username <strong>zh</strong>.</p>
    <p>Please reset your password by clicking the link below:</p>
    <p>
      <a href="z" style="color:#ffde59; font-weight:bold; text-decoration:none;">
        Reset Password
      </a>
    </p>
    <hr style="border-color:#C6BBA3;">
    <p>If you did not request this, please disregard this email.</p>
    <p>Best regards,<br>The z# Team</p>
  </div>
</body>
</html>
alternativez Password ResetSubjectznoreply@FromToplainhtmlOutMailServer   zReset email sent to zFailed to send reset email to z: )PingConfr   r   attachsmtplibSMTPsendmail	as_stringloggerdebug	Exceptionerror)email	handle_id
reset_codeusernameZ	reset_urltextrV   msgZpart1Zpart2serverer)   r)   r*   send_reset_emailE   sD    




8rk   /)response_class)requestc                    s6   t  }|| jd< td|  td| d|i dS )Nr$   z"Generated CAPTCHA code for reset: resetpw.htmlr8   rn   r"   r$   errors)rL   sessionr_   r`   r   TemplateResponse)rn   r$   r)   r)   r*   get_resetpw   s    
rt   .)rn   r"   r#   r$   c              
      s  i }d|i}t d|  zt|||d W nJ tyx } z2| D ]}|d d }|d ||< qFW Y d }~n
d }~0 0 | jd}	|  }
|	r|	 nd}t d	|
 d
| d |
|krd|d< |rt	 }|| jd< t
jd| |d ||dddS d }d }d }z8tt}|jdd}d|v rd|d|f | }|r|d }|d }|d }n4|d|f | }|r|d }|d }|d }|sd|d< t	 }|| jd< t
jd| |d ||dddW  d    W S t }|d||f |  t d|  t|||| W d    n1 s60    Y  W nx tjjtfy } zVt d|  t||d< t	 }|| jd< t
jd| |d ||dddW  Y d }~S d }~0 0 t
jd| td ddS )!Nr"   zReceived reset form data: )r"   r#   r$   locr   rh   r$   r8   zCAPTCHA comparison: submitted='z', stored=''z*Incorrect CAPTCHA input (case-insensitive)r#   ro   rp      status_codeT
dictionary@zRSELECT HandleID, Email, Handle FROM Handles WHERE Email = %s AND StatusCode != 'D'HandleIDZEmailHandlezSSELECT HandleID, Email, Handle FROM Handles WHERE Handle = %s AND StatusCode != 'D'z4No account found with this username or email addressz5UPDATE Handles SET ResetCode = %s WHERE HandleID = %sz#Reset code generated for HandleID: zError during reset: databasezresetpw_success.html)rn   rY   )r_   r`   r!   r&   rq   rr   getr%   r.   rL   r   rs   r   mysql_credscursorexecutefetchonerN   commitrk   mysql	connectorErrorra   rb   r4   rY   )rn   r"   r#   r$   rq   	form_datarj   rb   fieldZstored_captchaZsubmitted_captchaZstored_captcha_normZnew_captcha_coderd   rc   rf   connr   rowre   r)   r)   r*   post_resetpw   s    
$



2
r   z/resetpwconfirm)rn   idcodec              
      s   |r|st dtdS zttj}|jdd}|d||f | }|sdt dtdW  d    W S |d|f |  W d    n1 s0    Y  W nH tj	j
tfy } z(td|  t dtdW  Y d }~S d }~0 0 td| |d	d	i d
S )Nz/resetpw?error=invalidurlry   Trz   zdSELECT HandleID, ResetCode FROM Handles WHERE HandleID = %s AND ResetCode = %s AND StatusCode != 'D'z7UPDATE Handles SET ResetCode = NULL WHERE HandleID = %sz Error validating reset confirm: resetpwconfirm.htmlr8   rn   rd   passwordconfirm_passwordrq   )r
   r   r   r   r   r   r   r   r   r   r   ra   r_   rb   r   rs   )rn   r   r   r   r   r   rj   r)   r)   r*   get_resetpw_confirm  s4    
*"r   )rn   rd   r   r   r#   r$   c                    sL  i }||d}t d|  t|dk r2d|d< ||krBd|d< |rjtjd| ||d |d |d	d
dS zfttJ}| }	t	|}
|	
d|
|f |  t d|  W d    n1 s0    Y  W nn tjjtfy> } zLt d|  t||d< tjd| ||d |d |d	d
dW  Y d }~S d }~0 0 tdtdS )N)r   r   z/Received reset confirm form data for HandleID: r7   z+Password must be at least 6 characters longr   zPasswords do not matchr   r   r   rw   rx   zFUPDATE Handles SET Password = %s, ResetCode = NULL WHERE HandleID = %sz(Password reset successful for HandleID: zError updating password: r   z/logoutr   )r_   r`   lenr   rs   r   r   r   pwd_contexthashr   r   r   r   r   ra   rb   r4   r
   r   )rn   rd   r   r   r#   r$   rq   r   r   r   Zhashed_passwordrj   r)   r)   r*   post_resetpw_confirm0  sX    	

2r   )r7   )rM   )?fastapir   r   r   r   fastapi.templatingr   pydanticr   r   rer;   rE   starlette.responsesr	   r
   mysql.connectorr   configparserr[   email.mime.textr   Zemail.mime.multipartr   loggingosutils.pingdatar   r   r   
contextlibr   passlib.contextr   email.utilsr   typingr   Zstarlette.statusr   r   rY   r   basicConfigDEBUG	getLoggerr1   r_   routerr   r   r!   rL   rN   rk   r   rt   postr4   r   intr   r   r)   r)   r)   r*   <module>   s|   



<z#