async def pagedsearch(self, base, query, attributes, search_scope=2, size_limit=1000, typesOnly=False, derefAliases=0, timeLimit=None, controls=None): """ Paged search is the same as the search operation and uses it under the hood. Adds automatic control to read all results in a paged manner. :param base: base tree on which the search should be performed :type base: str :param query: filter query that defines what should be searched for :type query: str :param attributes: a list of attributes to be included in the response :type attributes: List[str] :param search_scope: Specifies the search operation's scope. Default: 2 (Subtree) :type search_scope: int :param types_only: indicates whether the entries returned should include attribute types only or both types and values. Default: False (both) :type types_only: bool :param size_limit: Size limit of result elements per query. Default: 1000 :type size_limit: int :param derefAliases: Specifies the behavior on how aliases are dereferenced. Default: 0 (never) :type derefAliases: int :param timeLimit: Maximum time the search should take. If time limit reached the server SHOULD return an error :type timeLimit: int :param controls: additional controls to be passed in the query :type controls: dict :return: Async generator which yields (`dict`, None) tuple on success or (None, `Exception`) on error :rtype: Iterator[(:class:`dict`, :class:`Exception`)] """ if self.status != MSLDAPClientStatus.RUNNING: yield None, Exception( 'Connection not running! Probably encountered an error') return try: cookie = b'' while True: ctrl_list_temp = [ Control({ 'controlType': b'1.2.840.113556.1.4.319', 'controlValue': SearchControlValue({ 'size': size_limit, 'cookie': cookie }).dump() }) ] if controls is not None: ctrl_list_temp.extend(controls) ctrs = Controls(ctrl_list_temp) async for res, err in self.search(base, query, attributes, search_scope=search_scope, size_limit=size_limit, types_only=typesOnly, derefAliases=derefAliases, timeLimit=timeLimit, controls=ctrs, return_done=True): if err is not None: yield (None, err) return if 'resultCode' in res['protocolOp']: for control in res['controls']: if control[ 'controlType'] == b'1.2.840.113556.1.4.319': try: cookie = SearchControlValue.load( control['controlValue'] ).native['cookie'] except Exception as e: raise e break else: raise Exception( 'SearchControl missing from server response!') else: yield (convert_result(res['protocolOp']), None) if cookie == b'': break except Exception as e: yield (None, e)
async def pagedsearch(self, base, filter, attributes, search_scope=2, paged_size=1000, typesOnly=False, derefAliases=0, timeLimit=None, controls=None): if self.status != MSLDAPClientStatus.RUNNING: yield None, Exception( 'Connection not running! Probably encountered an error') return try: cookie = b'' while True: ctrl_list_temp = [ Control({ 'controlType': b'1.2.840.113556.1.4.319', 'controlValue': SearchControlValue({ 'size': paged_size, 'cookie': cookie }).dump() }) ] if controls is not None: ctrl_list_temp.extend(controls) ctrs = Controls(ctrl_list_temp) async for res, err in self.search(base, filter, attributes, search_scope=search_scope, paged_size=paged_size, typesOnly=typesOnly, derefAliases=derefAliases, timeLimit=timeLimit, controls=ctrs, return_done=True): if err is not None: yield (None, err) return if 'resultCode' in res['protocolOp']: for control in res['controls']: if control[ 'controlType'] == b'1.2.840.113556.1.4.319': try: cookie = SearchControlValue.load( control['controlValue'] ).native['cookie'] except Exception as e: raise e break else: raise Exception( 'SearchControl missing from server response!') else: yield (convert_result(res['protocolOp']), None) if cookie == b'': break except Exception as e: yield (None, e)