From eb7293c1d254e491086310f68b3201761ca3e91f Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Tue, 20 Dec 2022 18:21:22 +0530 Subject: [PATCH] fix: suggested changes and added passwordless_login_expiry option rate limit, better description, redirect_post_login, removed subject --- .../doctype/system_settings/system_settings.json | 12 ++++++++++-- frappe/www/login.py | 15 ++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index bd4051cba4..0765bb4333 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -40,6 +40,7 @@ "allow_login_using_user_name", "disable_user_pass_login", "passwordless_login", + "passwordless_login_expiry", "allow_error_traceback", "strip_exif_metadata_from_uploaded_images", "allow_older_web_view_links", @@ -508,16 +509,23 @@ }, { "default": "0", - "description": "User will be able to login using the link sent on the email", + "description": "Allow users to log in without a password, using a login link sent to their email", "fieldname": "passwordless_login", "fieldtype": "Check", "label": "Passwordless Login" + }, + { + "default": "10", + "depends_on": "passwordless_login", + "fieldname": "passwordless_login_expiry", + "fieldtype": "Int", + "label": "Passwordless Login Link Expiry (in minutes)" } ], "icon": "fa fa-cog", "issingle": 1, "links": [], - "modified": "2022-12-20 15:39:31.751704", + "modified": "2022-12-20 18:17:31.759701", "modified_by": "Administrator", "module": "Core", "name": "System Settings", diff --git a/frappe/www/login.py b/frappe/www/login.py index 037f89438d..763028e567 100644 --- a/frappe/www/login.py +++ b/frappe/www/login.py @@ -7,6 +7,7 @@ from frappe import _ from frappe.auth import LoginManager from frappe.integrations.doctype.ldap_settings.ldap_settings import LDAPSettings from frappe.integrations.oauth2_logins import decoder_compat +from frappe.rate_limiter import rate_limit from frappe.utils import cint, get_url from frappe.utils.html_utils import get_icon_html from frappe.utils.jinja import guess_is_path @@ -148,14 +149,15 @@ def login_via_token(login_token): @frappe.whitelist(allow_guest=True) -def send_login_link(email: str, subject: str | None = None): +@rate_limit(limit=5, seconds=60 * 60) +def send_login_link(email: str): if not frappe.db.exists("User", email): frappe.throw( _("User with email address {0} does not exist").format(email), frappe.DoesNotExistError ) key = frappe.generate_hash("Login Link", 20) - minutes = 10 + minutes = frappe.get_system_settings("passwordless_login_expiry") or 10 frappe.cache().set_value(f"one_time_login_key:{key}", email, expires_in_sec=minutes * 60) link = get_url(f"/api/method/frappe.www.login.login_via_key?key={key}") @@ -164,13 +166,14 @@ def send_login_link(email: str, subject: str | None = None): frappe.get_website_settings("app_name") or frappe.get_system_settings("app_name") or _("Frappe") ) - subject = subject or _("Login To {0}").format(app_name) + subject = _("Login To {0}").format(app_name) frappe.sendmail( subject=subject, recipients=email, template="passwordless_login", args={"link": link, "minutes": minutes, "app_name": app_name}, + now=True, ) @@ -182,8 +185,10 @@ def login_via_key(key: str): if email: frappe.cache().delete_value(cache_key) frappe.local.login_manager.login_as(email) - frappe.response.type = "redirect" - frappe.response.location = "/app" + + redirect_post_login( + desk_user=frappe.db.get_value("User", frappe.session.user, "user_type") == "System User" + ) else: frappe.respond_as_web_page( _("Not Permitted"),