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")
async def login(request: Request):
async def login(request: Request, redirect: str = None):
"""
Redirect the user to the SSO providers login page.
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
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 dont 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:

View file

@ -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>