Merge pull request #37554 from AarDG10/refactor-password
refactor(user): misc. fixes and refactors
This commit is contained in:
commit
0122b49ef6
4 changed files with 63 additions and 27 deletions
|
|
@ -155,7 +155,9 @@ class LoginManager:
|
|||
self.authenticate(user=user, pwd=pwd)
|
||||
if self.force_user_to_reset_password():
|
||||
doc = frappe.get_doc("User", self.user)
|
||||
frappe.local.response["redirect_to"] = doc.reset_password(send_email=False, password_expired=True)
|
||||
frappe.local.response["redirect_to"] = doc._reset_password(
|
||||
send_email=False, password_expired=True
|
||||
)
|
||||
frappe.local.response["message"] = "Password Reset"
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ def _accept_invitation(key: str, in_test: bool) -> None:
|
|||
# set redirect_to
|
||||
redirect_to = frappe.utils.get_url(invitation.get_redirect_to_path())
|
||||
if should_update_password:
|
||||
redirect_to = f"{user.reset_password()}&redirect_to=/{invitation.get_redirect_to_path()}"
|
||||
redirect_to = f"{user._reset_password()}&redirect_to=/{invitation.get_redirect_to_path()}"
|
||||
|
||||
# GET requests do not cause an implicit commit
|
||||
frappe.db.commit() # nosemgrep
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class TestUser(IntegrationTestCase):
|
|||
|
||||
@staticmethod
|
||||
def reset_password(user) -> str:
|
||||
link = user.reset_password()
|
||||
link = user._reset_password()
|
||||
return parse_qs(urlparse(link).query)["key"][0]
|
||||
|
||||
def test_user_type(self):
|
||||
|
|
@ -415,6 +415,12 @@ class TestUser(IntegrationTestCase):
|
|||
|
||||
# test API endpoint
|
||||
with patch.object(user_module.frappe, "sendmail") as sendmail:
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
mock_q = MagicMock()
|
||||
mock_q.name = "test-email-queue-name"
|
||||
mock_q.message = "Subject: Test\n\nDear User, here is your link"
|
||||
sendmail.return_value = mock_q
|
||||
frappe.clear_messages()
|
||||
test_user = frappe.get_doc("User", "test2@example.com")
|
||||
self.assertEqual(reset_password(user="test2@example.com"), None)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: MIT. See LICENSE
|
||||
|
||||
import re
|
||||
from collections.abc import Iterable
|
||||
from datetime import timedelta
|
||||
from functools import cached_property
|
||||
|
|
@ -376,9 +377,23 @@ class User(Document):
|
|||
toggle_notifications(self.name, enable=cint(self.enabled), ignore_permissions=True)
|
||||
self.disable_email_fields_if_user_disabled()
|
||||
|
||||
def email_new_password(self, new_password=None):
|
||||
def set_new_password(self, new_password=None):
|
||||
"""Set New Password for user"""
|
||||
if new_password and not self.flags.in_insert:
|
||||
_update_password(user=self.name, pwd=new_password, logout_all_sessions=self.logout_all_sessions)
|
||||
outgoing_email_exists = frappe.db.exists(
|
||||
"Email Account", {"default_outgoing": 1, "awaiting_password": 0}
|
||||
)
|
||||
if outgoing_email_exists:
|
||||
email_message = _(
|
||||
"Your password has been changed and you might have been logged out of all systems.<br>Please contact the Administrator for further assistance."
|
||||
)
|
||||
user_email = frappe.db.get_value("User", self.name, "email")
|
||||
frappe.sendmail(
|
||||
recipients=[user_email],
|
||||
subject=_("Security Alert: Your password has been changed."),
|
||||
content=email_message,
|
||||
)
|
||||
|
||||
def set_system_user(self):
|
||||
"""For the standard users like admin and guest, the user type is fixed."""
|
||||
|
|
@ -433,25 +448,26 @@ class User(Document):
|
|||
def send_password_notification(self, new_password):
|
||||
try:
|
||||
if self.flags.in_insert:
|
||||
if self.name not in STANDARD_USERS:
|
||||
if new_password:
|
||||
# new password given, no email required
|
||||
_update_password(
|
||||
user=self.name, pwd=new_password, logout_all_sessions=self.logout_all_sessions
|
||||
)
|
||||
if self.name in STANDARD_USERS:
|
||||
return
|
||||
if new_password:
|
||||
# new password given, no email required
|
||||
_update_password(
|
||||
user=self.name, pwd=new_password, logout_all_sessions=self.logout_all_sessions
|
||||
)
|
||||
|
||||
if (
|
||||
not self.flags.no_welcome_mail
|
||||
and cint(self.send_welcome_email)
|
||||
and not self.flags.email_sent
|
||||
):
|
||||
self.send_welcome_mail_to_user()
|
||||
self.flags.email_sent = 1
|
||||
if frappe.session.user != "Guest":
|
||||
msgprint(_("Welcome email sent"))
|
||||
return
|
||||
if (
|
||||
not self.flags.no_welcome_mail
|
||||
and cint(self.send_welcome_email)
|
||||
and not self.flags.email_sent
|
||||
):
|
||||
self.send_welcome_mail_to_user()
|
||||
self.flags.email_sent = 1
|
||||
if frappe.session.user != "Guest":
|
||||
msgprint(_("Welcome email sent"))
|
||||
return
|
||||
else:
|
||||
self.email_new_password(new_password)
|
||||
self.set_new_password(new_password)
|
||||
|
||||
except frappe.OutgoingEmailError:
|
||||
frappe.clear_last_message()
|
||||
|
|
@ -465,7 +481,7 @@ class User(Document):
|
|||
def validate_reset_password(self):
|
||||
pass
|
||||
|
||||
def reset_password(self, send_email=False, password_expired=False):
|
||||
def _reset_password(self, send_email=False, password_expired=False):
|
||||
from frappe.utils import get_url
|
||||
|
||||
key = frappe.generate_hash()
|
||||
|
|
@ -490,18 +506,24 @@ class User(Document):
|
|||
def password_reset_mail(self, link):
|
||||
reset_password_template = frappe.db.get_system_setting("reset_password_template")
|
||||
|
||||
self.send_login_mail(
|
||||
q = self.send_login_mail(
|
||||
_("Password Reset"),
|
||||
"password_reset",
|
||||
{"link": link},
|
||||
now=True,
|
||||
custom_template=reset_password_template,
|
||||
)
|
||||
if q:
|
||||
raw_message = q.message
|
||||
parts = re.split(r"(?i)Dear", raw_message, maxsplit=1)
|
||||
if len(parts) > 1:
|
||||
redacted_message = parts[0] + "[THE FOLLOWING CONTENT HAS BEEN REDACTED FOR SECURITY REASONS]"
|
||||
frappe.db.set_value("Email Queue", q.name, "message", redacted_message, update_modified=False)
|
||||
|
||||
def send_welcome_mail_to_user(self):
|
||||
from frappe.utils import get_url
|
||||
|
||||
link = self.reset_password()
|
||||
link = self._reset_password()
|
||||
subject = None
|
||||
method = frappe.get_hooks("welcome_email")
|
||||
if method:
|
||||
|
|
@ -515,7 +537,7 @@ class User(Document):
|
|||
|
||||
welcome_email_template = frappe.db.get_system_setting("welcome_email_template")
|
||||
|
||||
self.send_login_mail(
|
||||
q = self.send_login_mail(
|
||||
subject,
|
||||
"new_user",
|
||||
dict(
|
||||
|
|
@ -524,6 +546,12 @@ class User(Document):
|
|||
),
|
||||
custom_template=welcome_email_template,
|
||||
)
|
||||
if q:
|
||||
raw_message = q.message
|
||||
parts = re.split(r"(?i)Hello", raw_message, maxsplit=1)
|
||||
if len(parts) > 1:
|
||||
redacted_message = parts[0] + "[THE FOLLOWING CONTENT HAS BEEN REDACTED FOR SECURITY REASONS]"
|
||||
frappe.db.set_value("Email Queue", q.name, "message", redacted_message, update_modified=False)
|
||||
|
||||
def send_login_mail(self, subject, template, add_args, now=None, custom_template=None):
|
||||
"""send mail with login details"""
|
||||
|
|
@ -555,7 +583,7 @@ class User(Document):
|
|||
subject = email_template.get("subject")
|
||||
content = email_template.get("message")
|
||||
|
||||
frappe.sendmail(
|
||||
return frappe.sendmail(
|
||||
recipients=self.email,
|
||||
sender=sender,
|
||||
subject=subject,
|
||||
|
|
@ -1135,7 +1163,7 @@ def reset_password(user: str) -> str:
|
|||
return "disabled"
|
||||
|
||||
user.validate_reset_password()
|
||||
user.reset_password(send_email=True)
|
||||
user._reset_password(send_email=True)
|
||||
|
||||
return frappe.msgprint(
|
||||
msg=_("Password reset instructions have been sent to {}'s email").format(user.full_name),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue