Merge pull request #16262 from RAJKRIS/develop

This commit is contained in:
Suraj Shetty 2022-05-19 11:06:37 +05:30 committed by GitHub
commit 58e779f0a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 9 deletions

View file

@ -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",

View file

@ -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})

View file

@ -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"

View file

@ -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