From 2ad495ea27610ddd9eade38f7458e9127af342de Mon Sep 17 00:00:00 2001 From: ckosiegbu Date: Tue, 25 Jul 2017 02:09:25 +0100 Subject: [PATCH] Added ability for either Administrator or user to reset the OTP secret. A user that is not Administrator can only reset their own OTP secret. Administrator can reset OTP secret of any user. --- frappe/core/doctype/user/user.js | 9 +++++++++ frappe/core/doctype/user/user.py | 25 ++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/user/user.js b/frappe/core/doctype/user/user.js index 39423ae600..d809d3a059 100644 --- a/frappe/core/doctype/user/user.js +++ b/frappe/core/doctype/user/user.js @@ -73,6 +73,15 @@ frappe.ui.form.on('User', { } }) }) + + frm.add_custom_button(__("Reset OTP Secret"), function() { + frappe.call({ + method: "frappe.core.doctype.user.user.reset_otp_secret", + args: { + "user": frm.doc.name + } + }) + }) frm.trigger('enabled'); diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 0bcfe0ec2b..c8fc9bb738 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -14,6 +14,7 @@ import frappe.share import re from frappe.limits import get_limits from frappe.website.utils import is_signup_enabled +from frappe.utils.background_jobs import enqueue STANDARD_USERS = ("Guest", "Administrator") @@ -618,8 +619,8 @@ def get_email_awaiting(user): return waiting else: frappe.db.sql("""update `tabUser Email` - set awaiting_password =0 - where parent = %(user)s""",{"user":user}) + set awaiting_password =0 + where parent = %(user)s""",{"user":user}) return False @frappe.whitelist(allow_guest=False) @@ -707,7 +708,7 @@ def ask_pass_update(): from frappe.utils import set_default users = frappe.db.sql("""SELECT DISTINCT(parent) as user FROM `tabUser Email` - WHERE awaiting_password = 1""", as_dict=True) + WHERE awaiting_password = 1""", as_dict=True) password_list = [ user.get("user") for user in users ] set_default("email_user_password", u','.join(password_list)) @@ -987,3 +988,21 @@ def send_token_via_email(tmp_id,token=None): delayed=False, retry=3) return True + +@frappe.whitelist(allow_guest=True) +def reset_otp_secret(user): + otp_issuer = frappe.db.get_value('System Settings', 'System Settings', 'otp_issuer_name') + user_email = frappe.db.get_value('User',user, 'email') + if frappe.session.user in ["Administrator", user] : + frappe.defaults.clear_default(user + '_otplogin') + frappe.defaults.clear_default(user + '_otpsecret') + email_args = { + 'recipients':user_email, 'sender':None, 'subject':'OTP Secret Reset - {}'.format(otp_issuer or "Frappe Framework"), + 'message':'

Your OTP secret on {} has been reset. If you did not perform this reset and did not request it, please contact your System Administrator immediately.

'.format(otp_issuer or "Frappe Framework"), + 'delayed':False, + 'retry':3 + } + enqueue(method=frappe.sendmail, queue='short', timeout=300, event=None, async=True, job_name=None, now=False, **email_args) + return frappe.msgprint(_("OTP Secret has been reset. Re-registration will be required on next login.")) + else: + return frappe.throw(_("OTP secret can only be reset by the Administrator.")) \ No newline at end of file