U
    xDeAy                     @   s   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T d dlmZ 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ejej dS )    N)LDAPException)TlsServer
ConnectionNTLMSIMPLE)commit_all_ds)*)
log_config)CmfResultSplitter)cmf_auth_ldap_plugin)cached_property)Pathc                       sZ  e Zd ZdZdZejjd Zee	j
dddZd4eedddZddd	d
dZdd ZedddZedddZeejddddd Zedd Zeejddddd Zeejddddd Zeejddddd Zedd Zd d! Zd"d# Zd$ddd% fd&d'
Z fd(d)Z d*d+ Z!d,d- Z"d.d/ Z#d0d1 fd2d3
Z$  Z%S )5CmfAuthLdapPluginN)logger)returnc                 C   s   | j r| j S | j rttj|  }|jddd |t	j
}|  ddlm}m}m} |tj || td| _ t	j| j |tjd nt	|  | _ | j S )uE    Журнал логирования процесса импорта T)parentsexist_okr   ) set_library_log_activation_levelset_library_log_detail_levelEXTENDEDldap3)level)_CmfAuthLdapPlugin__loggerdebugloadr   config
UPLOAD_DIRZjoinpathget_files_dirmkdirr
   LOG_NAMEZtouchZldap3.utils.logr   r   r   loggingZERRORZ	getLoggerZinit_loggerINFOZ
get_logger)selfZpath_logZfile_name_logr   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   ext_urlZext_portr   r   r*   ZbindZ
last_errorr   error	Exception)
r#   r&   r'   argskwargsZtls_configurationZserverr0   connerrr$   r$   r%   connect,   s2    

 
 
 zCmfAuthLdapPlugin.connect)r5   r7   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)rA   	cmf_alertr   infor   	exception)r#   r5   r7   r=   r>   er$   r$   r%   test_connectB   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"   Загружено записей )rA   extendZstandardZpaged_searchr   rC   )r#   rH   rI   rK   totalr?   Zentry_generatorentryr$   r$   r%   _paged_searchO   s    

 zCmfAuthLdapPlugin._paged_searchc                 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_user_dnuser_object_class_filterbase_dn;,u8   Ошибка загрузки пользователей)r3   rR   splitrQ   striprT   rS   r6   r<   r   rD   r#   Zadd_dnr$   r$   r%   	get_users]   s    *zCmfAuthLdapPlugin.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_filterrT   rU   rV   u(   Ошибка загрузки групп)r3   r[   rW   rQ   rX   rT   r\   r6   r<   r   rD   rY   r$   r$   r%   
get_groupsi   s    *zCmfAuthLdapPlugin.get_groupsT)Z	only_onceZsystem_taskc                  O   sV   t jdddgdddggddgd	D ].}|jr@|jj|jjd
 kr"t j|jjd q"d S )Nsync_status!=in_progress	auto_sync==T	sync_datesync_interval)filterfields<   )auth_plugin_id)r   listrc   agerd   r6   syncid)r=   r>   auth_pluginr$   r$   r%   	cron_syncu   s    
zCmfAuthLdapPlugin.cron_syncc                 C   s   t | j d S )N)cmf_deferred_taskrn   )clsr$   r$   r%   minutely_hook}   s    zCmfAuthLdapPlugin.minutely_hookc           	   
      s   fdd}t d|  d tjj| ddgd z jdkrl jjd	krZ j	d
 n j	d W dS  j	d  j
  d _   t   jstdtjjd d}d}t  t p t| D ]^\}}z( j	| d|  |  t  W q   t  |d7 } jd|  Y qX qW 5 Q R X W 5 Q R X |r`td| dd _   t  tddD ]<}t jjdkr j	d ttjj  qt d q~ j	d W nN tk
r } z.t!| d _   t   jd  W 5 d}~X Y nX dS )uP   
        Сохраняем данные в CmfPerson и CmfPersonGroup
        c                  3   sb   d} ddddgdddggdd gg}t jj|d	gd
| gd}|sDdS |D ]
}|V  qHt  q$dS )u]  Специально берем только первые 50 НЕ обработанных, потому что выше мы их обработаем и
            второй раз они уже не попадут в выборку

            Yields:
                CmfPluginData: необработанные raw данные
            2   ORdirtyrb   TZ	person_idNrm   r	   r   )re   rf   slice)modelsCmfAuthPluginDatari   gcZcollect)limit_filterdatarowrm   r$   r%   	paginated   s      z*CmfAuthLdapPlugin.apply.<locals>.paginatedzStart CmfAuthLdapPlugin.apply()r^   rc   rl   rf   r`        Синхронизация пользователей зависла, запускаем форсированно повторно2   Синхронизация уже запущенаN+   Запущена синхронизацияuH   Укажите "Домен для логина" в настройках.T)rt   rm   r       из rM   uF   Ошибка обработки данных пользователя u   Обнаружено u    ошибокclosedrg   u+   Синхронизируем с eva_accountu0   Изменения применены в eva_appr;   u4   Ошибка применения изменений)"gr   rv   r   getr^   rc   rj   r   rC   set_nowsavecommit_with_eventdomainAssertionErrorrw   countr1   disable_notifyr2   	enumerateZprocess_personZrollback_purge_eventrD   r<   range
global_varaccount_sync_statusro   	CmfPersonaccount_sync_userstimesleepr   )	rh   _args_kwargsr~   cnterrorsiraw_datarE   r$   r}   r%   apply   s\    


.zCmfAuthLdapPlugin.applyc           
   	   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$tjj| || || | gdD ]^}z6|jd| d|  |  |d	7 }|j  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rvd |	_|	
  W qT|	  |jd| d|  |d	7 }t  W n" tk
r   |jd Y nX qTd|_|
  |jd d S )NzStart CmfAuthLdapPlugin.clear(r   r^   rc   r   r`   r   u)   Очищаем синхронизациюrM   uh   Удаляем данные по пользователям (не самих пользователей)r}   d   r   )rm   ru   u   Удалено r   u/   Ошибка удаления CmfAuthPluginDatau   Удаляем группы
cmf_import)rm   rf   u,   Ошибка удаления CmfPersonGroupr   u!   Очистка завершена)r   r   rv   r   r   r^   r   rC   rc   r   r   r   rw   r   ri   deletedpcommitr<   rD   CmfPersonGroupr   rm   )
rh   r   r   rm   r   rO   stepnr{   groupr$   r$   r%   clear   sV    


$

zCmfAuthLdapPlugin.clearc           !      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 |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rF|d d |d< |d |jj}t|trl|d }|rz||d< |d |jj}t|tr|d }|r||d< |d |jjg |d< |||d < |j	|  q|j	d d}	d}
d}d}g }g }| D ]}|ds6|jd|  q|d 7 }d }d }d }zx|d |jj}t|trt|d }t|d |jj}t|tr|d }|st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rN|d }d }|j#r|d |j#j}t|tr|d }tj$j||d"gd#}|s|j	d$|  d%}tj$||d&}||_%|r||_&|r|r|d |j'j( |_'|r|r|d |j)j( |_)|r||_*|r$||_+|d |j,jg }g }|j-r|D ]f}|| }|d |d krH||d  |d |j.krH|j	d'|  ||j.|d < |j.|_.qHnv|D ]p}|j	d(|  ||}|r||d  |d |j.kr$||j.|d < |j.|_.n|j/d)|  qt|j.j0 D ] }||kr8|j.|= |j.|_.q8|j1pf|j2|_1|j1r|s|j	d*|  |jd%d+ |j34  || |r|	d 7 }	n|
d 7 }
W nP t5k
r } z0d,|_|j6d-| d.| d/|  |d 7 }W 5 d }~X Y nX qt78 ( |D ]}tj$j|d0}|  q(W 5 Q R X d}|jd,krtj$jd1d2|gdd3|ggd4D ]}|d 7 }|9  q~|j	d5| d6|	 d7|
 d8| d9| d: |jdkrd;|_|  t  t:dd<D ]0} t j;j<dkrt=tj>j?  qt@Ad  q|rV|jd=| d> t7jBd?| d@| d>|dA n|j	dB W nj t5k
r } zJtC| |r|j6dC d,|_|  t7jBd?| dD|dA t   W 5 d }~X Y nX d S )ENzStart CmfAuthLdapPlugin.sync(r   r(   r)   zplugin.loginr+   rT   r   zcmf_owner.logindirectory_typer^   use_user_groups_attrrc   r   r`   r   r   r   r   u   Грузим группыrJ   u-   У записи нет аттрибутов: r}   ZentryDNZdnext_idr   nametextmembersu5   Синхронизация пользователейrM   uW   Не удалось получить уникальный ИД пользователя**)r   rm   rf   u$   Импортируем учетку T)r   rm   u9   Добавляем пользователю группу u   Ищем группу u   Не нашли группу u9   Синхронизируем учетную запись )Z	only_datar;   uA   Ошибка синхронизации пользователя (z): )r   rm   rb   zNOT INre   u!   Синхронизировано u    учетных записей(u    новых, u    обновлено, u    удалено, u    ошибок)r   rg   uB   Синхронизация завершена с ошибками(z).u   Синхронизация u(    завершена с ошибками()obju=   Синхронизация успешно завершена.u?   Синхронизация завершена с ошибкойu%    завершена с ошибкой)Dr   r   rv   r   r   r^   rc   rj   r   rC   r   r   r   r]   Zwarningdictrl   r6   group_uid_attrZis_nullstr
isinstanceri   group_name_attrgroup_desc_attrgroup_users_attrrZ   user_full_name_attruser_uid_attrr   appenduser_display_name_attruser_name_attruser_last_name_attruser_email_attruser_employee_number_attrrw   loginr   Z
first_nameZ
max_length	last_nameZemailZemployee_numberuser_groups_attrr   groupswarnkeysrt   
is_changedr   r   r<   rD   r1   r   r   r   r   r   ro   r   r   r   r   Zadmin_alertr   )!rh   r   r   rm   Z
cached_grpgrpr   Zgrp_nameZgrp_attrZusers_addedZusers_updatedZ	users_allZsync_errorsZldap_users_idZ	processedr.   Znew_userr   r   Z	name_attrr   r   r   r   Zuser_rawZuser_groupsZcurrent_user_groupsZ	group_uidentry_dnrE   Zuser_deletedZ	user_datar   r$   r$   r%   rk      sr           










"zCmfAuthLdapPlugin.syncc                  C   sx   t jdkrdS g } tjjddgdD ]2}t|ddd}|  |j|j }}| 	| q$t
 | dd	d
}td| dS )u=   
        Отправляем в аккаунт 1к1
        FalseNr   plugin.*)rf   T)Zno_metaZno_acl)Zeva_app_tokenauth_pluginsZrpc_account_plugin_push)r>   methodz/auth/sync_accounts)r   ZEVA_ACCOUNT_USErv   r   ri   r   rW   metaresultr   Zgen_eva_app_tokenZcall_eva_account)r   r4   Zsplitterr   Zresult_dictr{   r$   r$   r%   account_plugin_push  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 )Nrh   )r>   )ra   r   ro   rv   r   r   rl   r6   r#   r$   r$   r%   _process_auto_sync  s    z$CmfAuthLdapPlugin._process_auto_syncc                 C   s   | j s| j js| j jjsd S td| j jj}|D ]L}tjjdd| j	gddd|d  dggd}|r2t
d	|d  d
dd q2d S )Nz(ldap|ldaps):\/\/(.+\..*)\/*rl   r_   r(   ZLIKE%rM   r   u)   Интеграция с сервером u    уже естьTabort)r4   r:   r   refindallr6   rv   r   r   rl   rB   )r#   searchresr   r$   r$   r%   
_check_url  s    zCmfAuthLdapPlugin._check_urlr   depthnotifyemitc                   s   t jstddd | jr,| js,tj g| _|   t j	| _
|   |   |   tjjdd| gddid t j||||d|S )	NuE   Модуль доступен только в версии On-PremiseTr   rm   rb   rt   )re   valuesr   )r   ZIS_BOX_VERSIONrB   Zis_newZdefault_groupsrv   r   Z
user_groupr   ZORG_NAMEZorg_name_process_directory_typer   r   rw   Zbulk_update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| _nv| j dkrd| _d| _d| _d| _d| _d| _d| _d	| _	d| _
d| _d| _d| _d| _d| _d| _d| _d| _d| _d S )NZadr.   z,(&(objectCategory=Person)(sAMAccountName=*))ZsAMAccountNameZcnZ	givenNameZsnZdisplayNameZmailZ
unicodePwdZ	plaintextZ
objectGUIDr   z6(&(objectCategory=group)(!(isCriticalSystemObject=*)))descriptionmemberZmemberOfZldapZinetorgpersonz(objectclass=inetorgperson)ZuserPasswordZshaZ	entryUUIDZgroupOfUniqueNamesz (objectclass=groupOfUniqueNames)ZuniqueMember)r   r   user_object_classrS   r   Zuser_rdn_attrr   r   r   r   Zuser_password_attrZuser_password_cryptr   r   Zgroup_object_classr\   r   r   r   r   r   r$   r$   r%   r     sP    

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   rT   r      z(&(ObjectClass=z)(=z))r	   )rJ   u   Ошибка u-    попытки авторизации login=u7   Не удалось авторизоваться login=Tr   N)r1   r2   r3   r   rA   r4   r5   r6   r7   r8   r   r   r   rT   entriesr   r   rD   rB   )r#   r   r/   r   r?   rz   r   Z
_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   r   r   rC   )r#   r=   r>   Z	file_pathr$   r$   r%   get_log_filename8  s    z"CmfAuthLdapPlugin.get_log_filenameF)forcec                   sJ   t jj| d}|r(td| dd d S t j|d|i| |   d S )Nr}   uM   Сначала очистите интегрированные данные: Tr   r   )rv   rw   r   rB   r   r   r   )r#   r   r=   r>   Zhas_datar   r$   r%   r   >  s    zCmfAuthLdapPlugin.delete)NN)&__name__
__module____qualname__Z_CmfAuthLdapPlugin__connectr   r   r   Zui_meta_skippropertyr!   ZLoggerr   r   rA   rF   rQ   ri   rZ   r]   staticmethodZ
celery_appZtaskrn   classmethodrq   r   r   rk   r   r   r   r   r   r   r   r   r   __classcell__r$   r$   r   r%   r      sF   
F- O

,r   )rx   r   r!   Zldap3.core.exceptionsr   r   r   r   r   r   r   Zcmf.data_providers.baser   Zcmf.includeZcmf.modules.logsr
   Zmodules.api.views.indexr   Zmodules.settings.fieldsr   r   r9   pathlibr   r   ZAPPZHOOK_CRON_MINUTELYr   rq   r$   r$   r$   r%   <module>   s$       8