Skip to content

Commit 956c961

Browse files
author
stroeder
committed
ldap.ldapobject split into module-package
1 parent b5e0c3c commit 956c961

File tree

4 files changed

+242
-221
lines changed

4 files changed

+242
-221
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Lib/
2222
* module ldif now uses functions b64encode() and b64decode()
2323
* fixed pickling and restoring of ReconnectLDAPObject
2424
* more modules with PEP-8 compliance
25+
* ldap.ldapobject split into module-package
2526

2627
Tests/
2728
* scripts do not directly call SlapdTestCase.setUpClass() anymore

Lib/ldap/ldapobject.py renamed to Lib/ldap/ldapobject/__init__.py

Lines changed: 3 additions & 221 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
ldapobject.py - wraps class _ldap.LDAPObject
2+
ldap.ldapobject - wraps class _ldap.LDAPObject
33
44
See https://www.python-ldap.org/ for details.
55
"""
@@ -1091,226 +1091,8 @@ def get_naming_contexts(self):
10911091
).get('namingContexts', [])
10921092

10931093

1094-
class ReconnectLDAPObject(SimpleLDAPObject):
1095-
"""
1096-
In case of server failure (ldap.SERVER_DOWN) the implementations
1097-
of all synchronous operation methods (search_s() etc.) are doing
1098-
an automatic reconnect and rebind and will retry the very same
1099-
operation.
1100-
1101-
This is very handy for broken LDAP server implementations
1102-
(e.g. in Lotus Domino) which drop connections very often making
1103-
it impossible to have a long-lasting control flow in the
1104-
application.
1105-
"""
1106-
1107-
__transient_attrs__ = set([
1108-
'_l',
1109-
'_ldap_object_lock',
1110-
'_trace_file',
1111-
'_reconnect_lock',
1112-
'_last_bind',
1113-
])
1114-
1115-
def __init__(
1116-
self,
1117-
uri,
1118-
trace_level=0, trace_file=None, trace_stack_limit=5,
1119-
retry_max=1, retry_delay=60.0
1120-
):
1121-
"""
1122-
Parameters like SimpleLDAPObject.__init__() with these
1123-
additional arguments:
1124-
1125-
retry_max
1126-
Maximum count of reconnect trials
1127-
retry_delay
1128-
Time span to wait between two reconnect trials
1129-
"""
1130-
self._uri = uri
1131-
self._options = []
1132-
self._last_bind = None
1133-
SimpleLDAPObject.__init__(self, uri, trace_level, trace_file, trace_stack_limit)
1134-
self._reconnect_lock = ldap.LDAPLock(desc='reconnect lock within %r' % self)
1135-
self._retry_max = retry_max
1136-
self._retry_delay = retry_delay
1137-
self._start_tls = 0
1138-
self._reconnects_done = 0L
1139-
1140-
def __getstate__(self):
1141-
"""
1142-
return data representation for pickled object
1143-
"""
1144-
state = dict([
1145-
(key, val)
1146-
for key, val in self.__dict__.items()
1147-
if key not in self.__transient_attrs__
1148-
])
1149-
state['_last_bind'] = (
1150-
self._last_bind[0].__name__,
1151-
self._last_bind[1],
1152-
self._last_bind[2],
1153-
)
1154-
return state
1155-
1156-
def __setstate__(self, data):
1157-
"""
1158-
set up the object from pickled data
1159-
"""
1160-
self.__dict__.update(data)
1161-
self._last_bind = (
1162-
getattr(SimpleLDAPObject, self._last_bind[0]),
1163-
self._last_bind[1],
1164-
self._last_bind[2],
1165-
)
1166-
self._ldap_object_lock = self._ldap_lock()
1167-
self._reconnect_lock = ldap.LDAPLock(desc='reconnect lock within %r' % (self))
1168-
self._trace_file = sys.stdout
1169-
self.reconnect(self._uri)
1170-
1171-
def _store_last_bind(self, method, *args, **kwargs):
1172-
self._last_bind = (method, args, kwargs)
1173-
1174-
def _apply_last_bind(self):
1175-
if self._last_bind != None:
1176-
func, args, kwargs = self._last_bind
1177-
func(self, *args, **kwargs)
1178-
else:
1179-
# Send explicit anon simple bind request to provoke
1180-
# ldap.SERVER_DOWN in method reconnect()
1181-
SimpleLDAPObject.simple_bind_s(self, '', '')
1182-
1183-
def _restore_options(self):
1184-
"""Restore all recorded options"""
1185-
for key, val in self._options:
1186-
SimpleLDAPObject.set_option(self, key, val)
1187-
1188-
def passwd_s(self, *args, **kwargs):
1189-
return self._apply_method_s(SimpleLDAPObject.passwd_s, *args, **kwargs)
1190-
1191-
def reconnect(self, uri, retry_max=1, retry_delay=60.0):
1192-
# Drop and clean up old connection completely
1193-
# Reconnect
1194-
self._reconnect_lock.acquire()
1195-
try:
1196-
reconnect_counter = retry_max
1197-
while reconnect_counter:
1198-
counter_text = '%d. (of %d)' % (retry_max-reconnect_counter+1, retry_max)
1199-
if __debug__ and self._trace_level >= 1:
1200-
self._trace_file.write('*** Trying %s reconnect to %s...\n' % (
1201-
counter_text, uri
1202-
))
1203-
try:
1204-
# Do the connect
1205-
self._l = ldap.functions._ldap_function_call(
1206-
ldap._ldap_module_lock,
1207-
_ldap.initialize,
1208-
uri
1209-
)
1210-
self._restore_options()
1211-
# StartTLS extended operation in case this was called before
1212-
if self._start_tls:
1213-
SimpleLDAPObject.start_tls_s(self)
1214-
# Repeat last simple or SASL bind
1215-
self._apply_last_bind()
1216-
except (ldap.SERVER_DOWN, ldap.TIMEOUT), e:
1217-
if __debug__ and self._trace_level >= 1:
1218-
self._trace_file.write('*** %s reconnect to %s failed\n' % (
1219-
counter_text, uri
1220-
))
1221-
reconnect_counter = reconnect_counter-1
1222-
if not reconnect_counter:
1223-
raise e
1224-
if __debug__ and self._trace_level >= 1:
1225-
self._trace_file.write('=> delay %s...\n' % (retry_delay))
1226-
time.sleep(retry_delay)
1227-
SimpleLDAPObject.unbind_s(self)
1228-
else:
1229-
if __debug__ and self._trace_level >= 1:
1230-
self._trace_file.write(
1231-
'*** %s reconnect to %s successful => repeat last operation\n' % (
1232-
counter_text,
1233-
uri,
1234-
)
1235-
)
1236-
self._reconnects_done = self._reconnects_done + 1L
1237-
break
1238-
finally:
1239-
self._reconnect_lock.release()
1240-
return # reconnect()
1241-
1242-
def _apply_method_s(self, func, *args, **kwargs):
1243-
if not hasattr(self, '_l'):
1244-
self.reconnect(self._uri, retry_max=self._retry_max, retry_delay=self._retry_delay)
1245-
try:
1246-
return func(self, *args, **kwargs)
1247-
except ldap.SERVER_DOWN:
1248-
SimpleLDAPObject.unbind_s(self)
1249-
# Try to reconnect
1250-
self.reconnect(self._uri, retry_max=self._retry_max, retry_delay=self._retry_delay)
1251-
# Re-try last operation
1252-
return func(self, *args, **kwargs)
1253-
1254-
def set_option(self, option, invalue):
1255-
self._options.append((option, invalue))
1256-
return SimpleLDAPObject.set_option(self, option, invalue)
1257-
1258-
def bind_s(self, *args, **kwargs):
1259-
res = self._apply_method_s(SimpleLDAPObject.bind_s, *args, **kwargs)
1260-
self._store_last_bind(SimpleLDAPObject.bind_s, *args, **kwargs)
1261-
return res
1262-
1263-
def simple_bind_s(self, *args, **kwargs):
1264-
res = self._apply_method_s(SimpleLDAPObject.simple_bind_s, *args, **kwargs)
1265-
self._store_last_bind(SimpleLDAPObject.simple_bind_s, *args, **kwargs)
1266-
return res
1267-
1268-
def start_tls_s(self, *args, **kwargs):
1269-
res = self._apply_method_s(SimpleLDAPObject.start_tls_s, *args, **kwargs)
1270-
self._start_tls = 1
1271-
return res
1272-
1273-
def sasl_interactive_bind_s(self, *args, **kwargs):
1274-
"""
1275-
sasl_interactive_bind_s(who, auth) -> None
1276-
"""
1277-
res = self._apply_method_s(SimpleLDAPObject.sasl_interactive_bind_s, *args, **kwargs)
1278-
self._store_last_bind(SimpleLDAPObject.sasl_interactive_bind_s, *args, **kwargs)
1279-
return res
1280-
1281-
def sasl_bind_s(self, *args, **kwargs):
1282-
res = self._apply_method_s(SimpleLDAPObject.sasl_bind_s, *args, **kwargs)
1283-
self._store_last_bind(SimpleLDAPObject.sasl_bind_s, *args, **kwargs)
1284-
return res
1285-
1286-
def add_ext_s(self, *args, **kwargs):
1287-
return self._apply_method_s(SimpleLDAPObject.add_ext_s, *args, **kwargs)
1288-
1289-
def cancel_s(self, *args, **kwargs):
1290-
return self._apply_method_s(SimpleLDAPObject.cancel_s, *args, **kwargs)
1291-
1292-
def compare_ext_s(self, *args, **kwargs):
1293-
return self._apply_method_s(SimpleLDAPObject.compare_ext_s, *args, **kwargs)
1294-
1295-
def delete_ext_s(self, *args, **kwargs):
1296-
return self._apply_method_s(SimpleLDAPObject.delete_ext_s, *args, **kwargs)
1297-
1298-
def extop_s(self, *args, **kwargs):
1299-
return self._apply_method_s(SimpleLDAPObject.extop_s, *args, **kwargs)
1300-
1301-
def modify_ext_s(self, *args, **kwargs):
1302-
return self._apply_method_s(SimpleLDAPObject.modify_ext_s, *args, **kwargs)
1303-
1304-
def rename_s(self, *args, **kwargs):
1305-
return self._apply_method_s(SimpleLDAPObject.rename_s, *args, **kwargs)
1306-
1307-
def search_ext_s(self, *args, **kwargs):
1308-
return self._apply_method_s(SimpleLDAPObject.search_ext_s, *args, **kwargs)
1309-
1310-
def whoami_s(self, *args, **kwargs):
1311-
return self._apply_method_s(SimpleLDAPObject.whoami_s, *args, **kwargs)
1312-
1313-
13141094
# The class called LDAPObject will be used as default for
13151095
# ldap.open() and ldap.initialize()
13161096
LDAPObject = SimpleLDAPObject
1097+
1098+
from reconnect import ReconnectLDAPObject

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy