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.

Signed-off-by: Lukas Fleischer <lfleischer@archlinux.org>
This commit is contained in:
Frédéric Mangano-Tarumi 2020-07-29 17:25:44 +02:00 committed by Lukas Fleischer
parent 87815d37c0
commit 8c28ba6e7f
2 changed files with 29 additions and 12 deletions

View file

@ -30,16 +30,21 @@ oauth.register(
@router.get("/sso/login") @router.get("/sso/login")
async def login(request: Request): async def login(request: Request, redirect: str = None):
""" """
Redirect the user to the SSO providers login page. Redirect the user to the SSO providers login page.
We specify prompt=login to force the user to input their credentials even We specify prompt=login to force the user to input their credentials even
if theyre already logged on the SSO. This is less practical, but given AUR if theyre already logged on the SSO. This is less practical, but given AUR
has the potential to impact many users, better safe than sorry. 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" authenticate_url = aurweb.config.get("options", "aur_location") + "/sso/authenticate"
return await oauth.sso.authorize_redirect(request, redirect_uri, prompt="login") 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): def is_account_suspended(conn, user_id):
@ -82,8 +87,15 @@ def is_ip_banned(conn, ip):
return result.fetchone() is not None 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") @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 Receive an OpenID Connect ID token, validate it, then process it to create
an new AUR session. an new AUR session.
@ -118,8 +130,7 @@ async def authenticate(request: Request, conn=Depends(aurweb.db.connect)):
return "Sorry, we dont seem to know you Sir " + sub return "Sorry, we dont seem to know you Sir " + sub
elif len(aur_accounts) == 1: elif len(aur_accounts) == 1:
sid = open_session(request, conn, aur_accounts[0][Users.c.ID]) sid = open_session(request, conn, aur_accounts[0][Users.c.ID])
response = RedirectResponse("/") response = RedirectResponse(redirect if redirect and is_aur_url(redirect) else "/")
# TODO redirect to the referrer
response.set_cookie(key="AURSID", value=sid, httponly=True, response.set_cookie(key="AURSID", value=sid, httponly=True,
secure=request.url.scheme == "https") secure=request.url.scheme == "https")
if "id_token" in token: if "id_token" in token:

View file

@ -9,6 +9,10 @@ if (!$disable_http_login || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'])) {
$login_error = $login['error']; $login_error = $login['error'];
} }
$referer = in_request('referer');
if ($referer === '')
$referer = $_SERVER['HTTP_REFERER'];
html_header('AUR ' . __("Login")); html_header('AUR ' . __("Login"));
?> ?>
<div id="dev-login" class="box"> <div id="dev-login" class="box">
@ -40,13 +44,15 @@ html_header('AUR ' . __("Login"));
<p> <p>
<input type="submit" class="button" value="<?php print __("Login"); ?>" /> <input type="submit" class="button" value="<?php print __("Login"); ?>" />
<a href="<?= get_uri('/passreset/') ?>">[<?= __('Forgot Password') ?>]</a> <a href="<?= get_uri('/passreset/') ?>">[<?= __('Forgot Password') ?>]</a>
<?php if (config_get('sso', 'openid_configuration')): ?> <?php if (config_get('sso', 'openid_configuration')):
<a href="<?= get_uri('/sso/login') ?>">[<?= __('Login through SSO') ?>]</a> $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 endif; ?>
<?php if (in_request('referer') !== ""): ?> <?php if (isset($referer)): ?>
<input id="id_referer" type="hidden" name="referer" value="<?= htmlspecialchars(in_request('referer'), ENT_QUOTES) ?>" /> <input id="id_referer" type="hidden" name="referer" value="<?= htmlspecialchars($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 endif; ?> <?php endif; ?>
</p> </p>
</fieldset> </fieldset>