Product
Introducing License Enforcement in Socket
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
A Python utility library for working with Lightweight Directory Access Protocol (LDAP) filters.
Build, generate, and validate LDAP filters
A Python 3 utility library for working with Lightweight Directory Access Protocol (LDAP) filters.
This project is a Python port of the node-ldap-filters project. The filters produced by the library are based on RFC 4515.
Note: This project is currently only compatible with Python 3.4 or higher.
Install via pip:
pip install ldap-filter
This library exposes a number of APIs that allow you to build filters programmatically. The logical and attribute methods of the Filter
object can be combined in a number of ways to generate filters ranging from very simple to very complex.
The following is a quick example of how you might build a filter programmatically:
from ldap_filter import Filter
output = Filter.AND([
Filter.attribute('name').equal_to('bob'),
Filter.attribute('mail').ends_with('@example.com'),
Filter.OR([
Filter.attribute('dept').equal_to('accounting'),
Filter.attribute('dept').equal_to('operations')
])
])
print(output.to_string()) # (&(name=bob)(mail=*@example.com)(|(dept=accounting)(dept=operations)))
Attribute methods are used to create LDAP attribute filter strings. The Filter.attribute(name)
method returns an Attribute
object that the following filter methods can be applied to.
output = Filter.attribute('name').equal_to('bob') # (name=bob)
Attribute.present() - Tests if an attribute is present.
(attribute=*)
Attribute.equal_to(value) - Tests if an attribute is equal to the provided value
.
(attribute=value)
Attribute.contains(value) - Tests if an attribute contains the provided value
.
(attribute=*value*)
Attribute.starts_with(value) - Tests if an attribute starts with the provided value
.
(attribute=value*)
Attribute.ends_with(value) - Tests if an attribute ends with the provided value
.
(attribute=*value)
Attribute.approx(value) - Tests if an attribute is an approximate match to the provided value
.
(attribute~=value)
Attribute.gte(value) - Tests if an attribute is greater than or equal to the provided value
.
(attribute>=value)
Attribute.lte(value) - Tests if an attribute is less than or equal to the provided value
.
(attribute<=value)
Attribute.raw(value) - Allows for a custom filter with escaped value
output.
(attribute=value)
Logical methods are used to aggregate simple attribute filters. You can nest as many logical methods as needed to produce complex filters.
output = Filter.OR([
Filter.attribute('name').equal_to('bob'),
Filter.attribute('name').equal_to('bill')
])
print(output) # (|(name=bob)(name=bill))
Filter.AND(filt) - Accepts a list of Filter
, Attribute
, or Group
objects.
(&(filt=1)(filt=2)..)
Filter.OR(filt) - Accepts a list of Filter
, Attribute
, or Group
objects.
(|(filt=1)(filt=2)..)
Filter.NOT(filt) - Accepts a single Attribute
object.
(!(filt=1))
The Filter.parse(input)
method can be used to create a Filter
object from an existing LDAP filter. This method can also be used to determine if a string is a valid LDAP filter or not.
input = '(|(name=bob)(name=bill))'
Filter.parse(input)
If an invalid LDAP filter string is passed a ParseError
exception will be thrown.
from ldap_filter import Filter, ParseError
input = '(|(name=bob)name=bill))'
try:
Filter.parse(input)
except ParseError as e:
print(e)
Error Output:
Line 1: expected [\x20], [\x09], "\r\n", "\n", '(', ')'
(|(name=bob)name=bill)
^
The Filter.simplify()
method can be used to eliminate unnecessary AND/OR filters that only have one child node.
input = '(&(name=bob))'
complex = Filter.parse(input)
print(complex.simplify()) # (name=bob)
There are a few options for getting a string output from your Filter
object with optional custom formatting.
You can get simple filter string by calling the Filter.to_string()
method. The Filter
class also implements Python's __str__
method, allowing you to type cast the Filter
object directly to a string or concatenate with other strings.
output = Filter.AND([
Filter.attribute('name').equal_to('bob'),
Filter.attribute('mail').ends_with('@example.com'),
])
# Filter.to_string() output.
print(output.to_string()) # (&(name=bob)(mail=*@example.com))
# Typecast output.
print(str(output)) # (&(name=bob)(mail=*@example.com))
# String concatenate output
print('LDAP Filter: ' + output) # LDAP Filter: (&(name=bob)(mail=*@example.com))
The Filter.to_string()
method provides additional formatting options to produce beautified filter strings.
You can get the default beautified format by passing True
to the Filter.to_string(indent)
method
output = Filter.AND([
Filter.attribute('name').equal_to('bob'),
Filter.attribute('mail').ends_with('@example.com'),
Filter.OR([
Filter.attribute('dept').equal_to('accounting'),
Filter.attribute('dept').equal_to('operations')
])
])
print(output.to_string(True))
Default Beautified Output:
(&
(name=bob)
(mail=*@example.com)
(|
(dept=accounting)
(dept=operations)
)
)
or you can customize the output by passing the indent
and/or indt_char
parameters to Filter.to_string(indent, indt_char)
. The indent
parameter accepts an integer value while the indt_char
parameter accepts any string or character value.
output = Filter.AND([
Filter.attribute('name').equal_to('bob'),
Filter.attribute('mail').ends_with('@example.com'),
Filter.OR([
Filter.attribute('dept').equal_to('accounting'),
Filter.attribute('dept').equal_to('operations')
])
])
print(output.to_string(2, '.'))
Custom Beautified Output:
(&
..(name=bob)
..(mail=*@example.com)
..(|
....(dept=accounting)
....(dept=operations)
..)
)
The Filter.match(data)
method allows you to evaluate a Python dictionary with attributes against an LDAP filter. The method will return True
if a match is found or False
if there is no match (or if an attribute matches a NOT exclusion).
filt = Filter.AND([
Filter.attribute('department').equal_to('accounting'),
Filter.NOT(
Filter.attribute('status').equal_to('terminated')
)
])
employee1 = {
'name': 'Bob Smith',
'department': 'Accounting',
'status': 'Active'
}
print(filt.match(employee1)) # True
employee2 = {
'name': 'Jane Brown',
'department': 'Accounting',
'status': 'Terminated'
}
print(filt.match(employee2)) # False
employee3 = {
'name': 'Bob Smith',
'department': 'Marketing',
'status': 'Active'
}
print(filt.match(employee3)) # False
In order to run the test suite the pytest library is required. You can install pytest by running:
pip install pytest
To run the unit tests simply type pytest
in the projects root directory
Project home page is https://github.com/SteveEwell/python-ldap-filter
The Python LDAP Filter project is open source software released under the MIT licence. Copyright 2024 Stephen Ewell
FAQs
A Python utility library for working with Lightweight Directory Access Protocol (LDAP) filters.
We found that ldap-filter demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Product
We're launching a new set of license analysis and compliance features for analyzing, managing, and complying with licenses across a range of supported languages and ecosystems.
Product
We're excited to introduce Socket Optimize, a powerful CLI command to secure open source dependencies with tested, optimized package overrides.