
    X(iA                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZ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 d dlmZ d dlmZ d d	l d
dlmZ ddlmZ ddlmZ d
dlmZ  G d dej>                        Zy)    N)pbkdf2_hmac)AES)SHA256)RSA)get_random_bytes)
PKCS1_v1_5)pad)*   )
send_email   )auth)LdapStatusCode)
Supervisorc                       e Zd ZdZdZej                  ej                  ej                  j                  ej                  ddd      g      ej                        Zed        Zed        Zd	 Zed
        Zd<dZed        Zd=dZd Zd>dZedefd       Zd>defdZed=d       Z ed        Z!ed        Z"ed        Z#ed        Z$d Z%d Z&d Z'd Z(d Z)ed        Z*ed        Z+ed         Z,d! Z-d?d"Z.d?d#Z/ed$        Z0ed%        Z1d@d&Z2	 	 dAd'e3d(e4d)e4d*e4d+ef
d,Z5ed-        Z6ed?d.       Z7 fd/Z8d0 Z9ed1        Z:ed2e;fd3       Z<ed4        Z=ed5        Z>ed6        Z?ed?d7       Z@e eAdd8dd9:      d;               ZB xZCS )BCmfAuth    
   modulesr   	templates)loader
autoescapec                 d    t        j                  | j                  j                  d      d         S )N$base64	b64decode	pass_hashsplitselfs    ./modules/auth/models/auth.pykeyzCmfAuth.key&   '     4 4S 9" =>>    c                 d    t        j                  | j                  j                  d      d         S )Nr   r   r!   s    r#   saltzCmfAuth.salt*   r%   r&   c                     t        j                  | j                        }|t        t	        t        j
                                     z  }|| j                  j                         z  }|S N)secrets	token_hextoken_lengthstrinttimer)   hex)r"   server_challenges     r#   gen_server_challengezCmfAuth.gen_server_challenge.   sO    ",,T->->?CDIIK 011DIIMMO+r&   c                 @   d| j                   dz  }}||| }||dz   }}||| }|t        |      }}t        j                  |||       }t	        j
                  d|j                         |d      }	t        j                  | j                         }
||
z   |z   |z   }t        t        j                        }t        j                  |	t        j                  |      }|j                  t        |j                         t        j                              }||z   j!                         S )Nr   r   r   sha256順 )r.   lenbytesfromhexhashlibr   encoder,   r-   r   r   
block_sizenewMODE_CBCencryptr	   r2   )clsloginpasswordr3   startendserver_randomserver_timestampserver_salttest_keyclient_randomsecretivcipherencrypted_secrets                  r#   test_gen_server_challenge_respz&CmfAuth.test_gen_server_challenge_resp4   s   ((1,s(s3#(s+E#6#./smm$4U3$?@&&hoo'g
  ))#*:*:;.1AAEIcnn-3<<4!>>#fmmos~~*NO%%**,,r&   c                 B   | j                  d       t        | j                        }|dk(  r| j                  |d<   |r1t	        d       d| d	t
        j                  j                  |       S t	        d       d
| d	t
        j                  j                  |       S )u   
        Сформируем ссылку на сброс и отправим её пользователю.
        Альтернативно переиспользуется для приглашения нового пользователя.
        F)reset)hrestore_passwordrB   T)absolutezservicedesk/auth/?zauth/)reset_pass_set_datadictreset_password_hashrB   auth_base_hrefurllibparse	urlencode)r"   endpointsdeskparamss       r#   reset_pass_linkzCmfAuth.reset_pass_linkO   s    
 	  u -001))"jjF7O$d344EhZqQWQ]Q]QgQghnQoPpqq$d34E(1V\\E[E[\bEcDdeer&   c           	      `   t         j                  j                  |g d      }|sOt        j	                         5  t         j
                  j                  ddd |ddd       d d d        t        d	      |j                  r|j                  t        j                         kD  rv|j                  d
z
  t        j                         dz
  kD  rOt        j	                         5  t         j
                  j                  ddd |ddd       d d d        t        d      dt        j                   } |j                         }| j                  j                  d      }|j!                  |t              }t         j"                  j%                         }|j'                  |j(                  j*                  ||       t        j	                         5  t         j
                  j                  ddd d|id       d d d        y # 1 sw Y   t        d	      xY w# 1 sw Y   t        d      xY w# 1 sw Y   y xY w)N)reset_password_expiresrB   emailrB   fieldsrestore_password_get_linkr   zLogin not foundrB   reasonfail)operatecmf_model_nameparent
audit_dataresult_statusu,   Такого пользователя нетQ i,  zAlready sentu   Вам на почту уже отправлена ссылка для сброса пароля. Для повторной отправки повторите попытку позже.uC   Ссылка для восстановления доступа к zreset_password_email.html)restore_linkconfig)subjectrB   ok)modelsr   getcmfutildisable_aclCmfAuditaudit_eventCmfAuthErrorrb   r1   CmfErrorrq   HOSTNAME_FQDNr`   
_jinja_envget_templaterenderCmfPluginMailBoxget_local_mailboxsend_messagerc   value)rA   rB   r   rr   linktemplatemessagemail_boxs           r#   send_pass_linkzCmfAuth.send_pass_link^   s   ~~!!6b!c$$& B++4O`i37e_pDq:@ , BB MNN&&++diik9++|<tyy{f?UU$$& B++4O`i37e_mDn:@ , BB  v w wWX^XlXlWmn#t##%>>../JK//tF/C**<<>djj..I  " 	<OO''0K\e/3%@P6: ( <	< 	</B MNNB  v w w	< 	<s#   (G8(H'H$8HH!$H-Tc                     |rdnt        j                  d      | _        |rdnt        t	        j                               dz   | _        | j                          y)u  
        Выставляем (или сбрасываем) секретик для сброса пароля
        Не очень хорошо, наверное хранить его в чистом виде, если упрут базу account будет печально,
        т.к. по сути даст доступ ко всем, кто в течение часа до угона БД запросил восстановление пароля.
        По хорошему хэшировать чем-то, что хранится отдельно от БД и периодически менять.
        Но это TODO-преTODO, т.к. паранойя.
        12 байт рандома дают нам 2**(8*12)=79,2E+27 значений. Перебирать по 1 в сек по сети - 2,5E+21 лет.
        :param reset - если True, выставляем всё в None, если False - генерируем новые значения
        N   ro   )r,   token_urlsaferX   r0   r1   rb   save)r"   rQ   s     r#   rV   zCmfAuth.reset_pass_set_data   s@     ,14g6K6KB6O .3dTYY[9IL9X#		r&   c                 b    | j                    xs! t        j                         | j                   kD  S )u_    Проверяем что ссылка для сброса пароля не протухла )rb   r1   r!   s    r#   reset_pass_is_expiredzCmfAuth.reset_pass_is_expired   s'    ...[$))+@[@[2[[r&   c                    ddd}|O| j                   j                  t        t        j                         d|z  z         | j                  j                  d}t        j                  t        j                  |      j                               j                         }t        j                  t        j                  |      j                               j                         }| d| S )NRS256JWT)algtypro   )rB   expscope.)rB   r   r0   r1   r   r   	b64encodejsondumpsr<   decode)r"   dayspayloadheaders       r#   
create_jwtzCmfAuth.create_jwt   s     /?))499;)<<=))G
 !!$**V"4";";"=>EEG""4::g#6#=#=#?@GGI7)$$r&   jwtc                 ,   t        j                  t        j                  | d         j	                               j                         }t        j                  t        j                  | d         j	                               j                         }| d| S )Nr   r   r   )r   r   r   r   r<   r   )r   r   r   s      r#   
jwt_to_strzCmfAuth.jwt_to_str   sq    !!$**S]";"B"B"DELLN""4::c)n#=#D#D#FGNNP7)$$r&   c                 N   || j                  |      }t        j                  t        j                        }t        j                         }|j                  |j                                |j                  |      }t        j                  |      j                         }| d| }|S )Nr   )r   r   r>   APPrsa_private_keyr   updater<   signr   r   r   )r"   r   r   signerdigestr   ress          r#   rsa_sign_pack_jwtzCmfAuth.rsa_sign_pack_jwt   s    ;//$'C 3 34cjjl#{{6"%,,.Qtfo
r&   c                    | j                  d      \  }}}t        j                         }| d| }|j                  |j	                                t        j                  |      }t        j                  t        j                        }|j                  ||      }|sy t        j                  |      j                         }t        j                  |      j                         }t        j                  |      }t        j                  |      }|rYt        t        j                               t        |d         kD  r-t         j#                  dt        j                         |d          y ||dS )Nr   r   u9   Время жизни токена закончилосьr   r   )r    r   r>   r   r<   r   r   r   r   rsa_public_keyverifyr   r   loadsr0   r1   gdebug)	rjwt	check_expr   r   	signaturer   r   verifierverifieds	            r#   rsa_verify_unpack_jwtzCmfAuth.rsa_verify_unpack_jwt   s   %)ZZ_"'#cjjl#$$Y/	>>#"4"45??695!!&)002""7+224F#**W%TYY[)C,??GGOQUQZQZQ\^efk^lm W55r&   c                    | j                  d      \  }}}t        j                  |      j                         }t        j                  |      j                         }t	        j
                  |      }t	        j
                  |      }||dS )Nr   r   )r    r   r   r   r   r   )r   r   r   r   s       r#   rsa_unpack_jwtzCmfAuth.rsa_unpack_jwt   so    %)ZZ_"!!&)002""7+224F#**W% W55r&   c                    | j                  d      \  }}}t        j                         }| d| }|j                  |j	                                t        j                  |      }d}	 t        j                  |      }t        j                  |      }	|	j                  ||      }|S # t        $ r+}
d|
 }t        j                  |       t        |      |
d }
~
ww xY w)Nr   Fu,   Не удалось разобрать JWT: )r    r   r>   r   r<   r   r   r   
import_keyr   r   
ValueErrorloggingerror)r   rsa_public_key_bytesr   r   r   r   r   r   r   r   er   s               r#   rsa_verify_jwtzCmfAuth.rsa_verify_jwt   s    %)ZZ_"'#cjjl#$$Y/		+ ^^,@AN!~~n5H//&)4C
 
	  	+B1#FEMM% U#*	+s   (<B& &	C/&CCc                    t         j                  d       |st         j                  d       y 	 | j                  |      }|st         j                  d       y  | d      }|d   d   |_        |d   d   |_        |d   d	   |_	        d |_
        d |_        d }t        j                  j                  t        d
z         r9t!        t        d
z         5 }|j#                         j%                         }d d d        | |_        |j                  xs dj'                  d      D ]f  }|r|j)                  | d      rd|_        |dk(  s&t         j*                  j,                  sAt         j                  d|        d|_
        d|_        h t         j                  d|j                   d|j                   d|j                          |S # t        $ r,}t        j
                  j                  d       d }Y d }~d }~ww xY w# 1 sw Y   xY w)Nzfrom_jwt: startzfrom_jwt: warn not jwtzfail unpack jwtz2from_jwt: warn not cls.rsa_verify_unpack_jwt(rjwt)T)emptyr   rB   r   z/custom/org_name  :r
   uC   from_jwt: Доступ по билету тех поддержки zfrom_jwt: jwt is ok, z, z, is_local=)r   r   r   	Exceptionr   logger	exceptionrB   rc   r   jwt_is_supportjwt_is_match_orgospathexistsPROJECT_DIRopenreadstripr    
startswithglobal_settingssupport_mode)rA   r   r   r   objorg_namefperms           r#   from_jwtzCmfAuth.from_jwt   s   	!"GG,-	++D1C GGHIo	N7+		N7+		N7+	!#77>>+(::;k$667 ,1668>>+, $,|YY_"++C0 	,Dt(1~>'+$s{q00==]^a]bcd%)"'+$	, 	
'		{"SYYK{3K_K_J`ab
=  	JJ  !23C	 , ,s#   G G=	G:!G55G:=Hc                 f   | j                  dd|gdg      }|s| j                  dd|gdg      }|s| j                  dd|gdg      }|s[t        j                  j                  j	                         5  t
        j                  j                  ddd d|id	d
||       d d d        y |j                  rt        j                  d|j                   d       t        j                  j                  j	                         5  t
        j                  j                  ddd |j                  ddd	d
|j                  |j                         d d d        t        dt        j                  j                   d       y |j                  j                   j                  d      rf|j                  j#                  d      \  }}t
        j$                  j'                  |      r't
        j$                  j)                  |dg      D ]j  }	 |j+                  |j,                  j                   |      }|t.        j0                  k(  r n-|t.        j2                  k(  rt        d        n|t.        j4                  k(  sv|j7                         r y d|_        |j;                          d| j=                         }t>        j@                  jC                  |d       t        j                  j                  j	                         5  t
        j                  j                  ddd |j,                  j                   dddd
|j,                  j                   |j,                  j                          d d d        |c S  t        j                  j                  j	                         5  t
        j                  j                  ddd |j,                  j                   ddd	d
|j,                  j                   |j,                  j                          d d d        |jF                  r_|j                  j                   j                  d!      r9|j7                         ry | jI                  ||jF                  j                         rd"|_        |j;                          d| j=                         }t>        j@                  jC                  |d       t        j                  j                  j	                         5  t
        j                  j                  ddd |d"ddd
||       d d d        |S t        j                  j                  j	                         5  t
        j                  j                  ddd |d"dd	d
||       d d d        |jK                          d| j=                         }t>        j@                  jC                  |d
       y # 1 sw Y   y xY w# 1 sw Y   zxY w# 1 sw Y   |c S xY w# tD        $ r&}	t        j                  d| d |	        Y d }	~	d }	~	ww xY w# 1 sw Y   xY w# 1 sw Y   |S xY w# 1 sw Y   xY w)#N	ext_loginILIKEz***)filterre   rB   rc   ident_failedr   ri   r   rj   rk   rl   rm   rn   security_levelparent_nameparent_codeus   Превышено количество попыток ввода пароля для учетной записи "u$   ", вход заблокированauth_failedzToo many failed login attemptsrg   un   Превышено количество попыток ввода пароля, повторите через u    минут
allow_ldap@)domainplugin.*)r   re   u6   Учетная запись заблокированаldapzauth:user_last_login_fail:r   auth_successed)rB   typers   u/   Ошибка авторизации через z: 
allow_basebase)&ru   cmfutilrv   rw   rt   rx   ry   fail_block_end_dater   r   rB   	cmf_alertr   auth_fail_timeoutauth_optionsr   r    CmfAuthLdapPlugincountlistsigninr   r   INVALID_CREDENTIALSUSER_DISABLEDSUCCESS_is_permanent_blocklast_auth_typeauth_success_hooklowerr   REDIS_DBsetr   r   check_secretauth_fail_hook)
rA   rB   challenge_respr   _r   auth_pluginldap_status_codedb_keyr   s
             r#   get_by_challenge_respzCmfAuth.get_by_challenge_resp  s   ggk7E:E7gK'''7E!:E7'KC'''7E!:E7'KC!!--/ R++NS\37WeDT:@QR8=5 , RR
 ""GG  J  KN  KT  KT  JU  Uy  z  {!!--/ 
++)#,),>^_"(#$ #		 #		 , 	
   G  HI  HY  HY  Hk  Hk  Gl  lw  x  y!!%%l3		,IAv''--V-<#)#;#;#@#@WaVb#@#c 'K'+6+=+=cmm>Q>QSa+b( ,~/Q/QQ!-1M1MM%&^_!-1G1GG"668'+17C.113'A%%I%O%O%QFLL,,VQ7!$!1!1!=!=!? ~ & ; ;DTenCG^a^k^k^q^q  |B  UCJN_`HKH[H[ilivivi|i| !< !~~ $'J5'8 XX%%113 rOO//V_7;RUR_R_ReReouHv>DUV<?MM<O<O]`]j]j]p]p 0 rr ==S--3377E&&(0C0CD%+"%%'5eW=CCE  +XX%%113 COO//8HYb7;RWagHh>BSTbg<A 0 CC 
 XX%%113 VOO//V_7;RWagHh>DUV<Au 0 VV 	-eW5;;=#{R
 

 
N~ $'J/ % f"QR]Q^^`ab`c deef2r r C 
V Vsc   4*V3>A	V?&W8A'WA'X+X<+X'3V<?W	W		X
$XX
XX$'X0c                    t         j                  j                  r| j                  rt         j	                  d| j
                   d       t        j                  j                  j                         5  t        j                  j                  ddd | j
                  dddd| j
                  | j
                  	       d d d        t        d
       yy# 1 sw Y   xY w)Nu   Учетная запись "u3   " перманентно заблокированаr   r   zPermanent blockrg   ri   r   r   ul   Учетная запись заблокирована, обратитесь к администраторуTF)r   r   auth_fail_permanent_blockfail_permanent_blockr   rB   r   r   rv   rw   rt   rx   ry   r   r!   s    r#   r   zCmfAuth._is_permanent_blockw  s    664;T;TGG3DJJ<?rst!!--/ 
++)#,)-?PQ"(#$ $

 $

 , 	
   E  F!
 
s   2A	CCc           
         t         j                  j                  sy | j                  dk(  ry t        j
                  j                  dd       }d| j                         }t        j                  j                  |      }dj                  t        j                  t        j                  d            }t        j                  j                  ||       |s5t         j"                  j%                  ddd |d	d
dd||       t'        d       |j)                         }|r||k7  r6t         j"                  j%                  ddd |dd
dd||       t'        d       y y )Nr   captchazauth:user_login_captcha:r      kr   r   zRequire captcharg   ri   r   r   i  zBad captcha)r   r   auth_check_captchafail_try_counterrequestvaluesru   r   r   r   joinrandomchoicesstringdigitsr   rt   rx   ry   abortr   )r"   rB   r  r  
db_captchanew_captchas         r#   _auth_check_captchazCmfAuth._auth_check_captcha  s+      33  A%..$$Y5+E7399;\\%%f-
ggfnnV]]a@A-OO''i/3%[l@m6<Q49u ( N #J&&(
'Z/OO''i/3%[h@i6<Q49u ( N #J 0r&   c                    | xj                   dz  c_         | j                   t        j                  j                  k(  rt        j                  j                  rd| _        n\t        j                  j                         t        j                  t        j                  j                  j                        z   | _        d| _         | j                          y )Nr   T)minutesr   )r  r   r   auth_fail_try_countr
  r  datetimenow	timedeltar   r   r   r   r!   s    r#   r  zCmfAuth.auth_fail_hook  s    "  A$5$5$I$II  ::,0)+3+<+<+@+@+BXEWEW--??EEF ,( %&D!		r&   c                 2    d| _         | j                          y )Nr   )r  r   r!   s    r#   r   zCmfAuth.auth_success_hook  s     !		r&   c                    | j                   r| j                   dk7  ry| j                  }|r$	 t        |      }|t        j
                         k  ryt        j                  j                  }|rW| j                  rK| j                  t        j                  |j                        z   }|| j                  j                         k  ryy# t        t        f$ r Y yw xY w)u   
        Проверка необходимости смены пароля с учетом типа последней авторизации.
        r   FTr   )r   password_expires_must_changefloat	TypeErrorr   r1   r   r   password_max_dayspassword_changed_dater!  r#  r   r"  )r"   password_expires_value
expires_tsr*  expire_dates        r#   need_change_passwordzCmfAuth.need_change_password  s     ""d&9&9V&C!%!B!B!"#9:
 TYY[(--??!;!;44x7I7IO`OfOf7ggKT77;;== z* s   C CCc                 T     |        }||_         ||_        |j                  ||       |S r+   )rB   rc   set_pass_hash)rA   rB   hashr)   r   s        r#   new_from_login_hash_saltz CmfAuth.new_from_login_hash_salt  s,    e		$%
r&   c           	      
   |j                  d      }|d   }|dk(  r[|dd  \  }}}t        j                  |      }t        j                  |      }	|	t        d|j	                         |t        |            k(  S t        d|       )Nr   r   pbkdf2_sha256r   r6   zNot Implemented for )r    r   r   r   r<   r0   NotImplementedError)
rA   rK   secret_hash
hash_parts	hash_algon_itersalt_b64hash_b64salt_bhash_bs
             r#   r  zCmfAuth.check_secret  s     &&s+
qM	')3AB&FHh%%h/F%%h/F[6==?FCPVKXXX!$8"DEEr&   c                    | j                  |g d      }|r| j                  ||j                  j                        r\t        j
                  j                  j                         5  t        j                  j                  ddd|id dd||       d d d        |S t        j
                  j                  j                         5  t        j                  j                  d	dd|id d
d||       d d d        y # 1 sw Y   |S xY w# 1 sw Y   y xY w)N)r   rB   r   rd   r   r   rB   rs   r   )rj   rk   rm   rl   rn   r   r   r   r   ri   )ru   r  r   r   r   r   rv   rw   rt   rx   ry   )rA   rB   rC   r   s       r#   from_login_passwordzCmfAuth.from_login_password  s    wwU+IwJ$..*>*>?XX%%113 VOO//8HYb<CU;K7;4`a<Au 0 VV
 XX))+ 	NOO''i4;U3C/36Z[49u ( N	N
 V
 	N
 s   &*C5*D5C?Dc                    t         j                  j                  sy t        j                  j                  | dgddgddg      D ]@  }|j                  s| j                  ||j                        s-t        |j                         y )Nz-cmf_created_atr      r   cmf_created_at)rl   order_byslicere   )
r   r   password_check_historyrt   CmfAuthHistoryslistr   r  CmfAuthReusePasswordErrorrC  )r"   rC   historys      r#   check_historyzCmfAuth.check_history   s       77,,22'8&9!QQ\^nPo 3 q 	LG   $$Xw/@/@A3G4J4JKK	Lr&   c                     t         j                  |      }t         j                  |      }| j                  |||       y )NrC   )r9   r:   set_pass_hash_bytes)r"   r2  r)   rC   
hash_bytes
salt_bytess         r#   r1  zCmfAuth.set_pass_hash  s3    ]]4(
]]4(
  Z( Kr&   c                    || j                  |       t        j                  |      j                         }t        j                  |      j                         }d| d| | _        | j
                  j                          t        j                  j                  | j                        }|rQ|j
                  j                          d|_        t        j                         5  |j                  d       d d d        y y # 1 sw Y   y xY w)Nzpbkdf2_sha256$100000$r   rB   FT)	only_data)rK  r   r   r   r   r+  set_nowrt   	CmfPersonru   rB   password_must_changerv   rw   r   )r"   rO  rP  rC   r<  r;  persons          r#   rN  zCmfAuth.set_pass_hash_bytes  s    x(##J/668##J/6680
!H:F""**,!!%%DJJ%7((002*/F'$$& ,d+, , , ,s   "C??Dc                 "    t         j                  S r+   )r   r   )rA   s    r#   current_authzCmfAuth.current_auth!  s    vvr&   c                     g }t        d      D ]E  }|j                  t        j                  t        j
                  t        j                  z                G dj                  |      j                  d      S )N   r   zutf-8)	rangeappendr  choicer  ascii_lettersr  r  r<   )rA   charsis      r#   gen_saltzCmfAuth.gen_salt%  sY    r 	NALLv';';fmm'KLM	Nwwu~$$W--r&   c                 D   | j                  dg       |st        t        j                  j                  j
                  |      }t        j                  j                  j
                  }t        j                  j                  j
                  }t        j                  j                  j
                  }| j                  ||||      }t        |       j                         }t        j                  d|j                         |d      }| j                  |||xr |       t         j"                  j$                  j'                         5  t(        j*                  j-                  ddd| j.                  idd	| j.                  | j.                  d
       ddd       |S # 1 sw Y   |S xY w)uO   
        Генерирует новый пароль
        :return:
        rB   )lengthis_upper_symbol	is_numberis_special_symbolr6   r7   rM  reset_passwordr   Nrs   r   )rj   rk   rm   rl   rn   r   r   r   )load_fieldsmaxr   r   password_min_lengthr   password_min_upper_symbolpassword_min_numberspassword_min_special_symbol_generate_passwordr   rb  r;   r   r<   rN  r   r   rv   rw   rt   rx   ry   rB   )	r"   rd  rC   forcere  rf  rg  r)   r2  s	            r#   rh  zCmfAuth.reset_password,  s^    	'#**>>DDfMF//IIOOO))>>DDI ! 1 1 M M S S..#7H / H
 Dz""$""8X__->gN  te6H IXX))+ 	ROO''0@QZ4;TZZ3H/34UYU_U_48JJq ( R	R
 	R
 s   AFFrd  rg  rf  re  returnc                 |   g }t         j                  t         j                  z   t         j                  z   }|rE|t         j                  z  }|j                  t        j                  t         j                               |r2|j                  t        j                  t         j                               |r2|j                  t        j                  t         j                               t        j                  ||t        |      z
        }|j                  |       t        j                  |       dj                  |      S )Nr  r   )r  r_  r  ascii_uppercasepunctuationr]  r  r^  r  r8   extendshuffler  )r"   rd  rg  rf  re  password_datalettersextra_symbolss           r#   ro  zCmfAuth._generate_passwordI  s     +-&&69O9OOv)))G  v/A/A!BC  v}}!=>  v/E/E!FGw&3};M2MN]+}%ww}%%r&   c                    dt         j                   }d|g}t        |||       t        j                  j
                  j                         5  t        j                  j                  ddd d|id||d       d d d        y # 1 sw Y   y xY w)	Nu&   Пароль для доступа к u   Пароль:send_passwordr   rc   rs   r   )rj   rk   rl   rm   rn   r   r   r   )
rq   r|   r   r   r   rv   rw   rt   rx   ry   )rA   rC   rc   rr   msg_contentss        r#   r{  zCmfAuth.send_password^  s    :6;O;O:PQ'2<%0XX))+ 	:OO''PY/3%@P6:[`78 ( :	: 	: 	:s   *B  B	c                 2   ddl m} 	  |       }t        j                  ||      }|j	                          |j                  t        dd       d|dd      }|j                  d	k7  rt        d
      t        |j                  j                  d            S )Nr   )session)rB   rg_member_ofT)rT   internalzauth/signup)rB   gen_pwd)data   u>   Не удалось создать учётную записьaccess_token)r  )requestsr~  rt   rU  r   postrY   status_coder   rW   cookiesru   )rA   rB   r  r~  srW  rs          r#   create_personzCmfAuth.create_personi  s    $	
 I!!L!I FFtd;<KH  
 ==C\]]~!>??r&   c                 @   | j                   j                  rd| _        | j                   j                  si| j                   D ]1  }| j                   |   D ]  }| xj                  d| d| z  c_         3 | j                  j                  j                         | _        t        |   |i |}| j                  j                  rNt        j                         5  t        j                  | | j                        j                          d d d        |S |S # 1 sw Y   |S xY w)Nr   r   r   )rl   r   )groups
is_changedr   is_nullr   r   superr   r   rv   rw   rt   rG  )r"   argskwargsr   grp_namer   	__class__s         r#   r   zCmfAuth.save  s    ;;!!DJ;;&& $ @H$(KK$9 @

(1XJ&??
@@ "ZZ--335
glD+F+>>$$$$& T%%TT^^%LQQST
s
T
s   0DDc                     | j                   j                  rg S t        | j                   j                  d      D cg c]  }|j                  d      d    c}      S c c}w )Nr   r   r   )r   r  r   r    )r"   ra  s     r#   prepare_scopezCmfAuth.prepare_scope  sH    ::ITZZ-=-=c-BCAGGCLOCDDCs   Ac                 B   | j                  |      }t        j                  dk(  r|S |d   d   }	 t        j                  |      }| j                  ||      }|s,d|d   d    d}t        j                  |       t        |      |S # t
        $ r d}t        |      w xY w)NFalser   issuJ   Не удалось прочитать публичный ключ EvaTeamuE   Не удалось валидировать токен от EVA_APP r   !)
r   rq   EVA_ACCOUNT_USEr   read_crm_pub_keyRuntimeErrorr   r   r   r   )rA   eva_app_tokenr   r  crm_pub_keyr   r   s          r#   check_tokenzCmfAuth.check_token  s      /!!W,J)nU#	#$55c:K ##M;?[\_`i\jku\v[wwxyEMM% E""
  	#`EE""	#s   B Busersc          
         | j                  |      }|d   d   }|D ]=  }	 t        |d         j                         j                         }g d}	d}
|j	                  d      rY| j	                  t        |d         j                         j                         |	      }
|
r||
_        n'| j	                  ||	      }
n| j	                  ||	      }
|
s>t        j                  |      }
t        j                  d	|        |
j                          |j	                  d
      xs d}t        |      j                         j                         xs ||
_        |j	                  d      xs d}t        |      j                         j                         xs d|
_        |
j                  j                  ri |
_        |
j                  sg |
_        ||
j                  vr|
j                  j!                  |       g |
j                  |<   |d   r~t        j                  dj#                  ||             ||
j                  vr|
j                  j%                  |       |
j                  |= d|
j                  _        |
j                          g|d   D ]O  }t        j                  d| d| d|        |
j                  |   j!                  |       d|
j                  _        Q |d   |
_        t        j                  d|        t        j                  d|
j                          |
j                          t+                t        j                  d|
j,                          @ ddiS # t.        $ r t        j1                  d|         w xY w)u   
        Метод вызывается из eva_app при синхронизации
        создает и привязывает пользователей
        https://bcrm.carbonsoft.ru/project/Document/DOC-003025#spec-0-ldap
        r   r   rB   )r  r   r  reg_org_name_listrc   r   
is_supportis_adminN	old_loginrd   rR  u(   Создали пользователя rc   r   r   cmf_deletedu4   Пользователь {} удален из Eva {}Tr  u,   Добавляем пользователю u    права u    в Eva r   z
user_dict=zuser.groups=zuser.scope=u)   Не удалось обработать resultrs   )r  r/   r   r   ru   rB   rt   r   r   r   r   rc   r   r  r  r  r]  formatremover  r   
cmf_commitr   r   r   )rA   r  r  r  r  r   r   	user_dictrB   _fieldsuserrc   r   grp_codes                 r#   rpc_account_sync_pushzCmfAuth.rpc_account_sync_push  s"    oom,y>*- 6	I5Ig./557==?`==-77Y{-C)D)J)J)L)R)R)T]d7eD%*
"wwU7wC77w7?D!>>>6D MM$LUG"TUIIK!g.4" Z--/557@5
%MM+6<"	!$Y!5!5!7!=!=!?!G4;;&&"$DK---/D*4#9#99**11(;(*H%]+MM"X"_"_`ego"pqt'='==..55h?H--1DKK*IIK ). 9 2HMM$PQVPWWcdlcmmuv~u  #A  BKK)00:-1DKK*2 %.n$=!
9+67T[[M:;		DJJ<89g6	p $	  !!$Mi["YZs   I M!CM!!#Nc          	         t         j                  sy d }t         j                  sy | j                  |      }|d   d   }|D ]  }t        j                  j                  |d   d   dg      }	|	st        j	                         }	 ||	|d          |d   d   |	_        |	j                          t        j                  j                  |d   ddg      }
|
st        j                         }
 ||
|       ||
_	        |d   |
_        |	|
_
        |
j                           t        j                  j                  d	d
|D cg c]  }|d   	 c}g      D ]  }	|	j                           ddiS c c}w )Nc                     |D ]F  }|dv s"|j                  d      s|j                  d      r*t        | |      s7t        | |||          H y )N)idcodeext_ipcmf__id)r   endswithhasattrsetattr)r   obj_dict
field_names      r#   copy_fz/CmfAuth.rpc_account_plugin_push.<locals>.copy_f  sV    & C
!99%008J<O<OPU<V3
+CXj-ABCr&   r   r   pluginr  r
   )ext_idre   r   r  zNOT IN)r   r  rs   )rq   IS_BOX_VERSIONr  rt   	CmfPluginru   r  r   r   r   r  r   delete)rA   r  auth_pluginsr  r  r  r   r   r  r  auth_plugin_objr   s               r#   rpc_account_plugin_pushzCmfAuth.rpc_account_plugin_push  sv   $$	C $$oom,y>*-' 	#K%%))X1Ft1LVYUZ)[F))+6;x01'1$7FMKKM$66::+dBS]`bl\m:nO""(":":"<?K0'/O$%0%6O"%+O"  "	# ..33HhfrPs_bQTUYQZPs;t3u 	FMMO	$ Qts   9E'c           	      z   | j                   t        j                  | j                  j                        z   t        j                  t
        j                        z   }t        t
        dt        j                        } |j                  d| j                         f||dddd| t        j                  |||fi | y )N)secondsr&  AUTH_SESSION_COOKIE_DOMAINsession_tokenTLaxr   expiressecurehttponlysamesite)reauth_dater!  r#  access_token_expires_inr   rq   PROLONG_DAYSgetattrr  host
set_cookie	get_tokenr   set_nginx_token)r~  responsecookie_kwargsr  cookie_domains        r#   set_session_tokenzCmfAuth.set_session_token  s    ##h&8&8A`A`AfAf&ggjrj|j|  CI  CV  CV  kW  W(DgllS 	
	

 !$
	
 
	
 	-RMRr&   c           	           |j                   d | j                  t        j                  dz
        f|t        j                  j                         t	        j                  t        j                  t        j                  z         z   dddd| y )Nr  r   r&  Tr  r  )r  r   rq   TOKEN_TTL_DAYSr!  r"  r#  r  )r   r  r  r  s       r#   set_access_tokenzCmfAuth.set_access_token  s     #D""(=(=(AB		

 !%%))+h.@.@**V-@-@@/B B$	
 	
r&   c           	          |sCt         j                   j                         t        j                  t        j                        z   } | j
                  	 	 d||dddd| y )Nr&  Tr  r  )nginx_auth_tokenpassword123)r!  r"  r#  rq   r  r  )r  r  r  r  s       r#   r  zCmfAuth.set_nginx_token.  sc    %%))+h.@.@fF[F[.\\G	
 !$	
 	
r&   u_   Разблокировка учетных записей по истечению времениz	@minutely)	only_oncedescription
system_jobschedulec                      t         j                  j                  ry t        j                  j	                         } 	 t
        j                  j                  dgdd| gddg      }|sy |D ]  }d |_         |j                           t                U)Nr   <r   d   )re   r   rE  )r   r   r
  r!  r"  rt   r   r   r   r   r  )r"  blocked_usersr   s      r#   )cron_unblock_users_after_block_expirationz1CmfAuth.cron_unblock_users_after_block_expiration;  s     66##%"NN//-.-sC8#h 0 M !% +/(		 L r&   )rS   F)T)r   Nr+   )   NN)FFF)D__name__
__module____qualname__r.   	ts_lengthjinja2EnvironmentFileSystemLoaderr   r   r  rq   r   r   select_jinja_autoescaper}   propertyr$   r)   r4   classmethodrO   r`   r   rV   r   r   staticmethodrW   r   r/   r   r   r   r   r   r  r   r  r  r   r/  r3  r  r@  rK  r1  rN  rY  rb  rh  r0   boolro  r{  r  r   r  r  r   r  r  r  r  r  cmf_deferred_jobr  __classcell__)r  s   @r#   r   r      s   LI##&&V5G5GSY[f(g'hi.. $ J
 ? ? ? ?  - -4f < <@\
% % % %
c 
 6 60 6 6  $ % %N d dL,>0   	F 	F  $
LL
,    . .< 6;9>&&.2&&26& 
&* : : @ @.E  " @  @  @ D    B S S" 
 
 

 

 u	 r&   r   ) r   r!  r;   r   r  r,   r  r1   rZ   r   Crypto.Cipherr   Crypto.Hashr   Crypto.PublicKeyr   Crypto.Randomr   Crypto.Signaturer   Crypto.Util.Paddingr	   cmf.includerc   r   re   r   enumsr   
supervisorr   r    r&   r#   <module>r     sV                  * ' #    " "ydll yr&   