U
    `fá                     @   s   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mZm	Z	m
Z
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Zd d
lmZ G dd dejZdS )    N)LDAPException)TlsServer
ConnectionNTLMSIMPLE)cmf_context)commit_all_ds)*)
log_config)cmf_auth_ldap_plugin)cached_property)Pathc                       s  e Zd ZdZdZejjd Zee	j
dddZdCeedddZddd	d
dZdd ZdDedddZedddZeedddddddd Zeedddddddd Zdd Zeedddddd d! Zeeddd"d#d$ ZdEd%d&Zeeddddd'dd(d)d*Zd+d, Zd-d. Zed/d0 Zd1d2 Zd3ddd4 fd5d6
Z  fd7d8Z!d9d: Z"d;d< Z#d=d> Z$d?d@ fdAdB
Z%  Z&S )FCmfAuthLdapPluginN)logger)returnc                 C   s   | j r| j S tjj| tjd}|stj| tjd}|  |jsJ|d ddl	m
}m}m} |tj || td| _ tj| j |jtjd nt|  | _ | j S )uE    Журнал логирования процесса импорта )parentname    r   ) set_library_log_activation_levelset_library_log_detail_levelEXTENDEDldap3)level)_CmfAuthLdapPlugin__loggermodelsZCmfAttachmentgetr   LOG_NAMEsaveZfile_existsZupload_fileZldap3.utils.logr   r   r   loggingZERRORZ	getLoggerZinit_loggerZfull_path_fileINFOZ
get_loggerget_files_dir)selfZ
attachmentr   r   r    r#   1./modules/settings/models/cmf_auth_ldap_plugin.pyr      s    

zCmfAuthLdapPlugin.logger)ldap_user_nameldap_user_pwdc           
   
   O   s   t   | dddddg |s,| jjj}|s<| jj }tt	j
t	jdd}t| jj d| jj |d	}t}t||||d
| jjd}| r|W  5 Q R  S d|j }	| j|	 t|	W 5 Q R X d S )Nplugin.ext_urlplugin.ext_portconnection_timeoutzplugin.ext_loginplugin.ext_passwordz"/etc/ssl/certs/ca-certificates.crt)ZvalidateversionZca_certs_file:)ZtlsF)userpasswordauthenticationZauto_referralsZreceive_timeoutu@   Не удалось подключиться к серверу: )cmfutildisable_aclload_fieldsplugin	ext_loginvalueext_passworddecryptr   sslZCERT_OPTIONALZPROTOCOL_TLSv1_2r   Zext_urlZext_portr   r   r)   ZbindZ
last_errorr   error	Exception)
r"   r%   r&   argskwargsZtls_configurationZserverr/   connerrr#   r#   r$   connect.   s2    

 
 
 zCmfAuthLdapPlugin.connect)r4   r6   c             
   O   sz   z2|  || W 5 Q R X td | jd W dS  tk
rt } z$td|  | jd W Y dS d }~X Y nX d S )NuK   Подключение к серверу выполнено успешно.TuO   Подключение к серверу выполнено с ошибкой: uN   Подключение к серверу выполнено с ошибкой.F)r?   	cmf_alertr   infor   	exception)r"   r4   r6   r;   r<   er#   r#   r$   test_connectD   s    
zCmfAuthLdapPlugin.test_connectc              	   c   sd   d}d}|   8}|jjj||d|ddd}|D ]}|V  |d7 }q0W 5 Q R X | jd|  d S )N
   r   r
   T)search_basesearch_filter
attributes
paged_size	generatorZget_operational_attributes   u"   Загружено записей )r?   extendZstandardZpaged_searchr   rA   )r"   rF   rG   rI   totalr=   Zentry_generatorentryr#   r#   r$   _paged_searchQ   s    

 zCmfAuthLdapPlugin._paged_searchc              	   c   s   z|  dddg | jj}|r4| jr.| jj}nW d S |d dkrXtddtdd|}|r| jd	krx|d
| d7 }n|d| d7 }|ddkrd| d}| jr| j	dD ]&}| 
|  d| j |E d H  qn| 
| jj|E d H  W n$ tk
r   | jd  Y nX d S )Nadditional_user_dnuser_object_class_filterbase_dnrK   &z\)$ z\(&adz(whenCreated>=)z(modifyTimeStamp>=)(r   z(&;,u8   Ошибка загрузки пользователей)r2   rQ   r5   user_disabled_filterresubdirectory_typecountrP   splitrO   striprR   r:   r   rB   )r"   prev_sync_gtdisabledrG   add_dnr#   r#   r$   ldap_get_users_   s,    

&z CmfAuthLdapPlugin.ldap_get_usersc                 c   s   zn|  dddg | jrR| jdD ]*}| |  d| j | jjE d H  q$n| | jj| jjE d H  W n" tk
r   | j	
d  Y nX d S )Nadditional_group_dngroup_object_class_filterrR   rX   rY   u(   Ошибка загрузки групп)r2   re   r_   rO   r`   rR   rf   r5   r:   r   rB   )r"   rc   r#   r#   r$   ldap_get_groups{   s    *z!CmfAuthLdapPlugin.ldap_get_groupsTz	@minutely  	   )	only_once
system_jobZschedulesoft_time_limitpriorityc                  C   s^   t jdddgddgdD ]@} | jr6| jj| jjd krt j| jjdd	 t j| jjd
 qd S )N	auto_sync==T	sync_datesync_intervalfilterfields<   auth_plugin_iddelta_minutesrx   )	r   listrp   agerq   r5   syncidapplyauth_pluginr#   r#   r$   	cron_sync   s    
zCmfAuthLdapPlugin.cron_syncz	H 4 * * *ip  c                  C   sf   t jdddgddgdD ]H} | jr>| jj| jjd d d krt j| jjd d	 t j| jjd
 qd S )Nrn   ro   Trp   sync_all_intervalrr   ru      rw   rz   )	r   r{   rp   r|   r   r5   r}   r~   r   r   r#   r#   r$   cron_full_sync   s    
"z CmfAuthLdapPlugin.cron_full_syncc           
   	   C   s  | j d t }dddg}| j|dD ]B}|jj D ].\}}||krNq:|| d| d}| j d| d|d	   tj	j
d
dd| dg| d}|stj	j
d	d|d	 g| d}|s| j d|  tj	|d	 |d}|j s||_||jkr|j | |_| D ]0\}}	|d
kr6q t||r t|||	 q |jr:|  |j  q:q(| j dt| d d S )Nu)   Синхронизируем группы--r~   groupsrt   z::u-   Обрабатываем группу ext_id=z name=r   ext_idZLIKE%rr   ro   u0   Не нашли группу, создадим: )r   r   u   Обработано u    групп)r   rA   setall_raw_datar   r5   itemsaddr   CmfPersonGroupr   keysr   loadhasattrsetattr
is_changedr   dpcommitlen)
r"   Zsyncedrt   objZgroup_idvalr   groupkeyr5   r#   r#   r$   process_groups   s>    

"

z CmfAuthLdapPlugin.process_groups)rk   rj   rl   rm   c              
   O   sr  t d|  d tjj| ddgd}z|jdkr`|jjdkrN|j	d n|j	d	 W d
S |j	d |j
  d|_|  t  tj  |  |j  |jstdtjjdddgddd
gdd|ggddid t  t  tjjdddgdd|ggdddgdD ]}tjj| dgdj}|dkrB qz0|j	d|j  |  |j  t  W n(   |j  |jd|  Y nX qW 5 Q R X W 5 Q R X d|_|  t  tddD ]<}t j j!dkr|j	d t"tj#j$  qt%&d q|j	d W nN t'k
rl } z.t(| d |_|  t  |jd!  W 5 d
}~X Y nX d
S )"uP   
        Сохраняем данные в CmfPerson и CmfPersonGroup
        zStart CmfAuthLdapPlugin.apply(rV   sync_statusrp   r~   rt   in_progressrh      Синхронизация пользователей зависла, запускаем форсированно повторно2   Синхронизация уже запущенаN+   Запущена синхронизацияuH   Укажите "Домен для логина" в настройках.dirtyro   FZ	person_idr   T)rs   valuesr   r~   loginrr   u   Обрабатываем login=uF   Ошибка обработки данных пользователя closedr   ru   u+   Синхронизируем с eva_accountrK   u0   Изменения применены в eva_appr9   u4   Ошибка применения изменений))gdebugr   r   r   r   rp   r|   r   rA   set_nowr   commit_with_eventr   
ldap_groupr   r   r   domainAssertionErrorCmfAuthPluginDataZbulk_updater0   Zdisable_notifyr1   r{   sgetr   Zprocess_personZrollbackrB   range
global_varaccount_sync_statusschedule_deferred_job	CmfPersonaccount_sync_userstimesleepr:   r	   )rx   _args_kwargsr   raw_data
new_statusirC   r#   r#   r$   r      sp    








0zCmfAuthLdapPlugin.apply)rj   rk   c              	   O   s`  t d|  d tjj| ddgd}|jdkr@|jd d S |jd |j	  d|_|
  t  d	}|jd
 tjj| d}d}d}||k r|| |k rtjj| d|gdddddgdD ]}z|jr4|jjs|jjd|j  d|j_tj }	|	|jjkr"|jj|	 |jj
  d |_|  |d	7 }|j  |jd| d|  W q tk
r   |jd Y qX q|d	7 }qd	}tjj| d}|jd tjj| dgdD ]x}
zN|
jrd |
_|

  W q|
  |jd| d|  |d	7 }t  W n" tk
r<   |jd Y nX qd|_|
  |jd d S )NzStart CmfAuthLdapPlugin.clear(rV   r   rp   r   r   r   u)   Очищаем синхронизациюrK   uh   Удаляем данные по пользователям (не самих пользователей)r   d   r   zperson.does_not_workzperson.rg_member_ofr   zperson.is_adminzperson.is_support)r   slicert   u    Блокируем учетку T   Удалено u    из u/   Ошибка удаления CmfAuthPluginDatau   Удаляем группы
cmf_import)r   rt   u,   Ошибка удаления CmfPersonGroupr   u!   Очистка завершена)r   r   r   r   r   r   r   rA   rp   r   r   r   r   r^   r{   ZpersonZis_adminr   Zdoes_not_workr   r   Zrg_member_ofremover5   deleter   r   r:   rB   r   )rx   r   r   r   r   rM   stepndataZldap_grpr   r#   r#   r$   clear   sl    






zCmfAuthLdapPlugin.clearc                 c   sp   ddl }d}tjjdd| gd}t||| D ]8}tjjdd| g||| || | gdD ]
}|V  q^q2dS )uB  Частями загружаем в память и отдаем, иначе будет утечка памяти

        Args:
            fields (list, optional): Поля для загрузки. Defaults to None.

        Yields:
            CmfAuthPluginData: загруженные сырые данные
        r   Nr   r   ro   )rs   )rs   rt   r   )mathr   r   r^   r   Zceilr{   )r"   rt   r   r   Zcntr   rowr#   r#   r$   r   8  s    	
zCmfAuthLdapPlugin.all_raw_data)rj   rk   rl   rm   ry   c                 O   s,  t d|  d tjj| ddddddd	d
dddgd}z|jdkrr|jjdkr`|j	d n|j	d W d S |j	d |r|jj
|dnd }|j }d|_|  t  |j	d i }| D ],}|ds|jd|  qt|jjd}	|jdks|jjr$t|d |	d< nt|d |jj|	d< t|	d tr^|	d d |	d< |d |jj}
t|
tr|
d }
|
r|
|	d< |d |jj}t|tr|d }|r||	d< |d |jjg |	d< |	||d < |j	|	  q|j	d  t }dd!dd"d#d$d%d&d'd(d)g}t }t }|j|d*D ]&}||}|sZqB|||d < qBt|rt | }t|| }|j	d+t| d,d-|d.d/|d0d1  t }t }|jr|jd2|d3D ]&}||}|sq|||d < qt|rVt | }t|| }|j	d+t| d4d-|d.d/|d0d1  d}d}d}d}t }|r|j |d5D ]}ztjj!| dgdj}|dkrW  q|j"|krW q|#t|j"}|sW q|$||| d2|_%|d67 }|j"|kr
d2|_&|j'rB|j	d7|d!   |d67 }d2|_(|jd2d8 W nX t)k
r } z8|j*d9|d!  d:|d  d;|  d<|_|d67 }W 5 d }~X Y nX qt | }|r|| }|j	d=| d>d-|d.d/|d0d1  |r|| }|j	d?| d>d-|d.d/|d0d1  t }|+ D ]\}}z|tjj!| dgdj}|dkr^W  q|j	d@|d!   tj,||dA}|$||| d2|_(|  |j-.  |d67 }W nX t)k
r
 } z8d<|_|j*d9|d!  d:|d  d;|  |d67 }W 5 d }~X Y nX q.|rTt | }|| }|j	dB| d>d-|d.d/|d0d1  d}|s|jd<kr|j |d5D ]:}t/|dCr|j%svd2|_0d2|_(|jd2d8 |d67 }qv|rt | }|| }|j	dD| d>d-|d.d/|d0d1  |jdkrdE|_|  t  tj12  tj34  t5ddFD ]0}t j6j7dkrXt8tj1j9  qft:d6 q4|r|jdG| dH t;j<dI| dJ| dH|dK n|j	dL ||j_|  W nj t)k
r& } zJt=| |r|j*dM d<|_|  t;j<dI| dN|dK t   W 5 d }~X Y nX d S )ONzStart CmfAuthLdapPlugin.sync(rV   r'   r(   zplugin.loginr*   rR   r   zcmf_owner.loginr]   r   use_user_groups_attrrp   r   r   i0*  r   r   r   r   u   Загружаем группыrH   u-   У записи нет аттрибутов: r   ZentryDNdnr   r   r   textmembersu*   Загружаем сырые данныеr   
first_name	last_nameemailemployee_numberr   ldap_disabledr   ldap_deleted)ra   u   Загружено u0    изменённых пользователейz (z.1fu
    сек., z.0fu    польз./сек.)T)rb   ra   u2    отключенных пользователейr   rK   u9   Синхронизируем учетную запись )Z	only_datauA   Ошибка синхронизации пользователя (z): r9   u   Проверено u    пользователейu!   Синхронизировано u$   Импортируем учетку )r   r   u   Добавлено _ldap_synchronizedr   r   ru   uC   Синхронизация завершена с ошибками (z).u   Синхронизация u(    завершена с ошибками()r   u=   Синхронизация успешно завершена.u?   Синхронизация завершена с ошибкойu%    завершена с ошибкой)>r   r   r   r   r   r   rp   r|   r   rA   Zgeneralized_timeZnowr   r   rg   Zwarningdictr~   r5   group_uid_attrZis_nullstr
isinstancer{   group_name_attrgroup_desc_attrgroup_users_attrr   rd   ldap_user_attributesr   rZ   r   r   r   popupdate_raw_datar   r   r   r   r:   rB   r   r   r   r   r   r   r   Zflush_all_notify_opt_cacheZCmfProjectNotifySchemeZtrigger_reloadr   r   r   r   r   r   r0   Zadmin_alertr	   )rx   ry   r   r   r   ra   Z
sync_start
cached_grpgrpr   Zgrp_nameZgrp_attrZ
start_timert   Zldap_users_dict	ldap_userr-   ZdurationZspeedZldap_disabled_users_dictZsync_errorsZusers_addedZusers_synchronizedZusers_updatedr   r   rC   r   raw_userZusers_deletedr   r#   r#   r$   r}   J  s           


    




&

&

zCmfAuthLdapPlugin.syncc              
   C   s`  | dsd S |d  | jj}t|tr2|d }t|d  | jj}t|trZ|d }|sftd|d  | jj}t|tr|d }|d  | j	j}t|tr|d }|d  | j
j}t|tr|d }|d  | jj}t|tr|d }|d  | jjg }t||||||||d d}	| jr\|d  | jj}
t|
trT|
d }
|
|	d< |	S )NrH   r   uW   Не удалось получить уникальный ИД пользователяr   )r   r   	name_attruser_name_attruser_last_name_attruser_email_attruser_groupsr   user_employee_number_attr)r   user_full_name_attrr5   r   r{   r   user_uid_attrr   user_display_name_attrr   r   r   user_groups_attrr   r   )r"   r   r   r   r   r   r   r   r   r-   r   r#   r#   r$   r     sH    






  z&CmfAuthLdapPlugin.ldap_user_attributesc           	      C   s  |d |_ d|kr|d |_nd |_d|krL|d rL|d d |jj |_nd |_d|krz|d rz|d d |jj |_nd |_d|kr|d |_nd |_d|kr|d |_nd |_g }| jr(|D ]`}|| }|d |d kr||d	  |d	 |j	kr| j
d
|  ||j	|d	 < |j	|_	qnz|d D ]p}| j
d|  ||}|r||d	  |d	 |j	kr||j	|d	 < |j	|_	n| j
d|  q0t|j	j D ] }||kr|j	|= |j	|_	qd S )Nr   r   r   r   r   r   r   r   r   u9   Добавляем пользователю группу r   u   Ищем группу u   Не нашли группу )r   r   r   Z
max_lengthr   r   r   r   appendr   r   rA   r   warnr{   r5   r   )	r"   r   r   r   Zcurrent_user_groupsZ	group_uidr   entry_dnZ	gr_ext_idr#   r#   r$   r   A  sN    



z!CmfAuthLdapPlugin.update_raw_datac                  C   sZ   t jdkrdS g } tjjddgdD ]}| |d q$t | ddd	}td
| dS )u=   
        Отправляем в аккаунт 1к1
        FalseNz**plugin.*r   r   )Zeva_app_tokenauth_pluginsZrpc_account_plugin_push)r<   methodz/auth/sync_accounts)	configZEVA_ACCOUNT_USEr   r   r{   r   dumpsZgen_eva_app_tokenZcall_eva_account)r   r3   r   r#   r#   r$   account_plugin_pushv  s    

z%CmfAuthLdapPlugin.account_plugin_pushc                 C   s.   | j jsd S | j r*ttjjd| jjid d S )Nrx   )r<   )rn   r   r   r   r   r   r~   r5   r"   r#   r#   r$   _process_auto_sync  s    z$CmfAuthLdapPlugin._process_auto_syncr   depthnotifyemitc                   s^   t jstddd | jr,| js,tj g| _t j| _	| 
  |   t j||||d|S )NuE   Модуль доступен только в версии On-PremiseTabortr   )r   ZIS_BOX_VERSIONr@   Zis_newZdefault_groupsr   r   Z
user_groupZORG_NAMEZorg_name_process_directory_typer   superr   )r"   r   r   r   r;   r<   	__class__r#   r$   r     s    zCmfAuthLdapPlugin.savec                    s   t   ddg S )Nr
   r   )r  save_preload_fieldsr   r  r#   r$   r    s    z%CmfAuthLdapPlugin.save_preload_fieldsc                 C   s  | j jsd S | j dkrd| _d| _d| _d| _d| _d| _d| _d	| _	d
| _
d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _n~| j dkrd| _d| _d| _d| _d| _d| _d| _d	| _	d
| _
d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _d S )NrU   r-   z,(&(objectCategory=Person)(sAMAccountName=*))zZ(&(objectCategory=Person)(sAMAccountName=*)(userAccountControl:1.2.840.113556.1.4.803:=2))ZsAMAccountNameZcnZ	givenNameZsnZdisplayNameZmailZ
unicodePwdZ	plaintextZ
objectGUIDr   z6(&(objectCategory=group)(!(isCriticalSystemObject=*)))descriptionmemberZmemberOfZldapZinetorgpersonz(objectclass=inetorgperson)rT   ZuserPasswordZshaZ	entryUUIDZgroupOfUniqueNamesz (objectclass=groupOfUniqueNames)ZuniqueMember)r]   r   user_object_classrQ   rZ   r   Zuser_rdn_attrr   r   r   r   Zuser_password_attrZuser_password_cryptr   r   Zgroup_object_classrf   r   r   r   r   r   r#   r#   r$   r     sT    
z)CmfAuthLdapPlugin._process_directory_typec                 C   s   t   | ddddg tdD ]}z| | jjj| jj	 }d| j
 d| j d| d	}|j| jj|d
dr|jD ]L}| |j|4}|W  5 Q R    W  5 Q R  W   W  5 Q R  S Q R X q~W 5 Q R X W q&   | jd| d|  Y q&X q&td| dd W 5 Q R X dS )u?   Авторизация через внешнюю системуr  r   rR   r      z(&(ObjectClass=rW   =z))r
   )rH   u   Ошибка u-    попытки авторизации login=u7   Не удалось авторизоваться login=Tr   N)r0   r1   r2   r   r?   r3   r4   r5   r6   r7   r  r   searchrR   entriesr   r   rB   r@   )r"   r   r.   r   r=   Z_filterresZ
_test_connr#   r#   r$   signin  s    
H zCmfAuthLdapPlugin.signinc                 O   sF   t j|  tj}t jt jtj|s8| j	
d t jd|S )NZinitfiles)ospathjoinr!   r   r   existsr   Z
UPLOAD_DIRr   rA   )r"   r;   r<   Z	file_pathr#   r#   r$   get_log_filename  s    z"CmfAuthLdapPlugin.get_log_filenameF)forcec                   sL   t jj| d}|r(td| dd d S t j||dd| |   d S )Nr   uM   Сначала очистите интегрированные данные: Tr   )r  	recursive)r   r   r^   r@   r  r   r   )r"   r  r;   r<   Zhas_datar  r#   r$   r     s    zCmfAuthLdapPlugin.delete)NN)NN)N)'__name__
__module____qualname__Z_CmfAuthLdapPlugin__connectr   r   r   Zui_meta_skippropertyr   ZLoggerr   r   r?   rD   rO   r{   rd   rg   staticmethodZcmf_deferred_jobr   r   r   r   r   r   r}   r   r   r   r   r   r  r   r  r  r   __classcell__r#   r#   r  r$   r      sN   	">
8
 S#5
.r   )gcr   r   r[   Zldap3.core.exceptionsr   r   r   r   r   r   r   Zcmf.appr   Zcmf.data_providers.baser	   Zcmf.includeZcmf.modules.logsr   Zmodules.settings.fieldsr   r   r8   pathlibr   r   r#   r#   r#   r$   <module>   s   