Merge pull request #16262 from RAJKRIS/develop
This commit is contained in:
commit
58e779f0a3
4 changed files with 56 additions and 9 deletions
|
|
@ -43,6 +43,7 @@
|
|||
"password_settings",
|
||||
"logout_on_password_reset",
|
||||
"force_user_to_reset_password",
|
||||
"reset_password_link_expiry_duration",
|
||||
"password_reset_limit",
|
||||
"column_break_31",
|
||||
"enable_password_policy",
|
||||
|
|
@ -495,12 +496,19 @@
|
|||
"fieldname": "disable_change_log_notification",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable Change Log Notification"
|
||||
},
|
||||
{
|
||||
"default": "1200",
|
||||
"fieldname": "reset_password_link_expiry_duration",
|
||||
"fieldtype": "Duration",
|
||||
"label": "Reset Password Link Expiry Duration",
|
||||
"non_negative": 1
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-cog",
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2022-05-09 18:53:35.218721",
|
||||
"modified": "2022-05-19 00:00:18.095269",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "System Settings",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: MIT. See LICENSE
|
||||
import json
|
||||
import time
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
|
|
@ -256,7 +257,8 @@ class TestUser(unittest.TestCase):
|
|||
<span class="mention" data-id="Team" data-value="Team" data-is-group="true" data-denotation-char="@">
|
||||
<span><span class="ql-mention-denotation-char">@</span>Team</span>
|
||||
</span> and
|
||||
<span class="mention" data-id="Unknown Team" data-value="Unknown Team" data-is-group="true" data-denotation-char="@">
|
||||
<span class="mention" data-id="Unknown Team" data-value="Unknown Team" data-is-group="true"
|
||||
data-denotation-char="@">
|
||||
<span><span class="ql-mention-denotation-char">@</span>Unknown Team</span>
|
||||
</span><!-- this should be ignored-->
|
||||
please check
|
||||
|
|
@ -365,7 +367,7 @@ class TestUser(unittest.TestCase):
|
|||
self.assertEqual(update_password(new_password, key=test_user.reset_password_key), "/app")
|
||||
self.assertEqual(
|
||||
update_password(new_password, key="wrong_key"),
|
||||
"The Link specified has either been used before or Invalid",
|
||||
"The reset password link has either been used before or is invalid",
|
||||
)
|
||||
|
||||
# password verification should fail with old password
|
||||
|
|
@ -374,7 +376,6 @@ class TestUser(unittest.TestCase):
|
|||
|
||||
# reset password
|
||||
update_password(old_password, old_password=new_password)
|
||||
|
||||
self.assertRaisesRegex(
|
||||
frappe.exceptions.ValidationError, "Invalid key type", update_password, "test", 1, ["like", "%"]
|
||||
)
|
||||
|
|
@ -434,6 +435,21 @@ class TestUser(unittest.TestCase):
|
|||
[m.get("module_name") for m in get_modules_from_all_apps()],
|
||||
)
|
||||
|
||||
def test_reset_password_link_expiry(self):
|
||||
new_password = "new_password"
|
||||
# set the reset password expiry to 1 second
|
||||
frappe.db.set_value(
|
||||
"System Settings", "System Settings", "reset_password_link_expiry_duration", 1
|
||||
)
|
||||
frappe.set_user("testpassword@example.com")
|
||||
test_user = frappe.get_doc("User", "testpassword@example.com")
|
||||
test_user.reset_password()
|
||||
time.sleep(1) # sleep for 1 sec to expire the reset link
|
||||
self.assertEqual(
|
||||
update_password(new_password, key=test_user.reset_password_key),
|
||||
"The reset password link has been expired",
|
||||
)
|
||||
|
||||
|
||||
def delete_contact(user):
|
||||
frappe.db.delete("Contact", {"email_id": user})
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"new_password",
|
||||
"logout_all_sessions",
|
||||
"reset_password_key",
|
||||
"last_reset_password_key_generated_on",
|
||||
"last_password_reset_date",
|
||||
"redirect_url",
|
||||
"document_follow_notifications_section",
|
||||
|
|
@ -613,6 +614,14 @@
|
|||
"label": "Module Profile",
|
||||
"options": "Module Profile"
|
||||
},
|
||||
{
|
||||
"description": "Stores the datetime when the last reset password key was generated.",
|
||||
"fieldname": "last_reset_password_key_generated_on",
|
||||
"fieldtype": "Datetime",
|
||||
"hidden": 1,
|
||||
"label": "Last Reset Password Key Generated On",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_75",
|
||||
"fieldtype": "Column Break"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: MIT. See LICENSE
|
||||
from datetime import timedelta
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
import frappe
|
||||
|
|
@ -276,6 +278,7 @@ class User(Document):
|
|||
|
||||
key = random_string(32)
|
||||
self.db_set("reset_password_key", key)
|
||||
self.db_set("last_reset_password_key_generated_on", now_datetime())
|
||||
|
||||
url = "/update-password?key=" + key
|
||||
if password_expired:
|
||||
|
|
@ -780,16 +783,27 @@ def _get_user_for_update_password(key, old_password):
|
|||
# verify old password
|
||||
result = frappe._dict()
|
||||
if key:
|
||||
result.user = frappe.db.get_value("User", {"reset_password_key": key})
|
||||
if not result.user:
|
||||
result.message = _("The Link specified has either been used before or Invalid")
|
||||
|
||||
user = frappe.db.get_value(
|
||||
"User", {"reset_password_key": key}, ["name", "last_reset_password_key_generated_on"]
|
||||
)
|
||||
result.user, last_reset_password_key_generated_on = user or (None, None)
|
||||
if result.user:
|
||||
reset_password_link_expiry = cint(
|
||||
frappe.db.get_single_value("System Settings", "reset_password_link_expiry_duration")
|
||||
)
|
||||
if (
|
||||
reset_password_link_expiry
|
||||
and now_datetime()
|
||||
> last_reset_password_key_generated_on + timedelta(seconds=reset_password_link_expiry)
|
||||
):
|
||||
result.message = _("The reset password link has been expired")
|
||||
else:
|
||||
result.message = _("The reset password link has either been used before or is invalid")
|
||||
elif old_password:
|
||||
# verify old password
|
||||
frappe.local.login_manager.check_password(frappe.session.user, old_password)
|
||||
user = frappe.session.user
|
||||
result.user = user
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue