|
407 |
raise UDM_Error( get_exception_msg(e) ) |
407 |
raise UDM_Error( get_exception_msg(e) ) |
408 |
|
408 |
|
409 |
@LDAP_Connection |
409 |
@LDAP_Connection |
410 |
def search( self, container = None, attribute = None, value = None, superordinate = None, scope = 'sub', filter = '', ldap_connection = None, ldap_position = None ): |
410 |
def search( self, container = None, attribute = None, value = None, superordinate = None, scope = 'sub', filter = '', simple = False, simple_attrs = None, ldap_connection = None, ldap_position = None ): |
411 |
"""Searches for LDAP objects based on a search pattern""" |
411 |
"""Searches for LDAP objects based on a search pattern""" |
412 |
if container == 'all': |
412 |
if container == 'all': |
413 |
container = ldap_position.getBase() |
413 |
container = ldap_position.getBase() |
|
421 |
result = None |
421 |
result = None |
422 |
try: |
422 |
try: |
423 |
sizelimit = int(ucr.get('directory/manager/web/sizelimit', '2000')) |
423 |
sizelimit = int(ucr.get('directory/manager/web/sizelimit', '2000')) |
424 |
result = self.module.lookup( None, ldap_connection, filter_s, base = container, superordinate = superordinate, scope = scope, sizelimit = sizelimit ) |
424 |
if simple: |
|
|
425 |
object_type_filter = 'univentionObjectType=%s' % self.module.module |
426 |
if filter: |
427 |
if not filter.startswith('('): |
428 |
filter = '(%s)' % filter |
429 |
object_type_filter = '(&(%s)%s)' % (object_type_filter, filter) |
430 |
if simple_attrs is not None: |
431 |
result = ldap_connection.search( filter = object_type_filter, base = container, scope = scope, sizelimit = sizelimit, attr = simple_attrs ) |
432 |
else: |
433 |
result = ldap_connection.searchDn( filter = object_type_filter, base = container, scope = scope, sizelimit = sizelimit ) |
434 |
else: |
435 |
result = self.module.lookup( None, ldap_connection, filter_s, base = container, superordinate = superordinate, scope = scope, sizelimit = sizelimit ) |
425 |
except udm_errors.insufficientInformation, e: |
436 |
except udm_errors.insufficientInformation, e: |
426 |
return [] |
437 |
return [] |
427 |
except udm_errors.ldapTimeout, e: |
438 |
except udm_errors.ldapTimeout, e: |
|
1004 |
filter_s = '(&%s%s)' % (property_filter_s, filter_s) |
1015 |
filter_s = '(&%s%s)' % (property_filter_s, filter_s) |
1005 |
return filter_s |
1016 |
return filter_s |
1006 |
|
1017 |
|
1007 |
LDAP_ATTR_RE = re.compile(r'^%\(([^(]*)\)s$') # '%(username)s' -> 'username' |
1018 |
LDAP_ATTR_RE = re.compile(r'^%\(([^)]*)\)s$') # '%(username)s' -> 'username' |
1008 |
def _get_syntax( syntax_name ): |
1019 |
def _get_syntax( syntax_name ): |
1009 |
if syntax_name not in udm_syntax.__dict__: |
1020 |
if syntax_name not in udm_syntax.__dict__: |
1010 |
return None |
1021 |
return None |
|
1051 |
filter_s = _create_ldap_filter( syn, options, module ) |
1062 |
filter_s = _create_ldap_filter( syn, options, module ) |
1052 |
if filter_s is not None: |
1063 |
if filter_s is not None: |
1053 |
try: |
1064 |
try: |
1054 |
size += len( module.search( filter = filter_s ) ) |
1065 |
size += len( module.search( filter = filter_s, simple=True ) ) |
1055 |
except udm_errors.ldapSizelimitExceeded: |
1066 |
except udm_errors.ldapSizelimitExceeded: |
1056 |
return {'performs_well' : True, 'size_limit_exceeded' : True} |
1067 |
return {'performs_well' : True, 'size_limit_exceeded' : True} |
1057 |
return {'size' : size, 'performs_well' : True } |
1068 |
return {'size' : size, 'performs_well' : True } |
|
1065 |
|
1076 |
|
1066 |
if issubclass( syn.__class__, udm_syntax.UDM_Objects ): |
1077 |
if issubclass( syn.__class__, udm_syntax.UDM_Objects ): |
1067 |
syn.choices = [] |
1078 |
syn.choices = [] |
1068 |
def map_choices( obj_list ): |
1079 |
# try to avoid using the slow udm interface |
1069 |
result = [] |
1080 |
simple = False |
1070 |
for obj in obj_list: |
1081 |
attr = [] |
1071 |
obj.open() |
1082 |
if not syn.always_use_objects and not syn.udm_filter: |
|
|
1083 |
attr.extend(re.findall(r'%\(([^)]+)\)', syn.key)) |
1084 |
if syn.label: |
1085 |
attr.extend(re.findall(r'%\(([^)]+)\)', syn.label)) |
1086 |
attr = set(attr) |
1087 |
for udm_module in syn.udm_modules: |
1088 |
module = UDM_Module( udm_module ) |
1089 |
if module is not None: |
1090 |
mapping = module.module.mapping |
1091 |
if not all([mapping.mapName(att) for att in attr]): |
1092 |
break |
1093 |
else: |
1094 |
simple = True |
1095 |
def extract_key_label(syn, dn, info): |
1096 |
key = label = None |
1097 |
if syn.key == 'dn': |
1098 |
key = dn |
1099 |
else: |
1100 |
try: |
1101 |
key = syn.key % info |
1102 |
except KeyError: |
1103 |
pass |
1104 |
if syn.label == 'dn': |
1105 |
label = dn |
1106 |
elif syn.label is None: |
1107 |
pass |
1108 |
else: |
1109 |
try: |
1110 |
label = syn.label % info |
1111 |
except KeyError: |
1112 |
pass |
1113 |
return key, label |
1114 |
if not simple: |
1115 |
def map_choices( obj_list ): |
1116 |
result = [] |
1117 |
for obj in obj_list: |
1118 |
# first try it without obj.open() (expensive) |
1119 |
key, label = extract_key_label(syn, obj.dn, obj.info) |
1120 |
if key is None or label is None: |
1121 |
obj.open() |
1122 |
key, label = extract_key_label(syn, obj.dn, obj.info) |
1123 |
if key is None: |
1124 |
# ignore the entry as the key is important for a selection, there |
1125 |
# is no sensible fallback for the key (Bug #26994) |
1126 |
continue |
1127 |
if label is None: |
1128 |
# fallback to the default description as this is just what displayed |
1129 |
# to the user (Bug #26994) |
1130 |
label = udm_objects.description( obj ) |
1131 |
result.append( (key, label) ) |
1132 |
return result |
1072 |
|
1133 |
|
1073 |
if syn.key == 'dn': |
1134 |
for udm_module in syn.udm_modules: |
1074 |
key = obj.dn |
1135 |
module = UDM_Module( udm_module ) |
|
|
1136 |
if module is None: |
1137 |
continue |
1138 |
filter_s = _create_ldap_filter( syn, options, module ) |
1139 |
if filter_s is None: |
1140 |
syn.choices = [] |
1075 |
else: |
1141 |
else: |
1076 |
try: |
1142 |
search_options = {'filter' : filter_s} |
1077 |
key = syn.key % obj.info |
1143 |
search_options.update(module_search_options) |
1078 |
except KeyError: |
1144 |
syn.choices.extend( map_choices( module.search( **search_options ) ) ) |
1079 |
# ignore the entry as the key is important for a selection, there |
1145 |
else: |
1080 |
# is no sensible fallback for the key (Bug #26994) |
1146 |
for udm_module in syn.udm_modules: |
1081 |
continue |
1147 |
module = UDM_Module( udm_module ) |
1082 |
if syn.label is None: |
1148 |
if module is None: |
1083 |
label = udm_objects.description( obj ) |
1149 |
continue |
1084 |
elif syn.label == 'dn': |
1150 |
filter_s = _create_ldap_filter( syn, options, module ) |
1085 |
label = obj.dn |
1151 |
if filter_s is not None: |
1086 |
else: |
1152 |
if filter_s and not filter_s.startswith('('): |
1087 |
try: |
1153 |
filter_s = '(%s)' % filter_s |
1088 |
label = syn.label % obj.info |
1154 |
mapping = module.module.mapping |
1089 |
except KeyError: |
1155 |
ldap_attr = [mapping.mapName(att) for att in attr] |
1090 |
# fallback to the default description as this is just what displayed |
1156 |
search_options = {'filter' : filter_s, 'simple' : True} |
1091 |
# to the user (Bug #26994) |
1157 |
search_options.update(module_search_options) |
1092 |
label = udm_objects.description( obj ) |
1158 |
if ldap_attr: |
1093 |
|
1159 |
search_options['simple_attrs'] = ldap_attr |
1094 |
result.append( (key, label) ) |
1160 |
result = module.search( **search_options ) |
1095 |
return result |
1161 |
for dn, ldap_map in result: |
1096 |
|
1162 |
info = univention.admin.mapping.mapDict(mapping, ldap_map) |
1097 |
for udm_module in syn.udm_modules: |
1163 |
key, label = extract_key_label(syn, dn, info) |
1098 |
module = UDM_Module( udm_module ) |
1164 |
if key is None: |
1099 |
if module is None: |
1165 |
continue |
1100 |
continue |
1166 |
if label is None: |
1101 |
filter_s = _create_ldap_filter( syn, options, module ) |
1167 |
label = ldap_connection.explodeDn(dn, 1)[0] |
1102 |
if filter_s is None: |
1168 |
syn.choices.append((key, label)) |
1103 |
syn.choices = [] |
1169 |
else: |
1104 |
else: |
1170 |
keys = module.search( **search_options ) |
1105 |
search_options = {'filter' : filter_s} |
1171 |
if syn.label == 'dn': |
1106 |
search_options.update(module_search_options) |
1172 |
labels = keys |
1107 |
syn.choices.extend( map_choices( module.search( **search_options ) ) ) |
1173 |
else: |
|
|
1174 |
labels = [ldap_connection.explodeDn(dn, 1)[0] for dn in keys] |
1175 |
syn.choices.extend(zip(keys, labels)) |
1108 |
if isinstance( syn.static_values, ( tuple, list ) ): |
1176 |
if isinstance( syn.static_values, ( tuple, list ) ): |
1109 |
for value in syn.static_values: |
1177 |
for value in syn.static_values: |
1110 |
syn.choices.insert( 0, value ) |
1178 |
syn.choices.insert( 0, value ) |