
    ΔaZy                     <   d dl mZ 	 eZg dZ	 d dlmZ d dl	Z	d dl
Z
d dlZd dlmZ d dlZd dlmZ d dlZ	 d dlmZ 	 d dlmZ d dlZd d	lmZmZ d d
lmZ eeu reZneZd dl m!Z! d dl"m#Z$m%Z%m&Z&m'Z' d dl(m)Z) dZ*dZ+dZ,dZ-dZ.e/e0e1fZ2d Z3d Z4 G d de&      Z5 G d de$      Z# G d de$      Z6 G d de7      Z8 G d de8      Z9 G d d e8      Z: G d! d"e8      Z; G d# d$e7      Z< G d% d&e<      Z= G d' d(e=      Z> G d) d*e?      Z@ G d+ d,e@      ZA G d- d.e@      ZB G d/ d0eB      ZC G d1 d2eB      ZD G d3 d4eD      ZE G d5 d6e@      ZF G d7 d8e@      ZG G d9 d:e@      ZH G d; d<e@      ZIy# e$ r
 d dlmZ Y aw xY w# e$ r
 d dlmZ Y Lw xY w# e$ r
 d dlmZ Y Ww xY w)=    )print_function)AccessTokenAnonymousAccessToken AuthorizeRequestTokenWithBrowserCredentialStoreRequestTokenAuthorizationEngineConsumerCredentials)StringION)select)stdin)	urlencode)urljoin)	b64decode	b64encode)parse_qs)	HTTPError)r   r	   OAuthAuthorizerSystemWideConsumer)urisz+request-tokenz+access-tokenz+authorize-token   i  c                  T    t        t        j                  j                  dd            S )zWhether the user has disabled SSL certificate connection.

    Some testing servers have broken certificates.  Rather than raising an
    error, we allow an environment variable,
    ``LP_DISABLE_SSL_CERTIFICATE_VALIDATION`` to disable the check.
    %LP_DISABLE_SSL_CERTIFICATE_VALIDATIONF)boolosenvironget     :/usr/lib/python3/dist-packages/launchpadlib/credentials.py$_ssl_certificate_validation_disabledr!   V   s     

FNOOr   c                     t               }t        j                  |      j                  | d|t	        |            \  }}|j
                  dk7  rt        ||      ||fS )zPOST to ``url`` with ``headers`` and a body of urlencoded ``params``.

    Wraps it up to make sure we avoid the SSL certificate validation if our
    environment tells us to.  Also, raises an error on non-200 statuses.
    )"disable_ssl_certificate_validationPOST)methodheadersbody   )r!   httplib2Httprequestr   statusr   )urlr&   paramscert_disabledresponsecontents         r    
_http_postr2   c   sa     9:M +8gc&'	&8IgJ Hg #'**Wr   c                   z    e Zd ZdZdZdZdZdZdZd Z	e
d        Zdej                  efd	Zej                  fd
Zy)r
   zStandard credentials storage and usage class.

    :ivar consumer: The consumer (application)
    :type consumer: `Consumer`
    :ivar access_token: Access information on behalf of the user
    :type access_token: `AccessToken`
    Nuridictz<BR>
c                     t               }| j                  |       |j                         }t        |t              r|j                  d      }|S )zeTurn this object into a string.

        This should probably be moved into OAuthAuthorizer.
        utf-8)r   savegetvalue
isinstanceunicode_typeencode)selfsio
serializeds      r    	serializezCredentials.serialize   sA    
 j		#\\^
j,/#**73Jr   c                      |        }t        |t              s|j                  d      }|j                  t	        |             |S )z}Create a `Credentials` object from a serialized string.

        This should probably be moved into OAuthAuthorizer.
        r8   )r;   r<   decodeloadr   )clsvaluecredentialss      r    from_stringzCredentials.from_string   s;     e%.LL)E%)r   c                    | j                   J d       | j                  J d       t        j                  |      }t	        | j                   j
                  dd      }|t        z   }d|i}|| j                  k(  rd|d<   t        |||      \  }}t        |t              r|j                  d	      }|| j                  k(  r8t        j                  |      }|||d
<   t        j                  |      | _        |S t        j#                  |      | _        |t$        d| j                   j
                  }||| j                   _        |d|z  z  }|S )a  Request an OAuth token to Launchpad.

        Also store the token in self._request_token.

        This method must not be called on an object with no consumer
        specified or if an access token has already been obtained.

        :param context: The context of this token, that is, its scope of
            validity within Launchpad.
        :param web_root: The URL of the website on which the token
            should be requested.
        :token_format: How the token should be
            presented. URI_TOKEN_FORMAT means just return the URL to
            the page that authorizes the token.  DICT_TOKEN_FORMAT
            means return a dictionary describing the token
            and the site's authentication policy.

        :return: If token_format is URI_TOKEN_FORMAT, the URL for the
            user to authorize the `AccessToken` provided by
            Launchpad. If token_format is DICT_TOKEN_FORMAT, a dict of
            information about the new access token.
        zConsumer not specified.zAccess token already obtained.	PLAINTEXT&)oauth_consumer_keyoauth_signature_methodoauth_signatureRefererzapplication/jsonAcceptr8   
lp.context?oauth_token=z&lp.context=%s)consumeraccess_tokenr   lookup_web_rootr5   keyrequest_token_pageDICT_TOKEN_FORMATr2   r;   bytesrC   jsonloadsr   from_params_request_tokenrH   authorize_token_pagecontext)	r>   r_   web_roottoken_formatr.   r-   r&   r0   r1   s	            r    get_request_tokenzCredentials.get_request_token   sW   8 }}(C*CC(  (J*JJ(''1#}}00#.

 ++h'4111 2GH&sGV<'gu%nnW-G4111ZZ(F"'.|$"-"9"9&"ADM"-"9"9'"BD$##''C
 ".5##+''11Jr   c                 ^   | j                   J d       t        j                  |      }t        | j                  j
                  d| j                   j
                  d| j                   j                  z        }|t        z   }d|i}t        |||      \  }}t        j                  |      | _        y)ad  Exchange the previously obtained request token for an access token.

        This method must not be called unless get_request_token() has been
        called and completed successfully.

        The access token will be stored as self.access_token.

        :param web_root: The base URL of the website that granted the
            request token.
        Nz5get_request_token() doesn't seem to have been called.rJ   z&%s)rL   rM   oauth_tokenrN   rO   )r]   r   rU   r5   rS   rV   secretaccess_token_pager2   r   rH   rT   )r>   r`   r.   r-   r&   r0   r1   s          r    'exchange_request_token_for_access_tokenz3Credentials.exchange_request_token_for_access_token   s     +	CB	C+''1#}}00#.++//!D$7$7$>$>>	
 **h'&sGV<''33G<r   )__name__
__module____qualname____doc__r]   URI_TOKEN_FORMATrX   ITEM_SEPARATORNEWLINErA   classmethodrH   r   STAGING_WEB_ROOTrb   rg   r   r   r    r
   r
   r   sd     NNG
 	 	 &&%	;| ,,=r   r
   c                   0    e Zd ZdZed        Zed        Zy)r   zAn OAuth access token.c                 L    |d   }|d   }|j                  d      } | |||      S )z:Create and return a new `AccessToken` from the given dict.rd   oauth_token_secretrQ   )r   )rE   r.   rV   re   r_   s        r    r\   zAccessToken.from_params   s6     ]#,-**\*3((r   c                 H   t        |t              s|j                  d      }t        |d      }|d   }t	        |      dk(  sJ d       |d   }|d   }t	        |      dk(  sJ d	       |d   }|j                  d
      }|t	        |      dk(  sJ d       |d   } | |||      S )z<Create and return a new `AccessToken` from the given string.r8   F)keep_blank_valuesrd   r   z/Query string must have exactly one oauth_token.r   rs   z*Query string must have exactly one secret.rQ   z*Query string must have exactly one context)r;   r<   rC   r   lenr   )rE   query_stringr.   rV   re   r_   s         r    rH   zAccessToken.from_string   s     ,5'..w7L,%@]#3x1}OOO}!f,-6{aM!MM**\*G!<;<!ajG3((r   N)rh   ri   rj   rk   ro   r\   rH   r   r   r    r   r      s+     ) ) ) )r   r   c                   "     e Zd ZdZ fdZ xZS )r   zoAn OAuth access token that doesn't authenticate anybody.

    This token can be used for anonymous access.
    c                 .    t         t        |   dd       y )N )superr   __init__)r>   	__class__s    r    r|   zAnonymousAccessToken.__init__  s    "D22r:r   )rh   ri   rj   rk   r|   __classcell__r}   s   @r    r   r     s    
; ;r   r   c                   0    e Zd ZdZddZd Zd Zd Zd Zy)	r   zStore OAuth credentials locally.

    This is a generic superclass. To implement a specific way of
    storing credentials locally you'll need to subclass this class,
    and implement `do_save` and `do_load`.
    Nc                     || _         y)a  Constructor.

        :param credential_save_failed: A callback to be invoked if the
            save to local storage fails. You should never invoke this
            callback yourself! Instead, you should raise an exception
            from do_save().
        N)credential_save_failed)r>   r   s     r    r|   zCredentialStore.__init__&  s     '=#r   c                     	 | j                  ||       |S # t        $ r  t        $ r)}| j                  || j                          Y d}~|S d}~ww xY w)zSave the credentials and invoke the callback on failure.

        Do not override this method when subclassing. Override
        do_save() instead.
        N)do_saveEXPLOSIVE_ERRORS	Exceptionr   )r>   rG   unique_consumer_ides       r    r9   zCredentialStore.save0  sa    	*LL&89    	 	***2''))		*s    AAAc                     t               )zStore newly-authorized credentials locally for later use.

        :param credentials: A Credentials object to save.
        :param unique_consumer_id: A string uniquely identifying an
            OAuth consumer on a Launchpad instance.
        NotImplementedError)r>   rG   r   s      r    r   zCredentialStore.do_save@  s     "##r   c                 $    | j                  |      S )a0  Retrieve credentials from a local store.

        This method is the inverse of `save`.

        There's no special behavior in this method--it just calls
        `do_load`. There _is_ special behavior in `save`, and this
        way, developers can remember to implement `do_save` and
        `do_load`, not `do_save` and `load`.

        :param unique_key: A string uniquely identifying an OAuth consumer
            on a Launchpad instance.

        :return: A `Credentials` object if one is found in the local
            store, and None otherise.
        )do_loadr>   
unique_keys     r    rD   zCredentialStore.loadI  s      ||J''r   c                     t               )a@  Retrieve credentials from a local store.

        This method is the inverse of `do_save`.

        :param unique_key: A string uniquely identifying an OAuth consumer
            on a Launchpad instance.

        :return: A `Credentials` object if one is found in the local
            store, and None otherise.
        r   r   s     r    r   zCredentialStore.do_load[  s     "##r   N)	rh   ri   rj   rk   r|   r9   r   rD   r   r   r   r    r   r     s     = $($$r   r   c                   D     e Zd ZdZdZd fd	Zed        Zd Zd Z	 xZ
S )KeyringCredentialStorezStore credentials in the GNOME keyring or KDE wallet.

    This is a good solution for desktop applications and interactive
    scripts. It doesn't work for non-interactive scripts, or for
    integrating third-party websites into Launchpad.
    s   <B64>c                 `    t         t        |   |       d | _        |rt	        |      | _        y y r   )r{   r   r|   	_fallbackMemoryCredentialStore)r>   r   fallbackr}   s      r    r|   zKeyringCredentialStore.__init__s  s0    $d45KL23IJDN r   c                  v    dt               vrddladt               vr	 ddlma yy# t        $ r	 t
        aY yw xY w)aG  Ensure the keyring module is imported (postponing side effects).

        The keyring module initializes the environment-dependent backend at
        import time (nasty).  We want to avoid that initialization because it
        may do things like prompt the user to unlock their password store
        (e.g., KWallet).
        keyringr   NNoKeyringError)r   )globalsr   keyring.errorsr   ImportErrorRuntimeErrorr   r   r    _ensure_keyring_importedz/KeyringCredentialStore._ensure_keyring_importedy  s>     GI%79,.9 -  .!-.s   & 88c                 x   | j                          |j                         }| j                  t        |      z   }	 t        j                  d||j                  d             y# t        $ rO}t        t        k(  rdt        |      vr | j                  r| j                  j                  ||       n Y d}~yd}~ww xY w)z2Store newly-authorized credentials in the keyring.launchpadlibr8   $No recommended backend was availableN)r   rA   	B64MARKERr   r   set_passwordrC   r   r   strr   r9   )r>   rG   r   r@   r   s        r    r   zKeyringCredentialStore.do_save  s    %%' **,
 ^^i
&;;
	  
J,=,=g,F  	 ,.:#a&H~~##K< =	s   &A! !	B9*AB44B9c                 0   | j                          	 t        j                  d|      }|vt        |t              r|j                  d      }|j                  | j                        r"	 t        |t        | j                        d       }	 t         j#                  |      }|S y# t        $ rM}t        t        k(  rdt        |      vr | j                  r | j                  j                  |      cY d}~S  d}~ww xY w# t        $ r Y yw xY w# t$        $ r Y yw xY w)z&Retrieve credentials from the keyring.r   r   Nutf8)r   r   get_passwordr   r   r   r   rD   r;   r<   r=   
startswithr   r   rv   	TypeErrorr
   rH   r   )r>   r   credential_stringr   rG   s        r    r   zKeyringCredentialStore.do_load  s   %%'	 ' 4 4
! (+\:$5$<$<V$D! ++DNN; (1)#dnn*=*?@)%)556GH"" A  	 ,.:#a&H~~~~**:66	( !        	sH   B! '!C: 	D	 !	C7*AC2+C71C22C7:	DD		DD)NF)rh   ri   rj   rk   r   r|   staticmethodr   r   r   r~   r   s   @r    r   r   i  s3     IK . .$2'r   r   c                   0     e Zd ZdZd fd	Zd Zd Z xZS )UnencryptedFileCredentialStorezStore credentials unencrypted in a file on disk.

    This is a good solution for scripts that need to run without any
    user interaction.
    c                 :    t         t        |   |       || _        y r   )r{   r   r|   filename)r>   r   r   r}   s      r    r|   z'UnencryptedFileCredentialStore.__init__  s    ,d<"	
 !r   c                 :    |j                  | j                         y)zSave the credentials to disk.N)save_to_pathr   r>   rG   r   s      r    r   z&UnencryptedFileCredentialStore.do_save  s      /r   c                     t         j                  j                  | j                        rRt        j                  | j                        t        j
                     dk(  st        j                  | j                        S y)zLoad the credentials from disk.r   N)r   pathexistsr   statST_SIZEr
   load_from_pathr   s     r    r   z&UnencryptedFileCredentialStore.do_load  sN     GGNN4==)GGDMM*4<<8A=--dmm<<r   r   rh   ri   rj   rk   r|   r   r   r~   r   s   @r    r   r     s    !0r   r   c                   0     e Zd ZdZd fd	Zd Zd Z xZS )r   zCredentialStore that stores keys only in memory.

    This can be used to provide a CredentialStore instance without
    actually saving any key to persistent storage.
    c                 :    t         t        |   |       i | _        y r   )r{   r   r|   _credentials)r>   r   r}   s     r    r|   zMemoryCredentialStore.__init__  s    #T34JKr   c                 "    || j                   |<   y)z!Store the credentials in our dictN)r   r   s      r    r   zMemoryCredentialStore.do_save  s    (3*%r   c                 8    | j                   j                  |      S )z&Retrieve the credentials from our dict)r   r   r   s     r    r   zMemoryCredentialStore.do_load  s      $$Z00r   r   r   r   s   @r    r   r     s    41r   r   c                   J    e Zd ZdZdZ	 	 	 d
dZed        Zd Zd Z	d Z
d	 Zy)r   a/  The superclass of all request token authorizers.

    This base class does not implement request token authorization,
    since that varies depending on how you want the end-user to
    authorize a request token. You'll need to subclass this class and
    implement `make_end_user_authorize_token`.
    UNAUTHORIZEDNc                 $   t        j                  |      | _        t        j                  |      | _        ||t        d      ||t        d|d|d      |dg}t        |      }nt        |      }|}|| _        || _	        |xs g | _
        y)aD  Base class initialization.

        :param service_root: The root of the Launchpad instance being
            used.

        :param application_name: The name of the application that
            wants to use launchpadlib. This is used in conjunction
            with a desktop-wide integration.

            If you specify this argument, your values for
            consumer_name and allow_access_levels are ignored.

        :param consumer_name: The OAuth consumer name, for an
            application that wants its own point of integration into
            Launchpad. In almost all cases, you want to specify
            application_name instead and do a desktop-wide
            integration. The exception is when you're integrating a
            third-party website into Launchpad.

        :param allow_access_levels: A list of the Launchpad access
            levels to present to the user. ('READ_PUBLIC' and so on.)
            Your value for this argument will be ignored during a
            desktop-wide integration.
        :type allow_access_levels: A list of strings.
        Nz:You must provide either application_name or consumer_name.zOYou must provide only one of application_name and consumer_name. (You provided z and z.)DESKTOP_INTEGRATION)r   lookup_service_rootservice_rootweb_root_for_service_rootr`   
ValueErrorr   r	   rS   application_nameallow_access_levels)r>   r   r   consumer_namer   rS   s         r    r|   z(RequestTokenAuthorizationEngine.__init__	  s    @ !44\B66|D#(=L  'M,E $]4    $9"9)*:;H  .H,  0#6#<" r   c                 N    | j                   j                  dz   | j                  z   S )z7Return a string identifying this consumer on this host.@)rS   rV   r   )r>   s    r    r   z2RequestTokenAuthorizationEngine.unique_consumer_idI  s$     }}  3&):):::r   c                     t         d|}d}t        | j                        dkD  r!|||j                  | j                        z   z  }t	        | j
                  |      S )zReturn the authorization URL for a request token.

        This is the URL the end-user must visit to authorize the
        token. How exactly does this happen? That depends on the
        subclass implementation.
        rR   z&allow_permission=r   )r^   rv   r   joinr   r`   )r>   request_tokenpageallow_permissions       r    authorization_urlz1RequestTokenAuthorizationEngine.authorization_urlN  sc     ';MJ/t''(1,$'7'<'<(((  D t}}d++r   c                     | j                  |      }| j                  ||       |j                  y|j                  || j                         |S )ad  Authorize a token and associate it with the given credentials.

        If the credential store runs into a problem storing the
        credential locally, the `credential_save_failed` callback will
        be invoked. The callback will not be invoked if there's a
        problem authorizing the credentials.

        :param credentials: A `Credentials` object. If the end-user
            authorizes these credentials, this object will have its
            .access_token property set.

        :param credential_store: A `CredentialStore` object. If the
            end-user authorizes the credentials, they will be
            persisted locally using this object.

        :return: If the credentials are successfully authorized, the
            return value is the `Credentials` object originally passed
            in. Otherwise the return value is None.
        N)rb   make_end_user_authorize_tokenrT   r9   r   )r>   rG   credential_storerequest_token_strings       r    __call__z(RequestTokenAuthorizationEngine.__call__]  sQ    (  $55kB**;8LM##+k4+B+BCr   c                 b    |j                  | j                  t        j                        }|d   S )z\Get a new request token from the server.

        :param return: The request token.
        )r`   ra   rd   )rb   r`   r
   rX   )r>   rG   authorization_jsons      r    rb   z1RequestTokenAuthorizationEngine.get_request_token{  s6    
 )::]]1N1N ; 
 "-00r   c                     t               )a5  Authorize the given request token using the given credentials.

        Your subclass must implement this method: it has no default
        implementation.

        Because an access token may expire or be revoked in the middle
        of a session, this method may be called at arbitrary points in
        a launchpadlib session, or even multiple times during a single
        session (with a different request token each time).

        In most cases, however, this method will be called at the
        beginning of a launchpadlib session, or not at all.
        r   )r>   rG   r   s      r    r   z=RequestTokenAuthorizationEngine.make_end_user_authorize_token  s     "##r   NNN)rh   ri   rj   rk   UNAUTHORIZED_ACCESS_LEVELr|   propertyr   r   r   rb   r   r   r   r    r   r     sH     !/
  >=@ ; ;,<1$r   r   c                   6    e Zd ZdZdZdZd Zd Zd Zd Z	d Z
y	)
AuthorizeRequestTokenWithURLzAuthorize using a URL.

    This authorizer simply shows the URL for the user to open for
    authorization, and waits until the server responds.
    zPlease open this authorization page:
 (%s)
in your browser. Use your browser to authorize
this program to access Launchpad on your behalf.z.Press Enter after authorizing in your browser.c                     t        |       y)zDisplay a message.

        By default, prints the message to standard output. The message
        does not require any user interaction--it's solely
        informative.
        N)print)r>   messages     r    outputz#AuthorizeRequestTokenWithURL.output  s     	gr   c                 @    | j                  | j                  |z         y)Notify the end-user of the URL.N)r   WAITING_FOR_USER)r>   r   s     r    !notify_end_user_authorization_urlz>AuthorizeRequestTokenWithURL.notify_end_user_authorization_url  s    D)),==>r   c                 \   	 |j                  | j                         |j                  duS # t        $ rw}|j                  j                  dk(  rt        |j                        |j                  j                  dk7  rt        d       t        |       t        |j                        d}~ww xY w)z Check if the end-user authorizedi  i  z#Unexpected response from Launchpad:N)
rg   r`   r   r0   r,   EndUserDeclinedAuthorizationr1   r   EndUserNoAuthorizationrT   )r>   rG   r   s      r    check_end_user_authorizationz9AuthorizeRequestTokenWithURL.check_end_user_authorization  s    	8??N ''t33  	8zz  C' 3199==::$$+?@!H,QYY77	8s   + 	B+A2B&&B+c                     | j                  | j                         t        j                          | j	                  |       y)"Wait for the end-user to authorizeN)r   WAITING_FOR_LAUNCHPADr   readliner   )r>   rG   s     r    wait_for_end_user_authorizationz<AuthorizeRequestTokenWithURL.wait_for_end_user_authorization  s,    D../))+6r   c                 j    | j                  |      }| j                  |       | j                  |       y)z2Have the end-user authorize the token using a URL.N)r   r   r   )r>   rG   r   r   s       r    r   z:AuthorizeRequestTokenWithURL.make_end_user_authorize_token  s0     22=A../@A,,[9r   N)rh   ri   rj   rk   r   r   r   r   r   r   r   r   r   r    r   r     s3    	;  M?4$7:r   r   c                   N     e Zd ZdZdZdZdZdZdZ	 	 	 d
 fd	Z	 fdZ
d	 Z xZS )r   aS  Authorize using a URL that pops-up automatically in a browser.

    This authorizer simply opens up the end-user's web browser to a
    Launchpad URL and lets the end-user authorize the request token
    themselves.

    This is the same as its superclass, except this class also
    performs the browser automatic opening of the URL.
    zThe authorization page:
 (%s)
should be opening in your browser. Use your browser to authorize
this program to access Launchpad on your behalf.z/Press Enter to continue or wait (%d) seconds...   )zwww-browserlinkslinks2lynxelinkszelinks-litenetrikw3mz5Waiting to hear from Launchpad about your decision...c                 2    t         t        |   ||d|       y)ao  Constructor.

        :param service_root: See `RequestTokenAuthorizationEngine`.
        :param application_name: See `RequestTokenAuthorizationEngine`.
        :param consumer_name: The value of this argument is
            ignored. If we have the capability to open the end-user's
            web browser, we must be running on the end-user's computer,
            so we should do a full desktop integration.
        :param credential_save_failed: See `RequestTokenAuthorizationEngine`.
        :param allow_access_levels: The value of this argument is
            ignored, for the same reason as consumer_name.
        N)r{   r   r|   )r>   r   r   r   r   r   r}   s         r    r|   z)AuthorizeRequestTokenWithBrowser.__init__  s     . 	.>*D2H	
r   c                    t         t        |   |       	 t        j                         }t        |dd      }|| j                  v }|r_| j                  | j                  | j                  z         t        t        gg g | j                        \  }}}|rt        j                          |t        j                  |       yy# t        j                  $ r d}d}Y w xY w)r   basenameNF)r{   r   r   
webbrowserr   getattrTERMINAL_BROWSERSErrorr   TIMEOUT_MESSAGETIMEOUTr   r   r   open)r>   r   browser_objbrowserconsole_browserrlist_r}   s          r    r   zBAuthorizeRequestTokenWithBrowser.notify_end_user_authorization_url  s    ,d	,,=
>	$$..*Kk:t<G%)?)??O
 KK,,t||;< !%"b$,,?KE1a "OO-. #  	$K#O	$s   /B? ?CCc                 n   | j                  | j                         t        j                         }|j                  kt        j                  t
               	 | j                  |      ry	 t        j                         |t        z   k\  rt        dt        z        |j                  jyy# t        $ r Y Jw xY w)r   NzTimed out after %d seconds.)
r   r   timerT   sleepaccess_token_poll_timer   r   access_token_poll_timeoutTokenAuthorizationTimedOut)r>   rG   
start_times      r    r   z@AuthorizeRequestTokenWithBrowser.wait_for_end_user_authorization&  s    D../YY[
&&.JJ-.44[A B yy{j+DDD014MM  &&.
 * s   B( (	B43B4r   )rh   ri   rj   rk   r   r  r  r   r   r|   r   r   r~   r   s   @r    r   r     sL    	;  HOG	 	@  # 
6/2r   r   c                       e Zd Zy)TokenAuthorizationExceptionNrh   ri   rj   r   r   r    r  r  7      r   r  c                       e Zd Zy)RequestTokenAlreadyAuthorizedNr  r   r   r    r  r  ;  r  r   r  c                       e Zd ZdZy)EndUserAuthorizationFailedz?Superclass exception for all failures of end-user authorizationNrh   ri   rj   rk   r   r   r    r  r  ?  s    Ir   r  c                       e Zd ZdZy)r   zEnd-user declined authorizationNr  r   r   r    r   r   E  s    )r   r   c                       e Zd ZdZy)r   z*End-user did not perform any authorizationNr  r   r   r    r   r   K  s    4r   r   c                       e Zd ZdZy)r  z<End-user did not perform any authorization in timeout periodNr  r   r   r    r  r  Q  s    Fr   r  c                       e Zd Zy)ClientErrorNr  r   r   r    r  r  W  r  r   r  c                       e Zd Zy)ServerErrorNr  r   r   r    r  r  [  r  r   r  c                       e Zd Zy)NoLaunchpadAccountNr  r   r   r    r!  r!  _  r  r   r!  c                       e Zd Zy)TooManyAuthenticationFailuresNr  r   r   r    r#  r#  c  r  r   r#  )J
__future__r   type__metaclass____all__	cStringIOr   r   ior)   rZ   r   r   r   sysr   r
  urllib.parser   urllibr   urlparser   base64r   r   six.moves.urllib.parser   rY   r   unicoder<   lazr.restfulclient.errorsr   "lazr.restfulclient.authorize.oauthr   _AccessTokenr	   r   r   r   r   rW   rf   r^   r  r  MemoryErrorKeyboardInterrupt
SystemExitr   r!   r2   r
   r   objectr   r   r   r   r   r   r   r   r  r  r  r   r   r  r  r  r!  r#  r   r   r    <module>r8     s  " & :"   	    !&!$ 
 ,C<LL /  % # )  # !2J? 
P=/ =D), )@;< ;H$f H$Vc_ cL_ 61O 1(U$f U$p8:#B 8:vc'C cL	) 		$? 		!< 		#= 		7 		!7 		- 		- 		4 		$? 	C    !  !  !  !s3   E( E: F (E76E7:F	F	FF