o
    >h.                     @   s   d dl Z d dl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
mZ d dlmZmZ d dlmZ d dlmZ eeZG dd	 d	ZG d
d dZG dd dZG dd dZdd Zde jfddZdS )    N)datetimetimezone)sleep)Any	AwaitableCallableUnion)RequestTokenErrTokenRenewalErr)IdentityProviderInterface)TokenResponsec                   @   s   e Zd ZdZdd Zedeeegdf e	f fddZ
e
jdeeegdf e	f ddfd	dZ
edeeegdf e	f fd
dZejdeeegdf e	f ddfddZdS )CredentialsListenerzz
    Listeners that will be notified on events related to credentials.
    Accepts callbacks and awaitable callbacks.
    c                 C   s   d | _ d | _d S N)_on_next	_on_errorself r   x/var/www/vedio/testing/chatpythonscript.ninositsolution.com/env/lib/python3.10/site-packages/redis/auth/token_manager.py__init__      
zCredentialsListener.__init__returnNc                 C      | j S r   r   r   r   r   r   on_next      zCredentialsListener.on_nextcallbackc                 C   
   || _ d S r   r   r   r   r   r   r   r         
c                 C   r   r   r   r   r   r   r   on_error!   r   zCredentialsListener.on_errorc                 C   r   r   r    r   r   r   r   r!   %   r   )__name__
__module____qualname____doc__r   propertyr   r   r   r   r   setter	Exceptionr!   r   r   r   r   r      s    "&"*r   c                   @   s:   e Zd ZdedefddZdefddZdefdd	Zd
S )RetryPolicymax_attemptsdelay_in_msc                 C   s   || _ || _d S r   )r*   r+   )r   r*   r+   r   r   r   r   +   r   zRetryPolicy.__init__r   c                 C   r   )zW
        Retry attempts before exception will be thrown.

        :return: int
        )r*   r   r   r   r   get_max_attempts/      zRetryPolicy.get_max_attemptsc                 C   r   )zI
        Delay between retries in seconds.

        :return: int
        )r+   r   r   r   r   get_delay_in_ms7   r-   zRetryPolicy.get_delay_in_msN)r"   r#   r$   intfloatr   r,   r.   r   r   r   r   r)   *   s    r)   c                   @   s^   e Zd ZdedededefddZdefdd	Zdefd
dZdefddZ	defddZ
dS )TokenManagerConfigexpiration_refresh_ratiolower_refresh_bound_millis%token_request_execution_timeout_in_msretry_policyc                 C   s   || _ || _|| _|| _d S r   )_expiration_refresh_ratio_lower_refresh_bound_millis&_token_request_execution_timeout_in_ms_retry_policy)r   r2   r3   r4   r5   r   r   r   r   A   s
   
zTokenManagerConfig.__init__r   c                 C   r   )a&  
        Represents the ratio of a token's lifetime at which a refresh should be triggered. # noqa: E501
        For example, a value of 0.75 means the token should be refreshed
        when 75% of its lifetime has elapsed (or when 25% of its lifetime remains).

        :return: float
        )r6   r   r   r   r   get_expiration_refresh_ratioO   s   	z/TokenManagerConfig.get_expiration_refresh_ratioc                 C   r   )a  
        Represents the minimum time in milliseconds before token expiration
        to trigger a refresh, in milliseconds.
        This value sets a fixed lower bound for when a token refresh should occur,
        regardless of the token's total lifetime.
        If set to 0 there will be no lower bound and the refresh will be triggered
        based on the expirationRefreshRatio only.

        :return: int
        )r7   r   r   r   r   get_lower_refresh_bound_millisZ   s   z1TokenManagerConfig.get_lower_refresh_bound_millisc                 C   r   )z
        Represents the maximum time in milliseconds to wait
        for a token request to complete.

        :return: int
        )r8   r   r   r   r   )get_token_request_execution_timeout_in_msg   s   z<TokenManagerConfig.get_token_request_execution_timeout_in_msc                 C   r   )z_
        Represents the retry policy for token requests.

        :return: RetryPolicy
        )r9   r   r   r   r   get_retry_policyp   r-   z#TokenManagerConfig.get_retry_policyN)r"   r#   r$   r0   r/   r)   r   r:   r;   r<   r=   r   r   r   r   r1   @   s    
	r1   c                   @   s  e Zd ZdedefddZdd Z	d&ded	ed
e	g df fddZ
			d'dededed	ed
e	g df f
ddZdd Zd&d
efddZd&d
efddZdeded
efddZdefddZdedefdd Z	d(d	ed!ejfd"d#Z	d(d	ed!ejfd$d%ZdS ))TokenManageridentity_providerconfigc                 C   s(   || _ || _d | _d | _d | _d| _d S )Nr   )_idp_config_next_timer	_listener_init_timer_retries)r   r?   r@   r   r   r   r   z   s   
zTokenManager.__init__c                 C   s   t d |   d S )NzToken manager are disposed)loggerinfostopr   r   r   r   __del__   s   
zTokenManager.__del__Flistenerskip_initialr   Nc                 C   s   || _ zt }W n ty#   t }tjt|fdd}|  Y nw t	 }|
d| j||| _td t| |  | jS )NT)targetargsdaemonr   Token manager started)rD   asyncioget_running_loopRuntimeErrornew_event_loop	threadingThread_start_event_loop_in_threadstartEvent
call_later_renew_tokenrE   rG   rH   run_coroutine_threadsafewaitresultrI   )r   rK   rL   loopthread
init_eventr   r   r   rX      s"   	

zTokenManager.startr   block_for_initialinitial_delay_in_msc                    s\   || _ t }t }t|| j||}||d || _t	d |r+|
 I d H  | jS )N  rP   )rD   rQ   rR   rY   _async_to_sync_wrapper_renew_token_asyncrZ   rE   rG   rH   r]   rI   )r   rK   rb   rc   rL   r_   ra   wrappedr   r   r   start_async   s   

zTokenManager.start_asyncc                 C   s0   | j d ur
| j   | jd ur| j  d S d S r   )rE   cancelrC   r   r   r   r   rI      s
   


zTokenManager.stopc              
   C   s   z| j |}W n5 ty= } z)| j| j  k r7|  jd7  _t| j  d  | 	|W  Y d }~S |d }~ww d| _t
|S N   rd   r   )rA   request_tokenr	   rF   rB   r=   r,   r   r.   acquire_tokenr   r   force_refreshtokener   r   r   rm      s   zTokenManager.acquire_tokenc              
      s   z| j |}W n< tyE } z0| j| j  k r?|  jd7  _t| j 	 d I d H  | 
|I d H W  Y d }~S |d }~ww d| _t|S rj   )rA   rl   r	   rF   rB   r=   r,   rQ   r   r.   acquire_token_asyncr   rn   r   r   r   rr      s   

z TokenManager.acquire_token_asyncexpire_date
issue_datec                 C   s4   |  |}| ||}t||}|dk rdS |d S )Nr   rd   )_delay_for_lower_refresh_delay_for_ratio_refreshmin)r   rs   rt   delay_for_lower_refreshdelay_for_ratio_refreshdelayr   r   r   _calculate_renewal_delay   s   

z%TokenManager._calculate_renewal_delayc                 C   s"   || j   ttj d  S Nrd   )rB   r;   r   nowr   utc	timestamp)r   rs   r   r   r   ru      s   z%TokenManager._delay_for_lower_refreshc                 C   s6   || }||| j    }|| ttj d  S r|   )rB   r:   r   r}   r   r~   r   )r   rs   rt   	token_ttlrefresh_beforer   r   r   rv      s   z%TokenManager._delay_for_ratio_refreshra   c              
   C   sn  zz| j dd}| |  |  }|  r td| jjdu r7t	
d W W |r5|  dS dS |sTz
| j|  W n tyS } zt|d}~ww |dkrdW W |rb|  dS dS t }||| j| _t	d| d |W W |r|  S S  ty } z| jjdu r|| j| W Y d}~nd}~ww W |r|  dS dS |r|  w w )	zq
        Task to renew token from identity provider.
        Schedules renewal tasks based on token TTL.
        Tro   Requested token is expiredN@No registered callback for token renewal task. Renewal cancelledr    Next token renewal scheduled in  seconds)rm   r{   	get_tokenget_expires_at_msget_received_at_ms
is_expiredr
   rD   r   rG   warningsetr(   rQ   rR   rZ   r[   rC   rH   r!   )r   rL   ra   	token_resrz   rq   r_   r   r   r   r[      s^   



zTokenManager._renew_tokenc              
      sx  zz| j ddI dH }| |  |  }|  r$td| jjdu r;t	
d W W |r9|  dS dS |s[z| j| I dH  W n tyZ } zt|d}~ww |dkrkW W |ri|  dS dS t }t|| j}t	d| d ||| W n# ty } z| jjdu r|| j|I dH  W Y d}~nd}~ww W |r|  dS dS |r|  w w )	zx
        Async task to renew tokens from identity provider.
        Schedules renewal tasks based on token TTL.
        Tr   Nr   r   r   r   r   )rr   r{   r   r   r   r   r
   rD   r   rG   r   r   r(   rQ   rR   re   rf   rH   rZ   r!   )r   rL   ra   r   rz   rq   r_   rg   r   r   r   rf   (  sZ   


zTokenManager._renew_token_async)F)Fr   F)FN)r"   r#   r$   r   r1   r   rJ   r   boolr   rX   r0   rh   rI   r   rm   rr   r{   ru   rv   rQ   rY   r[   rf   r   r   r   r   r>   y   s^    






/r>   c                    s    fdd}|S )a  
    Wraps an asynchronous function so it can be used with loop.call_later.

    :param loop: The event loop in which the coroutine will be executed.
    :param coro_func: The coroutine function to wrap.
    :param args: Positional arguments to pass to the coroutine function.
    :param kwargs: Keyword arguments to pass to the coroutine function.
    :return: A regular function suitable for loop.call_later.
    c                      s   t j i d d S )N)r_   )rQ   ensure_futurer   rN   	coro_funckwargsr_   r   r   rg   b  s   z'_async_to_sync_wrapper.<locals>.wrappedr   )r_   r   rN   r   rg   r   r   r   re   W  s   re   
event_loopc                 C   s   t |  |   dS )z
    Starts event loop in a thread.
    Used to be able to schedule tasks using loop.call_later.

    :param event_loop:
    :return:
    N)rQ   set_event_looprun_forever)r   r   r   r   rW   i  s   
rW   )rQ   loggingrU   r   r   timer   typingr   r   r   r   redis.auth.errr	   r
   redis.auth.idpr   redis.auth.tokenr   	getLoggerr"   rG   r   r)   r1   r>   re   AbstractEventLooprW   r   r   r   r   <module>   s"    
9 _