
    ɯeiP>                    N   d dl mZ d dlZd dlZd dlZd dlZ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 d dlmZ d dlmZmZ dd	lmZmZmZ dd
lmZmZ ddlmZmZ  ej>                  e       Z! ed      Z" G d de      Z# G d de$      Z%e G d d             Z&d,dZ' G d de
      Z( G d de$      Z) G d de)      Z* G d de)      Z+ G d de)      Z, G d de)      Z- G d  d!e)      Z. G d" d#e)      Z/ G d$ d%e)      Z0 G d& d'e(      Z1 G d( d)e(      Z2 G d* d+e(      Z3y)-    )annotationsN)ABCabstractmethod)	dataclass)Enum)Path)AnyTypeVar   )IS_LINUXIS_MACOS
IS_WINDOWS)FileLockFileLockError)installed_keyringkeyringTc                       e Zd ZdZdZdZdZdZy)	TokenTypeaj  Types of credentials that can be cached to avoid repeated authentication.

    - ID_TOKEN: SSO identity token from external browser/Okta authentication
    - MFA_TOKEN: Multi-factor authentication token to skip MFA prompts
    - OAUTH_ACCESS_TOKEN: Short-lived OAuth access token
    - OAUTH_REFRESH_TOKEN: Long-lived OAuth token to obtain new access tokens
    ID_TOKEN	MFA_TOKENOAUTH_ACCESS_TOKENOAUTH_REFRESH_TOKENN)__name__
__module____qualname____doc__r   r   r   r        a/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/connector/token_cache.pyr   r      s     HI-/r   r   c                      e Zd Zy)_InvalidTokenKeyErrorNr   r   r   r   r   r    r"   r"   '       r   r"   c                  <    e Zd ZU ded<   ded<   ded<   d	dZd	dZy)
TokenKeystruserhostr   	tokenTypec                *   t        | j                        dk(  rt        d      t        | j                        dk(  rt        d      | j                  j	                          d| j                  j	                          d| j
                  j                   S )Nr   zInvalid key, host is emptyzInvalid key, user is empty:)lenr)   r"   r(   upperr*   valueselfs    r    
string_keyzTokenKey.string_key1   st    tyy>Q'(DEEtyy>Q'(DEE))//#$Adiioo&7%8$..:N:N9OPPr   c                    t        j                         }|j                  | j                         j	                  d             |j                         S )Nutf-8)encoding)hashlibsha256updater2   encode	hexdigest)r1   ms     r    hash_keyzTokenKey.hash_key8   s;    NN	"))7);<{{}r   N)returnr'   )r   r   r   __annotations__r2   r<   r   r   r    r&   r&   +   s    
I
IQr   r&   c                j    t         j                  |        t        d| z   t        j                         y )Nz	Warning: )file)loggerwarningprintsysstderr)rB   s    r    _warnrF   >   s!    
NN7	+
cjj1r   c                  Z    e Zd ZdZeddd       Zed	d       Zed
d       Zedd       Z	y)
TokenCachea  Secure storage for authentication credentials to avoid repeated login prompts.

    Platform-specific implementations:
    - macOS/Windows: Uses OS keyring (Keychain/Credential Manager) via 'keyring' library
    - Linux: Uses encrypted JSON file in ~/.cache/snowflake/ with 0o600 permissions
    - Fallback: NoopTokenCache (no caching) if secure storage unavailable

    Tokens are keyed by (host, user, token_type) to support multiple accounts.
    c                    t         st        r%t        st        d       t	               S t               S t        r.t        j                  |       }|r|S t        d       t	               S y )Na.  Dependency 'keyring' is not installed, cannot cache id token. You might experience multiple authentication pop ups while using ExternalBrowser/OAuth/MFA Authenticator. To avoid this please install keyring module using the following command:
 pip install snowflake-connector-python[secure-local-storage]zFailed to initialize file based token cache. You might experience multiple authentication pop ups while using ExternalBrowser/OAuth/MFA Authenticator.)	r   r   r   rF   NoopTokenCacheKeyringTokenCacher   FileTokenCachemake)skip_file_permissions_checkcaches     r    rM   zTokenCache.makeN   sf    z$T &''$&&"''(CDEk &'' r   c                     y Nr   r1   keytokens      r    storezTokenCache.storef       r   c                     y rQ   r   r1   rS   s     r    retrievezTokenCache.retrievej   rV   r   c                     y rQ   r   rX   s     r    removezTokenCache.removen   rV   r   NF)rN   boolr=   rH   rS   r&   rT   r'   r=   NonerS   r&   r=   z
str | NonerS   r&   r=   r_   )
r   r   r   r   staticmethodrM   r   rU   rY   r[   r   r   r    rH   rH   C   sW     ( (.      r   rH   c                      e Zd Zy)_FileTokenCacheErrorNr#   r   r   r    rd   rd   s   r$   r   rd   c                      e Zd Zy)_OwnershipErrorNr#   r   r   r    rf   rf   w   r$   r   rf   c                      e Zd Zy)_PermissionsTooWideErrorNr#   r   r   r    rh   rh   {   r$   r   rh   c                      e Zd Zy)_CacheDirNotFoundErrorNr#   r   r   r    rj   rj      r$   r   rj   c                      e Zd Zy)_InvalidCacheDirErrorNr#   r   r   r    rl   rl      r$   r   rl   c                      e Zd Zy)_MalformedCacheFileErrorNr#   r   r   r    rn   rn      r$   r   rn   c                      e Zd Zy)_CacheFileReadErrorNr#   r   r   r    rp   rp      r$   r   rp   c                      e Zd Zy)_CacheFileWriteErrorNr#   r   r   r    rr   rr      r$   r   rr   c                      e Zd ZdZeddd       Z	 d	 	 	 	 	 ddZddZddZddZ	ddZ
ddZdd	Zdd
Zeddd       Ze	 d	 	 	 	 	 dd       ZddZy)rL   a  Linux implementation: stores tokens in JSON file with strict security.

    Cache location (in priority order):
    1. $SF_TEMPORARY_CREDENTIAL_CACHE_DIR/credential_cache_v1.json
    2. $XDG_CACHE_HOME/snowflake/credential_cache_v1.json
    3. $HOME/.cache/snowflake/credential_cache_v1.json

    Security: File must have 0o600 permissions and be owned by current user.
    Uses file locks to prevent concurrent access corruption.
    c                    t         j                  |       }|)t        j                  t              j                  d       y t        ||       S )NzfFailed to find suitable cache directory for token cache. File based token cache initialization failed.)rN   )rL   find_cache_dirlogging	getLoggerr   debug)rN   	cache_dirs     r    rM   zFileTokenCache.make   sM    "112MN	h'--x !7R r   c                \    t        j                  t              | _        || _        || _        y rQ   )rv   rw   r   rA   ry   _skip_file_permissions_check)r1   ry   rN   s      r    __init__zFileTokenCache.__init__   s%     ''1(,G)r   c                H   	 t         j                  | j                  | j                         t	        | j                               5  | j                         }||d   |j                         <   | j                  |       d d d        y # 1 sw Y   y xY w# t        $ r(}| j                  j                  d|       Y d }~y d }~wt        $ r(}| j                  j                  d|       Y d }~y d }~wt        $ r(}| j                  j                  d|       Y d }~y d }~ww xY w)NtokenszFailed to store token: e=Unable to lock file lock: e=Failed to produce token key e=)rL   validate_cache_dirry   r{   r   	lock_file_read_cache_filer<   _write_cache_filerd   rA   errorr   r"   )r1   rS   rT   rO   es        r    rU   zFileTokenCache.store   s    	C-- A A $..*+ .--/27h/&&u-. . . $ 	>KK :t<== 	AKK =1$?@@$ 	CKK ?QDABB	CsN   AB 8B=B BB B 	D!B>>D!
C--D!9DD!c                x   	 t         j                  | j                  | j                         t	        | j                               5  | j                         }|d   j                  |j                         d       }t        |t              r|cd d d        S 	 d d d        y # 1 sw Y   y xY w# t        $ r(}| j                  j                  d|       Y d }~y d }~wt        $ r(}| j                  j                  d|       Y d }~y d }~wt        $ r(}| j                  j                  d|       Y d }~y d }~ww xY w)Nr~   zFailed to retrieve token: e=r   r   )rL   r   ry   r{   r   r   r   getr<   
isinstancer'   rd   rA   r   r   r"   )r1   rS   rO   rT   r   s        r    rY   zFileTokenCache.retrieve   s
   	-- A A $..*+  --/h++CLLNDAeS) 	           $ 	KK =1$?@ 	KK =1$?@$ 	KK ?QDAB	s[   AB* AB
	B* BB* B'#B* 'B* *	D93CD9"DD9D44D9c                b   	 t         j                  | j                  | j                         t	        | j                               5  | j                         }|d   j                  |j                         d        | j                  |       d d d        y # 1 sw Y   y xY w# t        $ r(}| j                  j                  d|       Y d }~y d }~wt        $ r(}| j                  j                  d|       Y d }~y d }~wt        $ r(}| j                  j                  d|       Y d }~y d }~ww xY w)Nr~   zFailed to remove token: e=r   r   )rL   r   ry   r{   r   r   r   popr<   r   rd   rA   r   r   r"   )r1   rS   rO   r   s       r    r[   zFileTokenCache.remove   s    	C-- A A $..*+ .--/h##CLLND9&&u-. . . $ 	?KK ;=>> 	AKK =1$?@@$ 	CKK ?QDABB	CsO   AB AB
B BB B 	D.(CD.C::D.D))D.c                     | j                   dz  S )Nzcredential_cache_v1.jsonry   r0   s    r    
cache_filezFileTokenCache.cache_file   s    ~~ :::r   c                     | j                   dz  S )Nzcredential_cache_v1.json.lckr   r0   s    r    r   zFileTokenCache.lock_file   s    ~~ >>>r   c                   d}di i}	 t        j                  | j                         t         j                        }| j                  s| j                  |d       t        j                  |dt         j                        }t        j                  |dt         j                         t        j                  ||      }t        j                  t        j                  |d            }|dkD  rt        j0                  |       	 d|vst3        |d   t4              si |d<   |S # t        $ r/ | j                  j!                  | j                          d       Y pt        j"                  j$                  $ rM}| j                  j'                  d| j                          d|j(                  j*                          Y d }~d }~wt,        $ rN}| j                  j'                  d	| j                          d|j(                  j*                          Y d }~)d }~wt.        $ r:}| j                  j'                  d
| j                          d|        Y d }~jd }~ww xY w# |dkD  rt        j0                  |       w w xY w)Nr~     r   r4   z
 not foundz+Failed to decode json read from cache file z: z,Failed to decode utf-8 read from cache file zFailed to read cache file )osopenr   O_RDONLYr{   _ensure_permissionslseekSEEK_ENDSEEK_SETreadjsonloadscodecsdecodeFileNotFoundErrorrA   rx   decoderJSONDecodeErrorrB   	__class__r   UnicodeErrorOSErrorcloser   dict)r1   fd	json_datasizedatar   s         r    r   zFileTokenCache._read_cache_file   s   rN		*BKK8B44((U388B2;;/DHHRBKK(772t$D

6==w#?@I Av9$Jy7JD,Q"$Ih' ! 	@KK!2 3:>?||++ 	KK=doo>O=PPRSTS^S^SgSgRhi   	KK>t?P>QQSTUT_T_ThThSij   	WKK"<T__=N<OrRSQT UVV	W Av s\   CD 5II I-AF50I 5IAH
I 
I/II II I0c                t   d}| j                   j                  d| j                                 	 t        j                  | j                         t        j
                  t        j                  z  t        j                  z  d      }| j                  s| j                  |d       t        j                  |t        j                  t        j                  |      d             ||dkD  rt        j                  |       S S # t         $ r}t#        d|      d }~ww xY w# |dkD  rt        j                  |       w w xY w)Nr   zWriting cache file r   r4   r   zFailed to write cache file)rA   rx   r   r   r   O_WRONLYO_CREATO_TRUNCr{   r   writer   r9   r   dumpsr   r   rr   )r1   r   r   r   s       r    r   z FileTokenCache._write_cache_file  s    /0A/BCD	!2;;#;bjj#H%B 44((U3HHRtzz)'<gFG Av   	H&'CQGG	H Av s$   B1C= =	DDDD D7c                X     d fdfdfdfdg}|D ]  } |       }|s|c S  y )Nc                r   t        j                  |       }|t        j                  d|  d       y t	        |      }t        |      dkD  r|j                         s#t        j                  dt        |       d       y |j                         s#t        j                  dt        |       d       y |d d D ]  }||z  }|j                  dd	
        ||d   z  }|j                  dd
       	 t        j                  |       |S # t        $ r%}t        dt        |       d| d       Y d }~y d }~ww xY w)NzEnvironment variable z0 not set. Skipping it in cache directory lookup.r   zPath z7 does not exist. Skipping it in cache directory lookup.z; is not a directory. Skipping it in cache directory lookup.r   Ti  )exist_okmode  z&Cache directory validation failed for z due to error 'z)'. Skipping it in cache directory lookup.)r   getenvrA   rx   r   r-   existsr'   is_dirmkdirrL   r   rd   rF   )env_varsubpath_segmentsenv_val	directorysubpathr   rN   s         r    lookup_env_dirz5FileTokenCache.find_cache_dir.<locals>.lookup_env_dir"  sZ   ii(G+G94de WI#$q( '')LLI//fg   '')LLI//jk  /4 ?G )G 3IOOTO>? &(8(<<	E:	11: ! ' <S^<LO\][^  _H  I 	s   0D 	D6D11D6c                       dg       S )N!SF_TEMPORARY_CREDENTIAL_CACHE_DIRr   r   s   r    <lambda>z/FileTokenCache.find_cache_dir.<locals>.<lambda>L  s    N#FK r   c                       ddg      S )NXDG_CACHE_HOME	snowflaker   r   s   r    r   z/FileTokenCache.find_cache_dir.<locals>.<lambda>M  s    N#3k]C r   c                       dddg      S )NHOMEz.cacher   r   r   s   r    r   z/FileTokenCache.find_cache_dir.<locals>.<lambda>N  s    N6Hk+BC r   )r   r'   r   z	list[str]r=   Path | Noner   )rN   lookup_functionslfry   r   s   `   @r    ru   zFileTokenCache.find_cache_dir   sC    '	T LCC
 # 	!BI  	!
 r   c                   	 | j                         }| t        d      t        j                  |j                        st	        d|  d      |syt        j
                  |j                        }|dk7  rt        d|  d|dd      t        j                         }|j                  |k7  rt        d|  d| d	|j                         y y # t        $ r t        d|  d
      w xY w)NzCache dir was not foundz
Cache dir z is not a directoryr    has incorrect permissions. oz != 0700 has incorrect owner.  != z was not found. Failed to stat.)statrj   S_ISDIRst_moderl   S_IMODErh   r   geteuidst_uidrf   r   )ry   rN   statinfopermissionseuids        r    r   z!FileTokenCache.validate_cache_dirX  s	   	 ~~'H ,-FGG<< 0 01+jCV,WXX."ll8+;+;<%'2$YK/KKXY?Zbc  zz|??d*)$YK/EdV4PXP_P_O`a  + / ! 	(YK'FG 	s   CC	 	C"c           	     |   	 t        j                  |      }t        j                  |j                        }||k7  r$t        d| j                          d|dd|d      t        j                         }|j                  |k7  r,t        d| j                          d| d|j                         y # t        $ r Y y w xY w)NzCache file r   r   r   r   )r   fstatr   r   r   rh   r   r   r   rf   r   )r1   r   r   r   actual_permissionsr   s         r    r   z"FileTokenCache._ensure_permissionsw  s    	xx|H!%h.>.>!?![0.!$//"3!44PQ\]^P__cdvwxcyz  ::<D$&%!$//"3!44J4&PTU]UdUdTef  '
 ! 		s   B,B/ /	B;:B;Nr\   )rN   r]   r=   zFileTokenCache | None)ry   r   rN   r]   r=   r_   r^   r`   ra   )r=   r   )r=   zdict[str, dict[str, Any]])r   r   )rN   r]   r=   r   )ry   r   rN   r]   r=   r_   )r   intr   r   r=   r_   )r   r   r   r   rb   rM   r|   rU   rY   r[   r   r   r   r   ru   r   r   r   r   r    rL   rL      s    	 
 
 DIHH<@H	HC ,C ;?@" 5 5n DI=A	 <r   rL   c                  0    e Zd ZdZddZddZd	dZd
dZy)rK   a  macOS/Windows implementation: uses OS-native secure credential storage.

    - macOS: Stores tokens in Keychain
    - Windows: Stores tokens in Windows Credential Manager

    Tokens are stored with service="{HOST}:{USER}:{TOKEN_TYPE}" and username="{USER}".
    c                @    t        j                  t              | _        y rQ   )rv   rw   r   rA   r0   s    r    r|   zKeyringTokenCache.__init__  s    ''1r   c                   	 t        j                  |j                         |j                  j	                         |       y # t
        $ r5}| j                  j                  d|j                   d|       Y d }~y d }~wt         j                  j                  $ r/}| j                  j                  dt        |             Y d }~y d }~ww xY w)NCould not retrieve  from keyring, e=z'Could not store id_token to keyring, %s)r   set_passwordr2   r(   r.   r"   rA   r   r*   errorsKeyringErrorr'   )r1   rS   rT   r   kes        r    rU   zKeyringTokenCache.store  s    		R    
 % 	XKK 3CMM?BTRSQUVWW~~** 	RKKGRQQ	Rs#   =A   	C	+A99 C%CCc           	        	 t        j                  |j                         |j                  j	                               S # t         j
                  j                  $ rR}| j                  j                  dj                  |j                  j                  t        |                   Y d }~y d }~wt        $ r5}| j                  j                  d|j                   d|       Y d }~y d }~ww xY w)Nz.Could not retrieve {} from secure storage : {}r   r   )r   get_passwordr2   r(   r.   r   r   rA   r   formatr*   r/   r'   r"   )r1   rS   r   r   s       r    rY   zKeyringTokenCache.retrieve  s    	X''    ~~** 	KK@GGMM''R 
 % 	XKK 3CMM?BTRSQUVWW	Xs"   ;> C)AB((C)4+C$$C)c                Z   	 t        j                  |j                         |j                  j	                                y # t
        $ r5}| j                  j                  d|j                   d|       Y d }~y d }~wt        $ r&}| j                  j                  d|       Y d }~y d }~ww xY w)Nr   r   z4Failed to delete credential in the keyring: err=[%s])
r   delete_passwordr2   r(   r.   r"   rA   r   r*   	Exception)r1   rS   r   exs       r    r[   zKeyringTokenCache.remove  s    
	##   	 % 	XKK 3CMM?BTRSQUVWW
 		  	KKF  			s!   <? 	B*+A88B*B%%B*N)r=   r_   r^   r`   ra   )r   r   r   r   r|   rU   rY   r[   r   r   r    rK   rK     s    2
RXr   rK   c                  $    e Zd ZddZddZddZy)rJ   c                     y rQ   r   rR   s      r    rU   zNoopTokenCache.store      r   c                     y rQ   r   rX   s     r    rY   zNoopTokenCache.retrieve  r   r   c                     y rQ   r   rX   s     r    r[   zNoopTokenCache.remove  r   r   Nr^   r`   ra   )r   r   r   rU   rY   r[   r   r   r    rJ   rJ     s    r   rJ   )rB   r'   r=   r_   )4
__future__r   r   r6   r   rv   r   r   rD   abcr   r   dataclassesr   enumr   pathlibr   typingr	   r
   compatr   r   r   	file_lockr   r   optionsr   r   rw   r   rA   r   r   r   r"   r&   rF   rH   rd   rf   rh   rj   rl   rn   rp   rr   rL   rK   rJ   r   r   r    <module>r      s%   "     	  
 # !    2 2 . /			8	$CL0 0	I 	   $2
- -`	9 		* 		3 		1 		0 		3 		. 		/ 	uZ up3
 3lZ r   