mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-12 16:32:01 -05:00
Move filter making methods to LDAPConnection
Part of the work for: https://fedorahosted.org/freeipa/ticket/2660
This commit is contained in:
1 parent
6fb115751c
commit
ddee3aa900
2 files changed
+139
-121
No files matched your search
@@ -32,6 +32,7 @@ from decimal import Decimal
|
|||||||
import ldap
|
import ldap
|
||||||
import ldap as _ldap
|
import ldap as _ldap
|
||||||
import ldap.sasl
|
import ldap.sasl
|
||||||
|
import ldap.filter
|
||||||
from ldap.controls import LDAPControl
|
from ldap.controls import LDAPControl
|
||||||
from ldap.ldapobject import SimpleLDAPObject
|
from ldap.ldapobject import SimpleLDAPObject
|
||||||
import ldapurl
|
import ldapurl
|
||||||
@@ -782,6 +783,16 @@ class LDAPConnection(object):
|
|||||||
subclasses, IPAdmin or the ldap2 plugin.
|
subclasses, IPAdmin or the ldap2 plugin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# rules for generating filters from entries
|
||||||
|
MATCH_ANY = '|' # (|(filter1)(filter2))
|
||||||
|
MATCH_ALL = '&' # (&(filter1)(filter2))
|
||||||
|
MATCH_NONE = '!' # (!(filter1)(filter2))
|
||||||
|
|
||||||
|
# search scope for find_entries()
|
||||||
|
SCOPE_BASE = _ldap.SCOPE_BASE
|
||||||
|
SCOPE_ONELEVEL = _ldap.SCOPE_ONELEVEL
|
||||||
|
SCOPE_SUBTREE = _ldap.SCOPE_SUBTREE
|
||||||
|
|
||||||
def __init__(self, ldap_uri):
|
def __init__(self, ldap_uri):
|
||||||
self.ldap_uri = ldap_uri
|
self.ldap_uri = ldap_uri
|
||||||
self.log = log_mgr.get_logger(self)
|
self.log = log_mgr.get_logger(self)
|
||||||
@@ -940,6 +951,133 @@ class LDAPConnection(object):
|
|||||||
parent_dn = self.normalize_dn(parent_dn)
|
parent_dn = self.normalize_dn(parent_dn)
|
||||||
return DN((primary_key, entry_attrs[primary_key]), parent_dn)
|
return DN((primary_key, entry_attrs[primary_key]), parent_dn)
|
||||||
|
|
||||||
|
# generating filters for find_entry
|
||||||
|
# some examples:
|
||||||
|
# f1 = ldap2.make_filter_from_attr(u'firstName', u'Pavel')
|
||||||
|
# f2 = ldap2.make_filter_from_attr(u'lastName', u'Zuna')
|
||||||
|
# f = ldap2.combine_filters([f1, f2], ldap2.MATCH_ALL)
|
||||||
|
# # f should be (&(firstName=Pavel)(lastName=Zuna))
|
||||||
|
# # it should be equivalent to:
|
||||||
|
# entry_attrs = {u'firstName': u'Pavel', u'lastName': u'Zuna'}
|
||||||
|
# f = ldap2.make_filter(entry_attrs, rules=ldap2.MATCH_ALL)
|
||||||
|
|
||||||
|
def combine_filters(self, filters, rules='|'):
|
||||||
|
"""
|
||||||
|
Combine filters into one for ldap2.find_entries.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
rules -- see ldap2.make_filter
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert isinstance(filters, (list, tuple))
|
||||||
|
|
||||||
|
filters = [f for f in filters if f]
|
||||||
|
if filters and rules == self.MATCH_NONE: # unary operator
|
||||||
|
return '(%s%s)' % (self.MATCH_NONE,
|
||||||
|
self.combine_filters(filters, self.MATCH_ANY))
|
||||||
|
|
||||||
|
if len(filters) > 1:
|
||||||
|
flt = '(%s' % rules
|
||||||
|
else:
|
||||||
|
flt = ''
|
||||||
|
for f in filters:
|
||||||
|
if not f.startswith('('):
|
||||||
|
f = '(%s)' % f
|
||||||
|
flt = '%s%s' % (flt, f)
|
||||||
|
if len(filters) > 1:
|
||||||
|
flt = '%s)' % flt
|
||||||
|
return flt
|
||||||
|
|
||||||
|
def make_filter_from_attr(
|
||||||
|
self, attr, value, rules='|', exact=True,
|
||||||
|
leading_wildcard=True, trailing_wildcard=True):
|
||||||
|
"""
|
||||||
|
Make filter for ldap2.find_entries from attribute.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
rules -- see ldap2.make_filter
|
||||||
|
exact -- boolean, True - make filter as (attr=value)
|
||||||
|
False - make filter as (attr=*value*)
|
||||||
|
leading_wildcard -- boolean:
|
||||||
|
True - allow heading filter wildcard when exact=False
|
||||||
|
False - forbid heading filter wildcard when exact=False
|
||||||
|
trailing_wildcard -- boolean:
|
||||||
|
True - allow trailing filter wildcard when exact=False
|
||||||
|
False - forbid trailing filter wildcard when exact=False
|
||||||
|
"""
|
||||||
|
if isinstance(value, (list, tuple)):
|
||||||
|
if rules == self.MATCH_NONE:
|
||||||
|
make_filter_rules = self.MATCH_ANY
|
||||||
|
else:
|
||||||
|
make_filter_rules = rules
|
||||||
|
flts = [
|
||||||
|
self.make_filter_from_attr(
|
||||||
|
attr, v, exact=exact,
|
||||||
|
leading_wildcard=leading_wildcard,
|
||||||
|
trailing_wildcard=trailing_wildcard)
|
||||||
|
for v in value
|
||||||
|
]
|
||||||
|
return self.combine_filters(flts, rules)
|
||||||
|
elif value is not None:
|
||||||
|
value = ldap.filter.escape_filter_chars(value_to_utf8(value))
|
||||||
|
if not exact:
|
||||||
|
template = '%s'
|
||||||
|
if leading_wildcard:
|
||||||
|
template = '*' + template
|
||||||
|
if trailing_wildcard:
|
||||||
|
template = template + '*'
|
||||||
|
value = template % value
|
||||||
|
if rules == self.MATCH_NONE:
|
||||||
|
return '(!(%s=%s))' % (attr, value)
|
||||||
|
return '(%s=%s)' % (attr, value)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def make_filter(
|
||||||
|
self, entry_attrs, attrs_list=None, rules='|', exact=True,
|
||||||
|
leading_wildcard=True, trailing_wildcard=True):
|
||||||
|
"""
|
||||||
|
Make filter for ldap2.find_entries from entry attributes.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
attrs_list -- list of attributes to use, all if None (default None)
|
||||||
|
rules -- specifies how to determine a match (default ldap2.MATCH_ANY)
|
||||||
|
exact -- boolean, True - make filter as (attr=value)
|
||||||
|
False - make filter as (attr=*value*)
|
||||||
|
leading_wildcard -- boolean:
|
||||||
|
True - allow heading filter wildcard when exact=False
|
||||||
|
False - forbid heading filter wildcard when exact=False
|
||||||
|
trailing_wildcard -- boolean:
|
||||||
|
True - allow trailing filter wildcard when exact=False
|
||||||
|
False - forbid trailing filter wildcard when exact=False
|
||||||
|
|
||||||
|
rules can be one of the following:
|
||||||
|
ldap2.MATCH_NONE - match entries that do not match any attribute
|
||||||
|
ldap2.MATCH_ALL - match entries that match all attributes
|
||||||
|
ldap2.MATCH_ANY - match entries that match any of attribute
|
||||||
|
"""
|
||||||
|
if rules == self.MATCH_NONE:
|
||||||
|
make_filter_rules = self.MATCH_ANY
|
||||||
|
else:
|
||||||
|
make_filter_rules = rules
|
||||||
|
flts = []
|
||||||
|
if attrs_list is None:
|
||||||
|
for (k, v) in entry_attrs.iteritems():
|
||||||
|
flts.append(
|
||||||
|
self.make_filter_from_attr(
|
||||||
|
k, v, make_filter_rules, exact,
|
||||||
|
leading_wildcard, trailing_wildcard)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for a in attrs_list:
|
||||||
|
value = entry_attrs.get(a, None)
|
||||||
|
if value is not None:
|
||||||
|
flts.append(
|
||||||
|
self.make_filter_from_attr(
|
||||||
|
a, value, make_filter_rules, exact,
|
||||||
|
leading_wildcard, trailing_wildcard)
|
||||||
|
)
|
||||||
|
return self.combine_filters(flts, rules)
|
||||||
|
|
||||||
|
|
||||||
class IPAdmin(LDAPConnection):
|
class IPAdmin(LDAPConnection):
|
||||||
|
|
||||||
|
|||||||
+1
-121
@@ -39,8 +39,7 @@ import ldap.filter as _ldap_filter
|
|||||||
|
|
||||||
from ipapython.dn import DN, RDN
|
from ipapython.dn import DN, RDN
|
||||||
from ipaserver.ipaldap import (
|
from ipaserver.ipaldap import (
|
||||||
SASL_AUTH, unicode_from_utf8, value_to_utf8, IPASimpleLDAPObject,
|
SASL_AUTH, unicode_from_utf8, IPASimpleLDAPObject, LDAPConnection)
|
||||||
LDAPConnection)
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -75,16 +74,6 @@ class ldap2(LDAPConnection, CrudBackend):
|
|||||||
# only MOD_REPLACE operations are generated for them
|
# only MOD_REPLACE operations are generated for them
|
||||||
_FORCE_REPLACE_ON_UPDATE_ATTRS = []
|
_FORCE_REPLACE_ON_UPDATE_ATTRS = []
|
||||||
|
|
||||||
# rules for generating filters from entries
|
|
||||||
MATCH_ANY = '|' # (|(filter1)(filter2))
|
|
||||||
MATCH_ALL = '&' # (&(filter1)(filter2))
|
|
||||||
MATCH_NONE = '!' # (!(filter1)(filter2))
|
|
||||||
|
|
||||||
# search scope for find_entries()
|
|
||||||
SCOPE_BASE = _ldap.SCOPE_BASE
|
|
||||||
SCOPE_ONELEVEL = _ldap.SCOPE_ONELEVEL
|
|
||||||
SCOPE_SUBTREE = _ldap.SCOPE_SUBTREE
|
|
||||||
|
|
||||||
def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None,
|
def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None,
|
||||||
schema=None):
|
schema=None):
|
||||||
try:
|
try:
|
||||||
@@ -236,115 +225,6 @@ class ldap2(LDAPConnection, CrudBackend):
|
|||||||
except _ldap.LDAPError, e:
|
except _ldap.LDAPError, e:
|
||||||
self.handle_errors(e)
|
self.handle_errors(e)
|
||||||
|
|
||||||
# generating filters for find_entry
|
|
||||||
# some examples:
|
|
||||||
# f1 = ldap2.make_filter_from_attr(u'firstName', u'Pavel')
|
|
||||||
# f2 = ldap2.make_filter_from_attr(u'lastName', u'Zuna')
|
|
||||||
# f = ldap2.combine_filters([f1, f2], ldap2.MATCH_ALL)
|
|
||||||
# # f should be (&(firstName=Pavel)(lastName=Zuna))
|
|
||||||
# # it should be equivalent to:
|
|
||||||
# entry_attrs = {u'firstName': u'Pavel', u'lastName': u'Zuna'}
|
|
||||||
# f = ldap2.make_filter(entry_attrs, rules=ldap2.MATCH_ALL)
|
|
||||||
|
|
||||||
def combine_filters(self, filters, rules='|'):
|
|
||||||
"""
|
|
||||||
Combine filters into one for ldap2.find_entries.
|
|
||||||
|
|
||||||
Keyword arguments:
|
|
||||||
rules -- see ldap2.make_filter
|
|
||||||
"""
|
|
||||||
|
|
||||||
assert isinstance(filters, (list, tuple))
|
|
||||||
|
|
||||||
filters = [f for f in filters if f]
|
|
||||||
if filters and rules == self.MATCH_NONE: # unary operator
|
|
||||||
return '(%s%s)' % (self.MATCH_NONE,
|
|
||||||
self.combine_filters(filters, self.MATCH_ANY))
|
|
||||||
|
|
||||||
if len(filters) > 1:
|
|
||||||
flt = '(%s' % rules
|
|
||||||
else:
|
|
||||||
flt = ''
|
|
||||||
for f in filters:
|
|
||||||
if not f.startswith('('):
|
|
||||||
f = '(%s)' % f
|
|
||||||
flt = '%s%s' % (flt, f)
|
|
||||||
if len(filters) > 1:
|
|
||||||
flt = '%s)' % flt
|
|
||||||
return flt
|
|
||||||
|
|
||||||
def make_filter_from_attr(self, attr, value, rules='|', exact=True,
|
|
||||||
leading_wildcard=True, trailing_wildcard=True):
|
|
||||||
"""
|
|
||||||
Make filter for ldap2.find_entries from attribute.
|
|
||||||
|
|
||||||
Keyword arguments:
|
|
||||||
rules -- see ldap2.make_filter
|
|
||||||
exact -- boolean, True - make filter as (attr=value)
|
|
||||||
False - make filter as (attr=*value*)
|
|
||||||
leading_wildcard -- boolean, True - allow heading filter wildcard when exact=False
|
|
||||||
False - forbid heading filter wildcard when exact=False
|
|
||||||
trailing_wildcard -- boolean, True - allow trailing filter wildcard when exact=False
|
|
||||||
False - forbid trailing filter wildcard when exact=False
|
|
||||||
"""
|
|
||||||
if isinstance(value, (list, tuple)):
|
|
||||||
make_filter_rules = self.MATCH_ANY if rules == self.MATCH_NONE else rules
|
|
||||||
flts = [ self.make_filter_from_attr(attr, v, exact=exact,
|
|
||||||
leading_wildcard=leading_wildcard,
|
|
||||||
trailing_wildcard=trailing_wildcard) for v in value ]
|
|
||||||
return self.combine_filters(flts, rules)
|
|
||||||
elif value is not None:
|
|
||||||
value = _ldap_filter.escape_filter_chars(value_to_utf8(value))
|
|
||||||
if not exact:
|
|
||||||
template = '%s'
|
|
||||||
if leading_wildcard:
|
|
||||||
template = '*' + template
|
|
||||||
if trailing_wildcard:
|
|
||||||
template = template + '*'
|
|
||||||
value = template % value
|
|
||||||
if rules == self.MATCH_NONE:
|
|
||||||
return '(!(%s=%s))' % (attr, value)
|
|
||||||
return '(%s=%s)' % (attr, value)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def make_filter(self, entry_attrs, attrs_list=None, rules='|', exact=True,
|
|
||||||
leading_wildcard=True, trailing_wildcard=True):
|
|
||||||
"""
|
|
||||||
Make filter for ldap2.find_entries from entry attributes.
|
|
||||||
|
|
||||||
Keyword arguments:
|
|
||||||
attrs_list -- list of attributes to use, all if None (default None)
|
|
||||||
rules -- specifies how to determine a match (default ldap2.MATCH_ANY)
|
|
||||||
exact -- boolean, True - make filter as (attr=value)
|
|
||||||
False - make filter as (attr=*value*)
|
|
||||||
leading_wildcard -- boolean, True - allow heading filter wildcard when exact=False
|
|
||||||
False - forbid heading filter wildcard when exact=False
|
|
||||||
trailing_wildcard -- boolean, True - allow trailing filter wildcard when exact=False
|
|
||||||
False - forbid trailing filter wildcard when exact=False
|
|
||||||
|
|
||||||
rules can be one of the following:
|
|
||||||
ldap2.MATCH_NONE - match entries that do not match any attribute
|
|
||||||
ldap2.MATCH_ALL - match entries that match all attributes
|
|
||||||
ldap2.MATCH_ANY - match entries that match any of attribute
|
|
||||||
"""
|
|
||||||
make_filter_rules = self.MATCH_ANY if rules == self.MATCH_NONE else rules
|
|
||||||
flts = []
|
|
||||||
if attrs_list is None:
|
|
||||||
for (k, v) in entry_attrs.iteritems():
|
|
||||||
flts.append(
|
|
||||||
self.make_filter_from_attr(k, v, make_filter_rules, exact,
|
|
||||||
leading_wildcard, trailing_wildcard)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
for a in attrs_list:
|
|
||||||
value = entry_attrs.get(a, None)
|
|
||||||
if value is not None:
|
|
||||||
flts.append(
|
|
||||||
self.make_filter_from_attr(a, value, make_filter_rules, exact,
|
|
||||||
leading_wildcard, trailing_wildcard)
|
|
||||||
)
|
|
||||||
return self.combine_filters(flts, rules)
|
|
||||||
|
|
||||||
def find_entries(self, filter=None, attrs_list=None, base_dn=None,
|
def find_entries(self, filter=None, attrs_list=None, base_dn=None,
|
||||||
scope=_ldap.SCOPE_SUBTREE, time_limit=None, size_limit=None,
|
scope=_ldap.SCOPE_SUBTREE, time_limit=None, size_limit=None,
|
||||||
normalize=True, search_refs=False):
|
normalize=True, search_refs=False):
|
||||||
|
|||||||
Reference in new issue
Block a user