
    i/                    l   U d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dl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ded<   ddiZ G d de          Zdd dfd9d"Z d:d&Z!d;d)Z"d<d.Z#d=d0Z$d>d2Z%d>d3Z&d?d7Z'd@d8Z(dS )A    )annotationsN)Callable)AnyLiteral)parse_qs)Session)OAuth1Session   )http)OAuth1TokenOAuth2Token)GarthExceptionzname="_csrf"\s+value="(.+?)"z<title>(.+?)</title>z5https://thegarth.s3.amazonaws.com/oauth_consumer.jsonzdict[str, str]OAUTH_CONSUMERz
User-Agentz%com.garmin.android.apps.connectmobilec                  $     e Zd Z	 dd fdZ xZS )GarminOAuth1SessionNparentSession | Nonec               H   t           s+t          j        t                                                    a  t                      j        t           d         t           d         fi | |;|                     d|j        d                    |j	        | _	        |j
        | _
        d S d S )Nconsumer_keyconsumer_secretzhttps://)r   requestsgetOAUTH_CONSUMER_URLjsonsuper__init__mountadaptersproxiesverify)selfr   kwargs	__class__s      D/root/projects/butler/venv/lib/python3.11/site-packages/garth/sso.pyr   zGarminOAuth1Session.__init__   s      	E%\*<==BBDDN>*,-	
 	
 	
 	
 	

 JJz6?:#>???!>DL -DKKK     N)r   r   )__name__
__module____qualname__r   __classcell__)r#   s   @r$   r   r      sG         "&( ( ( ( ( ( ( ( ( ( (r%   r   c                      t          d          S )Nz
MFA code: )input r%   r$   <lambda>r.   5   s    %*=*= r%   Fclienthttp.Client | None
prompt_mfaCallable | Nonereturn_on_mfaboolemailstrpasswordreturnMtuple[OAuth1Token, OAuth2Token] | tuple[Literal['needs_mfa'], dict[str, Any]]c               n   |pt           j        }d|j         d}| d}t          dd|          }i |t          |||||          }|                    dd	|
           |                    dd|d           t          |j        j                  }	|                    dd|dt          | |d|	                     t          |j        j                  }
d|
v r5|s|d||dfS t          |||           t          |j        j                  }
|
dk    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)rF   referrer)usernamer7   embed_csrfrF   rG   dataMFAN	needs_mfa)signin_paramsr/   SuccesszUnexpected title: )r   r/   domaindictr   get_csrf_token	last_resptextpost	get_title
handle_mfar   _complete_login)r5   r7   r/   r1   r3   SSO	SSO_EMBEDSSO_EMBED_PARAMSSIGNIN_PARAMS
csrf_tokentitles              r$   loginr`   0   s   4 "t{F -
,
,
,CI  
	
	
)2,5
 
 
	M JJul+;J<<< JJ	       0 566J KK	
 
 
     f&+,,E ~~ 	J.!. ! !  
 	6=*555&*/00	9%99:::6"""r%   tickethttp.Clientr   c                d   t          |j                  }d|j         d}d|j         d}| d|  d| d}|                    |t          |j        	          }|                                 t          |j                  }d
 |	                                D             }t          dd|j        i|S )N)r   https://connectapi./oauth-service/oauth/r;   rE   zpreauthorized?ticket=z&login-url=z&accepts-mfa-tokens=true)headerstimeoutc                &    i | ]\  }}||d          S )r   r-   ).0kvs      r$   
<dictcomp>z$get_oauth1_token.<locals>.<dictcomp>   s"    000AQ!000r%   rQ   r-   )r   sessrQ   r   
USER_AGENTrg   raise_for_statusr   rU   itemsr   )	ra   r/   rm   base_url	login_urlurlrespparsedtokens	            r$   get_oauth1_tokenrw      s    fk222DIV]IIIH8v}888I 	# 	#& 	# 	#Y 	# 	# 	#  88   D
 	di  F00000E55fm5u555r%   oauth1r   c                x   t          | j        | j        |j                  }| j        rt          | j                  ni }d|j         d}| d}i t          ddi}|                    ||||j	                  }|
                                 |                                }t          d	i t          |          S )
N)resource_owner_keyresource_owner_secretr   )	mfa_tokenrd   re   zexchange/user/2.0zContent-Typez!application/x-www-form-urlencoded)rf   rL   rg   r-   )r   oauth_tokenoauth_token_secretrm   r|   rR   rQ   rn   rV   rg   ro   r   r   set_expirations)	rx   r/   rm   rL   rq   rs   rf   rt   rv   s	            r$   exchanger      s    !-$7{  D
 06/?G4&*++++RDIV]IIIH
(
(
(C
>
?G 99	   D 	IIKKE00//000r%   rO   rR   r   Nonec                    t          | j        j                  }t          j        |          rt          j         |                      }n
 |            }|                     dd|d|d|dd           d S )NrD   z /sso/verifyMFA/loginEnterMfaCodeTr<   setupEnterMfaCode)zmfa-coderI   rJ   fromPagerK   )rS   rT   rU   inspectiscoroutinefunctionasynciorunrV   )r/   rO   r1   r^   mfa_codes        r$   rX   rX      s       0 566J":..  ;zz||,,:<<
KK* +	
 
      r%   rv   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)rv   s    r$   r   r      sT    dikkE,,??@@E,(+	e677) )E
$% Lr%   htmlc                    t                               |           }|st          d          |                    d          S )NzCouldn't find CSRF tokenr
   )CSRF_REsearchr   groupr   ms     r$   rS   rS      s:    tA 97888771::r%   c                    t                               |           }|st          d          |                    d          S )NzCouldn't find titler
   )TITLE_REr   r   r   r   s     r$   rW   rW      s:    A 42333771::r%   client_stater   tuple[OAuth1Token, OAuth2Token]c                j    | 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/   rO   c                      S r&   r-   )r   s   r$   r.   zresume_login.<locals>.<lambda>   s    h r%   )rX   rY   )r   r   r/   rO   s    `  r$   resume_loginr      sC     (#F 1Mv}&6&6&6&67776"""r%   c                    t          j        d| j        j                  }|st	          d          |                    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   rT   rU   r   r   rw   r   )r/   r   ra   rx   oauth2s        r$   rY   rY      sr     		+V-=-BCCA 
.
 
 	
 WWQZZFff--Fff%%F6>r%   )r/   r0   r1   r2   r3   r4   r5   r6   r7   r6   r8   r9   )ra   r6   r/   rb   r8   r   )rx   r   r/   rb   r8   r   )r/   rb   rO   rR   r1   r   r8   r   )rv   rR   r8   rR   )r   r6   r8   r6   )r   rR   r   r6   r8   r   )r/   rb   r8   r   ))
__future__r   r   r   r   r   collections.abcr   typingr   r   urllib.parser   r   r   requests_oauthlibr	    r   auth_tokensr   r   excr   compiler   r   r   r   __annotations__rn   r   r`   rw   r   rX   r   rS   rW   r   rY   r-   r%   r$   <module>r      s,   " " " " " " "   				  $ $ $ $ $ $         ! ! ! ! ! !        + + + + + +       1 1 1 1 1 1 1 1       "*4
5
52:-..L !# # # # #CD
( ( ( ( (- ( ( (2 "&"="=W# W# W# W# W#t6 6 6 6&1 1 1 10   ,         # # # #$     r%   