o
    gfV'                     @   s  d Z ddlmZ ddlmZ ddlmZ zddlZW n e	y9   zddlZW n e	y6   ddl
mZ Y nw Y nw ddlmZmZ ddlmZmZmZmZmZ ddlmZ d	Zd
ZdZdZdZdZdgZddgZdZdZ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%G dd  d e%Z&ed!rd!pd"Z'G d#d$ d$eZ(d%d& Z)d'd( Z*d)d* Z+e$e&e(d+Z,dS ),a  
Google OpenID and OAuth support

OAuth works straightforward using anonymous configurations, username
is generated by requesting email to the not documented, googleapis.com
service. Registered applications can define settings GOOGLE_CONSUMER_KEY
and GOOGLE_CONSUMER_SECRET and they will be used in the auth process.
Setting GOOGLE_OAUTH_EXTRA_SCOPE can be used to access different user
related data, like calendar, contacts, docs, etc.

OAuth2 works similar to OAuth but application must be defined on Google
APIs console https://code.google.com/apis/console/ Identity option.

OpenID also works straightforward, it doesn't need further configurations.
    )	urlencode)RequestN)
simplejson)settingdsa_urlopen)
OpenIdAuthConsumerBasedOAuth
BaseOAuth2OAuthBackendOpenIDBackend)
AuthFailedzwww.google.comz3https://www.google.com/accounts/OAuthAuthorizeTokenz4https://www.google.com/accounts/OAuthGetRequestTokenz3https://www.google.com/accounts/OAuthGetAccessTokenzaccounts.google.com)https://accounts.google.com/o/oauth2/authz.https://www.googleapis.com/auth/userinfo#emailz.https://www.googleapis.com/auth/userinfo.emailz0https://www.googleapis.com/auth/userinfo.profilez)https://www.googleapis.com/userinfo/emailz-https://www.googleapis.com/oauth2/v1/userinfoz%https://www.google.com/accounts/o8/idc                   @   s$   e Zd ZdZdZdd Zdd ZdS )GoogleOAuthBackendz#Google OAuth authentication backendgoogle-oauthc                 C      t | |d  |d S )zUse google email as unique idemailvalidate_whitelistsselfdetailsresponse r   \/var/www/html/humari/django-venv/lib/python3.10/site-packages/social_auth/backends/google.pyget_user_id<   s   zGoogleOAuthBackend.get_user_idc                 C   s(   | dd}|ddd |ddddS )z&Return user details from Orkut accountr    @   r   usernamer   fullname
first_name	last_namegetsplitr   r   r   r   r   r   get_user_detailsA   s   z#GoogleOAuthBackend.get_user_detailsN)__name__
__module____qualname____doc__namer   r'   r   r   r   r   r   8   s
    r   c                       s4   e Zd ZdZdZg dZ fddZdd Z  ZS )GoogleOAuth2Backendz$Google OAuth2 authentication backendgoogle-oauth2))refresh_tokenr/   T)
expires_inexpires)
token_typer2   Tc                    s(   t t| ||}tddr|d S |S )z#Use google email or id as unique id GOOGLE_OAUTH2_USE_UNIQUE_USER_IDFid)superr-   r   r   )r   r   r   user_id	__class__r   r   r   T   s   
zGoogleOAuth2Backend.get_user_idc                 C   s@   | dd}|ddd || dd| dd| ddd	S )
Nr   r   r   r   r   r,   
given_namefamily_namer   r#   r&   r   r   r   r'   \   s   


z$GoogleOAuth2Backend.get_user_details)	r(   r)   r*   r+   r,   
EXTRA_DATAr   r'   __classcell__r   r   r7   r   r-   K   s    r-   c                   @   s   e Zd ZdZdZdd ZdS )GoogleBackendz$Google OpenID authentication backendgooglec                 C   r   )z
        Return user unique id provided by service. For google user email
        is unique enought to flag a single user. Email comes from schema:
        http://axschema.org/contact/email
        r   r   r   r   r   r   r   i   s   zGoogleBackend.get_user_idN)r(   r)   r*   r+   r,   r   r   r   r   r   r=   e       r=   c                   @   s   e Zd ZdZeZdd ZdS )
GoogleAuthzGoogle OpenID authenticationc                 C   s   t S )z Return Google OpenID service url)GOOGLE_OPENID_URLr   r   r   r   
openid_urly   s   zGoogleAuth.openid_urlN)r(   r)   r*   r+   r=   AUTH_BACKENDrC   r   r   r   r   r@   u   r?   r@   c                   @   s$   e Zd ZdZeZeZeZdd ZdS )BaseGoogleOAuthz%Base class for Google OAuth mechanismc                 O   s   t d)zLoads user data from G servicezImplement in subclass)NotImplementedErrorr   access_tokenargskwargsr   r   r   	user_data      zBaseGoogleOAuth.user_dataN)r(   r)   r*   r+   AUTHORIZATION_URLREQUEST_TOKEN_URLACCESS_TOKEN_URLrK   r   r   r   r   rE   ~   s    rE   c                       sb   e Zd ZdZeZdZdZdd Zdd Z	d fd	d
	Z
e fddZedd Zdd Z  ZS )GoogleOAuthz$Google OAuth authorization mechanismGOOGLE_CONSUMER_KEYGOOGLE_CONSUMER_SECRETc                 O   s0   |  |tddi}| dd\}}t||S ) Return user data from Google APIaltjson?r   )oauth_requestGOOGLEAPIS_EMAILto_urlr%   googleapis_email)r   rH   rI   rJ   requesturlparamsr   r   r   rK      s
   
zGoogleOAuth.user_datac                 C   s   t j| j|| jdS )z*Generate OAuth request to authorize token.)tokenhttp_url)OAuthRequestfrom_consumer_and_tokenconsumerrM   )r   r^   r   r   r   oauth_authorization_request   s   z'GoogleOAuth.oauth_authorization_requestNc                    sX   |pi }t tdg  }|dd|i |  s"tdd}||d< tt| |||S )NGOOGLE_OAUTH_EXTRA_SCOPEscope GOOGLE_DISPLAY_NAMEzSocial Authxoauth_displayname)GOOGLE_OAUTH_SCOPEr   updatejoin
registeredr5   rP   rW   )r   r^   r\   extra_paramsre   rh   r7   r   r   rW      s   

zGoogleOAuth.oauth_requestc                    s&   zt t|  W S  ty   Y dS w )a.  Return Google OAuth Consumer Key and Consumer Secret pair, uses
        anonymous by default, beware that this marks the application as not
        registered and a security badge is displayed on authorization page.
        http://code.google.com/apis/accounts/docs/OAuth_ref.html#SigningOAuth
        	anonymousro   )r5   rP   get_key_and_secretAttributeErrorclsr7   r   r   rp      s
   zGoogleOAuth.get_key_and_secretc                 C   s   dS )z:Google OAuth is always enabled because of anonymous accessTr   rr   r   r   r   enabled   s   zGoogleOAuth.enabledc                 C   s   |   dkS )z>Check if Google OAuth Consumer Key and Consumer Secret are setrn   )rp   rB   r   r   r   rl      s   zGoogleOAuth.registered)N)r(   r)   r*   r+   r   rD   SETTINGS_KEY_NAMESETTINGS_SECRET_NAMErK   rc   rW   classmethodrp   rt   rl   r<   r   r   r7   r   rP      s    
rP   GOOGLE_OAUTH2_CLIENT_IDGOOGLE_OAUTH2_CLIENT_KEYc                   @   sX   e Zd ZdZeZdZdZdZdZ	e
ZdZdZeZdZd	d
 Zedd Zedd ZdS )GoogleOAuth2zGoogle OAuth2 supportr   z*https://accounts.google.com/o/oauth2/tokenz+https://accounts.google.com/o/oauth2/revokeGETGOOGLE_OAUTH2_CLIENT_SECRETrd   Fc                 O   s
   t t|S )rS   )googleapis_profileGOOGLEAPIS_PROFILErG   r   r   r   rK      s   
zGoogleOAuth2.user_datac                 C   s   d|iS )Nr^   r   rs   r^   uidr   r   r   revoke_token_params   rL   z GoogleOAuth2.revoke_token_paramsc                 C   s   ddiS )NzContent-typezapplication/jsonr   r   r   r   r   revoke_token_headers   rL   z!GoogleOAuth2.revoke_token_headersN)r(   r)   r*   r+   r-   rD   rM   rO   REVOKE_TOKEN_URLREVOKE_TOKEN_METHOD_OAUTH2_KEY_NAMEru   rv   SCOPE_VAR_NAMEGOOGLE_OAUTH2_SCOPEDEFAULT_SCOPEREDIRECT_STATErK   rw   r   r   r   r   r   r   rz      s"    
rz   c              
   C   sL   t | d | d|id}ztt| d W S  tttfy%   Y dS w )a  Loads user data from googleapis service, only email so far as it's
    described in http://sites.google.com/site/oauthgoog/Home/emaildisplayscope

    Parameters must be passed in queryset and Authorization header as described
    on Google OAuth documentation at:
    http://groups.google.com/group/oauth/browse_thread/thread/d15add9beb418ebc
    and: http://code.google.com/apis/accounts/docs/OAuth2.html#CallingAnAPI
    rV   Authorization)headersdataN)r   r   loadsr   read
ValueErrorKeyErrorIOError)r\   r]   r[   r   r   r   rZ      s   	rZ   c              
   C   sN   |dd}t | d t| }z
tt| W S  tttfy&   Y dS w )z
    Loads user data from googleapis service, such as name, given_name,
    family_name, etc. as it's described in:
    https://developers.google.com/accounts/docs/OAuth2Login
    rU   )rH   rT   rV   N)	r   r   r   r   r   r   r   r   r   )r\   rH   r   r[   r   r   r   r}      s   
r}   c                 C   sV   t dg }t dg }|s|sdS |t|v rdS |ddd t|v r&dS t| d)z
    Validates allowed domains and emails against the following settings:
        GOOGLE_WHITE_LISTED_DOMAINS
        GOOGLE_WHITE_LISTED_EMAILS

    All domains and emails are allowed if setting is an empty list.
    GOOGLE_WHITE_LISTED_EMAILSGOOGLE_WHITE_LISTED_DOMAINSTr   r   zUser not allowed)r   setr%   r   )backendr   emailsdomainsr   r   r   r      s   


r   )r>   r   r.   )-r+   urllibr   urllib2r   oauth2r`   rU   r   ImportErrordjango.utilssocial_auth.utilsr   r   social_auth.backendsr   r   r	   r
   r   social_auth.exceptionsr   GOOGLE_OAUTH_SERVERrM   rN   rO   GOOGLE_OAUTH2_SERVERGOOGLE_OATUH2_AUTHORIZATION_URLri   r   rX   r~   rA   r   r-   r=   r@   rE   rP   r   rz   rZ   r}   r   BACKENDSr   r   r   r   <module>   sb    	5
