o
    l>j	7                     @   s   d Z ddlZddlZddlmZ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 ddlZddl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!m"Z"m#Z#m$Z$ erjddl%m&Z& e'h dZ(G dd dej)Z*dS )zPyicloud Session handling    N)JSONDecodeErrordumpload)pathmatch)TYPE_CHECKINGAnyNoReturnOptionalUnioncast)Response)CONTENT_TYPECONTENT_TYPE_JSONCONTENT_TYPE_TEXT_JSONERROR_ACCESS_DENIEDERROR_AUTHENTICATION_FAILEDERROR_ZONE_NOT_FOUNDHEADER_DATAAppleAuthError)PyiCloudCookieJar)PyiCloud2FARequiredExceptionPyiCloud2SARequiredExceptionPyiCloudAPIResponseExceptionPyiCloudAuthRequiredException$PyiCloudServiceNotActivatedException)PyiCloudService>   middataptknsalttopictxnidakdataidmsdatanextStep	next_step
push_tokensessionUUIDsession_uuidencryptedCodesource_app_idencrypted_codetopics_by_hashconnection_pathc                       s  e Zd ZdZ		d8dddededed	eeeef  d
df fddZe	d
eee
f fddZe	d
ejfddZd9ddZd9ddZd:ded
dfddZded
dfddZded
efddZ														d;d
efddZ														d;d
efd d!Zd
ef fd"d#Zd
ef fd$d%Zed&ejjd
efd'd(Zd)eded
efd*d+Z ded
dfd,d-Z!ded.ee"eef  d/ed
efd0d1Z#e	d<d2d3Z$e	d
efd4d5Z%e	d
efd6d7Z&  Z'S )=PyiCloudSessionziCloud session.FNservicer   	client_idcookie_directoryverifyheadersreturnc                    sx   t    || _|| _|| _t| jd| _i | _t	
t| _|r&| j| |   | jds:| jd|i dS dS )z>Initialize the persisted requests session used by the service.filenamer2   N)super__init___servicer4   _cookie_directoryr   cookiejar_pathcookies_datalogging	getLogger__name___loggerr5   update_load_session_dataget)selfr1   r2   r3   r4   r5   	__class__ E/home/thesage/.local/lib/python3.10/site-packages/pyicloud/session.pyr:   ?   s   
	zPyiCloudSession.__init__c                 C      | j S )zGets the session data)r?   rG   rJ   rJ   rK   r   Z      zPyiCloudSession.datac                 C   rL   )zGets the request logger)rC   rM   rJ   rJ   rK   logger_   rN   zPyiCloudSession.loggerc              
   C   s   t j| jr7z
tt| j  W n% tt	fy6 } z| j
d| j| tt| j  W Y d}~nd}~ww | j
d| j i | _z!t| jdd}t|| _W d   W dS 1 s\w   Y  W dS  ttfyu   | j
d Y dS w )zLoad session_data from file.zDFailed to load cookie jar %s: %s; starting without persisted cookiesNzUsing session file %sutf-8encodingzSession file does not exist)osr   existsr=   r   r   r>   r   OSError
ValueErrorrC   warningcleardebugsession_pathr?   openr   info)rG   exc	session_frJ   rJ   rK   rE   d   s0   &
z"PyiCloudSession._load_session_datac              
   C   s   | j rtj| j stj| j dd t| jddd}tdd t| j	
 D | | jd| j W d	   n1 s<w   Y  ztt| j  | jd
| j W d	S  ttfyp } z| jd| W Y d	}~d	S d	}~ww )zSave session_data to file.T)exist_okwrP   rQ   c                 S   s   i | ]\}}|t vr||qS rJ   )NON_PERSISTED_SESSION_KEYS).0keyvaluerJ   rJ   rK   
<dictcomp>   s
    z6PyiCloudSession._save_session_data.<locals>.<dictcomp>zSaved session data to file: %sNzSaved cookies data to file: %szFailed to save cookies data: %s)r<   rS   r   isdirmakedirsr[   rZ   r   dictr?   itemsrO   rY   r   r   r>   saver=   rU   rV   rW   )rG   outfiler]   rJ   rJ   rK   _save_session_data|   s$   z"PyiCloudSession._save_session_dataTremove_filesc              
   C   s   z
t t| j  W n$ ttfy. } z| jd| j| t| jd| _W Y d}~nd}~ww i | _	|rO| j| j
fD ]}zt| W q: tyL   Y q:w dS |   dS )z)Clear persisted session and cookie state.zAFailed to clear cookie jar %s: %s; resetting in-memory cookie jarr7   N)r   r   r>   rX   KeyErrorRuntimeErrorrC   rW   r=   r?   rZ   rS   removeFileNotFoundErrorrl   )rG   rm   r]   persisted_pathrJ   rJ   rK   clear_persistence   s*   z!PyiCloudSession.clear_persistenceresponsec                 C   s>   t  D ]\}}|j|r|}| j||j|i qdS )z"Update session_data with new data.N)r   ri   r5   rF   r?   rD   )rG   rt   headerrd   session_argrJ   rJ   rK   _update_session_data   s   z$PyiCloudSession._update_session_datac                 C   s(   |j td}ttg}|dd |v S )zHReturn whether a response advertises one of the accepted JSON mimetypes. ;r   )r5   rF   r   r   r   split)rG   rt   content_typejson_mimetypesrJ   rJ   rK   _is_json_response   s
   z!PyiCloudSession._is_json_responsec                 C   *   | j |||||||||	|
||||||dS )zCDispatch a request through the normalized session request pipeline.paramsr   r5   r>   filesauthtimeoutallow_redirectsproxieshooksstreamr4   certjson)_requestrG   methodurlr   r   r5   r>   r   r   r   r   r   r   r   r4   r   r   rJ   rJ   rK   request   s$   zPyiCloudSession.requestc                 C   r~   )z9Dispatch a request without response-status normalization.r   )_request_rawr   rJ   rJ   rK   request_raw   s$   zPyiCloudSession.request_rawc              
      sv   | j d|| zt jd||d|}W n tjjy/ } z| | W Y d}~nd}~ww | | | 	  |S )zCPerform a request and persist cookies/session data without raising.%s %sr   r   NrJ   )
rO   rY   r9   r   requests
exceptionsRequestException_raise_request_exceptionrw   rl   )rG   r   r   kwargsrt   errrH   rJ   rK   r   	  s&   

zPyiCloudSession._request_rawc              
      s   | j d|| zKt jd||d|}| | |   t|j}|js@| 	|p6|t
jt
jt
jt
jfv fr@| j||dW S |  | 	|sL|W S | | |W S  tjjym } z| | W Y d}~dS d}~ww )zRequest method.r   r   )status_codert   NrJ   )rO   rY   r9   r   rw   rl   intr   okr}   r   TWO_FACTOR_REQUIREDFIND_MY_REAUTH_REQUIREDLOGIN_TOKEN_EXPIREDGENERAL_AUTH_ERROR_handle_request_errorraise_for_status_decode_json_responser   r   r   r   )rG   r   r   r   rt   r   r   rH   rJ   rK   r   "  sL   





zPyiCloudSession._requestr   c                 C   s6   t | tjr| jdurt| jj| jjd| td| )zKNormalize low-level requests failures into the session's public error type.N)reasoncodezRequest failed to iCloud)
isinstancer   	HTTPErrorrt   r   textr   )r   rJ   rJ   rK   r   U  s   
z(PyiCloudSession._raise_request_exceptionr   c                 C   sd   |t jkr| |r| ddkrt| jj|d|t jkr(t	| jj|d| 
|||j dS )zHandle request error.authTypehsa2)apple_idrt   N)r   r   r}   r   rF   r   r1   account_namer   r   _raise_errorr   )rG   r   rt   rJ   rJ   rK   r   `  s   

z%PyiCloudSession._handle_request_errorc              
   C   s   t |jdkr	dS zJ| }t|trN|d}|p|d}|p%|d}|p,|d}|r6t|ts6d}|rQ|d}|pC|d	}| ||| W dS W dS W dS  tyh   | j	
d
t|dd Y dS w )zDecode JSON response.r   NerrorMessager   errorReasonerrorzUnknown reason	errorCodeserverErrorCodezFFailed to parse response body as JSON despite JSON mimetype; status=%sr   unknown)lencontentr   r   rh   rF   strr   r   rO   rY   getattr)rG   rt   r   r   r   rJ   rJ   rK   r   x  s.   




z%PyiCloudSession._decode_json_responser   r   c                 C   sz   | j jr|dkrt| j j|ttfv rd}t||||tkr$|d }t|t	r7|t
jt
jt
jt
jfv r7d}t|||)zGRaise the session's public exception for a parsed iCloud error payload.z$Missing X-APPLE-WEBAUTH-TOKEN cookiezUPlease log into https://icloud.com/ to manually finish setting up your iCloud servicezd.  Please wait a few minutes then try again.The remote servers might be trying to throttle requests.z$Authentication required for Account.)r1   requires_2sar   r   r   r   r   r   r   r   r   r   r   r   r   r   )rG   rt   r   r   rJ   rJ   rK   r     s&   zPyiCloudSession._raise_errorc                 C   rL   )zGets the service.)r;   rM   rJ   rJ   rK   r1     rN   zPyiCloudSession.servicec                 C   &   t | jddd | jjD d S )zGet path for cookiejar file.rx   c                 S      g | ]	}t d |r|qS z\wr   rb   crJ   rJ   rK   
<listcomp>      z2PyiCloudSession.cookiejar_path.<locals>.<listcomp>z
.cookiejarr   joinr<   r1   r   rM   rJ   rJ   rK   r=        zPyiCloudSession.cookiejar_pathc                 C   r   )zGet path for session data file.rx   c                 S   r   r   r   r   rJ   rJ   rK   r     r   z0PyiCloudSession.session_path.<locals>.<listcomp>z.sessionr   rM   rJ   rJ   rK   rZ     r   zPyiCloudSession.session_path)FN)r6   N)T)NNNNNNNTNNNNNN)r6   r   )(rB   
__module____qualname____doc__r   boolr   rh   r:   propertyr	   r   r@   LoggerrO   rE   rl   rs   r   rw   r}   r   r   r   r   staticmethodr   r   r   r
   r   r   r   r   r   r   r1   r=   rZ   __classcell__rJ   rJ   rH   rK   r0   <   s    


+
(3


r0   )+r   r@   rS   r   r   r   r   r   rer   typingr   r	   r
   r   r   r   r   requests.modelsr   pyicloud.constr   r   r   r   r   r   r   r   pyicloud.cookie_jarr   pyicloud.exceptionsr   r   r   r   r   pyicloud.baser   	frozensetra   Sessionr0   rJ   rJ   rJ   rK   <module>   s$     (
