
    h              
       j   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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mZ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#m$Z$ d dl%m&Z& d dl'Z'd dl(Z( e	dgd      Z) e       Z*de+de+de,fdZ-de+de+fdZ.d0de/de+fdZ0dedefdZ1dede+de+defd Z2dede+de+deee,f   fd!Z3dedefd"Z4dede+de+defd#Z5d1d$e6d%eedf   fd&Z7d1d$e6d%eedf   fd'Z8ded(e/d)e+fd*Z9 ee*       ee      fd+edefd,Z: ee:      fd-efd.Z; ee;      fd-efd/Z<y)2    )datetime	timedeltatimezone)Union)JWTErrorjwt)CryptContext)DependsHTTPExceptionstatus)
HTTPBearerHTTPAuthorizationCredentials)Session)get_db)
SECRET_KEY	ALGORITHMACCESS_TOKEN_EXPIRE_MINUTESREFRESH_TOKEN_EXPIRE_DAYS)User)
UserCreate)UserRole)generate_otpset_otp_expiry
verify_otpclear_otp_for_user)
send_emailNbcryptauto)schemes
deprecatedplain_passwordhashed_passwordreturnc                 .    t         j                  | |      S )z"Verify a password against its hash)pwd_contextverify)r!   r"   s     >/home/www/40-admission.kofcorporation.com/app/services/auth.pyverify_passwordr(      s    no>>    passwordc                 ,    t         j                  |       S )zHash a password)r%   hash)r*   s    r'   get_password_hashr-      s    H%%r)   lengthc                     t         j                  t         j                  z   t         j                  z   dj	                  fdt        |       D              }|S )zHGenerate a random password with letters, digits, and special characters. c              3   H   K   | ]  }t        j                          y wN)secretschoice).0i
characterss     r'   	<genexpr>z+generate_random_password.<locals>.<genexpr>#   s     Iaw~~j1Is   ")stringascii_lettersdigitspunctuationjoinrange)r.   r*   r7   s     @r'   generate_random_passwordr?       s?    %%58J8JJJwwI5=IIHOr)   dbuserc                 *  K   | j                  t              j                  t        j                  |j                  k(        j	                         }|rt        dd      t        |j                        }t               }t        |j                  |j                  ||j                  d      }| j                  |       | j                          | j                  |       t        | ||       t        |j                  gdd|        d	{    |S 7 w)
zCreate a new user  zEmail already registeredstatus_codedetailF)email	full_namer"   role	is_activezVerify your email addresszYour OTP is: rG   subjectbodyN)queryr   filterrG   firstr   r-   r*   r   rH   rI   addcommitrefreshr   r   )r@   rA   db_userr"   otp_codes        r'   create_userrV   &   s     hhtn##DJJ$**$<=CCEG4NOO'6O~Hjj..'YYG FF7OIIKJJw2w)
zzl+XJ'   Ns   DD
DDrG   otpc                    | j                  t              j                  t        j                  |k(        j	                         }|st        dd      |j                  rt        dd      |j                  r0|j                  t        j                  t        j                        k  rt        dd      t        ||      st        dd      d|_        t        | |       |S )	z.Verify OTP for registration and activate user.  User not foundrD   rC   zUser is already activeOTP has expiredInvalid OTPTrN   r   rO   rG   rP   r   rJ   
otp_expiryr   nowr   utcr   r   r@   rG   rW   rA   s       r'   verify_registration_otprb   D   s    88D>  u!45;;=D4DEE~~4LMM??dooX\\0JJ4EFFdC MBBDNr4 Kr)   c                     | j                  t              j                  t        j                  |k(        j	                         }|syt        ||j                        sy|S )z)Authenticate a user by email and passwordF)rN   r   rO   rG   rP   r(   r"   )r@   rG   r*   rA   s       r'   authenticate_userrd   T   sJ    88D>  u!45;;=D8T%9%9:Kr)   c                    K   t               }t        | ||       t        |j                  gdd|        d{    y7 w)z Generate and send OTP for login.zYour login OTPzYour login OTP is: rK   N)r   r   r   rG   )r@   rA   rU   s      r'   send_login_otprf   ]   sA     ~H2tX&
zzl "8*-  s   7A?Ac                    | j                  t              j                  t        j                  |k(        j	                         }|st        dd      |j                  st        dd      |j                  r0|j                  t        j                  t        j                        k  rt        dd      t        ||      st        dd      t        | |       |S )zVerify OTP for login.rY   rZ   rD   rC   zUser is not activer[   r\   r]   ra   s       r'   verify_login_otprh   g   s    88D>  u!45;;=D4DEE>>4HII??dooX\\0JJ4EFFdC MBBr4 Kr)   dataexpires_deltac                 F   | j                         }|r't        j                  t        j                        |z   }n4t        j                  t        j                        t        t              z   }|j                  d|i       t        j                  |t        t              }|S )zCreate a JWT access token)minutesexp	algorithm)copyr   r_   r   r`   r   r   updater   encoder   r   ri   rj   	to_encodeexpireencoded_jwts        r'   create_access_tokenrw   v   sn    		Ihll+m;hll+i@[.\\eV_%**Y
iHKr)   c                 F   | j                         }|r't        j                  t        j                        |z   }n4t        j                  t        j                        t        t              z   }|j                  d|i       t        j                  |t        t              }|S )zCreate a JWT refresh token)daysrm   rn   )rp   r   r_   r   r`   r   r   rq   r   rr   r   r   rs   s        r'   create_refresh_tokenrz      sn    		Ihll+m;hll+i=V.WWeV_%**Y
iHKr)   user_idrefresh_tokenc                     | j                  t              j                  t        j                  |k(        j	                         }|r(||_        | j                          | j                  |       |S )z#Update the refresh token for a user)rN   r   rO   idrP   r|   rR   rS   )r@   r{   r|   rA   s       r'   update_refresh_tokenr      sQ    88D>  G!34::<D*
		


4Kr)   credentialsc                 ~  K   | j                   }t        t        j                  dddi      }	 t	        j
                  |t        t        g      }|j                  d      }||	 |j                  t              j                  t        j                  |k(        j                         }|||S # t        $ r |w xY ww)z#Get the current user from JWT tokenzCould not validate credentialszWWW-AuthenticateBearer)rE   rF   headers)
algorithmssub)r   r   r   HTTP_401_UNAUTHORIZEDr   decoder   r   getr   rN   r   rO   rG   rP   )r   r@   tokencredentials_exceptionpayloadrG   rA   s          r'   get_current_userr      s     ##E)00/#X.
$**UJI;G[['='' 
 88D>  u!45;;=D|##K  $##$s   +B=6B. $A
B=.B::B=current_userc                 @   K   | j                   st        dd      | S w)zGet the current active userrC   zInactive userrD   )rJ   r   r   s    r'   get_current_active_userr      s"     !!ODDs   c                 v    | j                   t        j                  k7  rt        t        j
                  d      | S )zRequire admin rolezNot enough permissionsrD   )rI   r   ADMINr   r   HTTP_403_FORBIDDENr   s    r'   require_adminr      s5    HNN*11+
 	
 r)   )   r2   )=r   r   r   typingr   joser   r   passlib.contextr	   fastapir
   r   r   fastapi.securityr   r   sqlalchemy.ormr   app.core.databaser   app.core.configr   r   r   r   app.models.userr   app.schemas.userr   app.models.baser   app.services.otp_servicer   r   r   r   app.services.email_servicer   r3   r9   r%   oauth2_schemestrboolr(   r-   intr?   rV   rb   rd   rf   rh   dictrw   rz   r   r   r   r    r)   r'   <module>r      s   2 2   ( 2 2 E " $ i i   ' $ a a 1   H:&A ?C ?# ?$ ?& & &S # '  <  # $  ' #  tTzAR W D   3 4 	d 	5D3I 		t 	E)T/4J 	W s 3  HO}G]mtu{m| (D cj * 8??O7P   (//F'G  r)   