o
    gf]'                     @   s~  d Z zddlZW n ey'   zddlZW n ey$   ddlmZ Y nw Y nw 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mZmZmZ dd	lmZmZmZmZ dd
lmZmZmZ dZdZdZg dZdZdZdZ ededdZ!e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'G d!d" d"e'Z(d&d#d$Z)e$e"se'ne(d%Z*dS )'z
vk.com OpenAPI and OAuth 2.0 support.

This contribution adds support for VK.com OpenAPI, OAuth 2.0 and IFrame apps.
Username is retrieved from the identity returned by server.
    N)
simplejson)authenticate)	urlencode)md5)time)SocialAuthBackendOAuthBackendBaseAuth
BaseOAuth2)AuthTokenRevokedAuthExceptionAuthCanceled
AuthFailed)settinglogdsa_urlopenzhttp://oauth.vk.com/authorizez!https://oauth.vk.com/access_tokenzvk.com)
first_name	last_namescreen_namenicknamephotozhttps://api.vk.com/method/zhttp://api.vk.com/api.phpz3.0VK_LOCAL_HTMLVKONTAKTE_LOCAL_HTMLzvkontakte.htmlVKAPP_APP_IDFc                   @   s$   e Zd ZdZdZdd Zdd ZdS )VKOpenAPIBackendz!VK OpenAPI authentication backend
vk-openapic                 C      |d S )z$Return user unique id provided by VKid selfdetailsresponser   r   `/var/www/html/humari/django-venv/lib/python3.10/site-packages/social_auth/backends/contrib/vk.pyget_user_id2      zVKOpenAPIBackend.get_user_idc                 C   sh   | dp|d }t|ttfr|d }|ddd|v r"| dd ndd|v r0| dd dS ddS )z#Return user details from VK requestr   r   r    r   r   )usernameemailfullnamer   r   )get
isinstancelisttuple)r    r"   r   r   r   r#   get_user_details6   s   z!VKOpenAPIBackend.get_user_detailsN)__name__
__module____qualname____doc__namer$   r.   r   r   r   r#   r   .   s
    r   c                   @   s@   e Zd ZdZeZedZdd Zdd Z	dd Z
ed	d
 ZdS )VKOpenAPIAuthz)VKontakte OpenAPI authorization mechanismVKONTAKTE_APP_IDc                 O   s   t | jjS N)dictrequestGET)r    access_tokenargskwargsr   r   r#   	user_dataK   s   zVKOpenAPIAuth.user_datac                 C   s>   ddl m}m} | j| jd}|t}|| j|}||S )z\Returns local VK authentication page, not necessary for
        VK to authenticate.
        r   )RequestContextloader)	VK_APP_IDVK_COMPLETE_URL)	django.templater>   r?   APP_IDredirectget_template
LOCAL_HTMLr8   render)r    r>   r?   r7   vk_templatecontextr   r   r#   	auth_htmlN   s   

zVKOpenAPIAuth.auth_htmlc              	      s   d| j  }d| jjvs|| jjvrt| tdd | jj| dD  d fdddD }t|t	d	 
 }| d
 ksJt d t k rNtd|d| d|  d | jjdi t|i |S )zIPerforms check of authentication in VK, returns User if
        succeededvk_app_r   c                 s   s    | ]}| d V  qdS =N)split.0itemr   r   r#   	<genexpr>e   s    z.VKOpenAPIAuth.auth_complete.<locals>.<genexpr>&r&   c                 3        | ]}|d   |  V  qdS rL   r   rO   cookie_dictr   r#   rR   g   s    )expiremidsecretsidVK_API_SECRETsigrW   z&VK authentication failed: invalid hashauthr"   rX   T)rC   r8   r9   COOKIESr   r7   rN   joinr   r   	hexdigestintr   r   updater=   AUTH_BACKENDr3   r   )r    r;   r<   
app_cookie	check_strhashr   rU   r#   auth_complete\   s&   
zVKOpenAPIAuth.auth_completec                 C   s   dS )zVK does not require visiting server url in order
        to do authentication, so auth_xxx methods are not needed to be called.
        Their current implementation is just an exampleFr   r    r   r   r#   uses_redirectv   s   zVKOpenAPIAuth.uses_redirectN)r/   r0   r1   r2   r   rc   r   rC   r=   rJ   rg   propertyri   r   r   r   r#   r4   F   s    r4   c                   @   s,   e Zd ZdZdZddgZdd Zdd Zd	S )
VKOAuth2BackendzVKOAuth2 authentication backendvk-oauth)r   r   )expiresrm   c                 C   r   )z4OAuth providers return an unique user id in responseuser_idr   r   r   r   r#   r$      r%   zVKOAuth2Backend.get_user_idc                 C   s    | dd| d| ddS )z#Return user details from VK accountr   r&   r   r   )r'   r(   r   r   )r*   )r    r"   r   r   r#   r.      s
   z VKOAuth2Backend.get_user_detailsN)r/   r0   r1   r2   r3   
EXTRA_DATAr$   r.   r   r   r   r#   rk   ~   s    rk   c                   @   s   e Zd ZdZdS )VKApplicationBackendzvk-appN)r/   r0   r1   r3   r   r   r   r#   rp      s    rp   c                   @   s8   e Zd ZdZeZeZeZ	dZ
dZdZdd Zdd Zd	S )
VKOAuth2zVK OAuth mechanismr@   r[   VK_EXTRA_SCOPEc                 C   s   t tjpt dS )NVK_OAUTH2_EXTRA_SCOPE)r   rq   SCOPE_VAR_NAMErh   r   r   r#   	get_scope   s   
zVKOAuth2.get_scopec           
      O   s   d ttdg  }|||dd}td|}|dr8|d }|dd}	|d	d
kr3t| |	t| |	|rH|dd }|d|d< |S )zLoads user data from service,VK_EXTRA_DATArn   )r:   fieldsuidsz	users.geterror	error_msgzUnknown error
error_code   r"   r   r   
user_photo)r_   VK_DEFAULT_DATAr   r*   vk_apir   r   )
r    r:   r"   r;   r<   rx   paramsdatarz   msgr   r   r#   r=      s    



zVKOAuth2.user_dataN)r/   r0   r1   r2   VK_AUTHORIZATION_URLAUTHORIZATION_URLVK_ACCESS_TOKEN_URLACCESS_TOKEN_URLrk   rc   SETTINGS_KEY_NAMESETTINGS_SECRET_NAMErt   ru   r=   r   r   r   r#   rq      s    rq   c                       sH   e Zd ZdZeZdZdZ fddZdddZ	dd	d
Z
dd Z  ZS )	VKAppAuthz,VKontakte Application Authentication supportr   VKAPP_API_SECRETc                    s:   | j |i |\}}|r|S |rd S tt| j|i |S r6   )application_authsuperr   rg   )r    r;   r<   stopapp_auth	__class__r   r#   rg      s   zVKAppAuth.auth_completeNc                 C   s<   |dd}|r||d< t d|dddd }|r|d S d S )	Nr   )ry   rx   r:   getProfilesTis_appr"   r   r   r*   )r    rn   r:   r   profilesr   r   r#   user_profile   s   
zVKAppAuth.user_profilec                 C   s*   d|i}|r
||d< t d|ddddS )z"Returns app usage flag from VK APIuidr:   	isAppUserTr   r"   r   r   )r    rn   r:   r   r   r   r#   is_app_user   s   zVKAppAuth.is_app_userc                 O   s   d}|D ]}|| j jvr dS q| j jd}|r8tdt| j| j jdt| jg }||kr8t	dtdd}| j jd}|r\|d	krQ| j jd
n| 
|}	t|	s\dS | |}
||
d< dt|i d| d| j d|
| jjdifS )N)r   	viewer_idr:   api_id)FNauth_key_r   z*VK authentication failed: invalid auth keyVKAPP_USER_MODEr      r   )TNrn   Tr]   r8   r"   )r8   REQUESTr*   r   r_   r   r   r   r`   
ValueErrorr   ra   r   r   rc   r3   )r    r;   r<   required_paramsparamr   	check_key
user_checkrn   is_userr   r   r   r#   r      s>   


zVKAppAuth.application_authr6   )r/   r0   r1   r2   rp   rc   r   r   rg   r   r   r   __classcell__r   r   r   r#   r      s    



r   c                    s   d vrGd vrt  d< d vrt|rdnd d< |  d< d d< t}t|r)d	nd
}tt fdd D }td||   d< nt|  }t	 }|d| 7 }zt
t|W S  tttttfyw   tdddt dd Y dS w )zCalls VK OpenAPI method
        https://vk.com/apiclub,
        https://vk.com/pages.php?o=-1&p=%C2%FB%EF%EE%EB%ED%E5%ED%E8%E5%20%E7'
                                        %E0%EF%F0%EE%F1%EE%E2%20%EA%20API
    r:   vr   r   r@   methodjsonformatr   r[   c                 3   rT   rL   r   rO   r   r   r#   rR   #  s    zvk_api.<locals>.<genexpr>r&   r\   ?rz   zCould not load data from vk.comTr   )exc_infoextraN)VK_API_VERSIONr   VK_SERVER_API_URLsortedr,   r   r_   r`   
VK_API_URLr   r   loadr   	TypeErrorKeyErrorIOErrorr   
IndexErrorr   r7   )r   r   r   urlrY   
param_listr   r   r   r#   r     s,   
r   )r   rl   )F)+r2   r   r   ImportErrordjango.utilsdjango.contrib.authr   urllibr   hashlibr   r   social_auth.backendsr   r   r	   r
   social_auth.exceptionsr   r   r   r   social_auth.utilsr   r   r   r   r   	VK_SERVERr   r   r   r   rF   USE_APP_AUTHr   r4   rk   rp   rq   r   r   BACKENDSr   r   r   r#   <module>   sN   
8'
N&

