From a6325e0744e8852722783c20111400f8f9fe6dd2 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Wed, 4 Dec 2024 16:33:12 +0000 Subject: [PATCH 1/2] Refactor already-signed-in check into a decorator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It makes sense for this check-and-redirect code to be a decorator because: - it’s checking a similar thing to other decorators like `is_platform_admin` - it’s repeated in 2 places and by making it a decorator we can reuse it --- app/main/views/register.py | 6 ++---- app/main/views/sign_in.py | 7 ++----- app/main/views/two_factor.py | 6 ++---- app/utils/login.py | 17 +++++++++++++++-- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/app/main/views/register.py b/app/main/views/register.py index df250cfd32..01a1538052 100644 --- a/app/main/views/register.py +++ b/app/main/views/register.py @@ -1,7 +1,6 @@ from datetime import datetime, timedelta from flask import abort, redirect, render_template, session, url_for -from flask_login import current_user from app.main import main from app.main.forms import ( @@ -12,14 +11,13 @@ from app.main.views.verify import activate_user from app.models.user import InvitedOrgUser, InvitedUser, User from app.utils import hide_from_search_engines +from app.utils.login import redirect_if_logged_in @main.route("/register", methods=["GET", "POST"]) @hide_from_search_engines +@redirect_if_logged_in def register(): - if current_user and current_user.is_authenticated: - return redirect(url_for("main.show_accounts_or_dashboard")) - form = RegisterUserForm() if form.validate_on_submit(): _do_registration(form, send_sms=False) diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py index 1a17a2f49c..e58f17e9ec 100644 --- a/app/main/views/sign_in.py +++ b/app/main/views/sign_in.py @@ -19,17 +19,14 @@ from app.models.user import InvitedUser, User from app.utils import hide_from_search_engines from app.utils.constants import JSON_UPDATES_BLUEPRINT_NAME -from app.utils.login import is_safe_redirect_url +from app.utils.login import redirect_if_logged_in @main.route("/sign-in", methods=(["GET", "POST"])) @hide_from_search_engines +@redirect_if_logged_in def sign_in(): # noqa: C901 redirect_url = request.args.get("next") - if current_user and current_user.is_authenticated: - if redirect_url and is_safe_redirect_url(redirect_url): - return redirect(redirect_url) - return redirect(url_for("main.show_accounts_or_dashboard")) form = LoginForm() password_reset_url = url_for(".forgot_password", next=request.args.get("next")) diff --git a/app/main/views/two_factor.py b/app/main/views/two_factor.py index 02d03f226f..62b2f298ea 100644 --- a/app/main/views/two_factor.py +++ b/app/main/views/two_factor.py @@ -7,7 +7,6 @@ session, url_for, ) -from flask_login import current_user from itsdangerous import SignatureExpired from notifications_utils.url_safe_token import check_token @@ -19,8 +18,8 @@ from app.utils.login import ( email_needs_revalidating, log_in_user, + redirect_if_logged_in, redirect_to_sign_in, - redirect_when_logged_in, ) @@ -36,10 +35,9 @@ def two_factor_email_interstitial(token): @main.route("/email-auth/", methods=["POST"]) +@redirect_if_logged_in def two_factor_email(token): redirect_url = request.args.get("next") - if current_user.is_authenticated: - return redirect_when_logged_in(platform_admin=current_user.platform_admin) # checks url is valid, and hasn't timed out try: diff --git a/app/utils/login.py b/app/utils/login.py index 43c9c63272..67459c43b6 100644 --- a/app/utils/login.py +++ b/app/utils/login.py @@ -32,10 +32,10 @@ def log_in_user(user_id): session.pop("user_details", None) session.pop("file_uploads", None) - return redirect_when_logged_in(platform_admin=user.platform_admin) + return redirect_when_logged_in() -def redirect_when_logged_in(platform_admin): +def redirect_when_logged_in(): next_url = request.args.get("next") if next_url and is_safe_redirect_url(next_url): return redirect(next_url) @@ -43,6 +43,19 @@ def redirect_when_logged_in(platform_admin): return redirect(url_for("main.show_accounts_or_dashboard")) +def redirect_if_logged_in(f): + from app import current_user + + @wraps(f) + def wrapped(*args, **kwargs): + if current_user and current_user.is_authenticated: + return redirect_when_logged_in() + else: + return f(*args, **kwargs) + + return wrapped + + def email_needs_revalidating(user): return not is_less_than_days_ago(user.email_access_validated_at, 90) From c5cc8f6d353d54d99f0e7aa6d1bad0c7f1590238 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Wed, 4 Dec 2024 16:34:36 +0000 Subject: [PATCH 2/2] Remove complexity warning By removing some code we have snuck the complexity level of this code within the limit of 10, so it passes `ruff` now --- app/main/views/sign_in.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py index e58f17e9ec..3e8ef4e73a 100644 --- a/app/main/views/sign_in.py +++ b/app/main/views/sign_in.py @@ -25,7 +25,7 @@ @main.route("/sign-in", methods=(["GET", "POST"])) @hide_from_search_engines @redirect_if_logged_in -def sign_in(): # noqa: C901 +def sign_in(): redirect_url = request.args.get("next") form = LoginForm()