o
    %                     @   s  d 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 ddlm	Z
 ddlmZ ddlmZ ddlmZ dZd	Zd
ZeeZdd Zdd Zdd Zdd ZG dd deZG dd deZG dd deZG dd deZG dd deZdd Z 	d!dd Z!dS )"zBA module that provides functions for handling rapt authentication.    N)reauth_errors)errors)model)authenticator)urllibz)https://reauth.googleapis.com/v2/sessionsz/https://www.googleapis.com/auth/accounts.reauthzhttps://accounts.google.comc                 C   s   d| v rt | d d | S )Nerrormessage)r   ReauthAPIError)msg r   D/tmp/google-cloud-sdk/lib/third_party/oauth2client/contrib/reauth.pyHandleErrors(   s   r   c                 C   s
   t  | S )zGet password from user.

    Override this function with a different logic if you are using this library
    outside a CLI. Returns the password.)getpass)textr   r   r   GetUserPassword.   s   
r   c                   C   s
   t j S )a  Check if we are in an interractive environment.

    If the rapt token needs refreshing, the user needs to answer the challenges.
    If the user is not in an interractive environment, the challenges can not be
    answered and we just wait for timeout for no reason.)sysstdinisattyr   r   r   r   InteractiveCheck7   s   
r   c                   C   s   t jjS )zGet preferred output function.)r   stderrwriter   r   r   r   GetPrintCallbackA   s   r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )ReauthChallengez!Base class for reauth challenges.c                 C   s   || _ || _d S N)http_requestaccess_tokenselfr   r   r   r   r   __init__J   s   
zReauthChallenge.__init__c                 C      t  )z"Returns the name of the challenge.NotImplementedErrorr   r   r   r   GetNameN      zReauthChallenge.GetNamec                 C   r   )zAReturns true if a challenge is supported locally on this machine.r    r"   r   r   r   IsLocallyEligibleR   r$   z!ReauthChallenge.IsLocallyEligiblec                 C   sh   |  |}|s	dS ||d d|d}| jdt|dt|dd| j id	\}}t|}t| |S )
z;Execute challenge logic and pass credentials to reauth API.NchallengeIdRESPOND)	sessionIdr&   actionproposalResponsez{0}/{1}:continuePOSTAuthorizationBearer methodbodyheaders)	InternalObtainCredentialsr   format
REAUTH_APIjsondumpsr   loadsr   )r   metadata
session_idclient_inputr0   _contentresponser   r   r   ExecuteV   s"   



zReauthChallenge.Executec                 C   r   )z=Performs logic required to obtain credentials and returns it.r    )r   r8   r   r   r   r2   m   r$   z)ReauthChallenge.InternalObtainCredentialsN)	__name__
__module____qualname____doc__r   r#   r%   r>   r2   r   r   r   r   r   G   s    r   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	PasswordChallengez(Challenge that asks for user's password.c                 C      dS )NPASSWORDr   r"   r   r   r   r#   u      zPasswordChallenge.GetNamec                 C   rE   NTr   r"   r   r   r   r%   x   rG   z#PasswordChallenge.IsLocallyEligiblec                 C   s   t d}|sd}d|iS )NzPlease enter your password: 
credential)r   )r   unused_metadatapasswdr   r   r   r2   {   s   z+PasswordChallenge.InternalObtainCredentialsNr?   r@   rA   rB   r#   r%   r2   r   r   r   r   rD   r   
    rD   c                   @   rC   )	SecurityKeyChallengez2Challenge that asks for user's security key touch.c                 C   rE   )NSECURITY_KEYr   r"   r   r   r   r#      rG   zSecurityKeyChallenge.GetNamec                 C   rE   rH   r   r"   r   r   r   r%      rG   z&SecurityKeyChallenge.IsLocallyEligiblec              
   C   s$  |d }|d }|d }g }|D ]'}|d  d}ttt|}|d  d}	t|	}	|||	d qztt	}
|
j
||t d}d|iW S  tjy } z*|jtjjkrat d	 n|jtjjkrnt d
 n	|W Y d }~d S W Y d }~d S d }~w tjy   t d Y d S w )NsecurityKey
challengesapplicationId	keyHandleascii	challenge)keyrV   )print_callbackzIneligible security key.
z0Timed out while waiting for security key touch.
zNo security key found.
)encoder   RegisteredKey	bytearraybase64urlsafe_b64decodeappendr   CreateCompositeAuthenticatorREAUTH_ORIGINAuthenticater   	u2ferrorsU2FErrorcodeDEVICE_INELIGIBLETIMEOUTNoDeviceFoundError)r   r8   skrR   app_idchallenge_datackhrW   rV   apir=   er   r   r   r2      sB   




z.SecurityKeyChallenge.InternalObtainCredentialsNrM   r   r   r   r   rO      rN   rO   c                   @   rC   )	SamlChallengez6Challenge that asks SAML users to complete SAML login.c                 C   rE   )NSAMLr   r"   r   r   r   r#      rG   zSamlChallenge.GetNamec                 C   rE   rH   r   r"   r   r   r   r%      rG   zSamlChallenge.IsLocallyEligiblec                 C   s   t  r   )r   ReauthSamlLoginRequiredError)r   rK   r   r   r   r2      s   z'SamlChallenge.InternalObtainCredentialsNrM   r   r   r   r   ro      rN   ro   c                   @   s:   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZd
S )ReauthManagerz4Reauth manager class that handles reauth challenges.c                 C   s   || _ || _|  | _d S r   )r   r   InternalBuildChallengesrR   r   r   r   r   r      s   zReauthManager.__init__c                 C   sJ   i }t | j| jt| j| jt| j| jfD ]}| r"||| < q|S r   )rO   r   r   rD   ro   r%   r#   )r   outrk   r   r   r   rs      s   z%ReauthManager.InternalBuildChallengesc                 C   s`   dt | j i}|r||d< | jdtdt|dd| j id\}}t	|}t
| |S )zADoes initial request to reauth API and initialize the challenges.supportedChallengeTypes oauthScopesForDomainPolicyLookupz	{0}:startr+   r,   r-   r.   )listrR   keysr   r3   r4   r5   r6   r   r7   r   )r   requested_scopesr0   r;   r<   r=   r   r   r   InternalStart   s   

zReauthManager.InternalStartc                 C   sB   d }|d D ]}|d dkrq| j |d  }|||d }q|S )NrR   statusREADYchallengeTyper(   )rR   r>   )r   r
   next_msgrV   rk   r   r   r   DoOneRoundOfChallenges   s   z$ReauthManager.DoOneRoundOfChallengesNc                 C   s   d}d}|r?|d8 }|s|  |}|d dkr|d S |d dks1|d dks1td	|d t s8t | |}|st )
z$Obtain proof of reauth (rapt token).N      r{   AUTHENTICATEDencodedProofOfReauthTokenCHALLENGE_REQUIREDCHALLENGE_PENDINGzChallenge status {0})rz   r   r	   r3   r   ReauthUnattendedErrorr   ReauthFailError)r   ry   r
   max_challenge_countr   r   r   ObtainProofOfReauth   s$   

z!ReauthManager.ObtainProofOfReauthr   )	r?   r@   rA   rB   r   rs   rz   r   r   r   r   r   r   rr      s    	
rr   c                 C   s   t | |}|j|d}|S )Nry   )rr   r   )r   r   ry   rmraptr   r   r   
ObtainRapt   s   
r   c              	   C   sx   t  d |||tdd}| |dtj|ddid\}}z	t|d }	W n ttfy2   t	j
w t| |	|d	}
|
S )
z?Given an http request method and refresh_token, get rapt token.zReauthentication required.
refresh_token)	client_idclient_secretr   scope
grant_typer+   zContent-Typez!application/x-www-form-urlencodedr.   r   r   )r   REAUTH_SCOPEr   parse	urlencoder5   r7   
ValueErrorKeyErrorr   ReauthAccessTokenRefreshErrorr   )r   r   r   r   	token_uriscopesquery_paramsr;   r<   reauth_access_token
rapt_tokenr   r   r   GetRaptToken  s0   


r   r   )"rB   r\   r   r5   loggingr   oauth2client.contribr   pyu2fr   rb   r   pyu2f.conveniencer   	six.movesr   r4   r   r`   	getLoggerr?   loggerr   r   r   r   objectr   rD   rO   ro   rr   r   r   r   r   r   r   <module>   s6   
	
+(F