diff --git a/frappe/auth.py b/frappe/auth.py index b9276ad186..0597e7d59e 100644 --- a/frappe/auth.py +++ b/frappe/auth.py @@ -10,7 +10,7 @@ import frappe.database import frappe.utils import frappe.utils.user from frappe import conf -from frappe.sessions import Session +from frappe.sessions import Session, clear_sessions, delete_session from frappe.modules.patch_handler import check_session_stopped class HTTPRequest: @@ -187,15 +187,12 @@ class LoginManager: def logout(self, arg='', user=None): if not user: user = frappe.session.user self.run_trigger('on_logout') - if user in ['demo@erpnext.com', 'Administrator']: - frappe.db.sql('delete from tabSessions where sid=%s', frappe.session.get('sid')) - frappe.cache().delete_value("session:" + frappe.session.get("sid")) - else: - from frappe.sessions import clear_sessions - clear_sessions(user) if user == frappe.session.user: + delete_session(frappe.session.sid) self.clear_cookies() + else: + clear_sessions(user) def clear_cookies(self): clear_cookies() diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 622aa09db1..4af36bfa82 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -94,11 +94,15 @@ class User(Document): self.user_image = "https://secure.gravatar.com/avatar/" + md5.md5(self.name).hexdigest() \ + "?d=retro" + @Document.hook + def validate_reset_password(self): + pass + def reset_password(self): from frappe.utils import random_string, get_url key = random_string(32) - frappe.db.set_value("User", self.name, "reset_password_key", key) + self.db_set("reset_password_key", key) self.password_reset_mail(get_url("/update-password?key=" + key)) def get_other_system_managers(self): @@ -314,18 +318,18 @@ def sign_up(email, full_name): @frappe.whitelist(allow_guest=True) def reset_password(user): - user = frappe.form_dict.get('user', '') - if user in ["demo@erpnext.com", "Administrator"]: - return "Not allowed" + if user=="Administrator": + return _("Not allowed to reset the password of {0}").format(user) - if frappe.db.sql("""select name from tabUser where name=%s""", (user,)): - # Hack! - frappe.session["user"] = "Administrator" + try: user = frappe.get_doc("User", user) + user.validate_reset_password() user.reset_password() - return "Password reset details sent to your email." - else: - return "No such user (%s)" % user + + return _("Password reset instructions have been sent to your email") + + except frappe.DoesNotExistError: + return _("User {0} does not exist").format(user) def user_query(doctype, txt, searchfield, start, page_len, filters): from frappe.widgets.reportview import get_match_cond diff --git a/frappe/model/document.py b/frappe/model/document.py index 547630c332..4abf03db04 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -57,7 +57,7 @@ class Document(BaseDocument): # filter self.name = frappe.db.get_value(arg1, arg2, "name") if self.name is None: - raise frappe.DoesNotExistError + raise frappe.DoesNotExistError, (arg1, arg2) else: self.name = arg2 diff --git a/frappe/sessions.py b/frappe/sessions.py index c563259ded..48e02f3eec 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -73,6 +73,10 @@ def clear_sessions(user=None, keep_current=False): frappe.cache().delete_value("session:" + sid[0]) frappe.db.sql("""delete from tabSessions where sid=%s""", (sid[0],)) +def delete_session(sid=None): + frappe.cache().delete_value("session:" + sid) + frappe.db.sql("""delete from tabSessions where sid=%s""", sid) + def get(): """get session boot info""" from frappe.core.doctype.notification_count.notification_count import \ @@ -224,8 +228,7 @@ class Session: return (cint(parts[0]) * 3600) + (cint(parts[1]) * 60) + cint(parts[2]) def delete_session(self): - frappe.cache().delete_value("session:" + self.sid) - frappe.db.sql("""delete from tabSessions where sid=%s""", (self.sid,)) + delete_session(self.sid) def start_as_guest(self): """all guests share the same 'Guest' session""" diff --git a/frappe/templates/includes/login.js b/frappe/templates/includes/login.js index 120c9486e3..e79af5dfad 100644 --- a/frappe/templates/includes/login.js +++ b/frappe/templates/includes/login.js @@ -17,7 +17,7 @@ login.bind_events = function() { if(!args.usr || !args.pwd) { frappe.msgprint(__("Both login and password required")); return false; - } + } login.call(args); }); @@ -85,30 +85,40 @@ login.call = function(args) { }) } -login.login_handlers = { - 200: function(data) { - if(data.message=="Logged In") { - window.location.href = "desk"; - } else if(data.message=="No App") { - if(localStorage) { - var last_visited = localStorage.getItem("last_visited") || "/index"; - localStorage.removeItem("last_visited"); - window.location.href = last_visited; - } else { - window.location.href = "/index"; +login.login_handlers = (function() { + var get_error_handler = function(default_message) { + return function(xhr, data) { + if(xhr.responseJSON) { + data = xhr.responseJSON; } - } else if(["#signup", "#forgot"].indexOf(window.location.hash)!==-1) { - frappe.msgprint(data.message); - } - }, - 401: function(xhr, data) { - if(xhr.responseJSON) { - data = xhr.responseJSON; - } - var message = data._server_messages ? JSON.parse(data._server_messages).join("\n") : __("Invalid Login"); - frappe.msgprint(message); + var message = data._server_messages + ? JSON.parse(data._server_messages).join("\n") : default_message; + frappe.msgprint(message); + }; } -} + + var login_handlers = { + 200: function(data) { + if(data.message=="Logged In") { + window.location.href = "desk"; + } else if(data.message=="No App") { + if(localStorage) { + var last_visited = localStorage.getItem("last_visited") || "/index"; + localStorage.removeItem("last_visited"); + window.location.href = last_visited; + } else { + window.location.href = "/index"; + } + } else if(["#signup", "#forgot"].indexOf(window.location.hash)!==-1) { + frappe.msgprint(data.message); + } + }, + 401: get_error_handler(__("Invalid Login")), + 417: get_error_handler(__("Oops! Something went wrong")) + }; + + return login_handlers; +})(); frappe.ready(function() { window.location.hash = "#login";