B
    f/                 @   s>   d dl T ddlmZ d dlmZmZmZ G dd dejZdS )    )*   )cmf_session)datetime	timedeltatimezonec                   s   e Zd Zi Zeeje	j
ddgZeed< ejf eZdZddddgZed	d
dZeed	ddZeddddedddZdd ZedddedddZ fddZeedddZed d! Zd"d# Z  ZS )$
CmfSessionZcmfZ	templatesloaderTtfa_check_codetfa_send_codeswitch_userswitch_disable)returnc             C   s   | j jdd }t|S )N:   )idvaluesplitcmfutilZcrypt)selfmessage r   ./cmf/models/cmf_session.py	get_token   s    zCmfSession.get_tokenc          
   C   sN  yt |}W n   td dS tjjd| dddgd}|rJtt	j
}||jt|jjd td	d
 kr|jr|dg |j|}nd|_|  |  |jrtd|j d tjjdddd|j|j|jd	d dS tjdd}|jj|_|jj|_|jj|_d|_d|_ td|j d|j d|j   ||fS dS )NuD   Не удалось расшифровать токен сессии)NNzCmfSession:Fr   plugin)r   expiredfields)secondsr   )Zminuteszplugin.plugin.*Tu&   Сессия пользователя u    истеклаZlogoutCmfAuthok)operatecmf_model_nameresult_statuscurrent_transactionparent_nameparent_codeparentsecurity_level)emptyzfrom_session_token: jwt is ok, z, z, is_local=)!r   decryptgdebugmodelsr   getr   nowr   utcreauth_dater   access_token_expires_inr   r   load_fieldsZrefresh_tokenr   saveswitch_check_timeout
user_loginCmfAuditaudit_eventuser_idr   login
user_emailemailZ
user_scopeZscopeZjwt_is_supportZjwt_is_match_org)clsZsession_tokenZdecrypted_tokensessionr.   objr   r   r   
from_token   s>    
"



"zCmfSession.from_tokenNany)two_factor_optmethodr=   )rA   c                s8  s
t j fdd} fdd}dd ldddg tjjjd	d
dgdjstt	d d d S | s
 } | r4jrʈj j  dk rt	ddj j     d S dfddtdD _j    | dkr|  |  n"| dkr$|  n| dkr4|  d S )Nc                 sX    dks dkrTj js0td ddd d S tj } | j jjj d d S )Nr@   phoneu   У абонента u.    не указан номер телефонаT)abortu&    ваш проверочный код.)	
two_factorrC   	cmf_alertr,   ZCmfPluginSMSGateZget_local_smsgatesend_messageZnumbersms_code)Zsms_gate)rB   personr=   r   r   send_smsB   s    
z*CmfSession.tfa_send_code.<locals>.send_smsc                 sp    dks dkrlj js0td ddd d S jd} | jjd}tj	 }|j
j jj|d	d
 d S )Nr@   r;   u   У абонента u    не указан emailT)rD   ztfa_mail.html)Ztfa_coderI   uJ   Код безопасности для учетной записи EvaTeam)Zsubject)rE   r;   rF   
_jinja_envZget_templateZrenderrH   r,   ZCmfPluginMailBoxZget_local_mailboxrG   r   )templateZ
email_bodyZmail_box)rB   rI   r=   r   r   
send_emailJ   s    
z,CmfSession.tfa_send_code.<locals>.send_emailr   sms_send_timerH   r8   ztwo_factor.*ztwo_factor.two_factor_optr   )r   r   u   У пользователя u    не настроена 2FA   uK   Следующая отправка будет доступна через  c             3   s   | ]}t  d dV  qdS )r   	   N)strZrandint).0_)randomr   r   	<genexpr>d   s    z+CmfSession.tfa_send_code.<locals>.<genexpr>   r@   Zsmsr;   )r*   r=   rU   r2   r,   	CmfPersonr-   r8   rE   rF   get_two_factor_optrN   r.   Ztotal_secondsjoinrangerH   set_nowr3   )rA   rB   r=   argskwargsrJ   rM   r   )rB   rI   rU   r=   r   r   >   s6     



zCmfSession.tfa_send_codec             C   s   ddl m} | jrd S | jtjjjkr.tj}ntj	j
| jdddgd}| r|jr`tjjs`d S dtji}||}tt  d| }tj
d	d
|jd< d|jd< d|jd< |S d S )Nr   )	urlencodeis_adminZ
is_supportztwo_factor.two_factor_opt)r   r   Znext_urlzauth/two-factor?ZOriginr   zAccess-Control-Allow-Origintruez Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headers)Zurllib.parser_   checkedr8   r*   Zcurrent_userr   r   r,   rX   r-   rY   r`   global_settingsZtwo_factor_adminZrequestZurlZredirectZauth_base_hrefZheaders)r   r_   rI   paramsZqsrr   r   r   tfa_check_two_factoro   s"    


zCmfSession.tfa_check_two_factorrC   )rB   r=   )codec      
   	   O   s  dd l }|stj}tjj|jddgd}d}|d kr^x(dD ] }t|j|r:|	dd }P q:W |spt
d| | jd	7  _|j  |j}|| krd
|_nB|jjrt  ||jj }	W d Q R X |	| }|rd
|_|rt|j| dd
 |j  |  |S )Nr   ztwo_factor.*r   )r   r   F)Zapplication_verifiedZemail_verifiedZphone_verifiedrT   u   Необходимо указать метод авторизации по которому происходит проверка method=r   TZ	_verified)pyotpr*   r=   r,   rX   r-   r8   getattrrE   r   AssertionErrorZsms_try_countZsms_try_timer\   rH   rb   Ztopt_secretr   Zdisable_aclZTOTPr)   Zverifysetattrr3   )
rg   rB   r=   r]   r^   rh   rI   resultmZtotpr   r   r   r
      s6    




zCmfSession.tfa_check_codec                s   d }| j r(| jt| j jd }|d}d }| jrP| jt| jjd }|d}| jrtj	j
ddt| jt| jddd| j| jd	 td	| j d
| d|  ntd| j d
| d|  | js| j| _t j||S )N)r   z%Y-%m-%d %H:%M:%S %Z%zZlogin_successedr   r   Tr   )	r    r!   Z
cmf_authorr&   r"   r#   r'   r$   r%   u-   Создали новую сессию login=u   , время жизни до u)   , обновление токена до u$   Обновили сессию login=)r1   r0   r   r   ZstrftimeZlifetimeZ	auth_dateZis_newr,   r6   r7   rR   r8   r5   r*   r+   real_user_idsuperr3   )r   r]   r^   Zrefresh_untilZlifetime_until)	__class__r   r   r3      s$    

 zCmfSession.save)r8   c             O   s   t jj| tjd}|stdt jjdd}|jtj	krDt
d dS t jjdd}t jj|jdd	}|j|krzt
d
 dS tjjtj_tjj  |jtj_|jtj_|jtj_tj  tjjdkrt jjtj|dtj dddd dS )u   Метод переключает пользователя в текущей сессии

        Args:
            user_id (str): ИД пользователя на которого хотим переключиться
        )r   r   u5   Пользователь не найден id=user_idZSuAvailable)rg   uH   Пользователь не состоит в группе SuAvailableNZ	SuExcludeT)Z
subject_idZid_onlyun   На этого пользователя нельзя переключится, он в группе SuExclude)Zon_session_starton_session_start_and_endu   Пользователь u$    вошел в ваш аккаунтrP   )r>   rI   namemsgforce_notify_current_person)r,   rX   sgetZAPPZcurrent_person_fieldsrj   ZCmfPersonGroupr   r*   Zcurrent_person__member_ofrF   ZCmfAccessListZsubject_full_group_listr=   r8   rn   switch_user_dater\   r9   r5   r;   r:   r3   rc   	su_notify	CmfNotifyplace_notifycurrent_person)r8   r]   r^   userZsu_availableZ
su_excludeZuser__member_ofr   r   r   r      s0    




zCmfSession.switch_userc              O   s   t jjrt jjt jjkrdS tjjt jjdddgd}|jt j_|j	t j_
|jt j_dt j_t j  t jjdkrtjjtt jd| dd	d
d dS )u)   Выключаем SU режим
        Nz--r9   r;   )r   r   )Zon_session_endrq   u   Пользователь u.    вышел из вашего аккаунтаrP   T)r>   rI   rr   rs   rt   )r*   r=   rn   r8   r,   rX   ru   r9   r5   r;   r:   r   rv   r3   rc   rw   rx   ry   r{   rz   )r]   r^   Z	real_userr   r   r   r      s    




zCmfSession.switch_disablec             C   s>   t tj}| jr:|| jttjjj	d kr:d| _
|   dS )u   Отключаем сессию если вышел таймаут на перключение пользователя
        )r   TN)r   r.   r   r/   rv   r   r*   rc   Zsu_session_time_limitr   r   r3   )r   r.   r   r   r   r4      s     zCmfSession.switch_check_timeout)__name__
__module____qualname__Z_optionsZjinja2ZFileSystemLoaderospathrZ   ZconfigZPROJECT_DIRZ_loaderZEnvironmentrK   Z	api_allowZapi_methodsrR   r   classmethodr?   staticmethodr   rf   r
   r3   r   r   r4   __classcell__r   r   )rp   r   r      s,   %0#r   N)Zcmf.includer   r   r   r   r   r   r   r   r   r   <module>   s   