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