From e2bcefce9a3f77a86542cb41d53a82ce2dcdc2ad Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Tue, 17 Sep 2024 17:50:16 +0300 Subject: Redirect users to login page if they attempt to access a service that requires authentication but are not logged in --- gn2/wqflask/oauth2/checks.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gn2/wqflask/oauth2/checks.py b/gn2/wqflask/oauth2/checks.py index 4a5a117f..944760ad 100644 --- a/gn2/wqflask/oauth2/checks.py +++ b/gn2/wqflask/oauth2/checks.py @@ -12,6 +12,7 @@ from .client import ( authserver_uri, oauth2_clientid, oauth2_clientsecret) +from .request_utils import authserver_authorise_uri def require_oauth2(func): @@ -22,8 +23,8 @@ def require_oauth2(func): def __clear_session__(_no_token): session.clear_session_info() - flash("You need to be logged in.", "alert-warning") - return redirect("/") + # redirect to the login page + return redirect(authserver_authorise_uri()) def __with_token__(token): resp = oauth2_client().get( -- cgit v1.2.3 From 0df6031dfcd266d37c091c9088eb30c6fc8ad64d Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 18 Sep 2024 12:10:28 +0300 Subject: Add new optional parameter to session object: redirect_url. --- gn2/wqflask/oauth2/session.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gn2/wqflask/oauth2/session.py b/gn2/wqflask/oauth2/session.py index b91534b0..78c766a8 100644 --- a/gn2/wqflask/oauth2/session.py +++ b/gn2/wqflask/oauth2/session.py @@ -24,6 +24,7 @@ class SessionInfo(TypedDict): masquerade: Optional[UserDetails] refreshing_token: bool auth_server_jwks: Optional[dict[str, Any]] + redirect_url: Optional[str] __SESSION_KEY__ = "GN::2::session_info" # Do not use this outside this module!! @@ -118,3 +119,10 @@ def toggle_token_refreshing(): def is_token_refreshing(): """Returns whether the token is being refreshed or not.""" return session_info().get("token_refreshing", False) + +def set_redirect_url(url): + """Save the current endpoint object""" + return save_session_info({ + **session_info(), + "redirect_url": url + }) -- cgit v1.2.3 From bb16286159c91c97840d228eba588322f9d4607d Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 18 Sep 2024 12:11:02 +0300 Subject: After login redirect users to the next request endpoint. --- gn2/wqflask/oauth2/toplevel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gn2/wqflask/oauth2/toplevel.py b/gn2/wqflask/oauth2/toplevel.py index 24d60311..425c598e 100644 --- a/gn2/wqflask/oauth2/toplevel.py +++ b/gn2/wqflask/oauth2/toplevel.py @@ -81,7 +81,8 @@ def authorisation_code(): "token": session.user_token(), "logged_in": True }) - return redirect("/") + redirect_url = session.session_info().get("redirect_url", "/") + return redirect(redirect_url) return no_token_post("auth/token", json=request_data).either( lambda err: __error__(process_error(err)), __success__) -- cgit v1.2.3 From 15200782f33f0f1f64d6686a8c00c79165257d0c Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 18 Sep 2024 12:12:06 +0300 Subject: feat(auth): implement redirect to login page and save current endpoint to session * Redirect users to the login page when authentication is required. * Save the current endpoint in the session for post-login redirection. --- gn2/wqflask/oauth2/checks.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/gn2/wqflask/oauth2/checks.py b/gn2/wqflask/oauth2/checks.py index 944760ad..6e90e7a3 100644 --- a/gn2/wqflask/oauth2/checks.py +++ b/gn2/wqflask/oauth2/checks.py @@ -2,7 +2,7 @@ from functools import wraps from urllib.parse import urljoin -from flask import flash, request, redirect +from flask import flash, request, redirect, url_for from authlib.integrations.requests_client import OAuth2Session from . import session @@ -20,10 +20,21 @@ def require_oauth2(func): @wraps(func) def __token_valid__(*args, **kwargs): """Check that the user is logged in and their token is valid.""" - def __clear_session__(_no_token): session.clear_session_info() - # redirect to the login page + flash("You need to be logged in.", "alert-warning") + return redirect("/") + + def __redirect_to_login__(_token): + """ + Save the current user request to session then + redirect to the login page. + """ + if request.method == "GET": + redirect_url = url_for(request.endpoint, **request.args) + else: + redirect_url = "/" + session.set_redirect_url(redirect_url, **request.args) return redirect(authserver_authorise_uri()) def __with_token__(token): @@ -33,9 +44,9 @@ def require_oauth2(func): if not user_details.get("error", False): return func(*args, **kwargs) - return __clear_session__(token) + return __redirect_to_login__(token) - return session.user_token().either(__clear_session__, __with_token__) + return session.user_token().either(__redirect_to_login__, __with_token__) return __token_valid__ -- cgit v1.2.3 From e751f31c1cc740f79adc630b4277e21aeab58b6d Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 18 Sep 2024 14:24:59 +0300 Subject: fix minor issue for setting redirect url. --- gn2/wqflask/oauth2/checks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gn2/wqflask/oauth2/checks.py b/gn2/wqflask/oauth2/checks.py index 6e90e7a3..55338930 100644 --- a/gn2/wqflask/oauth2/checks.py +++ b/gn2/wqflask/oauth2/checks.py @@ -34,7 +34,7 @@ def require_oauth2(func): redirect_url = url_for(request.endpoint, **request.args) else: redirect_url = "/" - session.set_redirect_url(redirect_url, **request.args) + session.set_redirect_url(redirect_url) return redirect(authserver_authorise_uri()) def __with_token__(token): -- cgit v1.2.3 From 88eae5f263bc816384fd124f06a28633ee8180ce Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 18 Sep 2024 16:09:48 +0300 Subject: Refactor: try to build endpoint with get request. If BuildError is raised default to "/" --- gn2/wqflask/oauth2/checks.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gn2/wqflask/oauth2/checks.py b/gn2/wqflask/oauth2/checks.py index 55338930..8a6e439e 100644 --- a/gn2/wqflask/oauth2/checks.py +++ b/gn2/wqflask/oauth2/checks.py @@ -4,6 +4,7 @@ from urllib.parse import urljoin from flask import flash, request, redirect, url_for from authlib.integrations.requests_client import OAuth2Session +from werkzeug.routing import BuildError from . import session from .client import ( @@ -30,9 +31,9 @@ def require_oauth2(func): Save the current user request to session then redirect to the login page. """ - if request.method == "GET": - redirect_url = url_for(request.endpoint, **request.args) - else: + try: + redirect_url = url_for(request.endpoint, _method="GET", **request.args) + except BuildError: redirect_url = "/" session.set_redirect_url(redirect_url) return redirect(authserver_authorise_uri()) -- cgit v1.2.3 From 3f62d5d3e86f3b52488fb50ec00c88f77d03ab27 Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 18 Sep 2024 16:10:54 +0300 Subject: Refactor: drop __clear_session__ function. --- gn2/wqflask/oauth2/checks.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gn2/wqflask/oauth2/checks.py b/gn2/wqflask/oauth2/checks.py index 8a6e439e..38e7e22f 100644 --- a/gn2/wqflask/oauth2/checks.py +++ b/gn2/wqflask/oauth2/checks.py @@ -21,11 +21,6 @@ def require_oauth2(func): @wraps(func) def __token_valid__(*args, **kwargs): """Check that the user is logged in and their token is valid.""" - def __clear_session__(_no_token): - session.clear_session_info() - flash("You need to be logged in.", "alert-warning") - return redirect("/") - def __redirect_to_login__(_token): """ Save the current user request to session then -- cgit v1.2.3