Skip to content
Snippets Groups Projects
Commit e050d915 authored by Denis Ledoux's avatar Denis Ledoux
Browse files

[ADD] auth_ldap: give possibility to users to change their ldap password


 - A user using ldap to sign in can now changes his password,
   providing hid old password.
 - When the ldap password is changed, empty the possible
   value for the password set in database so
   it can no longer be used.
 - Usually, in all res.users methods auth_ldap replaces,
   we first try to call `super` before fallbacking to
   ldap if the call to super fails.
   e.g. when authenticating,
   we first check the regular (super) credentials,
   before fallbacking to ldap if it fails.
   In this case, we do the opposite on purpose,
   to give the priority to ldap in case a user changes of password.
   e.g. a user has the same password in ldap and in database,
   when he changes, we rather like changing the ldap password
   and then empty the internal password.

closes odoo/odoo#50144

X-original-commit: 8bff93fe
Signed-off-by: default avatarOlivier Dony (odo) <odo@openerp.com>
Signed-off-by: default avatarDenis Ledoux (dle) <dle@odoo.com>
parent 67232303
No related branches found
No related tags found
No related merge requests found
......@@ -78,6 +78,22 @@ class CompanyLDAP(models.Model):
connection.start_tls_s()
return connection
def _get_entry(self, conf, login):
filter, dn, entry = False, False, False
try:
filter = filter_format(conf['ldap_filter'], (login,))
except TypeError:
_logger.warning('Could not format LDAP filter. Your filter should contain one \'%s\'.')
if filter:
results = self._query(conf, tools.ustr(filter))
# Get rid of (None, attrs) for searchResultReference replies
results = [i for i in results if i[0]]
if len(results) == 1:
entry = results[0]
dn = results[0][0]
return dn, entry
def _authenticate(self, conf, login, password):
"""
Authenticate a user against the specified LDAP server.
......@@ -95,23 +111,13 @@ class CompanyLDAP(models.Model):
if not password:
return False
entry = False
try:
filter = filter_format(conf['ldap_filter'], (login,))
except TypeError:
_logger.warning('Could not format LDAP filter. Your filter should contain one \'%s\'.')
dn, entry = self._get_entry(conf, login)
if not dn:
return False
try:
results = self._query(conf, tools.ustr(filter))
# Get rid of (None, attrs) for searchResultReference replies
results = [i for i in results if i[0]]
if len(results) == 1:
dn = results[0][0]
conn = self._connect(conf)
conn.simple_bind_s(dn, to_text(password))
conn.unbind()
entry = results[0]
conn = self._connect(conf)
conn.simple_bind_s(dn, to_text(password))
conn.unbind()
except ldap.INVALID_CREDENTIALS:
return False
except ldap.LDAPError as e:
......@@ -200,3 +206,20 @@ class CompanyLDAP(models.Model):
return SudoUser.create(values).id
raise AccessDenied(_("No local user found for LDAP login and not configured to create one"))
def _change_password(self, conf, login, old_passwd, new_passwd):
changed = False
dn, entry = self._get_entry(conf, login)
if not dn:
return False
try:
conn = self._connect(conf)
conn.simple_bind_s(dn, to_text(old_passwd))
conn.passwd_s(dn, old_passwd, new_passwd)
changed = True
conn.unbind()
except ldap.INVALID_CREDENTIALS:
pass
except ldap.LDAPError as e:
_logger.error('An LDAP exception occurred: %s', e)
return changed
......@@ -38,3 +38,22 @@ class Users(models.Model):
if Ldap._authenticate(conf, self.env.user.login, password):
return
raise
@api.model
def change_password(self, old_passwd, new_passwd):
if new_passwd:
Ldap = self.env['res.company.ldap']
for conf in Ldap._get_ldap_dicts():
changed = Ldap._change_password(conf, self.env.user.login, old_passwd, new_passwd)
if changed:
uid = self.env.user.id
self._set_empty_password(uid)
self.invalidate_cache(['password'], [uid])
return True
return super(Users, self).change_password(old_passwd, new_passwd)
def _set_empty_password(self, uid):
self.env.cr.execute(
'UPDATE res_users SET password=NULL WHERE id=%s',
(uid,)
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment