feat(ldap): allow resetting ldap password from user settings
currently, there is no way to reset password for those logging in through ldap. i understand that this shouldn't really be handled by erpnext, but there are people that have requested resetting the ldap password from with the instance itself, and hence, we'll let that happen now. Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
This commit is contained in:
parent
b7b27590e6
commit
94b2d856fc
2 changed files with 81 additions and 3 deletions
|
|
@ -97,6 +97,48 @@ frappe.ui.form.on('User', {
|
|||
});
|
||||
}, __("Password"));
|
||||
|
||||
frappe.db.get_single_value("LDAP Settings", "enabled").then((value) => {
|
||||
if (value === 1 && frm.name != "Administrator") {
|
||||
frm.add_custom_button(__("Reset LDAP Password"), function(){
|
||||
const d = new frappe.ui.Dialog({
|
||||
title: __("Reset LDAP Password"),
|
||||
fields: [
|
||||
{
|
||||
label: __("New Password"),
|
||||
fieldtype: "Password",
|
||||
fieldname: "new_password",
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
label: __("Confirm New Password"),
|
||||
fieldtype: "Password",
|
||||
fieldname: "confirm_password",
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
label: __("Logout All Sessions"),
|
||||
fieldtype: "Check",
|
||||
fieldname: "logout_sessions"
|
||||
}
|
||||
],
|
||||
primary_action: (values) => {
|
||||
d.hide();
|
||||
if(values.new_password !== values.confirm_password) {
|
||||
frappe.throw(__("Passwords do not match!"));
|
||||
}
|
||||
frappe.call(
|
||||
"frappe.integrations.doctype.ldap_settings.ldap_settings.reset_password", {
|
||||
user: frm.doc.email,
|
||||
password: values.new_password,
|
||||
logout: values.logout_sessions
|
||||
}).then(() => done());
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
}, __("Password"));
|
||||
}
|
||||
});
|
||||
|
||||
frm.add_custom_button(__("Reset OTP Secret"), function() {
|
||||
frappe.call({
|
||||
method: "frappe.core.doctype.user.user.reset_otp_secret",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe import _, safe_encode
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ class LDAPSettings(Document):
|
|||
else:
|
||||
frappe.throw(_("LDAP Search String needs to end with a placeholder, eg sAMAccountName={0}"))
|
||||
|
||||
def connect_to_ldap(self, base_dn, password):
|
||||
def connect_to_ldap(self, base_dn, password, read_only=True):
|
||||
try:
|
||||
import ldap3
|
||||
import ssl
|
||||
|
|
@ -44,7 +44,7 @@ class LDAPSettings(Document):
|
|||
user=base_dn,
|
||||
password=password,
|
||||
auto_bind=bind_type,
|
||||
read_only=True,
|
||||
read_only=read_only,
|
||||
raise_exceptions=True)
|
||||
|
||||
return conn
|
||||
|
|
@ -170,6 +170,34 @@ class LDAPSettings(Document):
|
|||
else:
|
||||
frappe.throw(_("Invalid username or password"))
|
||||
|
||||
def reset_password(self, user, password, logout_sessions=False):
|
||||
from ldap3 import HASHED_SALTED_SHA, MODIFY_REPLACE
|
||||
from ldap3.utils.hashed import hashed
|
||||
|
||||
search_filter = "({0}={1})".format(self.ldap_email_field, user)
|
||||
|
||||
conn = self.connect_to_ldap(self.base_dn, self.get_password(raise_exception=False),
|
||||
read_only=False)
|
||||
|
||||
if conn.search(
|
||||
search_base=self.organizational_unit,
|
||||
search_filter=search_filter,
|
||||
attributes=self.get_ldap_attributes()
|
||||
):
|
||||
if conn.entries and conn.entries[0]:
|
||||
entry_dn = conn.entries[0].entry_dn
|
||||
hashed_password = hashed(HASHED_SALTED_SHA, safe_encode(password))
|
||||
changes = {'userPassword': [(MODIFY_REPLACE, [hashed_password])]}
|
||||
if conn.modify(entry_dn, changes=changes):
|
||||
if logout_sessions:
|
||||
from frappe.sessions import clear_sessions
|
||||
clear_sessions(user=user, force=True)
|
||||
frappe.msgprint(_("Password changed successfully."))
|
||||
else:
|
||||
frappe.throw(_("Failed to change password."))
|
||||
else:
|
||||
frappe.throw(_("LDAP User does not exist!"))
|
||||
|
||||
def convert_ldap_entry_to_dict(self, user_entry):
|
||||
|
||||
# support multiple email values
|
||||
|
|
@ -211,3 +239,11 @@ def login():
|
|||
|
||||
# because of a GET request!
|
||||
frappe.db.commit()
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def reset_password(user, password, logout):
|
||||
ldap = frappe.get_doc("LDAP Settings")
|
||||
if not ldap.enabled:
|
||||
frappe.throw(_("LDAP is not enabled."))
|
||||
ldap.reset_password(user, password, logout_sessions=int(logout))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue