
    h                        U d dl Z d dlZd dlZd dlmZmZmZmZmZ d dl	m
Z
 d dl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  ej,                  d
      Z ej,                  d      ZdZi aeeef   ed<   ddiZ G d de      Zdd dfdddedz  dedededeeef   eed   e eef   f   z  fdZ!dedddefdZ"d edddefd!Z#ddd"e deddfd#Z$d$e de fd%Z%d&edefd'Z&d&edefd(Z'd)e d*edeeef   fd+Z(dddeeef   fd,Z)y)-    N)AnyCallableDictLiteralTuple)parse_qs)Session)OAuth1Session   )http)OAuth1TokenOAuth2Token)GarthExceptionzname="_csrf"\s+value="(.+?)"z<title>(.+?)</title>z5https://thegarth.s3.amazonaws.com/oauth_consumer.jsonOAUTH_CONSUMERz
User-Agentz%com.garmin.android.apps.connectmobilec                   .     e Zd Z	 ddedz  f fdZ xZS )GarminOAuth1SessionNparentc                &   t         s't        j                  t              j	                         a t        |   t         d   t         d   fi | |B| j                  d|j                  d          |j                  | _	        |j                  | _
        y y )Nconsumer_keyconsumer_secretzhttps://)r   requestsgetOAUTH_CONSUMER_URLjsonsuper__init__mountadaptersproxiesverify)selfr   kwargs	__class__s      D/var/www/html/python/myenv/lib/python3.12/site-packages/garth/sso.pyr   zGarminOAuth1Session.__init__   s     %\\*<=BBDN>*,-	
 	

 JJz6??:#>?!>>DL --DK     N)__name__
__module____qualname__r	   r   __classcell__)r#   s   @r$   r   r      s      "&( $( (r%   r   c                      t        d      S )Nz
MFA code: )input r%   r$   <lambda>r.   1   s    %*= r%   Fclientzhttp.Client | None
prompt_mfareturn_on_mfaemailpasswordreturn	needs_mfac                ^   |xs t         j                  }d|j                   d}| d}t        dd|      }i |t        |||||      }|j	                  dd	|
       |j	                  dd|d       t        |j                  j                        }	|j                  dd|dt        | |d|	             t        |j                  j                        }
d|
v r7|s|d||dfS t        |||       t        |j                  j                        }
|
dk7  rt        d|
       t        |      S )a9  Login to Garmin Connect.

    Args:
        email: Garmin account email
        password: Garmin account password
        client: Optional HTTP client to use
        prompt_mfa: Callable that prompts for MFA code. Returns on MFA if None.
        return_on_mfa: If True, returns dict with MFA info instead of prompting

    Returns:
        If return_on_mfa=False (default):
            Tuple[OAuth1Token, OAuth2Token]: OAuth tokens after login
        If return_on_mfa=True and MFA required:
            dict: Contains needs_mfa and client_state for resume_login()
    https://sso.z/ssoz/embedzgauth-widgettrue)idembedWidget	gauthHost)r;   servicesourceredirectAfterAccountLoginUrlredirectAfterAccountCreationUrlsso
/sso/embed)paramsz/sso/signinT)rB   referrer)usernamer3   embed_csrfrB   rC   dataMFAr5   )signin_paramsr/   SuccesszUnexpected title: )r   r/   domaindictr   get_csrf_token	last_resptextpost	get_title
handle_mfar   _complete_login)r2   r3   r/   r0   r1   SSO	SSO_EMBEDSSO_EMBED_PARAMSSIGNIN_PARAMS
csrf_tokentitles              r$   loginr[   ,   sz   4 "t{{F t
,C%vI
	
	
)2,5
	M JJul+;J< JJ	     0 0 5 56J KK	
   f&&++,E ~J.!. !  
 	6=*5&**//0	1%9::6""r%   ticketzhttp.Clientc                    t        |j                        }d|j                   d}d|j                   d}| d|  d| d}|j                  |t        |j
                  	      }|j                          t        |j                        }|j                         D 	ci c]  \  }}	||	d
    }
}}	t        dd|j                  i|
S c c}	}w )N)r   https://connectapi./oauth-service/oauth/r7   rA   zpreauthorized?ticket=z&login-url=z&accepts-mfa-tokens=true)headerstimeoutr   rL   r-   )r   sessrL   r   
USER_AGENTra   raise_for_statusr   rP   itemsr   )r\   r/   rb   base_url	login_urlurlrespparsedkvtokens              r$   get_oauth1_tokenrn      s    fkk2D$V]]O3HIHv}}oZ8I*)&YK"	#  88  D
 	dii F!'0AQ!W0E05fmm5u55 1s   Coauth1c                    t        | j                  | j                  |j                        }| j                  rt        | j                        ni }d|j                   d}| d}i t        ddi}|j                  ||||j                        }|j                          |j                         }t        d	i t        |      S )
N)resource_owner_keyresource_owner_secretr   )	mfa_tokenr^   r_   zexchange/user/2.0zContent-Typez!application/x-www-form-urlencoded)r`   rH   ra   r-   )r   oauth_tokenoauth_token_secretrb   rs   rM   rL   rc   rQ   ra   rd   r   r   set_expirations)	ro   r/   rb   rH   rf   rh   r`   ri   rm   s	            r$   exchangerw      s    !--$77{{D
 06/?/?4&**+RD$V]]O3HIHJ'
(C
>
?G 99	  D 	IIKE0/00r%   rJ   c                     t        | j                  j                        }t        j                  |      rt        j
                   |             }n |       }| j                  dd|d|d|dd       y )Nr@   z /sso/verifyMFA/loginEnterMfaCodeTr8   setupEnterMfaCode)zmfa-coderE   rF   fromPagerG   )rN   rO   rP   asyncioiscoroutinefunctionrunrQ   )r/   rJ   r0   rY   mfa_codes        r$   rS   rS      sm       0 0 5 56J"":.;;z|,<
KK* +	
  r%   rm   c                     t        t        j                         | d   z         | d<   t        t        j                         | d   z         | d<   | S )N
expires_in
expires_atrefresh_token_expires_inrefresh_token_expires_at)inttime)rm   s    r$   rv   rv      sL    diikE,,??@E,(+		e677)E
$% Lr%   htmlc                 h    t         j                  |       }|st        d      |j                  d      S )NzCouldn't find CSRF tokenr   )CSRF_REsearchr   groupr   ms     r$   rN   rN      s-    tA788771:r%   c                 h    t         j                  |       }|st        d      |j                  d      S )NzCouldn't find titler   )TITLE_REr   r   r   r   s     r$   rR   rR      s-    A233771:r%   client_stater~   c                 N    | d   }| d   }t        ||fd       t        |      S )a
  Complete login after MFA code is provided.

    Args:
        client_state: The client state from login() when MFA was needed
        mfa_code: The MFA code provided by the user

    Returns:
        Tuple[OAuth1Token, OAuth2Token]: The OAuth tokens after login
    r/   rJ   c                       S r&   r-   )r~   s   r$   r.   zresume_login.<locals>.<lambda>   s    h r%   )rS   rT   )r   r~   r/   rJ   s    `  r$   resume_loginr      s1     (#F 1Mv}&676""r%   c                     t        j                  d| j                  j                        }|st	        d      |j                  d      }t        ||       }t        ||       }||fS )zComplete the login process after successful authentication.

    Args:
        client: The HTTP client

    Returns:
        Tuple[OAuth1Token, OAuth2Token]: The OAuth tokens
    zembed\?ticket=([^"]+)"z Couldn't find ticket in responser   )rer   rO   rP   r   r   rn   rw   )r/   r   r\   ro   oauth2s        r$   rT   rT      se     			+V-=-=-B-BCA.
 	
 WWQZFff-Fff%F6>r%   )*r{   r   r   typingr   r   r   r   r   urllib.parser   r   r	   requests_oauthlibr
    r   auth_tokensr   r   excr   compiler   r   r   r   str__annotations__rc   r   boolrM   r[   rn   rw   rS   rv   rN   rR   r   rT   r-   r%   r$   <module>r      s    	  6 6 !   +  1  "**4
52::-.L !#S#X #CD
(- (2 $("=W# !	W#
 4W# W#W#W# 
+{
"#GK $sCx.012W#t6S 6- 6K 6&1[ 1- 1K 10*.<D	,4 D   C C ##"%#
;#$#$M eK4L.M r%   