o
    ߭h`                     @   s   d dl Z d dlmZmZmZmZ d dl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 d dlmZmZmZ d dlmZmZ d d	lmZ d
ZdZG dd deejejf ZG dd dZ G dd dZ!eeejejf  Z"dS )    N)AnyGenericOptionalUnion)RequestResponse)OAuth2PasswordRequestForm)
exceptionsmodelsschemas)BaseUserDatabase)
SecretType
decode_jwtgenerate_jwt)PasswordHelperPasswordHelperProtocol)DependencyCallablezfastapi-users:resetzfastapi-users:verifyc                   @   s  e Zd ZU dZeed< dZeed< eZ	e
ed< eed< dZeed< eZe
ed< eejejf ed	< eed
< 	d[d	eejejf d
ee fddZdedejfddZdejdejfddZde
dejfddZde
de
dejfddZ		d\dejdedee dejfd d!Z			d]ddd"d#d$d%e
d&e
de
d'e
d(ee d)ee
 dee d*ed+edejfd,d-Z 			d]d#d$d.ejd%e
d&e
de
d'e
d(ee d)ee
 dee dejfd/d0Z!	d[d.ejdee ddfd1d2Z"d[d3e
dee dejfd4d5Z#	d[d.ejdee ddfd6d7Z$	d[d3e
d8e
dee dejfd9d:Z%		d\d;ej&d.ejdedee dejf
d<d=Z'	d[d.ejdee ddfd>d?Z(d8e
d.e)ejejf ddfd@dAZ*	d[d.ejdee ddfdBdCZ+	d[d.ejdDe,e
ef dee ddfdEdFZ-	d[d.ejd3e
dee ddfdGdHZ.	d[d.ejdee ddfdIdJZ/	d[d.ejd3e
dee ddfdKdLZ0	d[d.ejdee ddfdMdNZ1		d^d.ejdee dOee2 ddfdPdQZ3	d[d.ejdee ddfdRdSZ4	d[d.ejdee ddfdTdUZ5dVe6deej fdWdXZ7d.ejdDe,e
ef dejfdYdZZ8dS )_BaseUserManageraC  
    User management logic.

    :attribute reset_password_token_secret: Secret to encode reset password token.
    :attribute reset_password_token_lifetime_seconds: Lifetime of reset password token.
    :attribute reset_password_token_audience: JWT audience of reset password token.
    :attribute verification_token_secret: Secret to encode verification token.
    :attribute verification_token_lifetime_seconds: Lifetime of verification token.
    :attribute verification_token_audience: JWT audience of verification token.

    :param user_db: Database adapter instance.
    reset_password_token_secreti  %reset_password_token_lifetime_secondsreset_password_token_audienceverification_token_secret#verification_token_lifetime_secondsverification_token_audienceuser_dbpassword_helperNc                 C   s$   || _ |d u rt | _d S || _d S N)r   r   r   )selfr   r    r   Z/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/fastapi_users/manager.py__init__+   s   
zBaseUserManager.__init__valuereturnc                 C   s   t  )z
        Parse a value into a correct models.ID instance.

        :param value: The value to parse.
        :raises InvalidID: The models.ID value is invalid.
        :return: An models.ID object.
        )NotImplementedError)r   r!   r   r   r   parse_id6   s   zBaseUserManager.parse_ididc                    (   | j |I dH }|du rt |S )z
        Get a user by id.

        :param id: Id. of the user to retrieve.
        :raises UserNotExists: The user does not exist.
        :return: A user.
        N)r   getr	   UserNotExists)r   r%   userr   r   r   r'   @   
   zBaseUserManager.get
user_emailc                    r&   )z
        Get a user by e-mail.

        :param user_email: E-mail of the user to retrieve.
        :raises UserNotExists: The user does not exist.
        :return: A user.
        N)r   get_by_emailr	   r(   )r   r+   r)   r   r   r   r,   O   r*   zBaseUserManager.get_by_emailoauth
account_idc                    s*   | j ||I dH }|du rt |S )z
        Get a user by OAuth account.

        :param oauth: Name of the OAuth client.
        :param account_id: Id. of the account on the external OAuth service.
        :raises UserNotExists: The user does not exist.
        :return: A user.
        N)r   get_by_oauth_accountr	   r(   )r   r-   r.   r)   r   r   r   r/   ^   s
   	z$BaseUserManager.get_by_oauth_accountFuser_createsaferequestc                    s   |  |j|I dH  | j|jI dH }|durt |r#| n| }|	d}| j
||d< | j|I dH }| ||I dH  |S )a
  
        Create a user in database.

        Triggers the on_after_register handler on success.

        :param user_create: The UserCreate model to create.
        :param safe: If True, sensitive values like is_superuser or is_verified
        will be ignored during the creation, defaults to False.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :raises UserAlreadyExists: A user already exists with the same e-mail.
        :return: A new user.
        Npasswordhashed_password)validate_passwordr3   r   r,   emailr	   UserAlreadyExistscreate_update_dictcreate_update_dict_superuserpopr   hashcreateon_after_register)r   r0   r1   r2   existing_user	user_dictr3   created_userr   r   r   r<   n   s   

zBaseUserManager.create)associate_by_emailis_verified_by_defaultr   z'BaseUserManager[models.UOAP, models.ID]
oauth_nameaccess_tokenaccount_email
expires_atrefresh_tokenrA   rB   c                   s  ||||||d}
z|  ||I dH }W n\ tjyq   z| |I dH }|s,t | j||
I dH }W Y |S  tjyp   | j }|| j	||	d}| j
|I dH }| j||
I dH }| ||I dH  Y Y |S w w |jD ]}|j|kr|j|kr| j|||
I dH }qu|S )a  
        Handle the callback after a successful OAuth authentication.

        If the user already exists with this OAuth account, the token is updated.

        If a user with the same e-mail already exists and `associate_by_email` is True,
        the OAuth account is associated to this user.
        Otherwise, the `UserNotExists` exception is raised.

        If the user does not exist, it is created and the on_after_register handler
        is triggered.

        :param oauth_name: Name of the OAuth client.
        :param access_token: Valid access token for the service provider.
        :param account_id: models.ID of the user on the service provider.
        :param account_email: E-mail of the user on the service provider.
        :param expires_at: Optional timestamp at which the access token expires.
        :param refresh_token: Optional refresh token to get a
        fresh access token from the service provider.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None
        :param associate_by_email: If True, any existing user with the same
        e-mail address will be associated to this user. Defaults to False.
        :param is_verified_by_default: If True, the `is_verified` flag will be
        set to `True` on newly created user. Make sure the OAuth Provider you're
        using does verify the email address before enabling this flag.
        Defaults to False.
        :return: A user.
        rC   rD   r.   rE   rF   rG   N)r6   r4   is_verified)r/   r	   r(   r,   r7   r   add_oauth_accountr   generater;   r<   r=   oauth_accountsr.   rC   update_oauth_account)r   rC   rD   r.   rE   rF   rG   r2   rA   rB   oauth_account_dictr)   r3   r?   existing_oauth_accountr   r   r   oauth_callback   sN   +	



zBaseUserManager.oauth_callbackr)   c	           
         s@   ||||||d}	| j ||	I dH }| |i |I dH  |S )a  
        Handle the callback after a successful OAuth association.

        We add this new OAuth account to the given user.

        :param oauth_name: Name of the OAuth client.
        :param access_token: Valid access token for the service provider.
        :param account_id: models.ID of the user on the service provider.
        :param account_email: E-mail of the user on the service provider.
        :param expires_at: Optional timestamp at which the access token expires.
        :param refresh_token: Optional refresh token to get a
        fresh access token from the service provider.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None
        :return: A user.
        rH   N)r   rJ   on_after_update)
r   r)   rC   rD   r.   rE   rF   rG   r2   rN   r   r   r   oauth_associate_callback   s   	z(BaseUserManager.oauth_associate_callbackc                    s\   |j st |jrt t|j|j| jd}t	|| j
| j}| |||I dH  dS )a{  
        Start a verification request.

        Triggers the on_after_request_verify handler on success.

        :param user: The user to verify.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :raises UserInactive: The user is inactive.
        :raises UserAlreadyVerified: The user is already verified.
        )subr6   audN)	is_activer	   UserInactiverI   UserAlreadyVerifiedstrr%   r6   r   r   r   r   on_after_request_verifyr   r)   r2   
token_datatokenr   r   r   request_verify  s   zBaseUserManager.request_verifyr\   c           	         s   zt || j| jg}W n tjy   t w z
|d }|d }W n ty.   t w z
| |I dH }W n tj	yE   t w z| 
|}W n tjyY   t w ||jkrct |jrjt | |ddiI dH }| ||I dH  |S )a  
        Validate a verification request.

        Changes the is_verified flag of the user to True.

        Triggers the on_after_verify handler on success.

        :param token: The verification token generated by request_verify.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :raises InvalidVerifyToken: The token is invalid or expired.
        :raises UserAlreadyVerified: The user is already verified.
        :return: The verified user.
        rS   r6   NrI   T)r   r   r   jwt
PyJWTErrorr	   InvalidVerifyTokenKeyErrorr,   r(   r$   	InvalidIDr%   rI   rW   _updateon_after_verify)	r   r\   r2   datauser_idr6   r)   	parsed_idverified_userr   r   r   verify2  sB   
zBaseUserManager.verifyc                    sV   |j st t|j| j|j| jd}t	|| j
| j}| |||I dH  dS )aK  
        Start a forgot password request.

        Triggers the on_after_forgot_password handler on success.

        :param user: The user that forgot its password.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :raises UserInactive: The user is inactive.
        )rS   password_fgptrT   N)rU   r	   rV   rX   r%   r   r;   r4   r   r   r   r   on_after_forgot_passwordrZ   r   r   r   forgot_passwordf  s   zBaseUserManager.forgot_passwordr3   c                    s   zt || j| jg}W n tjy   t w z
|d }|d }W n ty.   t w z| |}W n tj	yB   t w | 
|I dH }| j|j|\}	}
|	s[t |jsbt | |d|iI dH }| ||I dH  |S )a?  
        Reset the password of a user.

        Triggers the on_after_reset_password handler on success.

        :param token: The token generated by forgot_password.
        :param password: The new password to set.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :raises InvalidResetPasswordToken: The token is invalid or expired.
        :raises UserInactive: The user is inactive.
        :raises InvalidPasswordException: The password is invalid.
        :return: The user with updated password.
        rS   rj   Nr3   )r   r   r   r^   r_   r	   InvalidResetPasswordTokenra   r$   rb   r'   r   verify_and_updater4   rU   rV   rc   on_after_reset_password)r   r\   r3   r2   re   rf   password_fingerprintrg   r)   valid_password_fingerprint_updated_userr   r   r   reset_password  s@   zBaseUserManager.reset_passworduser_updatec                    sB   |r|  }n| }| ||I dH }| |||I dH  |S )a
  
        Update a user.

        Triggers the on_after_update handler on success

        :param user_update: The UserUpdate model containing
        the changes to apply to the user.
        :param user: The current user to update.
        :param safe: If True, sensitive values like is_superuser or is_verified
        will be ignored during the update, defaults to False
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        :return: The updated user.
        N)r8   r9   rc   rQ   )r   ru   r)   r1   r2   updated_user_datars   r   r   r   update  s   
zBaseUserManager.updatec                    s<   |  ||I dH  | j|I dH  | ||I dH  dS )z
        Delete a user.

        :param user: The user to delete.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        N)on_before_deleter   deleteon_after_deleter   r)   r2   r   r   r   ry     s   zBaseUserManager.deletec                       dS )aU  
        Validate a password.

        *You should overload this method to add your own validation logic.*

        :param password: The password to validate.
        :param user: The user associated to this password.
        :raises InvalidPasswordException: The password is invalid.
        :return: None if the password is valid.
        Nr   )r   r3   r)   r   r   r   r5        z!BaseUserManager.validate_passwordc                    r|   )a  
        Perform logic after successful user registration.

        *You should overload this method to add your own logic.*

        :param user: The registered user
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        Nr   r{   r   r   r   r=        z!BaseUserManager.on_after_registerupdate_dictc                    r|   )aT  
        Perform logic after successful user update.

        *You should overload this method to add your own logic.*

        :param user: The updated user
        :param update_dict: Dictionary with the updated user fields.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        Nr   )r   r)   r   r2   r   r   r   rQ        zBaseUserManager.on_after_updatec                    r|   )aI  
        Perform logic after successful verification request.

        *You should overload this method to add your own logic.*

        :param user: The user to verify.
        :param token: The verification token.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        Nr   r   r)   r\   r2   r   r   r   rY     r}   z'BaseUserManager.on_after_request_verifyc                    r|   )a  
        Perform logic after successful user verification.

        *You should overload this method to add your own logic.*

        :param user: The verified user.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        Nr   r{   r   r   r   rd   #  r~   zBaseUserManager.on_after_verifyc                    r|   )a^  
        Perform logic after successful forgot password request.

        *You should overload this method to add your own logic.*

        :param user: The user that forgot its password.
        :param token: The forgot password token.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        Nr   r   r   r   r   rk   1  r}   z(BaseUserManager.on_after_forgot_passwordc                    r|   )a#  
        Perform logic after successful password reset.

        *You should overload this method to add your own logic.*

        :param user: The user that reset its password.
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        Nr   r{   r   r   r   ro   @  r~   z'BaseUserManager.on_after_reset_passwordresponsec                    r|   )a2  
        Perform logic after user login.

        *You should overload this method to add your own logic.*

        :param user: The user that is logging in
        :param request: Optional FastAPI request
        :param response: Optional response built by the transport.
        Defaults to None
        Nr   )r   r)   r2   r   r   r   r   on_after_loginN  r   zBaseUserManager.on_after_loginc                    r|   a  
        Perform logic before user delete.

        *You should overload this method to add your own logic.*

        :param user: The user to be deleted
        :param request: Optional FastAPI request that
        triggered the operation, defaults to None.
        Nr   r{   r   r   r   rx   `  r~   z BaseUserManager.on_before_deletec                    r|   r   r   r{   r   r   r   rz   n  r~   zBaseUserManager.on_after_deletecredentialsc                    s   z|  |jI dH }W n tjy   | j|j Y dS w | j|j|j\}}|s.dS |dur>| j	
|d|iI dH  |S )z
        Authenticate and return a user following an email and a password.

        Will automatically upgrade password hash if necessary.

        :param credentials: The user credentials.
        Nr4   )r,   usernamer	   r(   r   r;   r3   rn   r4   r   rw   )r   r   r)   verifiedupdated_password_hashr   r   r   authenticate|  s   
zBaseUserManager.authenticatec              	      s   i }|  D ]J\}}|dkr3||jkr3z| |I d H  t  tjy2   ||d< d|d< Y qw |dkrM|d urM| ||I d H  | j||d< q|||< q| j	
||I d H S )Nr6   FrI   r3   r4   )itemsr6   r,   r	   r7   r(   r5   r   r;   r   rw   )r   r)   r   validated_update_dictfieldr!   r   r   r   rc     s$   

zBaseUserManager._updater   )FN)NNN)NN)9__name__
__module____qualname____doc__r   __annotations__r   intRESET_PASSWORD_TOKEN_AUDIENCEr   rX   r   VERIFY_USER_TOKEN_AUDIENCEr   r   r
   UPIDr   r   r    r   r$   r'   r,   r/   r   UCboolr   r<   UOAPrP   rR   r]   ri   rl   rt   UUrw   ry   r   r5   r=   dictrQ   rY   rd   rk   ro   r   r   rx   rz   r   r   rc   r   r   r   r   r      s  
 


-


[	

+
5

:
 












&r   c                   @   s    e Zd ZdedejfddZdS )UUIDIDMixinr!   r"   c              
   C   s@   t |tjr|S zt|W S  ty } zt |d }~ww r   )
isinstanceuuidUUID
ValueErrorr	   rb   r   r!   er   r   r   r$     s   
zUUIDIDMixin.parse_idN)r   r   r   r   r   r   r$   r   r   r   r   r     s    r   c                   @   s   e Zd ZdedefddZdS )IntegerIDMixinr!   r"   c              
   C   s@   t |tr	t zt|W S  ty } zt |d }~ww r   )r   floatr	   rb   r   r   r   r   r   r   r$     s   


zIntegerIDMixin.parse_idN)r   r   r   r   r   r$   r   r   r   r   r     s    r   )#r   typingr   r   r   r   r^   fastapir   r   fastapi.securityr   fastapi_usersr	   r
   r   fastapi_users.dbr   fastapi_users.jwtr   r   r   fastapi_users.passwordr   r   fastapi_users.typesr   r   r   r   r   r   r   r   UserManagerDependencyr   r   r   r   <module>   s*          

