
    1*)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T 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dS )    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                    e                    e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dAdZd ZdBdZedefd            ZdBdefdZedAd            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-dCd%Z.dCd&Z/ed'             Z0ed(             Z1dDd*Z2	 	 dEd+e3d,e4d-e4d.e4d/ef
d0Z5ed1             Z6edCd2            Z7 fd3Z8d4 Z9ed5             Z:ed6e;fd7            Z<ed8             Z=ed9             Z>ed:             Z?edCd;            Z@e eAdd<dd=>          d?                         ZB xZCS )FCmfAuth    
   modulesr   	templates)loader
autoescapec                 f    t          j        | j                            d          d                   S )N$base64	b64decode	pass_hashsplitselfs    ./modules/auth/models/auth.pykeyzCmfAuth.key&   (     4 4S 9 9" =>>>    c                 f    t          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                                        z  }|S N)secrets	token_hextoken_lengthstrinttimer)   hex)r"   server_challenges     r#   gen_server_challengezCmfAuth.gen_server_challenge.   sR    ",T->??CDIKK 0 0111DIMMOO+r&   c                 n   d| j         dz  }}|||         }||dz   }}|||         }|t          |          }}t                              |||                   }t	          j        d|                                |d          }	t          j        | j                   }
||
z   |z   |z   }t          t          j                  }t          j        |	t          j        |          }|                    t          |                                t          j                            }||z                                   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#I6#.//smm$4U3Y$?@@&hoo''g
 
  )#*:;;.1AAEIcn--3<44!>>#fmmoos~*N*NOO%%**,,,r&   restore_passwordFc                 P   |                      d           t          | j                  }|dk    r
| j        |d<   |r5t	          d           d| d	t
          j                            |           S t	          d           d
| d	t
          j                            |           S )u   
        Сформируем ссылку на сброс и отправим её пользователю.
        Альтернативно переиспользуется для приглашения нового пользователя.
        F)reset)hrP   rB   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111)))"jF7O 	f$d333qqhqqQWQ]QgQghnQoQoqqq$d333ee(eeV\E[E[\bEcEceeer&   c           	      N   t           j                            |g d          }|sgt                                          5  t           j                            ddd |ddd           d d d            n# 1 swxY w Y   t          d	          |j        r|j        t          j	                    k    r|j        d
z
  t          j	                    dz
  k    rgt                                          5  t           j                            ddd |ddd           d d d            n# 1 swxY w Y   t          d          dt          j         } |j                    }| j                            d          }|                    |t                    }t           j                                        }|                    |j        j        ||           t                                          5  t           j                            ddd d|id           d d d            d S # 1 swxY w Y   d S )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"   ~!!6b6b6b!cc 	O$$&& B B++4O`i37e_pDqDq:@ , B B BB B B B B B B B B B B B B B B MNNN& 		w+dikk99+|<ty{{f?UUU$$&& B B++4O`i37e_mDnDn:@ , B B BB B B B B B B B B B B B B B B  v w w wnX^Xlnn#t#%%>../JKK//tF/CC*<<>>dj.III  "" 	< 	<O''0K\e/3%@P6: ( < < <	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	< 	<s5   (A33A7:A7+(DD#&D#&'HH!HTc                     |rdnt          j        d          | _        |rdn"t          t	          j                              dz   | _        |                                  dS )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"   rR   s     r#   rV   zCmfAuth.reset_pass_set_data   sU     ,1#O44g6KB6O6O .3&XddTY[[9I9IL9X#		r&   c                 J    | j          pt          j                    | j         k    S )u_    Проверяем что ссылка для сброса пароля не протухла )rb   r1   r!   s    r#   reset_pass_is_expiredzCmfAuth.reset_pass_is_expired   s!    ..[$)++@[2[[r&   Nc                    ddd}|>| j         j        t          t          j                    d|z  z             | j        j        d}t          j        t          j        |          	                                          
                                }t          j        t          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     //?)49;;)<<==) G
 !$*V"4"4";";"="=>>EEGG"4:g#6#6#=#=#?#?@@GGII$$7$$$r&   jwtc                 P   t          j        t          j        | d                                                                                             }t          j        t          j        | d                                                                                             }| d| S )Nr   r   r   )r   r   r   r   r<   r   )r   r   r   s      r#   
jwt_to_strzCmfAuth.jwt_to_str   s    !$*S]";";"B"B"D"DEELLNN"4:c)n#=#=#D#D#F#FGGNNPP$$7$$$r&   c                 h   ||                      |          }t          j        t          j                  }t          j                    }|                    |                                           |                    |          }t          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44cjjll###{{6""%%,,..ootoo
r&   c                    |                      d          \  }}}t          j                    }| d| }|                    |                                           t          j        |          }t          j        t          j	                  }|
                    ||          }|sd S t          j        |                                          }t          j        |                                          }t          j        |          }t          j        |          }|rlt          t          j                              t          |d                   k    r5t                               dt          j                    |d                    d S ||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   sO   %)ZZ__"##'##cjjll###$Y//	>#"455??6955 	4!&))0022"7++2244F##*W%% 	TY[[))C,?,???GGOQUQZQ\Q\^efk^lmmm4 W555r&   c                 &   |                      d          \  }}}t          j        |                                          }t          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   s|    %)ZZ__"!&))0022"7++2244F##*W%% W555r&   c                    |                      d          \  }}}t          j                    }| d| }|                    |                                           t          j        |          }d}	 t          j        |          }t          j        |          }	|	
                    ||          }nA# t          $ r4}
d|
 }t                              |           t          |          |
d }
~
ww xY w|S )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__"##'##cjjll###$Y//		+ ^,@AAN!~n55H//&)44CC 	+ 	+ 	+F1FFEMM%   U##*	+ 
s   2>B1 1
C/;/C**C/c                 j   t                               d           |st                               d           d S 	 |                     |          }n8# t          $ r+}t          j                            d           d }Y d }~nd }~ww xY w|st                               d           d S  | d          }|d         d         |_        |d         d         |_        |d         d	         |_	        d |_
        d |_        d }t          j                            t          d
z             rUt!          t          d
z             5 }|                                                                }d d d            n# 1 swxY w Y   | |_        |j	        pd                    d          D ]e}|r|                    | d          rd|_        |dk    r<t           j        j        r+t                               d|            d|_
        d|_        ft                               d|j         d|j	         d|j                    |S )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   sr   	!""" 	GG,---4	++D11CC 	 	 	J  !2333CCCCCC	  	GGHIII4cooo	N7+		N7+		N7+	!#7>>+(::;; 	,k$6677 ,16688>>++, , , , , , , , , , , , , , , $,|Y_"++C00 	, 	,D ,t(~~~>> ,'+$s{{q0={c^accddd%)"'+$	a	aaSYaa3K_aabbb
s)   A 
B!B  B9'E,,E03E0c                    |                      dd|gdg          }|s|                      dd|gdg          }|s|                      dd|gdg          }|sft          j        j                                        5  t
          j                            ddd d|id	d
||           d d d            n# 1 swxY w Y   d S |j        rt          
                    d|j         d           t          j        j                                        5  t
          j                            ddd |j        ddd	d
|j        |j                   d d d            n# 1 swxY w Y   t          dt          j        j         d           d S |j        j                             d          rv|j                            d          \  }}t
          j                            |          r8t
          j                            |dg          D ]}	 |                    |j        j        |          }|t.          j        k    r n\|t.          j        k    rt          d            n:|t.          j        k    r|                                r d S d|_        |                                 d|                                 }t>          j         !                    |d           t          j        j                                        5  t
          j                            ddd |j        j        dddd
|j        j        |j        j                   d d d            n# 1 swxY w Y   |c S [# tD          $ r+}	t          
                    d| d |	            Y d }	~	d }	~	ww xY wt          j        j                                        5  t
          j                            ddd |j        j        ddd	d
|j        j        |j        j                   d d d            n# 1 swxY w Y   |j#        rt|j        j                             d!          rT|                                rd S | $                    ||j#        j                  rd"|_        |                                 d|                                 }t>          j         !                    |d           t          j        j                                        5  t
          j                            ddd |d"ddd
||           d d d            n# 1 swxY w Y   |S t          j        j                                        5  t
          j                            ddd |d"dd	d
||           d d d            n# 1 swxY w Y   |%                                 d|                                 }t>          j         !                    |d
           d S )#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  sV   ggk7E:E7gKK 	L'''7E!:E7'KKC 	L'''7E!:E7'KKC 	!--// R R++NS\37WeDT:@QR8=5 , R R RR R R R R R R R R R R R R R R
 4" 	GG  z  KN  KT  z  z  z  {  {  {!--// 
 
++)#,),>^__"(#$ #	 #	 , 	 	 	
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   x  HI  HY  Hk  x  x  x  y  y  y4!%%l33 #	r	,,IAv'--V-<< !r#)#;#@#@WaVb#@#c#c ' 'K'+6+=+=cm>QSa+b+b( ,~/QQQ!E-1MMM%&^___!E-1GGG"6688 ,'+tt17C.11333%I%%I%I%O%O%Q%QFL,,VQ777!$!1!=!=!?!? ~ ~ & ; ;DTenCG^a^k^q  |B  UC  UCJN_`HKH[ilivi| !< !~ !~ !~~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ $'JJJ H % f f f dR] d dab d deeeeeeeef2 X%1133 r rO//V_7;RUR_ReouHvHv>DUV<?M<O]`]j]p 0 r r rr r r r r r r r r r r r r r r = 	VS-377EE 	V&&((  40CDD V%+"%%'''=e==CCEE  +++X%1133 C CO//8HYb7;RWagHhHh>BSTbg<A 0 C C CC C C C C C C C C C C C C C C 
 X%1133 V VO//V_7;RWagHhHh>DUV<Au 0 V V VV V V V V V V V V V V V V V V 	5e55;;==###ts   ;*B11B58B5:EEE M5A	M

M	M	
N% NN6A	PPP)+T  T$'T$+VVVc                    t           j        j        r| j        rt                               d| j         d           t          j        j        	                                5  t          j                            ddd | j        dddd| j        | j        	           d d d            n# 1 swxY w Y   t          d
           dS dS )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 	4;T 	GGsDJsssttt!--// 
 
++)#,)-?PQQ"(#$ $
 $
 , 	 	 	
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   E  F  F  F4us   :B%%B),B)c           
         t           j        j        sd S | j        dk    rd S t          j                            dd           }d|                                 }t          j	                            |          }d
                    t          j        t          j        d                    }t          j	                            ||           |s9t           j                            ddd |d	d
dd||           t'          d           |                                }|r||k    r;t           j                            ddd |dd
dd||           t'          d           d S d S )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  sv     3 	F A%%F.$$Y553E3399;;\%%f--
ggfnV]a@@@AA--- 	O''i/3%[l@m@m6<Q49u ( N N N #JJJ&&((
 	'Z//O''i/3%[h@i@i6<Q49u ( N N N #JJJJJ 0/r&   c                 \   | xj         dz  c_         | j         t          j        j        k    rmt          j        j        rd| _        nMt          j                                        t          j        t          j        j	        j
                  z   | _        d| _         |                                  d S )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$III : ,0))+3+<+@+@+B+BXEW-?EF F F ,( %&D!		r&   c                 <    d| _         |                                  d S )Nr   )r  r   r!   s    r#   r   zCmfAuth.auth_success_hook  s     !		r&   c                 z   | j         r| j         dk    rdS | j        }|rB	 t          |          }n# t          t          f$ r Y dS w xY w|t          j                    k    rdS t          j        j        }|rH| j	        rA| j	        t          j        |j                  z   }|| j	                                        k     rdS dS )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&9V&C&C5!%!B! 	"#9::

z*   ttTY[[((t-? 	!; 	4x7IO`Of7g7g7ggKT7;;====tus   / AAc                 b     |             }||_         ||_        |                    ||           |S r+   )rB   rc   set_pass_hash)rA   rB   hashr)   r   s        r#   new_from_login_hash_saltz CmfAuth.new_from_login_hash_salt  s6    cee		$%%%
r&   c           	      B   |                     d          }|d         }|dk    rk|dd          \  }}}t          j        |          }t          j        |          }	|	t          d|                                |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	'')3ABB&FHh%h//F%h//F[6==??FCPVKKXXXX!"D"D"DEEEr&   c                    |                      |g d          }|r|                     ||j        j                  rft          j        j                                        5  t          j	        
                    ddd|id dd||           d d d            n# 1 swxY w Y   |S t          j        j                                        5  t          j	        
                    d	dd|id d
d||           d d d            n# 1 swxY w Y   d S )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+I+I+IwJJ 	$.*>?? X%1133 V VO//8HYb<CU;K7;4`a<Au 0 V V VV V V V V V V V V V V V V V V
 X))++ 	N 	NO''i4;U3C/36Z[49u ( N N N	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N 	N
 ts$   *BBB*C;;C?C?c                     t           j        j        sd S t          j                            | dgddgddg          D ]8}|j        r/|                     ||j                  rt          |j	                  9d S )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 	F,22'8&9!QQ\^nPo 3 q q 	L 	LG   L$$Xw/@AA L3G4JKKK	L 	Lr&   c                     t                               |          }t                               |          }|                     |||           d S )NrC   )r9   r:   set_pass_hash_bytes)r"   r2  r)   rC   
hash_bytes
salt_bytess         r#   r1  zCmfAuth.set_pass_hash  sE    ]]4((
]]4((
  Z( KKKKKr&   c                 :   ||                      |           t          j        |                                          }t          j        |                                          }d| d| | _        | j                                         t          j        	                    | j
                  }|rj|j                                         d|_        t                                          5  |                    d           d d d            d S # 1 swxY w Y   d S d S )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  sT   x(((#J//6688#J//6688FFFHFF"**,,,!%%DJ%77 	,(00222*/F'$$&& , ,d+++, , , , , , , , , , , , , , , , , ,	, 	,s   *DDDc                     t           j        S r+   )r   r   )rA   s    r#   current_authzCmfAuth.current_auth!  s	    vr&   c                     g }t          d          D ]@}|                    t          j        t          j        t          j        z                        Ad                    |                              d          S )N   r   zutf-8)	rangeappendr  choicer  ascii_lettersr  r  r<   )rA   charsis      r#   gen_saltzCmfAuth.gen_salt%  se    r 	N 	NALLv';fm'KLLMMMMwwu~~$$W---r&      c                    |                      dg           |st          t          j        j        j        |          }t          j        j        j        }t          j        j        j        }t          j        j        j        }| 	                    ||||          }t          |                                           }t          j        d|                                |d          }|                     |||o|           t           j        j                                        5  t(          j                            ddd| j        idd	| j        | j        d
           ddd           n# 1 swxY w Y   |S )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"   re  rC   forcerf  rg  rh  r)   r2  s	            r#   ri  zCmfAuth.reset_password,  s    	'### 
	*>DfMMF/IOO)>DI ! 1 M S..#7H /  H
 Dzz""$$"8X__->->gNN  te6H IIIX))++ 	R 	RO''0@QZ4;TZ3H/34UYU_48Jq ( R R R	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R
 s   9E$$E(+E(re  rh  rg  rf  returnc                 j   g }t           j        t           j        z   t           j        z   }|r@|t           j        z  }|                    t          j        t           j                             |r1|                    t          j        t           j                             |r1|                    t          j        t           j                             t          j        ||t          |          z
            }|
                    |           t          j        |           d                    |          S )Nr  r   )r  r_  r  ascii_uppercasepunctuationr]  r  r^  r  r8   extendshuffler  )r"   re  rh  rg  rf  password_datalettersextra_symbolss           r#   rp  zCmfAuth._generate_passwordI  s     +-&69OO 	Dv))G  v/A!B!BCCC 	?  v}!=!=>>> 	H  v/E!F!FGGGw&3};M;M2MNNN]+++}%%%ww}%%%r&   c                    dt           j         }d|g}t          |||           t          j        j                                        5  t          j        	                    ddd d|id||d           d d d            d S # 1 swxY w Y   d S )	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    Q6;OQQ'2<%000X))++ 	: 	:O''PY/3%@P6:[`78 ( : : :	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	:s   *A??BBc                 `   ddl m} 	  |            }t                              ||          }|                                 |                    t          dd           d|dd          }|j        d	k    rt          d
          t          |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    $$$$$$	
 GII!!L!II FFtd;;;HHH   
 
 =C\]]]~!>!>????r&   c                    | j         j        rfd| _        | j         j        sS| j         D ](}| j         |         D ]}| xj        d| d| z  c_        )| j        j                                        | _         t                      j        |i |}| j        j        rdt          
                                5  t                              | | j                                                   d d d            n# 1 swxY w Y   |S )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\   ;! 	6DJ;& 6 $ @ @H$(K$9 @ @

&?(&?&?X&?&??


@!Z-3355
egglD+F++>$ 	T$$&& T T%%TT^%LLQQSSST T T T T T T T T T T T T T T
s   24C22C69C6c                     | j         j        rg S t          d | j                             d          D                       S )Nc                 D    g | ]}|                     d           d         S )r   r   )r    ).0ra  s     r#   
<listcomp>z)CmfAuth.prepare_scope.<locals>.<listcomp>  s&    CCCAGGCLLOCCCr&   r   )r   r  r   r    r!   s    r#   prepare_scopezCmfAuth.prepare_scope  sA    : 	ICCTZ-=-=c-B-BCCCDDDr&   c                    |                      |          }t          j        dk    r|S |d         d         }	 t          j        |          }n# t
          $ r d}t          |          w xY w|                     ||          }|s;d|d         d          d}t          	                    |           t          |          |S )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#	#$5c::KK 	# 	# 	#`EE"""	# ##M;?? 	#y\_`i\jku\vyyyEMM%   E"""
s   A A(usersc          
         |                      |          }|d         d         }|D ]}	 t          |d                                                                                   }g d}	d}
|                    d          rp|                     t          |d                                                                                   |	          }
|
r||
_        n/|                     ||	          }
n|                     ||	          }
|
sLt                              |          }
t          	                    d	|            |

                                 |                    d
          pd}t          |                                                                          p||
_        |                    d          pd}t          |                                                                          pd|
_        |
j        j        ri |
_        |
j        sg |
_        ||
j        vr|
j                            |           g |
j        |<   |d         r{t          	                    d                    ||                     ||
j        vr|
j                            |           |
j        |= d|
j        _        |

                                 |d         D ]Q}t          	                    d| d| d|            |
j        |                             |           d|
j        _        R|d         |
_        t          	                    d|            t          	                    d|
j                    |

                                 t+                       t          	                    d|
j                    # t.          $ r t                              d|             w xY wddiS )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	 6	I5Ig.//5577==??` ` `==-- @77Y{-C)D)D)J)J)L)L)R)R)T)T]d7eeD D%*

"wwU7wCC77w7??D  !>>>66D MM"TU"T"TUUUIIKKK!g..4" ZZ--//5577@5
%MM+66<"	!$Y!5!5!7!7!=!=!?!?!G4;& %"$DK- 0-/D*4#999*11(;;;(*H%]+ MM"X"_"_`ego"p"pqqqt'===.55h???H--1DK*IIKKK ). 9 2 2HMM  #AQV  #A  #Adl  #A  #Av~  #A  #A  B  B  BK)00:::-1DK**$-n$=!6966777:T[::;;;		8DJ889999   !!"Yi"Y"YZZZ $s   JN2C*N22)Oc                &   t           j        sd S d }t           j        sd S |                     |          }|d         d         }|D ]}t          j                            |d         d         dg          }	|	st                                          }	 ||	|d                    |d         d         |	_        |	                                 t          j                            |d         ddg          }
|
st                                          }
 ||
|           ||
_	        |d         |
_        |	|
_
        |
                                 t          j                            d	d
d |D             g          D ]}	|	                                 ddiS )Nc                     |D ]X}|dv s*|                     d          s|                    d          r1t          | |          rt          | |||                    Yd S )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  s    & C C
!999%0088 :<F<O<OPU<V<V :3
++ CCXj-ABBBC Cr&   r   r   pluginr  r
   )ext_idre   r   r  zNOT INc                     g | ]
}|d          S )r   )r  r   s     r#   r  z3CmfAuth.rpc_account_plugin_push.<locals>.<listcomp>	  s     PsPsPs_bQTUYQZPsPsPsr&   )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_objs              r#   rpc_account_plugin_pushzCmfAuth.rpc_account_plugin_push  s   $ 	F	C 	C 	C $ 	Foom,,y>*-' 	# 	#K%))X1Ft1LVYUZ)[[F ,))++F6;x0111'1$7FMKKMMM$6::+dBS]`bl\m:nnO" ="(":":"<"<F?K000'/O$%0%6O"%+O"  """".33HhPsPsfrPsPsPs;t3uu 	 	FMMOOOO$r&   c           	      J   | j         t          j        | j        j                  z   t          j        t
          j                  z   }t          t
          dt          j	                  } |j
        d|                                 f||dddd| t          j        |||fi | d S )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A`Af&g&g&ggjrj|  CI  CV  kW  kW  kW  W(DglSS 	
	

 !$
	
 
	
 
	
 
	
 
	
 	-RRMRRRRRr&   c           	           |j         d | j        t          j        dz
            f|t          j                                        t	          j        t          j        t          j        z             z   dddd| d S )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BB		

 !%))++h.@*V-@@/B /B /B B$	
 	
 	
 	
 	
 	
 	
r&   c           	          |s>t           j                                         t          j        t          j                  z   } | j        	 	 d||dddd| d S )Nr&  nginx_auth_tokenpassword123Tr  r  )r  r  )r!  r"  r#  rq   r  r  )r  r  r  r  s       r#   r  zCmfAuth.set_nginx_token.  s     	]%))++h.@fF[.\.\.\\G	
 !$	
 	
 	
 	
 	
 	
 	
r&   u_   Разблокировка учетных записей по истечению времениz	@minutely)	only_oncedescription
system_jobschedulec                     t           j        j        rd S t          j                                        } 	 t
          j                            dgdd| gddg          }|sd S |D ]}d |_         |j	                     t                       V)NTr   <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 	F##%%	"N//-.-sC8#h 0  M ! %  +/(	LLL	r&   )rP   F)T)r   Nr+   )rc  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  ri  r0   boolrp  r|  r  r   r  r  r   r  r  r  r  r  cmf_deferred_jobr  __classcell__)r  s   @r#   r   r      s       LI##&&V5GSY[f(g(g'hii. $  J
 ? ? X? ? ? X?      - - [-4f f f f < < [<@   \ \ \
% 
% 
% 
% % % % % \%
 
c 
 
 
 
 6 6 6 \60 6 6 \6   \$ % % [%N d d [dL  ,  >      0   [ 	F 	F [	F   [$
L 
L 
LL L L L
, , , ,    [ . . [.   < 6;9>& &&.2&&26& 
& & & &* : : [: @ @ @ [@.    E E E   [" @  @  @  @  [@ D     [ B S 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&   r#   <module>r     sh                                          * * * * * * ' ' ' ' ' ' # # # # # #                 " " " " " " " " " " " "y y y y ydl y y y y yr&   