o
    O6ufT   ã                   @   sl   d dl Z zd dlZdZW n ey   dZY nw d dlZd dlmZmZ dZdZe  	d¡Z
G dd	„ d	ƒZdS )
é    NTF)ÚdatetimeÚ	timedeltaz	sos-toolsz,urn:ietf:params:oauth:grant-type:device_codeÚsosc                   @   sZ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zddd„ZdS )ÚDeviceAuthorizationClassz$
    Device Authorization Class
    c                 C   s*   d | _ d | _d | _|| _|| _|  ¡  d S ©N)Ú_access_tokenÚ_access_expires_atÚ&_DeviceAuthorizationClass__device_codeÚclient_identifier_urlÚtoken_endpointÚ_use_device_code_grant)Úselfr
   r   © r   ú</usr/lib/python3/dist-packages/sos/policies/auth/__init__.pyÚ__init__   s   z!DeviceAuthorizationClass.__init__c                 C   s$   |   ¡  td| j› �ƒ |  ¡  dS )zv
        Start the device auth flow. In the future we will
        store the tokens in an in-memory keyring.

        z<Please visit the following URL to authenticate this device: N)Ú_request_device_codeÚprintÚ_verification_uri_completeÚpoll_for_auth_completion©r   r   r   r   r   )   s   ÿÿz/DeviceAuthorizationClass._use_device_code_grantc              
   C   s¶   dt › �}ddi}tstdƒ‚z2tj| j||d�}| ¡  | ¡ }| d¡| _	| d¡| _
| d¡| _| d	¡| _| d
¡| _W dS  tjyZ } zt d|j› d|› �¡‚d}~ww )zm
        Initialize new Device Authorization Grant attempt by
        requesting a new device code.

        z
client_id=zcontent-typez!application/x-www-form-urlencodedúRpython3-requests is not installed and is required for obtaining device auth token.)ÚdataÚheadersÚ	user_codeÚverification_uriÚintervalÚdevice_codeÚverification_uri_completezNHTTP request failed while attempting to acquire the tokens.Error returned was ú N)ÚDEVICE_AUTH_CLIENT_IDÚREQUESTS_LOADEDÚ	ExceptionÚrequestsÚpostr
   Úraise_for_statusÚjsonÚgetÚ
_user_codeÚ_verification_uriÚ	_intervalr	   r   Ú	HTTPErrorÚstatus_code)r   r   r   ÚresÚresponseÚer   r   r   r   7   s6   
ýÿþý€ÿz-DeviceAuthorizationClass._request_device_codec              
   C   sî   t t| jdœ}tstdƒ‚| jdu rut | j¡ z9t	j
| j|d�}|j}|dkr4t d¡ |  | ¡ ¡ |dvr>t||jƒ‚|dkrP| ¡ d	 d
vrPt||jƒ‚W n t	jjym } zt d|› �¡ W Y d}~nd}~ww | jdu sdS dS )z�
        Continuously poll OIDC token endpoint until the user is successfully
        authenticated or an error occurs.

        )Ú
grant_typeÚ	client_idr   r   N©r   éÈ   z$The SSO authentication is successful)r2   é�  r3   Úerror)Úauthorization_pendingÚ	slow_downz)Error was found while posting a request: )ÚGRANT_TYPE_DEVICE_CODEr   r	   r    r!   r   ÚtimeÚsleepr)   r"   r#   r   r+   ÚloggerÚinfoÚ_set_token_datar%   ÚtextÚ
exceptionsÚRequestExceptionr4   )r   Ú
token_dataÚcheck_auth_completionr+   r.   r   r   r   r   U   s:   þ
ÿ

ÿ€€ÿïz1DeviceAuthorizationClass.poll_for_auth_completionc                 C   sn   |  d¡| _t ¡ t|  d¡d� | _|  d¡| _|  d¡| _| jdkr*tj| _	dS t ¡ t| jd� | _	dS )a@  
        Set the class attributes as per the input token_data received.
        In the future we will persist the token data in a local,
        in-memory keyring, to avoid visting the browser frequently.
        :param token_data: Token data containing access_token, refresh_token
        and their expiry etc.
        Úaccess_tokenÚ
expires_in©ÚsecondsÚrefresh_tokenÚrefresh_expires_inr   N)
r&   r   r   Úutcnowr   r   Ú_refresh_tokenÚ_refresh_expires_inÚmaxÚ_refresh_expires_at)r   r@   r   r   r   r<   v   s   ÿ


ÿz(DeviceAuthorizationClass._set_token_datac                 C   s2   |   ¡ r| jS |  ¡ r|  ¡  | jS |  ¡  | jS )zt
        Get the valid access_token at any given time.
        :return: Access_token
        :rtype: string
        )Úis_access_token_validr   Úis_refresh_token_validÚ_use_refresh_token_grantr   r   r   r   r   Úget_access_token‰   s   z)DeviceAuthorizationClass.get_access_tokenc                 C   ó$   | j o| jo| jtdd� t ¡ kS )z¢
        Check the validity of access_token. We are considering it invalid 180
        sec. prior to it's exact expiry time.
        :return: True/False

        é´   rD   )r   r   r   r   rH   r   r   r   r   rM   ™   s
   ÿÿz.DeviceAuthorizationClass.is_access_token_validc                 C   rQ   )z¤
        Check the validity of refresh_token. We are considering it invalid
        180 sec. prior to it's exact expiry time.

        :return: True/False

        rR   rD   )rI   rL   r   r   rH   r   r   r   r   rN   ¤   s
   ÿÿz/DeviceAuthorizationClass.is_refresh_token_validNc                 C   s´   t stdƒ‚td|s| jn|dœ}tj| j|d�}|jdkr'|  | 	¡ ¡ dS |jdkrKd| 	¡ d v rKt
 d	|j› d
| 	¡ d › d�¡ |  ¡  dS td|j› d| 	¡ d › �ƒ‚)z·
        Fetch the new access_token and refresh_token using the existing
        refresh_token and persist it.
        :param refresh_token: optional param for refresh_token

        r   rF   )r0   r/   rF   r1   r2   r3   Úinvalidr4   zAProblem while fetching the new tokens from refresh token grant - r   z%. New Device code will be requested !zcSomething went wrong while using the Refresh token grant for fetching tokens: Returned status code z and error N)r    r!   r   rI   r"   r#   r   r+   r<   r%   r:   Úwarningr   )r   rF   Úrefresh_token_dataÚrefresh_token_resr   r   r   rO   °   s:   ÿýÿ

ÿÿ

þþ
ýÿz1DeviceAuthorizationClass._use_refresh_token_grantr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r<   rP   rM   rN   rO   r   r   r   r   r      s    
!r   )Úloggingr"   r    ÚImportErrorr8   r   r   r   r7   Ú	getLoggerr:   r   r   r   r   r   Ú<module>   s   
ÿ
