瀏覽代碼

[password] reset via link, added update page for portal user

version-14
Rushabh Mehta 12 年之前
父節點
當前提交
3eab31b9a9
共有 8 個檔案被更改,包括 179 行新增55 行删除
  1. +74
    -17
      core/doctype/profile/profile.py
  2. +10
    -1
      core/doctype/profile/profile.txt
  3. +1
    -1
      webnotes/auth.py
  4. +0
    -23
      webnotes/handler.py
  5. +2
    -1
      webnotes/webutils.py
  6. +22
    -11
      website/js/website.js
  7. +1
    -1
      website/templates/includes/login.js
  8. +69
    -0
      website/templates/pages/update-password.html

+ 74
- 17
core/doctype/profile/profile.py 查看文件

@@ -85,8 +85,8 @@ class DocType:
def update_new_password(self): def update_new_password(self):
"""update new password if set""" """update new password if set"""
if self.doc.new_password: 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: if self.in_insert:
webnotes.msgprint("New user created. - %s" % self.doc.name) webnotes.msgprint("New user created. - %s" % self.doc.name)
@@ -94,11 +94,18 @@ class DocType:
self.send_welcome_mail(self.doc.new_password) self.send_welcome_mail(self.doc.new_password)
webnotes.msgprint("Sent welcome mail.") webnotes.msgprint("Sent welcome mail.")
else: 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', '') 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): def get_other_system_managers(self):
return webnotes.conn.sql("""select distinct parent from tabUserRole user_role return webnotes.conn.sql("""select distinct parent from tabUserRole user_role
where role='System Manager' and docstatus<2 where role='System Manager' and docstatus<2
@@ -111,25 +118,37 @@ class DocType:
return (self.doc.first_name or '') + \ return (self.doc.first_name or '') + \
(self.doc.first_name and " " or '') + (self.doc.last_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""" """reset password"""
txt = """ txt = """
## Password Reset ## Password Reset


Dear %(first_name)s, 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
<a href="%(link)s">%(link)s</a>


To login to %(product)s, please go to:
Thank you,<br>
%(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,<br> Thank you,<br>
%(user_fullname)s %(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): def send_welcome_mail(self, password):
"""send welcome mail to user with password and login url""" """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,<br> Thank you,<br>
%(user_fullname)s %(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""" """send mail with login details"""
import os import os
@@ -168,13 +188,14 @@ Thank you,<br>
args = { args = {
'first_name': self.doc.first_name or self.doc.last_name or "user", 'first_name': self.doc.first_name or self.doc.last_name or "user",
'user': self.doc.name, 'user': self.doc.name,
'password': password,
'company': webnotes.conn.get_default('company') or webnotes.get_config().get("app_name"), 'company': webnotes.conn.get_default('company') or webnotes.get_config().get("app_name"),
'login_url': get_request_site_address(), 'login_url': get_request_site_address(),
'product': webnotes.get_config().get("app_name"), 'product': webnotes.get_config().get("app_name"),
'user_fullname': full_name 'user_fullname': full_name
} }
args.update(add_args)
sender = webnotes.session.user not in ("Administrator", "Guest") and webnotes.session.user or None 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) 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 webnotes.add_cookies["full_name"] = fullname
if password: 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") 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) @webnotes.whitelist(allow_guest=True)
def sign_up(email, full_name): def sign_up(email, full_name):
@@ -331,7 +373,22 @@ def sign_up(email, full_name):
profile.ignore_permissions = True profile.ignore_permissions = True
profile.insert() profile.insert()
return _("Registration Details Emailed.") 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): def profile_query(doctype, txt, searchfield, start, page_len, filters):
from webnotes.widgets.reportview import get_match_cond from webnotes.widgets.reportview import get_match_cond
return webnotes.conn.sql("""select name, concat_ws(' ', first_name, middle_name, last_name) return webnotes.conn.sql("""select name, concat_ws(' ', first_name, middle_name, last_name)


+ 10
- 1
core/doctype/profile/profile.txt 查看文件

@@ -2,7 +2,7 @@
{ {
"creation": "2013-03-07 11:54:44", "creation": "2013-03-07 11:54:44",
"docstatus": 0, "docstatus": 0,
"modified": "2013-09-06 12:10:25",
"modified": "2013-09-16 14:47:47",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@@ -177,6 +177,15 @@
"no_copy": 1, "no_copy": 1,
"print_hide": 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", "depends_on": "eval:!doc.__islocal",
"doctype": "DocField", "doctype": "DocField",


+ 1
- 1
webnotes/auth.py 查看文件

@@ -263,7 +263,7 @@ class CookieManager:
webnotes.cookies[k][b'expires'] = expires.encode('utf-8') 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`) webnotes.conn.sql("""insert into __Auth (user, `password`)
values (%s, password(%s)) values (%s, password(%s))
on duplicate key update `password`=password(%s)""", (user, on duplicate key update `password`=password(%s)""", (user,


+ 0
- 23
webnotes/handler.py 查看文件

@@ -76,29 +76,6 @@ def uploadfile():
ret = None ret = None


return ret 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(): def handle():
"""handle request""" """handle request"""


+ 2
- 1
webnotes/webutils.py 查看文件

@@ -205,7 +205,8 @@ def get_website_settings():
"webnotes": webnotes, "webnotes": webnotes,
"utils": webnotes.utils, "utils": webnotes.utils,
"post_login": [ "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"}
] ]
}) })


+ 22
- 11
website/js/website.js 查看文件

@@ -4,16 +4,6 @@ if(!window.wn) wn = {};




wn = { wn = {
show_message: function(text, icon) {
if(!icon) icon="icon-refresh icon-spin";
treemapper.hide_message();
$('<div class="message-overlay"></div>')
.html('<div class="content"><i class="'+icon+' text-muted"></i><br>'
+text+'</div>').appendTo(document.body);
},
hide_message: function(text) {
$('.message-overlay').remove();
},
call: function(opts) { call: function(opts) {
wn.prepare_call(opts); wn.prepare_call(opts);
$.ajax({ $.ajax({
@@ -106,6 +96,26 @@ wn = {
get_sid: function() { get_sid: function() {
var sid = getCookie("sid"); var sid = getCookie("sid");
return sid && sid!=="Guest"; return sid && sid!=="Guest";
},
get_modal: function(title, body_html) {
var modal = $('<div class="modal" style="overflow: auto;">\
<div class="modal-dialog">\
<div class="modal-content">\
<div class="modal-header">\
<a type="button" class="close" \
data-dismiss="modal" aria-hidden="true">&times;</a>\
<h4 class="modal-title">'+title+'</h4>\
</div>\
<div class="modal-body ui-front">'+body_html+'\
</div>\
</div>\
</div>\
</div>').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, args: opts,
callback: opts.callback callback: opts.callback
}); });
}
}


+ 1
- 1
website/templates/includes/login.js 查看文件

@@ -27,7 +27,7 @@ login.do_login = function(){
return false; return false;
} }
} else if(window.is_forgot) { } else if(window.is_forgot) {
args.cmd = "reset_password";
args.cmd = "core.doctype.profile.profile.reset_password";
args.user = ($("#login_id").val() || "").trim(); args.user = ($("#login_id").val() || "").trim();
if(!args.user) { if(!args.user) {


+ 69
- 0
website/templates/pages/update-password.html 查看文件

@@ -0,0 +1,69 @@
{% extends base_template %}

{% block content %}
<div style="max-width: 750px;">
<div class="row" style="margin-top: 40px; margin-bottom: 20px">
<div class="col-sm-offset-3 col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h4><i class="icon-key"></i> Reset Password</h4>
</div>
<div class="panel-body">
<div class="form-group">
<input id="old_password" type="password"
class="form-control" placeholder="Old Password">
</div>
<div class="form-group">
<input id="new_password" type="password"
class="form-control" placeholder="New Password">
</div>
<div class="form-group">
<button type="submit" id="update"
class="btn btn-primary">Update</button>
</div>
</div>
</div>
</div>
</div>
</div>

<script>

$(document).ready(function() {
if(get_url_arg("key")) {
$("#old_password").parent().toggle(false);
}
$("#update").click(function() {
var args = {
key: get_url_arg("key") || "",
old_password: $("#old_password").val(),
new_password: $("#new_password").val()
}
if(!args.old_password && !args.key) {
wn.msgprint("Old Password Required.");
return;
}
if(!args.new_password) {
wn.msgprint("New Password Required.")
return;
}
wn.call({
type: "POST",
method: "core.doctype.profile.profile.update_password",
btn: $("#update"),
args: args,
callback: function(r) {
if(r.message) {
$("input").val("");
wn.msgprint(r.message);
}
}
})
})
});

</script>
{% endblock %}

Loading…
取消
儲存