o
    <‘ðid0  ã                   @   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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   úW/root/parts/websockify/install/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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                    sž   |ˆ_ zt ¡ ‰W n' ty0   t ¡ ‰t ¡ ‰‡‡fdd„}tj|dd�}| ¡  ˆ 	¡  Y nw t ¡ ‰ ‡ ‡‡fdd„}ˆ 
|¡ˆ_t d¡ ˆ  	¡  ˆjS )Nc                      s   t  ˆ ¡ ˆ ¡  ˆ  ¡  d S r   )ÚasyncioÚset_event_loopÚsetÚrun_foreverr   )ÚloopÚ
loop_readyr   r   Ú
start_loop˜   s   
z&TokenManager.start.<locals>.start_loopT)ÚtargetÚdaemonc                      s$   zˆ  ˆ¡ W ˆ  ¡  d S ˆ  ¡  w r   )Ú_renew_tokenrO   r   )Ú	init_doner   rL   r   r   Úrenew_with_callbackª   s   z/TokenManager.start.<locals>.renew_with_callbackúToken manager started)rD   rM   Úget_running_loopÚRuntimeErrorÚnew_event_loopÚ	threadingÚEventÚThreadÚstartÚwaitÚcall_soon_threadsaferE   rG   rH   rI   )r   rK   rL   rS   ÚthreadrX   r   )rW   rQ   rR   r   rL   r   r`   ˆ   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éè  rY   )rD   rM   rZ   r^   Ú_async_to_sync_wrapperÚ_renew_token_asyncÚ
call_laterrE   rG   rH   ra   rI   )r   rK   rd   re   rL   rQ   Ú
init_eventÚ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é   rf   r   )rA   Úrequest_tokenr	   rF   rB   r=   r,   r   r.   Úacquire_tokenr   ©r   Úforce_refreshÚtokenÚer   r   r   rq   Ö   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 rn   )rA   rp   r	   rF   rB   r=   r,   rM   r   r.   Úacquire_token_asyncr   rr   r   r   r   rv   ä   s   €
ÿ€ø
z TokenManager.acquire_token_asyncÚexpire_dateÚ
issue_datec                 C   s4   |   |¡}|  ||¡}t||ƒ}|dk rdS |d S )Nr   rf   )Ú_delay_for_lower_refreshÚ_delay_for_ratio_refreshÚmin)r   rw   rx   Ú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 ©Nrf   )rB   r;   r   Únowr   ÚutcÚ	timestamp)r   rw   r   r   r   ry   û   s   ÿþÿz%TokenManager._delay_for_lower_refreshc                 C   s6   || }||| j  ¡   }|| t tj¡ ¡ d  S r€   )rB   r:   r   r�   r   r‚   rƒ   )r   rw   rx   Ú	token_ttlÚrefresh_beforer   r   r   rz     s   ÿÿþÿz%TokenManager._delay_for_ratio_refreshc              
   C   s  zh| j dd�}|  | ¡  ¡ | ¡  ¡ ¡}| ¡  ¡ rtdƒ‚| jjdu r-t	 
d¡ W dS |sJz
| j | ¡ ¡ W n tyI } zt|ƒ‚d}~ww |dkrQW dS t ¡ }| || j¡| _t	 d|› d�¡ |W S  ty‰ } z| jjdu rx|‚| j |¡ W Y d}~dS d}~ww )	zq
        Task to renew token from identity provider.
        Schedules renewal tasks based on token TTL.
        T©rs   úRequested token is expiredNú@No registered callback for token renewal task. Renewal cancelledr   ú Next token renewal scheduled in ú seconds)rq   r   Ú	get_tokenÚget_expires_at_msÚget_received_at_msÚ
is_expiredr
   rD   r   rG   Úwarningr(   rM   rZ   ri   rV   rC   rH   r!   )r   rL   Ú	token_resr~   ru   rQ   r   r   r   rV     s@   

þÿ€ÿ€üzTokenManager._renew_tokenrj   c              
   Ã   sx  �z²zƒ| 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Š   )rv   r   r‹   rŒ   r�   rŽ   r
   rD   r   rG   r�   rO   r(   rM   rZ   rg   rh   rH   ri   r!   )r   rL   rj   r�   r~   ru   rQ   rk   r   r   r   rh   7  sZ   €

þÿÿí€ÿÿö€ü€ÿ
ÿzTokenManager._renew_token_async)F)Fr   F)FN)r"   r#   r$   r   r1   r   rJ   r   Úboolr   r`   r0   rl   rI   r   rq   rv   r   ry   rz   rV   rM   r^   rh   r   r   r   r   r>   y   sT    ÿ
ÿ
ýþý

ü3ûþýüû

ú*ÿÿÿ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)rQ   )rM   Úensure_futurer   ©ÚargsÚ	coro_funcÚkwargsrQ   r   r   rk   q  s   z'_async_to_sync_wrapper.<locals>.wrappedr   )rQ   r•   r”   r–   rk   r   r“   r   rg   f  s   rg   )rM   Úloggingr]   r   r   Útimer   Útypingr   r   r   r   Úredis.auth.errr	   r
   Úredis.auth.idpr   Úredis.auth.tokenr   Ú	getLoggerr"   rG   r   r)   r1   r>   rg   r   r   r   r   Ú<module>   s     
9 n