U
    h8                     @   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d%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_tokenFc           
   	   C   s  zt |}W n   td Y dS X tjjd| dddgd}|rt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|j|j|jd	d dS tjdd}|jj|_|jj|_|jj|_|js|rtjrtjj|jkrd}tj D ]D}|!drFt j"|dgd}	|	spqF|dt#j$ d|	j% 7 }qF||_d|_&d|_'td|j d|j d|j'  ||fS dS )NuD   Не удалось расшифровать токен сессии)NNzCmfSession:Fr   plugin)r   expiredfieldsZsecondsr   )Zminuteszplugin.plugin.*Tu&   Сессия пользователя u    истеклаZlogoutCmfAuthok)operatecmf_model_nameresult_statusparent_nameparent_codeparentsecurity_level)empty zCmfPersonGroup:code)r    r   z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_scopescopecurrent_usercurrent_person__member_of
startswithZget_obj_by_idconfigZORG_NAMEr)   Zjwt_is_supportZjwt_is_match_org)
clsZsession_tokenZrequire_scopesZdecrypted_tokensessionr0   objr>   Zgroup_idgroupr   r   r   
from_token   sV    
"
  


	&
"zCmfSession.from_tokenNany)two_factor_optmethodrD   )rI   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 )NrH   phone   У абонента u.    не указан номер телефонаTabortu&    ваш проверочный код.)	
two_factorrK   	cmf_alertr.   ZCmfPluginSMSGateZget_local_smsgatesend_messagenumbersms_code)Zsms_gaterJ   personrD   r   r   send_smsT   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 )NrH   r=   rL   u    не указан emailTrM   ztfa_mail.html)Ztfa_coderU   uJ   Код безопасности для учетной записи EvaTeam)Zsubject)rO   r=   rP   
_jinja_envZget_templateZrenderrS   r.   ZCmfPluginMailBoxZget_local_mailboxrQ   r   )templateZ
email_bodyZmail_boxrT   r   r   
send_email\   s    
  z,CmfSession.tfa_send_code.<locals>.send_emailr   sms_send_timerS   r:   two_factor.*two_factor.two_factor_optr   r   r   u   У пользователя u    не настроена 2FA   uK   Следующая отправка будет доступна через r(   c                 3   s   | ]}t  d dV  qdS )r   	   N)strZrandint).0_)randomr   r   	<genexpr>v   s     z+CmfSession.tfa_send_code.<locals>.<genexpr>   rH   Zsmsr=   )r,   rD   rc   r4   r.   	CmfPersonr/   r:   rO   rP   get_two_factor_optrZ   r0   Ztotal_secondsjoinrangerS   set_nowr5   )rI   rJ   rD   argskwargsrV   rY   r   )rJ   rU   rc   rD   r   r   P   s8    



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  d| }tjd	krt  d
| }t|}dtj |jd< d|jd< d|jd< |S d S )Nr   )	urlencodeis_adminZ
is_supportr\   r]   Znext_urlzauth/two-factor?Zsd_apizservicedesk/auth/two-factor?zhttps://zAccess-Control-Allow-Origintruez Access-Control-Allow-CredentialszContent-Type, x-ijtzAccess-Control-Allow-Headers)urllib.parserm   checkedr:   r,   r?   r   r   r.   rf   r/   rg   rn   global_settingsZtwo_factor_adminZrequesturlZauth_base_hrefZ	api_scopeZredirectrB   ZAPP_FQDNZheaders)r   rm   rU   paramsqsrs   rr   r   r   tfa_check_two_factor   s,     



zCmfSession.tfa_check_two_factorrK   )rJ   rD   r)   c          
   	   O   s  dd l }|stj}tjj|jddgd}d}|d kr\dD ]"}t|j|r8|	dd } q\q8|snt
d| | jd	7  _|j  |j| k }rd
|_nB|jjrt  ||jj }	W 5 Q R X |	|  }rd
|_|rt|j| dd
 |j  |  |S )Nr   r[   r   r]   F)Zapplication_verifiedZemail_verifiedZphone_verifiedrb   u   Необходимо указать метод авторизации по которому происходит проверка method=r   TZ	_verified)pyotpr,   rD   r.   rf   r/   r:   getattrrO   r   AssertionErrorZsms_try_countZsms_try_timerj   rS   rq   Ztopt_secretr   Zdisable_aclZTOTPr+   Zverifysetattrr5   )
r)   rJ   rD   rk   rl   ry   rU   resultmZtotpr   r   r   r
      s2    


zCmfSession.tfa_check_codec              
      s   t jd krdt _d }| jr8| jt| jjd }|d}d }| jr`| jt| jjd }|d}| j	rt
jjddt| jt| jdd| j| jd t d	| j d
| d|  nt d| j d
| d|  | js| j| _t j||S )NTr   z%Y-%m-%d %H:%M:%S %Z%zZlogin_successedr   r   r   )r    r!   Z
cmf_authorr%   r"   r&   r#   r$   u-   Создали новую сессию login=u   , время жизни до u)   , обновление токена до u$   Обновили сессию login=)r,   Zhack_session_need_commitr3   r2   r   r   strftimeZlifetimeZ	auth_dateZis_newr.   r8   r9   r`   r:   r7   r-   real_user_idsuperr5   )r   rk   rl   Zrefresh_untilZlifetime_until	__class__r   r   r5      s4    


      zCmfSession.save)r:   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_|jr|jjrdtj_tj  tjjdkrt jj|dtjj dddd dS )u   Метод переключает пользователя в текущей сессии

        Args:
            user_id (str): ИД пользователя на которого хотим переключиться
        r]   u5   Пользователь не найден id=user_idZSuAvailablerx   uH   Пользователь не состоит в группе SuAvailableNZ	SuExcludeT)Z
subject_idZid_onlyun   На этого пользователя нельзя переключится, он в группе SuExclude)Zon_session_starton_session_start_and_end   Пользователь u$    вошел в ваш аккаунтr(   rU   namemsgZforce_notify_current_person)r.   rf   sgetZAPPZcurrent_person_fieldsr{   ZCmfPersonGroupr   r,   r@   rP   ZCmfAccessListZsubject_full_group_listrD   r:   r   switch_user_daterj   r;   r7   r=   r<   rO   rI   rq   r5   rr   	su_notify	CmfNotifyplace_notifycurrent_person)r:   rk   rl   userZsu_availableZ
su_excludeZuser__member_ofr   r   r   r      s4    




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 jd|j dd	d
d dS )u)   Выключаем SU режим
        Nz--r;   r=   r]   )Zon_session_endr   r   u.    вышел из вашего аккаунтаr(   Tr   )r,   rD   r   r:   r.   rf   r   r;   r7   r=   r<   r   r   r5   rr   r   r   r   r   )rk   rl   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   r0   r   r1   r   r   r,   rr   Zsu_session_time_limitr   r   r5   )r   r0   r   r   r   r6   
  s     zCmfSession.switch_check_timeout)F)__name__
__module____qualname__Z_optionsZjinja2ZFileSystemLoaderospathrh   rB   ZPROJECT_DIRZ_loaderZEnvironmentrW   Z	api_allowZapi_methodsr`   r   classmethodrG   staticmethodr   rw   r
   r5   r   r   r6   __classcell__r   r   r   r   r      s0   70%
r   N)Zcmf.includer   r   r   r   r   r   r   r   r   r   <module>   s   