This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/ldap_ctxmgr
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/db/ldap_ctxmgr by this push:
     new 3f15d172d make ldap_conn() be a context manager, so unbind_s can be 
run automatically
3f15d172d is described below

commit 3f15d172d9e04341408dd4de986abbe3908327c5
Author: Dave Brondsema <dbronds...@slashdotmedia.com>
AuthorDate: Mon Jan 22 12:09:01 2024 -0500

    make ldap_conn() be a context manager, so unbind_s can be run automatically
---
 Allura/allura/lib/plugin.py | 62 +++++++++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 80c0525a2..47defa5db 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -25,6 +25,7 @@ import subprocess
 import string
 import crypt
 import random
+from contextlib import contextmanager
 from urllib.request import urlopen
 from urllib.parse import urlparse
 from io import BytesIO
@@ -628,17 +629,27 @@ class LocalAuthenticationProvider(AuthenticationProvider):
             d = self.user_registration_date(user)
         return d
 
-
-def ldap_conn(who=None, cred=None):
+def ldap_conn_staysopen(who=None, cred=None):
     '''
-    Init & bind a connection with the given creds, or the admin creds if not
-    specified. Remember to unbind the connection when done.
+    You must call .unbind_s() when done with this
     '''
     con = ldap.initialize(config['auth.ldap.server'])
     con.simple_bind_s(who or config['auth.ldap.admin_dn'],
                       cred or config['auth.ldap.admin_password'])
     return con
 
+@contextmanager
+def ldap_conn(who=None, cred=None):
+    '''
+    Init & bind a connection with the given creds, or the admin creds if not
+    specified.
+    '''
+    con = ldap_conn_staysopen(who, cred)
+    try:
+        yield con
+    finally:
+        con.unbind_s()
+
 
 def ldap_user_dn(username):
     'return a Distinguished Name for a given username'
@@ -667,7 +678,6 @@ class LdapAuthenticationProvider(AuthenticationProvider):
 
         # full registration into LDAP
         uid = str(M.AuthGlobals.get_next_uid()).encode('utf-8')
-        con = ldap_conn()
         uname = user_doc['username'].encode('utf-8')
         display_name = user_doc['display_name'].encode('utf-8')
         ldif_u = modlist.addModlist(dict(
@@ -681,12 +691,12 @@ class LdapAuthenticationProvider(AuthenticationProvider):
             loginShell=b'/bin/bash',
             gecos=uname,
             description=b'SCM user account'))
-        try:
-            con.add_s(ldap_user_dn(user_doc['username']), ldif_u)
-        except ldap.ALREADY_EXISTS:
-            log.exception('Trying to create existing user %s', uname)
-            raise
-        con.unbind_s()
+        with ldap_conn() as con:
+            try:
+                con.add_s(ldap_user_dn(user_doc['username']), ldif_u)
+            except ldap.ALREADY_EXISTS:
+                log.exception('Trying to create existing user %s', uname)
+                raise
 
         if asbool(config.get('auth.ldap.use_schroot', True)):
             argv = ('schroot -d / -c {} -u root /ldap-userconfig.py init 
{}'.format(
@@ -742,11 +752,10 @@ class LdapAuthenticationProvider(AuthenticationProvider):
         else:
             ldap_ident = ldap_pass = None
         try:
-            con = ldap_conn(ldap_ident, ldap_pass)
             new_password = self._encode_password(new_password)
-            con.modify_s(
-                dn, [(ldap.MOD_REPLACE, 'userPassword', new_password)])
-            con.unbind_s()
+            with ldap_conn(ldap_ident, ldap_pass) as con:
+                con.modify_s(
+                    dn, [(ldap.MOD_REPLACE, 'userPassword', new_password)])
             user.last_password_updated = datetime.utcnow()
             session(user).flush(user)
         except ldap.INVALID_CREDENTIALS:
@@ -792,8 +801,8 @@ class LdapAuthenticationProvider(AuthenticationProvider):
         except ValueError:
             return False
         try:
-            con = ldap_conn(ldap_user, password)
-            con.unbind_s()
+            with ldap_conn(ldap_user, password):
+                pass
             return True
         except (ldap.INVALID_CREDENTIALS, ldap.UNWILLING_TO_PERFORM, 
ldap.NO_SUCH_OBJECT):
             log.debug(f'LdapAuth: could not authenticate {username}', 
exc_info=True)
@@ -1740,13 +1749,11 @@ class 
LdapUserPreferencesProvider(UserPreferencesProvider):
             return LocalUserPreferencesProvider().get_pref(user, pref_name)
 
     def _get_pref(self, username, pref_name, multi=False):
-        con = ldap_conn()
-        try:
-            rs = con.search_s(ldap_user_dn(username), ldap.SCOPE_BASE)
-        except ldap.NO_SUCH_OBJECT:
-            rs = []
-        else:
-            con.unbind_s()
+        with ldap_conn() as con:
+            try:
+                rs = con.search_s(ldap_user_dn(username), ldap.SCOPE_BASE)
+            except ldap.NO_SUCH_OBJECT:
+                rs = []
         if not rs:
             log.warning(f'LdapUserPref: No user record found for: {username}')
             return ''
@@ -1767,10 +1774,9 @@ class 
LdapUserPreferencesProvider(UserPreferencesProvider):
                 ldap_val = [v.encode('utf-8', errors='replace') for v in 
pref_value]
             else:
                 ldap_val = pref_value.encode('utf-8', errors='replace')
-            con = ldap_conn()
-            con.modify_s(ldap_user_dn(user.username),
-                         [(ldap.MOD_REPLACE, ldap_attr, ldap_val)])
-            con.unbind_s()
+            with ldap_conn() as con:
+                con.modify_s(ldap_user_dn(user.username),
+                             [(ldap.MOD_REPLACE, ldap_attr, ldap_val)])
         else:
             return LocalUserPreferencesProvider().set_pref(user, pref_name, 
pref_value)
 

Reply via email to