[PATCH] Redirect to referer after SSO login
Introduce a `redirect` query argument to SSO login endpoints so that users are redirected to the page they were originally on when they clicked the Login link. --- aurweb/routers/sso.py | 23 +++++++++++++++++------ web/html/login.php | 18 ++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/aurweb/routers/sso.py b/aurweb/routers/sso.py index 2e4fbacc..4ef31b0a 100644 --- a/aurweb/routers/sso.py +++ b/aurweb/routers/sso.py @@ -30,16 +30,21 @@ oauth.register( @router.get("/sso/login") -async def login(request: Request): +async def login(request: Request, redirect: str = None): """ Redirect the user to the SSO provider’s login page. We specify prompt=login to force the user to input their credentials even if they’re already logged on the SSO. This is less practical, but given AUR has the potential to impact many users, better safe than sorry. + + The `redirect` argument is a query parameter specifying the post-login + redirect URL. """ - redirect_uri = aurweb.config.get("options", "aur_location") + "/sso/authenticate" - return await oauth.sso.authorize_redirect(request, redirect_uri, prompt="login") + authenticate_url = aurweb.config.get("options", "aur_location") + "/sso/authenticate" + if redirect: + authenticate_url = authenticate_url + "?" + urlencode([("redirect", redirect)]) + return await oauth.sso.authorize_redirect(request, authenticate_url, prompt="login") def is_account_suspended(conn, user_id): @@ -82,8 +87,15 @@ def is_ip_banned(conn, ip): return result.fetchone() is not None +def is_aur_url(url): + aur_location = aurweb.config.get("options", "aur_location") + if not aur_location.endswith("/"): + aur_location = aur_location + "/" + return url.startswith(aur_location) + + @router.get("/sso/authenticate") -async def authenticate(request: Request, conn=Depends(aurweb.db.connect)): +async def authenticate(request: Request, redirect: str = None, conn=Depends(aurweb.db.connect)): """ Receive an OpenID Connect ID token, validate it, then process it to create an new AUR session. @@ -118,8 +130,7 @@ async def authenticate(request: Request, conn=Depends(aurweb.db.connect)): return "Sorry, we don’t seem to know you Sir " + sub elif len(aur_accounts) == 1: sid = open_session(request, conn, aur_accounts[0][Users.c.ID]) - response = RedirectResponse("/") - # TODO redirect to the referrer + response = RedirectResponse(redirect if redirect and is_aur_url(redirect) else "/") response.set_cookie(key="AURSID", value=sid, httponly=True, secure=request.url.scheme == "https") if "id_token" in token: diff --git a/web/html/login.php b/web/html/login.php index 3a146f60..3f3d66cc 100644 --- a/web/html/login.php +++ b/web/html/login.php @@ -9,6 +9,10 @@ if (!$disable_http_login || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'])) { $login_error = $login['error']; } +$referer = in_request('referer'); +if ($referer === '') + $referer = $_SERVER['HTTP_REFERER']; + html_header('AUR ' . __("Login")); ?> <div id="dev-login" class="box"> @@ -40,13 +44,15 @@ html_header('AUR ' . __("Login")); <p> <input type="submit" class="button" value="<?php print __("Login"); ?>" /> <a href="<?= get_uri('/passreset/') ?>">[<?= __('Forgot Password') ?>]</a> - <?php if (config_get('sso', 'openid_configuration')): ?> - <a href="<?= get_uri('/sso/login') ?>">[<?= __('Login through SSO') ?>]</a> + <?php if (config_get('sso', 'openid_configuration')): + $sso_login_url = get_uri('/sso/login'); + if (isset($referer)) + $sso_login_url .= '?redirect=' . urlencode($referer); + ?> + <a href="<?= htmlspecialchars($sso_login_url, ENT_QUOTES) ?>">[<?= __('Login through SSO') ?>]</a> <?php endif; ?> - <?php if (in_request('referer') !== ""): ?> - <input id="id_referer" type="hidden" name="referer" value="<?= htmlspecialchars(in_request('referer'), ENT_QUOTES) ?>" /> - <?php elseif (isset($_SERVER['HTTP_REFERER'])): ?> - <input id="id_referer" type="hidden" name="referer" value="<?= htmlspecialchars($_SERVER['HTTP_REFERER'], ENT_QUOTES) ?>" /> + <?php if (isset($referer)): ?> + <input id="id_referer" type="hidden" name="referer" value="<?= htmlspecialchars($referer, ENT_QUOTES) ?>" /> <?php endif; ?> </p> </fieldset> -- 2.27.0
On Wed, 29 Jul 2020 at 11:25:44, Frédéric Mangano-Tarumi wrote:
Introduce a `redirect` query argument to SSO login endpoints so that users are redirected to the page they were originally on when they clicked the Login link. --- aurweb/routers/sso.py | 23 +++++++++++++++++------ web/html/login.php | 18 ++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-)
Thanks! I merged the patch into pu but we need to be careful here. It probably makes sense to have all the code go through a security review before we enable this feature in production in any case, so I am not too worried now.
participants (2)
-
Frédéric Mangano-Tarumi
-
Lukas Fleischer