24
24
25
25
import ldap
26
26
from moulinette .utils .filesystem import read_json
27
- from yunohost .authenticators .ldap_ynhuser import URI , USERDN , Authenticator as Auth , user_is_allowed_on_domain
27
+ from yunohost .authenticators .ldap_ynhuser import Authenticator as Auth , user_is_allowed_on_domain
28
28
from yunohost .user import _hash_user_password
29
29
from yunohost .utils .error import YunohostError , YunohostValidationError
30
- from yunohost .utils .ldap import LDAPInterface , _ldap_path_extract
30
+ from yunohost .utils .ldap import _get_ldap_interface , _ldap_path_extract , LDAPInterface
31
31
from yunohost .utils .password import (
32
32
assert_password_is_compatible ,
33
33
assert_password_is_strong_enough ,
41
41
42
42
def _get_user_infos (
43
43
user_attrs : list [str ],
44
- ) -> tuple [str , str , dict [str , Any ], LDAPInterface ]:
45
- auth = Auth ().get_session_cookie (decrypt_pwd = True )
44
+ ) -> tuple [str , str , dict [str , Any ]]:
45
+ auth = Auth ().get_session_cookie ()
46
46
username = auth ["user" ]
47
- ldap_interface = LDAPInterface (username , auth ["pwd" ])
48
- result = ldap_interface .search ("ou=users" , f"uid={ username } " , user_attrs )
47
+ result = _get_ldap_interface ().search ("ou=users" , f"uid={ username } " , user_attrs )
49
48
if not result :
50
49
raise YunohostValidationError ("user_unknown" , user = username )
51
50
52
- return username , auth ["host" ], result [0 ], ldap_interface
51
+ return username , auth ["host" ], result [0 ]
53
52
54
53
55
54
def _get_portal_settings (
@@ -123,7 +122,7 @@ def portal_me():
123
122
"""
124
123
Get user informations
125
124
"""
126
- username , domain , user , _ = _get_user_infos (
125
+ username , domain , user = _get_user_infos (
127
126
["cn" , "mail" , "maildrop" , "mailuserquota" , "memberOf" , "permission" ]
128
127
)
129
128
@@ -163,7 +162,7 @@ def portal_update(
163
162
from yunohost .domain import domain_list
164
163
165
164
domains = domain_list ()["domains" ]
166
- username , domain , current_user , ldap_interface = _get_user_infos (
165
+ username , domain , current_user = _get_user_infos (
167
166
["givenName" , "sn" , "cn" , "mail" , "maildrop" , "memberOf" ]
168
167
)
169
168
new_attr_dict = {}
@@ -198,7 +197,7 @@ def portal_update(
198
197
)
199
198
200
199
try :
201
- ldap_interface .validate_uniqueness ({"mail" : mail })
200
+ _get_ldap_interface () .validate_uniqueness ({"mail" : mail })
202
201
except YunohostError :
203
202
raise YunohostValidationError (
204
203
"mail_already_exists" , mail = mail , path = f"mailalias[{ index } ]"
@@ -221,19 +220,6 @@ def portal_update(
221
220
]
222
221
223
222
if newpassword :
224
- # FIXME: this ldap stuff should be handled in utils/ldap.py imho ?
225
-
226
- # Check that current password is valid
227
- try :
228
- con = ldap .ldapobject .ReconnectLDAPObject (URI , retry_max = 0 )
229
- con .simple_bind_s (USERDN .format (username = username ), currentpassword )
230
- except ldap .INVALID_CREDENTIALS :
231
- raise YunohostValidationError ("invalid_password" , path = "currentpassword" )
232
- finally :
233
- # Free the connection, we don't really need it to keep it open as the point is only to check authentication...
234
- if con :
235
- con .unbind_s ()
236
-
237
223
# Ensure compatibility and sufficiently complex password
238
224
try :
239
225
assert_password_is_compatible (newpassword )
@@ -248,10 +234,24 @@ def portal_update(
248
234
249
235
new_attr_dict ["userPassword" ] = [_hash_user_password (newpassword )]
250
236
237
+ # Check that current password is valid
238
+ # To be able to edit the user info, an authenticated ldap session is needed
239
+ if newpassword :
240
+ # When setting the password, check the user provided the valid current password
241
+ try :
242
+ ldap_interface = LDAPInterface (username , currentpassword )
243
+ except ldap .INVALID_CREDENTIALS :
244
+ raise YunohostValidationError ("invalid_password" , path = "currentpassword" )
245
+ else :
246
+ # Otherwise we use the encrypted password stored in the cookie
247
+ ldap_interface = LDAPInterface (username , Auth ().get_session_cookie (decrypt_pwd = True )["pwd" ])
248
+
251
249
try :
252
250
ldap_interface .update (f"uid={ username } ,ou=users" , new_attr_dict )
253
251
except Exception as e :
254
252
raise YunohostError ("user_update_failed" , user = username , error = e )
253
+ finally :
254
+ del ldap_interface
255
255
256
256
if "userPassword" in new_attr_dict :
257
257
Auth .invalidate_all_sessions_for_user (username )
0 commit comments