diff --git a/core/doctype/profile/profile.py b/core/doctype/profile/profile.py index 35961c1b80..e822ec5d3f 100644 --- a/core/doctype/profile/profile.py +++ b/core/doctype/profile/profile.py @@ -85,8 +85,8 @@ class DocType: def update_new_password(self): """update new password if set""" if self.doc.new_password: - from webnotes.auth import update_password - update_password(self.doc.name, self.doc.new_password) + from webnotes.auth import _update_password + _update_password(self.doc.name, self.doc.new_password) if self.in_insert: webnotes.msgprint("New user created. - %s" % self.doc.name) @@ -94,11 +94,18 @@ class DocType: self.send_welcome_mail(self.doc.new_password) webnotes.msgprint("Sent welcome mail.") else: - self.password_reset_mail(self.doc.new_password) - webnotes.msgprint("Password updated.") + self.password_update_mail(self.doc.new_password) + webnotes.msgprint("New Password Emailed.") webnotes.conn.set(self.doc, 'new_password', '') - + + def reset_password(self): + from webnotes.utils import random_string, get_request_site_address + + key = random_string(32) + webnotes.conn.set_value("Profile", self.doc.name, "reset_password_key", key) + self.password_reset_mail(get_request_site_address() + "/update-password?key=" + key) + def get_other_system_managers(self): return webnotes.conn.sql("""select distinct parent from tabUserRole user_role where role='System Manager' and docstatus<2 @@ -111,25 +118,37 @@ class DocType: return (self.doc.first_name or '') + \ (self.doc.first_name and " " or '') + (self.doc.last_name or '') - def password_reset_mail(self, password): + def password_reset_mail(self, link): """reset password""" txt = """ ## Password Reset Dear %(first_name)s, -Your password has been reset. Your new password is: +Please click on the following link to update your new password: -password: %(password)s +%(link)s -To login to %(product)s, please go to: +Thank you,
+%(user_fullname)s + """ + self.send_login_mail("Your " + webnotes.get_config().get("app_name") + " password has been reset", + txt, {"link": link}) + + def password_update_mail(self, password): + txt = """ +## Password Update Notification -%(login_url)s +Dear %(first_name)s, + +Your password has been updated. Here is your new password: %(new_password)s Thank you,
%(user_fullname)s """ - self.send_login_mail("Your " + webnotes.get_config().get("app_name") + " password has been reset", txt, password) + self.send_login_mail("Your " + webnotes.get_config().get("app_name") + " password has been reset", + txt, {"password": "password"}) + def send_welcome_mail(self, password): """send welcome mail to user with password and login url""" @@ -151,9 +170,10 @@ To login to your new %(product)s account, please go to: Thank you,
%(user_fullname)s """ - self.send_login_mail("Welcome to " + webnotes.get_config().get("app_name"), txt, password) + self.send_login_mail("Welcome to " + webnotes.get_config().get("app_name"), txt, + { "password": password }) - def send_login_mail(self, subject, txt, password): + def send_login_mail(self, subject, txt, add_args): """send mail with login details""" import os @@ -168,13 +188,14 @@ Thank you,
args = { 'first_name': self.doc.first_name or self.doc.last_name or "user", 'user': self.doc.name, - 'password': password, 'company': webnotes.conn.get_default('company') or webnotes.get_config().get("app_name"), 'login_url': get_request_site_address(), 'product': webnotes.get_config().get("app_name"), 'user_fullname': full_name } + args.update(add_args) + sender = webnotes.session.user not in ("Administrator", "Guest") and webnotes.session.user or None sendmail_md(recipients=self.doc.email, sender=sender, subject=subject, msg=txt % args) @@ -301,10 +322,31 @@ def update_profile(fullname, password=None): webnotes.add_cookies["full_name"] = fullname if password: - from webnotes.auth import update_password - update_password(webnotes.session.user, password) + from webnotes.auth import _update_password + _update_password(webnotes.session.user, password) return _("Updated") + +@webnotes.whitelist(allow_guest=True) +def update_password(new_password, key=None, old_password=None): + # verify old password + if old_password: + user = webnotes.session.user + if not webnotes.conn.sql("""select user from __Auth where password=password(%s) + and user=%s""", (old_password, user)): + return _("Cannot Update: Incorrect Password") + else: + if key: + user = webnotes.conn.get_value("Profile", {"reset_password_key":key}) + if not user: + return _("Cannot Update: Incorrect / Expired Link.") + + from webnotes.auth import _update_password + _update_password(user, new_password) + + webnotes.conn.set_value("Profile", user, "reset_password_key", "") + + return _("Password Updated") @webnotes.whitelist(allow_guest=True) def sign_up(email, full_name): @@ -331,7 +373,22 @@ def sign_up(email, full_name): profile.ignore_permissions = True profile.insert() return _("Registration Details Emailed.") - + +@webnotes.whitelist(allow_guest=True) +def reset_password(user): + user = webnotes.form_dict.get('user', '') + if user in ["demo@erpnext.com", "Administrator"]: + return "Not allowed" + + if webnotes.conn.sql("""select name from tabProfile where name=%s""", user): + # Hack! + webnotes.session["user"] = "Administrator" + profile = webnotes.bean("Profile", user) + profile.get_controller().reset_password() + return "Password reset details sent to your email." + else: + return "No such user (%s)" % user + def profile_query(doctype, txt, searchfield, start, page_len, filters): from webnotes.widgets.reportview import get_match_cond return webnotes.conn.sql("""select name, concat_ws(' ', first_name, middle_name, last_name) diff --git a/core/doctype/profile/profile.txt b/core/doctype/profile/profile.txt index a4336e8b09..245fea3bfe 100644 --- a/core/doctype/profile/profile.txt +++ b/core/doctype/profile/profile.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 11:54:44", "docstatus": 0, - "modified": "2013-09-06 12:10:25", + "modified": "2013-09-16 14:47:47", "modified_by": "Administrator", "owner": "Administrator" }, @@ -177,6 +177,15 @@ "no_copy": 1, "print_hide": 1 }, + { + "doctype": "DocField", + "fieldname": "reset_password_key", + "fieldtype": "Data", + "hidden": 1, + "label": "Reset Password Key", + "print_hide": 1, + "read_only": 1 + }, { "depends_on": "eval:!doc.__islocal", "doctype": "DocField", diff --git a/webnotes/auth.py b/webnotes/auth.py index 7d89ab4132..2ca71410eb 100644 --- a/webnotes/auth.py +++ b/webnotes/auth.py @@ -263,7 +263,7 @@ class CookieManager: webnotes.cookies[k][b'expires'] = expires.encode('utf-8') -def update_password(user, password): +def _update_password(user, password): webnotes.conn.sql("""insert into __Auth (user, `password`) values (%s, password(%s)) on duplicate key update `password`=password(%s)""", (user, diff --git a/webnotes/handler.py b/webnotes/handler.py index 8c75b14ab8..6643d4c4c2 100755 --- a/webnotes/handler.py +++ b/webnotes/handler.py @@ -76,29 +76,6 @@ def uploadfile(): ret = None return ret - -@webnotes.whitelist(allow_guest=True) -def reset_password(user): - from webnotes.model.code import get_obj - from webnotes.utils import random_string - - user = webnotes.form_dict.get('user', '') - if user in ["demo@erpnext.com", "Administrator"]: - return "Not allowed" - - if webnotes.conn.sql("""select name from tabProfile where name=%s""", user): - new_password = random_string(8) - webnotes.conn.sql("""update `__Auth` set password=password(%s) - where `user`=%s""", (new_password, user)) - - # Hack! - webnotes.session["user"] = "Administrator" - profile = get_obj("Profile", user) - profile.password_reset_mail(new_password) - return "Password has been reset and sent to your email id." - else: - return "No such user (%s)" % user - def handle(): """handle request""" diff --git a/webnotes/webutils.py b/webnotes/webutils.py index eeb745ea56..2af337d49c 100644 --- a/webnotes/webutils.py +++ b/webnotes/webutils.py @@ -205,7 +205,8 @@ def get_website_settings(): "webnotes": webnotes, "utils": webnotes.utils, "post_login": [ - {"label": "Logout", "url": "server.py?cmd=web_logout", "icon": "icon-signout"}, + {"label": "Reset Password", "url": "update-password", "icon": "icon-key"}, + {"label": "Logout", "url": "server.py?cmd=web_logout", "icon": "icon-signout"} ] }) diff --git a/website/js/website.js b/website/js/website.js index 986783edc4..6ead1f8f1b 100644 --- a/website/js/website.js +++ b/website/js/website.js @@ -4,16 +4,6 @@ if(!window.wn) wn = {}; wn = { - show_message: function(text, icon) { - if(!icon) icon="icon-refresh icon-spin"; - treemapper.hide_message(); - $('
') - .html('

' - +text+'
').appendTo(document.body); - }, - hide_message: function(text) { - $('.message-overlay').remove(); - }, call: function(opts) { wn.prepare_call(opts); $.ajax({ @@ -106,6 +96,26 @@ wn = { get_sid: function() { var sid = getCookie("sid"); return sid && sid!=="Guest"; + }, + get_modal: function(title, body_html) { + var modal = $('').appendTo(document.body); + + return modal; + }, + msgprint: function(html, title) { + return wn.get_modal(title || "Message", html).modal("show"); } } @@ -235,4 +245,5 @@ wn.send_message = function(opts, btn) { args: opts, callback: opts.callback }); -} \ No newline at end of file +} + diff --git a/website/templates/includes/login.js b/website/templates/includes/login.js index 1d0e3339fb..a05c339c07 100644 --- a/website/templates/includes/login.js +++ b/website/templates/includes/login.js @@ -27,7 +27,7 @@ login.do_login = function(){ return false; } } else if(window.is_forgot) { - args.cmd = "reset_password"; + args.cmd = "core.doctype.profile.profile.reset_password"; args.user = ($("#login_id").val() || "").trim(); if(!args.user) { diff --git a/website/templates/pages/update-password.html b/website/templates/pages/update-password.html new file mode 100644 index 0000000000..a05fb8ca42 --- /dev/null +++ b/website/templates/pages/update-password.html @@ -0,0 +1,69 @@ +{% extends base_template %} + +{% block content %} +
+
+
+
+
+

Reset Password

+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+ + +{% endblock %} \ No newline at end of file