LDAP Search Operations
Relevant source files
The following files were used as context for generating this wiki page:
LDAP Search Operations within the flext-ldap library provide a structured, type-safe interface for querying directory services. This system abstracts low-level protocol details into a high-level API that utilizes Pydantic models for request configuration and standardized result objects for data consumption.
The search architecture is built on the Railway-Oriented Programming (ROP) pattern, ensuring that all operations return a Result object rather than raising exceptions. This allows for clean error handling and predictable data flow across the FlextLdapOperations service and its underlying adapters.
Search Architecture and Data Flow
The search system follows a tiered approach where the FlextLdapOperations service acts as a coordinator, delegating the actual protocol execution to an adapter while handling DN normalization and input validation.
Component Relationship
The following diagram illustrates the relationship between the service layer, the adapter, and the data models used during a search operation.
Search Execution Flow
When a search is initiated, the base DN is normalized to ensure consistency across different LDAP server types. The request is then passed to the SearchExecutor within the adapter layer.
Search Configuration Models
Search operations are configured using specific Pydantic models that enforce type safety and provide default values for common LDAP parameters.
SearchOptions Model
The primary configuration object is SearchOptions, which defines the scope, filters, and attribute limits for a query.
| Field | Type | Default | Description |
|---|---|---|---|
base_dn | str | Required | The starting point for the directory search. |
scope | str | SUBTREE | The depth of the search (BASE, LEVEL, SUBTREE). |
filter_str | str | (objectClass=*) | The LDAP filter used to select entries. |
attributes | list[str] | None | The list of attributes to return; None returns none, * returns all. |
size_limit | int | 0 | Maximum number of entries to return (0 for no limit). |
time_limit | int | 0 | Maximum time in seconds for the operation (0 for no limit). |
Sources: src/flext_ldap/_models/ldap.py:59-106, src/flext_ldap/constants.py:141-143
Specialized Factory Methods
The library provides optimized factory methods for common search scenarios:
normalized(base_dn, settings): Creates search options based on aNormalizedConfigtemplate.base_scope(base_dn): Configures a search targeted at a single known DN, automatically requesting all user attributes (*) to ensure entry details are returned.
Sources: src/flext_ldap/_models/ldap.py:84-118
Search Results and Parsing
Search results are encapsulated in a SearchResult model, which provides utility properties for analyzing the returned data.
Result Structure and Metadata
The SearchResult model contains a sequence of entries, where each entry follows the flext-ldif entry model.
class SearchResult(m.BaseModel):
entries: Annotated[t.SequenceOf[m.Ldif.Entry], u.Field(default_factory=list)]
search_options: FlextLdapModelsLdap.SearchOptions
Sources: src/flext_ldap/_models/ldap.py:173-177
Grouping and Analysis
The SearchResult provides computed fields to simplify data processing:
total_count: Returns the length of the entries list.by_objectclass: A mapping that groups entries by their primaryobjectClass. This uses theget_entry_categoryhelper to extract the first value of theobjectClassattribute for classification.
Sources: src/flext_ldap/_models/ldap.py:180-201
Search Scopes and Constants
The library defines standardized search scopes compatible with the underlying ldap3 library while providing string-based aliases for readability.
| Constant Name | String Alias | Integer Value | Description |
|---|---|---|---|
BASE | "BASE" | 0 | Search only the base object. |
ONELEVEL | "LEVEL" | 1 | Search objects one level below the base. |
SUBTREE | "SUBTREE" | 2 | Search the entire subtree starting at the base. |
Sources: src/flext_ldap/constants.py:133-157
Service Integration
The FlextLdapOperations service integrates search into higher-level workflows, such as idempotent "upserts."
Upsert Existence Check
During a batch_upsert or single upsert operation, the service performs a base-scope search to determine if an entry already exists. If the search returns an entry, the system compares the existing attributes with the new ones to decide if a MODIFY operation is necessary.
Implementation Details
The FlextLdapLdap3Wrappers handles the low-level attribute conversion from the directory's raw format to Python strings.
Attribute Normalization
When processing search entries, the value_to_str_list utility converts various LDAP types (bytes, ints, lists) into a standardized list of strings to ensure compatibility with the Pydantic models used throughout the FLEXT framework.
Sources: tests/unit/test_ldap3_adapter_helpers.py:304-313, src/flext_ldap/constants.py:65-70
Error Handling
Search failures are captured using OperationResult within the ROP Result wrapper. Common failure patterns include:
- Invalid Base DN: Resulting from failed normalization.
- Network/Connection Issues: Captured via
LDAPExceptionor broad IO exceptions. - Protocol Errors: Such as syntax errors in the
filter_str.
Sources: src/flext_ldap/services/operations.py:465-502, src/flext_ldap/constants.py:108-112