o
    ßý°jdª  ã                   @   sš  d 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mZmZ d	d
l
mZmZmZmZmZmZmZmZ d	dlmZ ddlmZmZmZ ddlmZ ddlmZ ddl m!Z!m"Z" d	dl#m$Z$m%Z% d	dl&m'Z' d	dl(m)Z) d	dl*m+Z+m,Z, d	dl-m.Z. d	dl/mZ d	dl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 d	dl7m8Z8m9Z9m:Z:m;Z; eddƒZ<dd„ Z=dd„ Z>G dd„ de?ƒZ@G d d!„ d!e@ƒZAG d"d#„ d#e@ƒZBd$S )%Ú
é    )Ú
namedtuple)Údeepcopy)Údatetime)Úlinesep)Úsleepé   )ÚSTATUS_VIRTUALÚSTATUS_READÚSTATUS_WRITABLEé   )ÚSUBTREEÚLEVELÚDEREF_ALWAYSÚDEREF_NEVERÚBASEÚSEQUENCE_TYPESÚSTRING_TYPESÚget_config_parameter)ÚSTATUS_PENDING_CHANGES)Ú	AttributeÚOperationalAttributeÚWritableAttribute)ÚAttrDef)Ú	ObjectDef)ÚEntryÚWritableEntry)ÚLDAPCursorErrorÚLDAPObjectDereferenceError)ÚRESULT_SUCCESS)ÚCaseInsensitiveWithAliasDict)Úsafe_dnÚsafe_rdn)Úto_raw)r   )ÚlogÚlog_enabledÚERRORÚBASICÚPROTOCOLÚEXTENDED)ÚATTRIBUTE_DIRECTORY_OPERATIONÚATTRIBUTE_DISTRIBUTED_OPERATIONÚATTRIBUTE_DSA_OPERATIONÚCLASS_AUXILIARYÚ	Operation)ÚrequestÚresultÚresponsec                 C   s4   | d dv r| d dkr| d d | dd …  S | S )Nr   z<>~r   ú=© )Úvaluer3   r3   úˆ/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/ldap3/abstract/cursor.pyÚ_ret_search_value2   s   4r6   c                 C   sH   t ƒ }| r"|  d¡D ]}d|v r!| d¡}|d  ¡ ||d  ¡ < q
|S )zu
    Create a dictionary with query key:value definitions
    query_text is a comma delimited key:value sequence
    ú,ú:r   r   )ÚdictÚsplitÚstrip)Ú
query_textÚ
query_dictÚarg_value_strÚarg_value_listr3   r3   r5   Ú_create_query_dict6   s   
€r@   c                   @   s¼   e Zd Zd)dd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Ze	e
ur&dd„ Zndd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zed#d$„ ƒZed%d&„ ƒZed'd(„ ƒZdS )*ÚCursorFNc                 C   s,  dd„ t dƒD ƒ}|| _|| _|js|jr| ¡  t|ttfƒr0|j	r'| 
¡  t||jj|d�}|| _|rmg }t|tƒr?|g}|D ]}	|	| jjvrT|	 ¡ |vrT| |	¡ qA|rmdd |¡ }
ttƒrittd|
| ƒ t|
ƒ‚|rst|ƒn	tdd„ | jD ƒƒ| _|| _d | _g | _| jjj| _d	| _tƒ | _d S )
Nc                 S   ó   g | ]}|  ¡ ‘qS r3   ©Úlower©Ú.0Úvr3   r3   r5   Ú
<listcomp>M   ó    z#Cursor.__init__.<locals>.<listcomp>Ú#ATTRIBUTES_EXCLUDED_FROM_OBJECT_DEF)Úauxiliary_classz!Attributes '%s' non in definitionú, ú%s for <%s>c                 S   ó   g | ]}|j ‘qS r3   )Úname)rF   Úattrr3   r3   r5   rH   g   ó    F)r   Ú
connectionÚget_operational_attributesÚ_deferred_bindÚ_deferred_openÚ_fire_deferredÚ
isinstancer   r   ÚclosedÚbindr   ÚserverÚschemaÚ
definitionÚ_attributesrD   ÚappendÚjoinr%   r&   r$   r   ÚsetÚ
attributesÚcontrolsÚexecution_timeÚentriesÚ_do_not_resetÚlistÚ_operation_history)ÚselfrR   Ú
object_defrS   ra   rb   rK   Ú(conf_attributes_excluded_from_object_defÚnot_defined_attributesÚ	attributeÚerror_messager3   r3   r5   Ú__init__L   s<   

€"zCursor.__init__c                 C   s4  d| j j t }|dt| jƒ t 7 }|dd | jj¡ 7 }| jjr/|dd | jj¡ d 7 }|t7 }t	| dƒrL|dt
t| jƒƒ | jrFd	nd
 t 7 }t| tƒr½t	| dƒrh|dt
| jƒ | jrbdnd t 7 }t	| dƒr‰| jr‰|dt
| jƒ d| jv r~d
n| jrƒdnd t 7 }t	| dƒrª| jrª|dt
| jƒ d| jv rŸd
n| jr¤dnd t 7 }t	| dƒr½| jr½|dt
| jƒ t 7 }t	| dƒrß| jrß|dtt| jƒƒ 7 }|dt| j ¡ ƒ d t 7 }| j�r|dtt| jƒƒ d t| jƒdkr÷dnd
 d t| jƒdk�rd nd! d d"d#„ t| jƒD ƒ¡ d 7 }|S )$Nz	CURSOR : z	CONN   : z	DEFS   : rL   z [AUX: ú]ra   z	ATTRS  : z [OPERATIONAL]Ú Úbasez	BASE   : z [SUB]z [LEVEL]Ú_queryz	QUERY  : ú(z [AND]z [OR]Úvalidated_queryz	PARSED : Úquery_filterz	FILTER : rc   z	ENTRIES: z [executed at: zLAST OPERATION FAILED [z failurer   Úsz at operationzs ú c                 S   s&   g | ]\}}|j d  tkrt|ƒ‘qS ©r0   )r0   r   Ústr)rF   ÚiÚerrorr3   r3   r5   rH   Œ   s   & z#Cursor.__repr__.<locals>.<listcomp>)Ú	__class__Ú__name__r   ry   rR   r_   r\   Ú_object_classÚ_auxiliary_classÚhasattrÚreprÚsortedra   rS   rW   ÚReaderrq   Úsub_treerr   Úcomponents_in_andrt   ru   rc   Úlenrd   Ú	isoformatÚfailedÚerrorsÚ	enumerateÚ
operations)rh   Úrr3   r3   r5   Ú__repr__o   s.   
(

$22jzCursor.__repr__c                 C   s   |   ¡ S ©N)r�   ©rh   r3   r3   r5   Ú__str__�   s   zCursor.__str__c                 C   s
   | j  ¡ S rŽ   )rd   Ú__iter__r�   r3   r3   r5   r‘   “   ó   
zCursor.__iter__c                 C   sÌ   z| j | W S  ty   Y nw t|tƒrU|  |¡}t|ƒdkr$|d S t|ƒdkrUdt|ƒ t|ƒdkr7dndd dd	„ |D ƒ¡ d
  }ttƒrQt	td|| ƒ t
|ƒ‚d}ttƒrbt	td|| ƒ t
|ƒ‚)aP  Return indexed item, if index is not found then try to sequentially search in DN of entries.
        If only one entry is found return it else raise a KeyError exception. The exception message
        includes the number of entries that matches, if less than 10 entries match then show the DNs
        in the exception message.
        r   r   z7Multiple entries found: %d entries match the text in dné
   rp   z [z; c                 S   rN   r3   )Úentry_dn)rF   Úer3   r3   r5   rH   §   rQ   z&Cursor.__getitem__.<locals>.<listcomp>ro   rM   zno entry found)rd   Ú	TypeErrorrW   r   Úmatch_dnr†   r_   r%   r&   r$   ÚKeyError)rh   ÚitemÚfoundrm   r3   r3   r5   Ú__getitem__–   s$   ÿ

8zCursor.__getitem__c                 C   s
   t | jƒS rŽ   )r†   rd   r�   r3   r3   r5   Ú__len__±   r’   zCursor.__len__c                 C   ó   dS ©NTr3   r�   r3   r3   r5   Ú__bool__µ   ó   zCursor.__bool__c                 C   r�   rž   r3   r�   r3   r3   r5   Ú__nonzero__¸   r    zCursor.__nonzero__c                 C   s@  t dƒ}dd„ t dƒD ƒ}tƒ }tƒ }|D ]ì}|| }	d}
|d D ]}|	j ¡ | ¡ kr0|}
 nq!|
s9|	jtu�r|  |	|| ¡}||_|
rK|d |
 nd|_	|	j
rl|	j|d v rl|d tƒ krl|	 
|	j|d |
 ¡|_n&|	jtu s||
r„|d |
 tƒ kr„|d |
 |_nt|	jtƒr�|	jn|	jg|_t|jtƒs�|jg|_|	jrá|jrát| j|	jd| j| jd	�}g }|jD ]'}|j|krÅ| | |¡¡ qµd
|j|jjf }ttƒrÙttd|| ƒ t|ƒ‚~||_|||j< |jrñ| |j|j¡ |	jrü| |j|	j¡ | |
¡ q| j �r| !| j ¡ |d D ]�}
|
|v�rœd}|
| j"j#v �r8| j"j#|
 j$�s5| j"j#|
 j%t&t't(fv �r7d}nd}|�sf|
|v�rf|
 ¡ |v�rfd|
d )|j*j+¡|jf }ttƒ�rbttd|| ƒ t,|ƒ‚t-t.||
 ƒ|| ƒ}|d |
 |_	t|d |
 tƒ�r‡|d |
 n|d |
 g|_||
 |v�rœ||||
 < �q|S )að  Assign the result of the LDAP query to the Entry object dictionary.

        If the optional 'post_query' callable is present in the AttrDef it is called with each value of the attribute and the callable result is stored in the attribute.

        Returns the default value for missing attributes.
        If the 'dereference_dn' in AttrDef is a ObjectDef then the attribute values are treated as distinguished name and the relevant entry is retrieved and stored in the attribute value.

        Ú(ABSTRACTION_OPERATIONAL_ATTRIBUTE_PREFIXc                 S   rB   r3   rC   rE   r3   r3   r5   rH   Å   rI   z*Cursor._get_attributes.<locals>.<listcomp>rJ   Nra   Úraw_attributesrp   )rq   rS   rb   z5object %s is referencing itself in the '%s' attributerM   FTz4attribute '%s' not in object class '%s' for entry %srL   )/r   r    r`   rO   rD   ÚdefaultÚNotImplementedÚattribute_classr1   Ú
raw_valuesÚ
post_queryrf   ÚkeyÚvaluesrW   r   Údereference_dnrƒ   rR   rS   rb   r”   r^   Úsearch_objectr\   r%   r&   r$   r   Úother_namesÚ	set_aliasÚaddra   Úupdater[   Úattribute_typesÚno_user_modificationÚusager*   r+   r,   r_   Úentry_definitionr~   r   r   r   )rh   r1   Ú	attr_defsÚentryÚ!conf_operational_attribute_prefixrj   ra   Úused_attribute_namesrP   Úattr_defÚattribute_nameÚ	attr_namerl   Útemp_readerÚtemp_valuesÚelementrm   Úoperational_attributer3   r3   r5   Ú_get_attributes»   s‚   	þ" 




€
*€
0€zCursor._get_attributesc                 C   s0   g }| j D ]}| ¡ |j ¡ v r| |¡ q|S )zReturn entries with text in DN)rd   rD   r”   r^   )rh   ÚdnÚmatchedr¶   r3   r3   r5   r—     s   

€zCursor.match_dnc           	      C   s  g }t |tƒs
|g}| jD ]x}d}|D ]q}||v r„|| jD ]&}t|dƒr5t|dƒr5| ¡ | ¡ v r5d}n||kr;d}|rD| |¡  nq|rI n<t|ƒ}t |tt	fƒr„|| j
D ]&}t|dƒrpt|dƒrp| ¡ | ¡ v rpd}n||krvd}|r| |¡  nqY|r„ nqq|S )z;Return entries with text in one of the specified attributesFrD   T)rW   r   rd   rª   r€   rD   r^   r#   ÚbytesÚ	bytearrayr§   )	rh   ra   r4   rÂ   r¶   rš   rl   Ú
attr_valueÚ	raw_valuer3   r3   r5   Úmatch  sB   

$
þ$
þ€zCursor.matchc                 C   s‚   |d dksd S |   |d | ¡}|  || jj|¡|j_t|d ƒ|j_||j_t	 
¡ |j_|j | j¡ |D ]}||j|j< q6|S )NÚtypeÚsearchResEntryrÁ   r£   )Úentry_classrÀ   r\   r]   Ú_statera   r   r£   r1   r   ÚnowÚ	read_timeÚ
set_statusÚentry_initial_statusÚ__dict__r©   )rh   r1   r¶   rP   r3   r3   r5   Ú_create_entry6  s   zCursor._create_entryc              
   C   sÚ  | j sd}ttƒrttd|| ƒ t|ƒ‚d }|tkr&t| dƒr"| j}d| _n|  ¡  tt	ƒr9tt	d| j
| j|| ƒ | j �J | j j| j
| j|| j|rK|nt| jƒ| j| jd�}| j jjsg| j j|dd�\}}}n| j jjrs|\}}}}n| j j}| j j}| j j}W d   ƒ n1 s‰w   Y  |  |||¡ | jrŸ|  |d	 ¡S g | _|D ]:}	|  |	¡}
|
d urÞ| j |
¡ d
|
v rÞ|
jD ]!}| jrÝ| jj| j t!krÝ|| j"j#vrÝ| j"j# |¡ | j" $|¡ q¼q¤t% &¡ | _'|rë|| _d S d S )Núno connection establishedrM   ru   ú(objectclass=*)z<executing query - base: %s - filter: %s - scope: %s for <%s>©Úsearch_baseÚsearch_filterÚsearch_scopeÚdereference_aliasesra   rS   rb   T©Úget_requestr   ÚobjectClass)(rR   r%   r&   r$   r   r   r€   ru   Ú_create_query_filterr(   rq   ÚsearchrØ   rf   ra   rS   rb   ÚstrategyÚsyncÚget_responseÚthread_safer1   r0   r/   Ú_store_operation_in_historyre   rÑ   rd   r^   rÛ   r[   Úobject_classesÚkindr-   r\   r   Ú_populate_attr_defsr   rÌ   rc   )rh   Úquery_scopera   rm   Úold_query_filterr0   r1   r/   Ú_rŒ   r¶   Úobject_classr3   r3   r5   Ú_execute_queryF  sb   

ú

€ð

$€

ÿzCursor._execute_queryc                 C   s&   t tƒrttd|| ƒ | j |¡ d S )Nzremoving entry <%s> in <%s>)r%   r(   r$   rd   Úremove©rh   r¶   r3   r3   r5   rë   |  s   zCursor.removec                 C   s   t ƒ | _d S rŽ   )rf   rg   r�   r3   r3   r5   Ú_reset_history�  s   zCursor._reset_historyc                 C   s   | j  t|||ƒ¡ d S rŽ   )rg   r^   r.   )rh   r/   r0   r1   r3   r3   r5   râ   „  s   z"Cursor._store_operation_in_historyc                 C   ó   | j S rŽ   ©rg   r�   r3   r3   r5   r‹   ‡  ó   zCursor.operationsc                 C   s   dd„ | j D ƒS )Nc                 S   s   g | ]}|j d  tkr|‘qS rx   ©r0   r   ©rF   r{   r3   r3   r5   rH   �  s    z!Cursor.errors.<locals>.<listcomp>rï   r�   r3   r3   r5   r‰   ‹  s   zCursor.errorsc                 C   s"   t | dƒrtdd„ | jD ƒƒS d S )Nrg   c                 S   s   g | ]	}|j d  tk‘qS rx   rñ   rò   r3   r3   r5   rH   ’  s    z!Cursor.failed.<locals>.<listcomp>)r€   Úanyrg   r�   r3   r3   r5   rˆ   �  s   
ÿzCursor.failed©FNNN)r}   Ú
__module__Ú__qualname__rn   r�   r�   r‘   r›   rœ   ry   rÃ   rŸ   r¡   rÀ   r—   rÇ   rÑ   rê   rë   rí   râ   Úpropertyr‹   r‰   rˆ   r3   r3   r3   r5   rA   E   s0    
#!
P#6

rA   c                   @   s´   e Zd ZdZeZeZeZ	d"dd„Z
edd	„ ƒZejd
d	„ ƒZedd„ ƒZejdd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zd#dd„Zd$dd„Zd#dd„Zd#dd„Zdd„ Zd%d d!„ZdS )&rƒ   aq  Reader object to perform searches:

    :param connection: the LDAP connection object to use
    :type connection: LDAPConnection
    :param object_def: the ObjectDef of the LDAP object returned
    :type object_def: ObjectDef
    :param query: the simplified query (will be transformed in an LDAP filter)
    :type query: str
    :param base: starting base of the search
    :type base: str
    :param components_in_and: specify if assertions in the query must all be satisfied or not (AND/OR)
    :type components_in_and: bool
    :param sub_tree: specify if the search must be performed ad Single Level (False) or Whole SubTree (True)
    :type sub_tree: bool
    :param get_operational_attributes: specify if operational attributes are returned or not
    :type get_operational_attributes: bool
    :param controls: controls to be used in search
    :type controls: tuple

    rp   TFNc              	   C   st   t  | |||||	|
¡ || _|| _|| _|| _t| _d | _t	ƒ | _
t	ƒ | _d | _|  ¡  ttƒr8ttd| ƒ d S d S )Nz instantiated Reader Cursor: <%r>)rA   rn   Ú_components_in_andr„   rr   rq   r   rØ   rt   r9   Ú_query_dictÚ_validated_query_dictru   Úresetr%   r'   r$   )rh   rR   ri   rq   Úqueryr…   r„   rS   ra   rb   rK   r3   r3   r5   rn   ®  s   ÿzReader.__init__c                 C   rî   rŽ   )rr   r�   r3   r3   r5   rü   ¾  rð   zReader.queryc                 C   ó   || _ |  ¡  d S rŽ   )rr   rû   ©rh   r4   r3   r3   r5   rü   Â  ó   c                 C   rî   rŽ   )rø   r�   r3   r3   r5   r…   Ç  rð   zReader.components_in_andc                 C   rý   rŽ   )rø   rû   rþ   r3   r3   r5   r…   Ë  rÿ   c                 C   s   t | _|  ¡  dS )z,Clear the Reader search parameters

        N)r   rØ   rí   r�   r3   r3   r5   ÚclearÐ  s   zReader.clearc                 C   s<   |   ¡  d| _tƒ | _tƒ | _d| _d| _g | _|  ¡  dS )z)Clear all the Reader parameters

        N)	r   rt   r9   rù   rú   rc   ru   rd   rÜ   r�   r3   r3   r5   rû   ×  s   zReader.resetc                 C   sP  | j s	t| jƒ| _ d}t| j ƒD �]}|d dv r|dd… n|}| jD ]}d | ¡ ¡ ¡ |j ¡ kr9|j} nq$|| jv �rt| j |  d¡ƒ}||d dv rW|d | n|d 7 }|D ]�}| 	¡ }|d dkrld	nd
}d}|rž|dd…  
¡ d dvr‡|dd…  
¡ }	n.|dd…  
¡ d }|dd…  
¡ dd… }	n|d dvr©| 
¡ }	n|d }|dd…  
¡ }	| j| jrâ| j|  |	¡}
|
d
u rÜd||f }ttƒrØttd|| ƒ t|ƒ‚|
d	urâ|
}	|rï|d| t|	ƒ 7 }n||t|	ƒ 7 }|d7 }q^|dd… d }qd| }ttƒ�rttd|| ƒ t|ƒ‚|dd… | _t| jƒ| _dS )zçProcesses the text query and verifies that the requested friendly names are in the Reader dictionary
        If the AttrDef has a 'validate' property the callable is executed and if it returns False an Exception is raised

        rp   r   ú&|r   Nú;z: ú!TFr2   z=<>~z/validation failed for attribute %s and value %srM   éÿÿÿÿrL   z attribute '%s' not in definitionéþÿÿÿ)rù   r@   rr   r‚   r\   r_   r:   rD   r©   r;   ÚlstripÚvalidater%   r&   r$   r   ry   rt   rú   )rh   rü   ÚdrP   r¹   ÚvalsÚvalÚval_notÚval_search_operatorr4   Ú	validatedrm   r3   r3   r5   Ú_validate_queryä  s\   
þ$


zReader._validate_queryc           
      C   s<  d| _ | jjrf|  j d7  _ t| jjtƒr-t| jjƒdkr-|  j d| jjd  d 7  _ n9t| jjtƒrU|  j d7  _ | jjD ]}|  j d| d 7  _ q?|  j d7  _ nd}ttƒrbttd|| ƒ t	|ƒ‚| j
rŽ| j
 d	¡rŽ| j
 d¡rŽd
| j
 ¡ vrˆ|  j | j
d 7  _ dS | j
| _ dS | j
�r”| js�|  j d7  _ n| jjs¨|  j d7  _ |  ¡  d}t| jƒD ]¨}|d7 }d| j| v rÂdnd}t| j|  d¡ƒ}|d dv rÝ| j|dd…  n| j| }|j�rg }|D ]}	| |	d | |j|	dd… ¡ ¡ qê|}|�r|d dv �r|  j d	|d  7  _ n|  j d7  _ |D ]0}	|	d dk�r?|  j d|j t|	dd… ƒ d 7  _ �q |  j d	|j t|	ƒ d 7  _ �q |�r[|  j d7  _ q³| j�sh|  j d7  _ n|  j d7  _ | jj�s�|dk�r�| j dd… | _ | j dk�s�| j dk�r’d| _ dS dS | j dd… | _ dS )z0Converts the query dictionary to the filter textrp   z(&r   z(objectClass=r   ú)z'object class must be a string or a listrM   rs   ÚobjectclassNz(|r  TFr  r  z(!(z))r   r  z(|)z(&))ru   r\   r~   rW   r   r†   r%   r&   r$   r   rr   Ú
startswithÚendswithrD   r…   r  r‚   rú   r:   Ú	pre_queryr^   r©   rO   r6   )
rh   ré   rm   Úattr_counterrP   Úmultir	  r¹   Úmodvalsr
  r3   r3   r5   rÜ      sr    ÿ(&,$€
ÿzReader._create_query_filterc                 C   s<   |   ¡  | jr	tnt}ttƒrttd| ƒ |  ||¡ | jS )zKPerform the LDAP search

        :return: Entries found in search

        zperforming search in <%s>)	r   r„   r   r   r%   r(   r$   rê   rd   )rh   ra   ræ   r3   r3   r5   rÝ   g  s   zReader.searchc                 C   sh   t tƒr
ttd| ƒ |  ¡  |r | j}|| _|  t|¡ || _n|  t|¡ t| jƒdkr2| jd S dS )zgPerform the LDAP search operation SINGLE_OBJECT scope

        :return: Entry found in search

        z performing object search in <%s>r   N)	r%   r(   r$   r   rq   rê   r   r†   rd   )rh   r”   ra   Úold_baser3   r3   r5   r¬   u  s   zReader.search_objectc                 C   ó.   t tƒr
ttd| ƒ |  ¡  |  t|¡ | jS )zmPerform the LDAP search operation with SINGLE_LEVEL scope

        :return: Entries found in search

        z&performing single level search in <%s>)r%   r(   r$   r   rê   r   rd   ©rh   ra   r3   r3   r5   Úsearch_levelˆ  ó
   zReader.search_levelc                 C   r  )ziPerform the LDAP search operation WHOLE_SUBTREE scope

        :return: Entries found in search

        z'performing whole subtree search in <%s>)r%   r(   r$   r   rê   r   rd   r  r3   r3   r5   Úsearch_subtree•  r  zReader.search_subtreec                 c   s   � |D ]}|   |¡V  qd S rŽ   )rÑ   )rh   Ú	responsesr1   r3   r3   r5   Ú_entries_generator¢  s   €ÿzReader._entries_generatorc                 C   sÀ   t tƒrttd| t|ƒƒ | js!d}t tƒrttd|| ƒ t|ƒ‚|  ¡  |  ¡  g | _	t
 ¡ | _| jjjj| j| j| jr?tnt| j|rF|n| j| j| j|||d�
}|rY|  |¡S t|  |¡ƒS )a…  Perform a paged search, can be called as an Iterator

        :param attributes: optional attributes to search
        :param paged_size: number of entries returned in each search
        :type paged_size: int
        :param paged_criticality: specify if server must not execute the search if it is not capable of paging searches
        :type paged_criticality: bool
        :param generator: if True the paged searches are executed while generating the entries,
                          if False all the paged searches are execute before returning the generator
        :type generator: bool
        :return: Entries found in search

        z2performing paged search in <%s> with paged size %srÒ   rM   )
rÕ   rÖ   r×   rØ   ra   rS   rb   Ú
paged_sizeÚpaged_criticalityÚ	generator)r%   r(   r$   ry   rR   r&   r   r   rÜ   rd   r   rÌ   rc   ÚextendÚstandardÚpaged_searchrq   ru   r„   r   r   rØ   ra   rS   rb   r  rf   )rh   r  r   r!  ra   rm   r1   r3   r3   r5   Úsearch_paged¦  s2   
÷

zReader.search_paged)rp   TTFNNNrŽ   )NN)TTN)r}   rõ   rö   Ú__doc__r   rÊ   r   r¦   r
   rÏ   rn   r÷   rü   Úsetterr…   r   rû   r  rÜ   rÝ   r¬   r  r  r  r%  r3   r3   r3   r5   rƒ   •  s0    




<
G


rƒ   c                   @   sl   e Zd ZeZeZeZe	ddd„ƒZ
e	ddd„ƒZddd„Zdd
d„Zdd„ Zddd„Zdd„ Zddd„ZdS )ÚWriterNc                 C   s¬   |d u r| j }|d u r| j}t||| jd�}| jD ]+}t| tƒr)|j|||d� qt| tƒr/qdtt	| ƒƒ }t
tƒrAttd|ƒ t|ƒ‚| j|_t
tƒrTttd|| ƒ |S )N)ra   )Úcustom_validatorzunknown cursor type %sú%sz0instantiated Writer Cursor <%r> from cursor <%r>)rR   r\   r(  ra   rd   rW   rƒ   Úentry_writablery   rÈ   r%   r&   r$   r   rc   r'   )ÚcursorrR   ri   r)  Úwriterr¶   rm   r3   r3   r5   Úfrom_cursorÕ  s$   


zWriter.from_cursorc                 C   s¬   |d u r/| j jsd}ttƒrttd|ƒ t|ƒ‚| jr| j}nd}ttƒr+ttd|ƒ t|ƒ‚t| |ƒ}|D ]}|d dkrI| |¡}|j	 
|¡ q6ttƒrTttd|ƒ |S )Nz7with asynchronous strategies response must be specifiedr*  zresponse not presentrÈ   rÉ   z-instantiated Writer Cursor <%r> from response)rÞ   rß   r%   r&   r$   r   r1   r(  rÑ   rd   r^   r'   )rR   ri   r1   rm   r-  Úrespr¶   r3   r3   r5   Úfrom_responseë  s*   

€zWriter.from_responseFc              	   C   s8   t  | ||||||¡ t| _ttƒrttd| ƒ d S d S )Nz instantiated Writer Cursor: <%r>)rA   rn   r   rØ   r%   r'   r$   )rh   rR   ri   rS   ra   rb   rK   r3   r3   r5   rn     s
   ÿzWriter.__init__Tc                 C   sP   t tƒr
ttd| ƒ |  ¡  d}| jD ]}|j|| jdd�s d}qt ¡ | _	|S )Nzcommitted changes for <%s>TF)Úrefreshrb   Úclear_history)
r%   r(   r$   rí   rd   Úentry_commit_changesrb   r   rÌ   rc   )rh   r1  Ú
successfulr¶   r3   r3   r5   Úcommit  s   
€
zWriter.commitc                 C   s,   t tƒr
ttd| ƒ | jD ]}| ¡  qd S )Nzdiscarded changes for <%s>)r%   r(   r$   rd   Úentry_discard_changesrì   r3   r3   r5   Údiscard  s
   

ÿzWriter.discardé   r   c              
   C   sn  t tƒrttd|| ƒ | jsd}t tƒrttd|| ƒ t|ƒ‚g }| j�e d}||k r‚| jj|dtt|r6|n| j	| j
|d�}	| jjjsO| jj|	dd�\}}	}
n| jjjr[|	\}}	}}
n| jj}| jj}	| jj}
|	d	 tfv ront|ƒ |d
7 }|  |
|	|¡ ||k s+W d  ƒ n1 sŒw   Y  t|ƒd
krž|  |d ¡S t|ƒdkr¦dS d}t tƒr³ttd|| ƒ t|ƒ‚)zhPerforms the LDAP search operation SINGLE_OBJECT scope

        :return: Entry found in search

        zrefreshing object <%s> for <%s>rÒ   rM   r   rÓ   rÔ   TrÙ   r0   r   Nz5more than 1 entry returned for a single object search)r%   r(   r$   rR   r&   r   rÝ   r   r   ra   rS   rÞ   rß   rà   rá   r1   r0   r/   r   r   râ   r†   rÑ   )rh   r”   ra   ÚtriesÚsecondsrb   rm   r1   Úcounterr0   r/   rè   r3   r3   r5   Ú_refresh_object  sT   ú

ê€þzWriter._refresh_objectc                 C   sŒ  t tƒrttd|| ƒ t|ƒ}| jD ]}|j|kr*d}t tƒr&ttd|| ƒ t|ƒ‚qt|dd�}|  	|| ¡}|j
D ]}|  |jj| || ¡|jj|< |jj| |j|< q:|j | jj¡ |D ]R}|d |jjjv r�|jjj|d  j}||jjvr’|  |jj| || ¡|jj|< |jj| |j|< |j|  |d ¡ q_d|d  }t tƒr®ttd|| ƒ t|ƒ‚|j t¡ |j t¡ | j |¡ |S )	Nz creating new entry <%s> for <%s>zdn already present in cursorrM   T)Ú	decomposer   r   z,rdn type '%s' not in object class definition)r%   r'   r$   r!   rd   r”   r&   r   r"   rÊ   Úentry_mandatory_attributesr¦   rË   r\   ra   rÐ   r  r`   r~   r]   rO   rÎ   r	   r   r^   )rh   rÁ   r¶   rm   ÚrdnsrP   ÚrdnÚrdn_namer3   r3   r5   ÚnewQ  s>   

ü
z
Writer.newc                 C   sJ  t dƒ}d| _g }ttƒrttd|| ƒ |jjD ](}| ¡  | ¡ ¡r$q|jj	| j
r6| |jj	| j
¡ q| |jj	| j¡ q| j|j|||d�}d| _|r£|jj|j_|j ¡  |j|jd< |jjD ]}|jj| |j|< qe|jD ]$}||jjvr˜||jjv r˜t|j| || ƒ|jj|< |jj| |j|< qt|j |jj¡ dS dS )Nr¢   Tzrefreshing entry <%s> for <%s>)r:  FrË   )r   re   r%   r(   r$   rË   ra   rD   r  r\   rO   r^   r©   r<  r”   ÚoriginrÐ   r   Úentry_attributesr´   r]   r   rÎ   Ú_initial_status)rh   r¶   r9  r:  r·   Ú	attr_listrP   Ú
temp_entryr3   r3   r5   Úrefresh_entryr  s6   

€zWriter.refresh_entry)NNNrŽ   rô   )T)Nr8  r   N)r8  r   )r}   rõ   rö   r   rÊ   r   r¦   r   rÏ   Ústaticmethodr.  r0  rn   r5  r7  r<  rB  rH  r3   r3   r3   r5   r(  Ð  s    


3!r(  N)Cr&  Úcollectionsr   Úcopyr   r   Úosr   Útimer   rp   r	   r
   r   r   r   r   r   r   r   r   r   Úabstractr   rl   r   r   r   ÚattrDefr   Ú	objectDefr   r¶   r   r   Úcore.exceptionsr   r   Úcore.resultsr   Úutils.ciDictr    Úutils.dnr!   r"   Ú
utils.convr#   Úutils.configÚ	utils.logr$   r%   r&   r'   r(   r)   Úprotocol.oidr*   r+   r,   r-   r.   r6   r@   ÚobjectrA   rƒ   r(  r3   r3   r3   r5   Ú<module>   s>    ( 
  R  =