Merge pull request #9743 from Thunderbottom/ldap-password-reset
feat(ldap): allow resetting ldap password from user settings
This commit is contained in:
commit
02b256b089
2 changed files with 83 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.doc.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
|
||||
});
|
||||
}
|
||||
});
|
||||
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,36 @@ 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(_("No Entry for the User {0} found within LDAP!").format(user))
|
||||
else:
|
||||
frappe.throw(_("No LDAP User found for email: {0}").format(user))
|
||||
|
||||
def convert_ldap_entry_to_dict(self, user_entry):
|
||||
|
||||
# support multiple email values
|
||||
|
|
@ -211,3 +241,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