U
    #iW                     @  s
  d dl mZ 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mZmZmZmZmZmZ d dlmZ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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,m-Z-m.Z. G dd dZ/dS )    )annotations)partial)dumpsloads)Timer)time)AnyCallableDictOptionalTupleUnioncast)parse_qsurlparse)uuid4   )COOKIE_OPTIONSDEFAULT_HEADERS
GOTRUE_URLSTORAGE_KEY)APIError)
model_dumpmodel_validate)AuthChangeEventCookieOptionsProviderSessionSubscriptionUserUserAttributesUserAttributesDict   )SyncGoTrueAPI)SyncMemoryStorageSyncSupportedStoragec                   @  s`  e Zd Zei dde eeddddd
dddddd	d
dddddddZd dddZ	ddddZ
ddddZddddZdddddddddddddddZdddddddddddddd dddd!d"	d#d$Zdd%ddddd&d'd(Zd)dd*d+Zd,dd-d.Zd/dd0d1Zd2d3d4d5d6Zdd/d7d8d9Zdd/d:d;d<Zdd=ddd/d>d?d@ZdddAdBZdddCdDdEZdFdGdHdIdJZdddd/dKdLdMZddd/dNdOdPZdQddddRdSdTZdUddVdWZdddXdYZdddZd[Zdd\dd/d7d]d^Z d_dd`dadbZ!d/ddcdddeZ"d/ddcdfdgZ#dddhdiZ$djddkdldmZ%dS )nSyncGoTrueClientTNF)
urlheadersauto_refresh_tokenpersist_sessionlocal_storagecookie_optionsapireplace_default_headersverifyproxystrzDict[str, str]boolr%   r   zOptional[SyncGoTrueAPI]zOptional[str]None)r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   returnc       
         C  sp   | drtd i | _d| _d| _d| _|| _|| _|| _|rDi nt	}|||||	|
d}|pht
f || _dS )aD  Create a new client

        url : str
            The URL of the GoTrue server.
        headers : Dict[str, str]
            Any additional headers to send to the GoTrue server.
        auto_refresh_token : bool
            Set to "true" if you want to automatically refresh the token before
            expiring.
        persist_session : bool
            Set to "true" if you want to automatically save the user session
            into local storage.
        local_storage : SupportedStorage
            The storage engine to use for persisting the session.
        cookie_options : CookieOptions
            The options for the cookie.
        verify: bool
            Verify SSL, True by default, False disables verification.
        proxy: str
            HTTP Proxy string or None, None by default, None disables proxy.
        zhttp://z`Warning:

DO NOT USE HTTP IN PRODUCTION FOR GOTRUE EVER!
GoTrue REQUIRES HTTPS to work securely.N)r'   r(   r,   r/   r0   )
startswithprintstate_change_emittersrefresh_token_timercurrent_usercurrent_sessionr)   r*   r+   r   r#   r-   )selfr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   Zempty_or_default_headersargs r=   7/tmp/pip-unpacked-wheel-b8wmx3ip/gotrue/_sync/client.py__init__   s&    #
zSyncGoTrueClient.__init__)r4   c                 C  s   | S Nr=   r;   r=   r=   r>   	__enter__V   s    zSyncGoTrueClient.__enter__c                 C  s   |    d S r@   )close)r;   Zexc_tZexc_vexc_tbr=   r=   r>   __exit__Y   s    zSyncGoTrueClient.__exit__c                 C  s   | j   d S r@   )r-   rC   rA   r=   r=   r>   rC   \   s    zSyncGoTrueClient.closec                 C  s   |    |   dS )z/Recover the current session from local storage.N)_recover_session_recover_and_refreshrA   r=   r=   r>   init_recover_   s    zSyncGoTrueClient.init_recover)emailphonepasswordredirect_todatazOptional[Dict[str, Any]]zUnion[Session, User])rI   rJ   rK   rL   rM   r4   c                C  s   |    |r&|r&| jj||||d}n2|rB|rB| jj|||d}n|sPtdntdt|tr|| j|d | jt	j
d |S )a7  Creates a new user. If email and phone are provided, email will be
        used and phone will be ignored.

        Parameters
        ---------
        email : Optional[str]
            The user's email address.
        phone : Optional[str]
            The user's phone number.
        password : Optional[str]
            The user's password.
        redirect_to : Optional[str]
            A URL or mobile address to send the user to after they are confirmed.
        data : Optional[Dict[str, Any]]
            Optional user metadata.

        Returns
        -------
        response : Union[Session, User]
            A logged-in session if the server has "autoconfirm" ON
            A user if the server has "autoconfirm" OFF

        Raises
        ------
        APIError
            If an error occurs.
        )rI   rK   rL   rM   )rJ   rK   rM   z(Password must be defined, can't be None.z3Email or phone must be defined, both can't be None.sessionevent)_remove_sessionr-   Zsign_up_with_emailZsign_up_with_phone
ValueError
isinstancer   _save_session_notify_all_subscribersr   	SIGNED_IN)r;   rI   rJ   rK   rL   rM   responser=   r=   r>   sign_upd   s*    $  

zSyncGoTrueClient.sign_up)rI   rJ   rK   refresh_tokenproviderrL   scopescreate_userzOptional[Provider]zOptional[Union[Session, str]])	rI   rJ   rK   rZ   r[   rL   r\   r]   r4   c          
      C  s   |    |r4|r"| j|||d}	q| jj||d}	n`|r^|rL| j||d}	q| jj||d}	n6|rv| j|d | j}	n|r| j|||d}	nt	d|	S )a.  Log in an existing user, or login via a third-party provider.
        If email and phone are provided, email will be used and phone will be ignored.

        Parameters
        ---------
        email : Optional[str]
            The user's email address.
        phone : Optional[str]
            The user's phone number.
        password : Optional[str]
            The user's password.
        refresh_token : Optional[str]
            A valid refresh token that was returned on login.
        provider : Optional[Provider]
            One of the providers supported by GoTrue.
        redirect_to : Optional[str]
            A URL or mobile address to send the user to after they are confirmed.
        scopes : Optional[str]
            A space-separated list of scopes granted to the OAuth application.

        Returns
        -------
        response : Optional[Union[Session, str]]
            If only email are provided between the email and password,
            None is returned and send magic link to email

            If email and password are provided, a logged-in session is returned.

            If only phone are provided between the phone and password,
            None is returned and send message to phone

            If phone and password are provided, a logged-in session is returned.

            If refresh_token is provided, a logged-in session is returned.

            If provider is provided, an redirect URL is returned.

            Otherwise, error is raised.

        Raises
        ------
        APIError
            If an error occurs.
        rI   rK   rL   )rI   r]   rJ   rK   )rJ   r]   rZ   r[   rL   r\   zLEmail, phone, refresh_token, or provider must be defined, all can't be None.)
rR   _handle_email_sign_inr-   Zsend_magic_link_email_handle_phone_sign_inZsend_mobile_otp_call_refresh_tokenr:   _handle_provider_sign_inrS   )
r;   rI   rJ   rK   rZ   r[   rL   r\   r]   rX   r=   r=   r>   sign_in   s@    8  zSyncGoTrueClient.sign_in)rL   )rJ   tokenrL   r4   c                C  sB   |    | jj|||d}t|tr>| j|d | jtjd |S )a^  Log in a user given a User supplied OTP received via mobile.

        Parameters
        ----------
        phone : str
            The user's phone number.
        token : str
            The user's OTP.
        redirect_to : Optional[str]
            A URL or mobile address to send the user to after they are confirmed.

        Returns
        -------
        response : Union[Session, User]
            A logged-in session if the server has "autoconfirm" ON
            A user if the server has "autoconfirm" OFF

        Raises
        ------
        APIError
            If an error occurs.
        )rJ   rg   rL   rN   rP   )	rR   r-   Zverify_mobile_otprT   r   rU   rV   r   rW   )r;   rJ   rg   rL   rX   r=   r=   r>   
verify_otp   s    
zSyncGoTrueClient.verify_otpzOptional[User]c                 C  s   | j S )z4Returns the user data, if there is a logged in user.)r9   rA   r=   r=   r>   user&  s    zSyncGoTrueClient.userzOptional[Session]c                 C  s   | j S )z8Returns the session data, if there is an active session.)r:   rA   r=   r=   r>   rO   *  s    zSyncGoTrueClient.sessionr   c                 C  s   | j std|  S )zForce refreshes the session.

        Force refreshes the session including the user data incase it was
        updated in a different session.
        Not logged in.)r:   rS   rd   rA   r=   r=   r>   refresh_session.  s    z SyncGoTrueClient.refresh_sessionz)Union[UserAttributesDict, UserAttributes]r   )
attributesr4   c                C  sd   | j stdt|tr$tf |}n|}| jj| j j|d}|| j _| j	| j d | j
tjd |S )a  Updates user data, if there is a logged in user.

        Parameters
        ----------
        attributes : UserAttributesDict | UserAttributes
            Attributes to update, could be: email, password, email_change_token, data

        Returns
        -------
        response : User
            The updated user data.

        Raises
        ------
        APIError
            If an error occurs.
        rj   )jwtrl   rN   rP   )r:   rS   rT   dictr    r-   Zupdate_useraccess_tokenri   rU   rV   r   ZUSER_UPDATED)r;   rl   Zattributes_to_updaterX   r=   r=   r>   update8  s    
zSyncGoTrueClient.update)rZ   r4   c                C  s,   | j j|d}| j|d | jtjd |S )aT  Sets the session data from refresh_token and returns current Session

        Parameters
        ----------
        refresh_token : str
            A JWT token

        Returns
        -------
        response : Session
            A logged-in session

        Raises
        ------
        APIError
            If an error occurs.
        r`   rN   rP   )r-   refresh_access_tokenrU   rV   r   rW   r;   rZ   rX   r=   r=   r>   set_session[  s    zSyncGoTrueClient.set_session)ro   r4   c             	   C  sT   t |ddddddd}| jrD| jj|_| jj|_| jj|_| jj|_| j|d |S )a}  Overrides the JWT on the current client. The JWT will then be sent in
        all subsequent network requests.

        Parameters
        ----------
        access_token : str
            A JWT token

        Returns
        -------
        response : Session
            A logged-in session

        Raises
        ------
        APIError
            If an error occurs.
        ZbearerNro   
token_typeri   
expires_in
expires_atrZ   provider_tokenrN   )r   r:   rv   rw   rZ   rx   rU   )r;   ro   rO   r=   r=   r>   set_authr  s     	



zSyncGoTrueClient.set_auth)store_session)r'   rz   r4   c             	   C  s  t |}t|j}|d}|d}|d}|d}|d}	|rVt|d d|rb|d sltdd|rx|d std	d|	r|	d std
d|r|d stddztt t|d  }
W n tk
r   tddY nX | j	j
|d d}|d}t|d |	d |t|d |
|d |r4|d ndd}|r| j|d |d}| jtjd |r|d dkr| jtjd |S )a  Gets the session data from a URL string.

        Parameters
        ----------
        url : str
            The URL string.
        store_session : bool
            Optionally store the session in the browser

        Returns
        -------
        response : Session
            A logged-in session

        Raises
        ------
        APIError
            If an error occurs.
        error_descriptionro   rv   rZ   ru   r   i  zNo access_token detected.zNo refresh_token detected.zNo token_type detected.zNo expires_in detected.zInvalid expires_in.rm   rx   Nrt   rN   typerP   Zrecovery)r   r   querygetr   roundr   intrS   r-   Zget_userr   rU   rV   r   rW   ZPASSWORD_RECOVERY)r;   r'   rz   rM   r~   r{   ro   rv   rZ   ru   rw   rX   rx   rO   Zrecovery_moder=   r=   r>   get_session_from_url  sN    











	
z%SyncGoTrueClient.get_session_from_urlc                 C  s>   d}| j r| j j}|   | jtjd |r:| jj|d dS )zLog the user out.NrP   r|   )r:   ro   rR   rV   r   Z
SIGNED_OUTr-   sign_out)r;   ro   r=   r=   r>   r     s    zSyncGoTrueClient.sign_out)idr4   c                C  s   | j | dS )z Unsubscribe from a subscription.N)r7   pop)r;   r   r=   r=   r>   _unsubscribe  s    zSyncGoTrueClient._unsubscribez4Callable[[AuthChangeEvent, Optional[Session]], None]r   )callbackr4   c                C  s0   t  }t||t| j|jdd}|| j|j< |S )a  Receive a notification every time an auth event happens.

        Parameters
        ----------
        callback : Callable[[AuthChangeEvent, Optional[Session]], None]
            The callback to call when an auth event happens.

        Returns
        -------
        subscription : Subscription
            A subscription object which can be used to unsubscribe itself.

        Raises
        ------
        APIError
            If an error occurs.
        )r   )r   r   Zunsubscribe)r   r   r   r   hexr7   )r;   r   Z	unique_idZsubscriptionr=   r=   r>   on_auth_state_change  s    z%SyncGoTrueClient.on_auth_state_change)rI   rK   rL   r4   c                C  s0   | j j|||d}| j|d | jtjd |S )z Sign in with email and password.r^   rN   rP   )r-   Zsign_in_with_emailrU   rV   r   rW   )r;   rI   rK   rL   rX   r=   r=   r>   rb     s    z&SyncGoTrueClient._handle_email_sign_in)rJ   rK   r4   c                C  s.   | j j||d}| j|d | jtjd |S )z Sign in with phone and password.r_   rN   rP   )r-   Zsign_in_with_phonerU   rV   r   rW   )r;   rJ   rK   rX   r=   r=   r>   rc     s    z&SyncGoTrueClient._handle_phone_sign_inr   )r[   rL   r\   r4   c                C  s   | j j|||dS )zSign in with provider.ra   )r-   Zget_url_for_provider)r;   r[   rL   r\   r=   r=   r>   re     s
    z)SyncGoTrueClient._handle_provider_sign_inz"Optional[Tuple[Session, int, int]]c                 C  sv   | j t}|sdS t|}|d}|d}|rrt|trr|rrt|trrtt	|}t|}t
t }|||fS dS )zRecover common logicNrO   rw   )r+   Zget_itemr   r   r   rT   r   rn   r   r   r   r   )r;   jsonrM   Zsession_rawZexpires_at_rawrO   rw   time_nowr=   r=   r>   _recover_common*  s$    



z SyncGoTrueClient._recover_commonc                 C  s@   |   }|sdS |\}}}||kr<| j|d | jtjd dS )z-Attempts to get the session from LocalStorageNrN   rP   )r   rU   rV   r   rW   r;   resultrO   rw   r   r=   r=   r>   rF   =  s    
z!SyncGoTrueClient._recover_sessionc                 C  s   |   }|sdS |\}}}||k r`| jr`|jr`z| j|jd W q tk
r\   |   Y qX n6||k sr|rr|js||   n| j|d | jt	j
d dS )z4Recovers the session from LocalStorage and refreshesNr`   rN   rP   )r   r)   rZ   rd   r   rR   ri   rU   rV   r   rW   r   r=   r=   r>   rG   G  s    

z%SyncGoTrueClient._recover_and_refreshr`   c                C  s`   |d kr | j r| j j}ntd| jjtt|d}| j|d | jt	j
d | jt	jd |S )Nz2No current session and refresh_token not supplied.r`   rN   rP   )r:   rZ   rS   r-   rq   r   r1   rU   rV   r   ZTOKEN_REFRESHEDrW   rr   r=   r=   r>   rd   X  s    
z$SyncGoTrueClient._call_refresh_tokenr   )rQ   r4   c                C  s"   | j  D ]}||| j q
dS )z0Notify all subscribers that auth event happened.N)r7   valuesr   r:   )r;   rQ   valuer=   r=   r>   rV   d  s    z(SyncGoTrueClient._notify_all_subscribers)rO   r4   c                C  sd   || _ |j| _|jrHtt }|j| }|dkr4dnd}| j|| d | jr`|jr`| j|d dS )zSave session to client.<   g      ?)r   rN   N)	r:   ri   r9   rw   r   r   _start_auto_refresh_tokenr*   _persist_session)r;   rO   r   Z	expire_inZrefresh_duration_before_expiresr=   r=   r>   rU   i  s    

zSyncGoTrueClient._save_sessionc                C  s*   t ||jd}| jtt|td d S )N)rO   rw   )default)r   rw   r+   Zset_itemr   r   r1   )r;   rO   rM   r=   r=   r>   r   w  s    z!SyncGoTrueClient._persist_sessionc                 C  s,   d| _ d| _| jr| j  | jt dS )zRemove the session.N)r:   r9   r8   cancelr+   Zremove_itemr   rA   r=   r=   r>   rR   {  s
    
z SyncGoTrueClient._remove_sessionfloat)r   r4   c                C  s>   | j r| j   |dks| js"d S t|| j| _ | j   d S )Nr   )r8   r   r)   r   rd   start)r;   r   r=   r=   r>   r     s    
z*SyncGoTrueClient._start_auto_refresh_token)&__name__
__module____qualname__r   r$   r   Z	parse_objr   r?   rB   rE   rC   rH   rY   rf   rh   ri   rO   rk   rp   rs   ry   r   r   r   r   rb   rc   re   r   rF   rG   rd   rV   rU   r   rR   r   r=   r=   r=   r>   r&      sn   &9@"b(
#(A

r&   N)0
__future__r   	functoolsr   r   r   r   	threadingr   r   typingr   r	   r
   r   r   r   r   urllib.parser   r   uuidr   	constantsr   r   r   r   
exceptionsr   Zhelpersr   r   typesr   r   r   r   r   r   r    r!   r-   r#   Zstorager$   r%   r&   r=   r=   r=   r>   <module>   s   $(
