diff --git a/branches/ucs-3.2/ucs-3.2-1/management/univention-directory-manager-modules/modules/univention/admin/filter.py b/branches/ucs-3.2/ucs-3.2-1/management/univention-directory-manager-modules/modules/univention/admin/filter.py index 023601f..7a115ed 100644 --- a/branches/ucs-3.2/ucs-3.2-1/management/univention-directory-manager-modules/modules/univention/admin/filter.py +++ b/branches/ucs-3.2/ucs-3.2-1/management/univention-directory-manager-modules/modules/univention/admin/filter.py @@ -31,9 +31,9 @@ # . import re -import types import univention.admin.uexceptions + def escapeForLdapFilter(txt): """Escape LDAP filter value. Bug #19976: According to RFC2254 [*()\\\0] must be \\%02x encoded. @@ -141,6 +141,10 @@ def parse(filter_s, begin=0, end=-1): >> parse('(&(key=va\\)!\\(ue))') conjunction('&', [expression('key', 'va)!(ue', '=')]) """ + # filter is already parsed + if not isinstance(filter_s, basestring): + return filter_s + def split(str): expressions=[] depth=0 @@ -159,10 +163,6 @@ def parse(filter_s, begin=0, end=-1): i+=1 return expressions - # filter is already parsed - if type(filter_s) == types.InstanceType: - return filter_s - if end == -1: end=len(filter_s)-1 @@ -187,6 +187,7 @@ def parse(filter_s, begin=0, end=-1): variable, value=filter_s[begin:end+1].split('=', 1) return expression(variable, value) + def walk(filter, expression_walk_function=None, conjunction_walk_function=None, arg=None): """Walk LDAP filter expression tree. @@ -211,31 +212,39 @@ def walk(filter, expression_walk_function=None, conjunction_walk_function=None, if expression_walk_function: expression_walk_function(filter, arg) -FQDN_REGEX = re.compile( '^(.*?)\(?fqdn=([^)]+)\)?(.*)$' ) -def replace_fqdn_filter( filter_s ): + +FQDN_REGEX = re.compile(r'(?:^|\()fqdn=([^)]+)(?:\)|$)') + + +def replace_fqdn_filter(filter_s): ''' Replaces a filter expression for the read-only attribute fqdn. If no such expression can be found the unmodified filter is returned. - fqdn=host.doain.tld -> (&(cn=host)(associatedDomain=domain.tld)) + >>> replace_fqdn_filter('fqdn=host.domain.tld') + '(&(cn=host)(associatedDomain=domain.tld))' + >>> replace_fqdn_filter('(fqdn=host.domain.tld)') + '(&(cn=host)(associatedDomain=domain.tld))' + >>> replace_fqdn_filter('fqdn=domain') + '(|(cn=domain)(associatedDomain=domain))' + >>> replace_fqdn_filter('(|(fqdn=host.domain.tld)(fqdn=other.domain.tld2))') + '(|(&(cn=host)(associatedDomain=domain.tld))(&(cn=other)(associatedDomain=domain.tld2)))' ''' - if not isinstance( filter_s, basestring ): + if not isinstance(filter_s, basestring): return filter_s - if filter_s.find( 'fqdn=' ) != -1: - match = FQDN_REGEX.match( str( filter_s ) ) - if match: - prefix, value, suffix = match.groups() - if value.find( '.' ) >= 0: - host, domain = value.split( '.', 1 ) - operator = '&' - else: - host = value - domain = value - operator = '|' - fqdn_filter = '(%s(cn=%s)(associatedDomain=%s))' % ( operator, host, domain ) - return prefix + fqdn_filter + suffix - - return filter_s + return FQDN_REGEX.sub(_replace_fqdn_filter, filter_s) + + +def _replace_fqdn_filter(match): + value, = match.groups() + try: + host, domain = value.split('.', 1) + operator = '&' + except ValueError: + host = domain = value + operator = '|' + return '(%s(cn=%s)(associatedDomain=%s))' % (operator, host, domain) + if __name__ == '__main__': import doctest