Commit 4d0f2d22 authored by Frédéric Mangano-Tarumi's avatar Frédéric Mangano-Tarumi Committed by Lukas Fleischer
Browse files

Implement SSO logout


Signed-off-by: Lukas Fleischer's avatarLukas Fleischer <lfleischer@archlinux.org>
parent d12ea08f
import time import time
import uuid import uuid
from urllib.parse import urlencode
import fastapi import fastapi
from authlib.integrations.starlette_client import OAuth from authlib.integrations.starlette_client import OAuth
...@@ -82,3 +84,19 @@ async def authenticate(request: Request, conn=Depends(aurweb.db.connect)): ...@@ -82,3 +84,19 @@ async def authenticate(request: Request, conn=Depends(aurweb.db.connect)):
else: else:
# We’ve got a severe integrity violation. # We’ve got a severe integrity violation.
raise Exception("Multiple accounts found for SSO account " + sub) raise Exception("Multiple accounts found for SSO account " + sub)
@router.get("/sso/logout")
async def logout():
"""
Disconnect the user from the SSO provider, potentially affecting every
other Arch service. AUR logout is performed by `/logout`, before it
redirects to `/sso/logout`.
Based on the OpenID Connect Session Management specification:
https://openid.net/specs/openid-connect-session-1_0.html#RPLogout
"""
metadata = await oauth.sso.load_server_metadata()
# TODO Supply id_token_hint to the end session endpoint.
query = urlencode({'post_logout_redirect_uri': aurweb.config.get('options', 'aur_location')})
return RedirectResponse(metadata["end_session_endpoint"] + '?' + query)
...@@ -5,16 +5,28 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); ...@@ -5,16 +5,28 @@ set_include_path(get_include_path() . PATH_SEPARATOR . '../lib');
include_once("aur.inc.php"); # access AUR common functions include_once("aur.inc.php"); # access AUR common functions
include_once("acctfuncs.inc.php"); # access AUR common functions include_once("acctfuncs.inc.php"); # access AUR common functions
$redirect_uri = '/';
# if they've got a cookie, log them out - need to do this before # if they've got a cookie, log them out - need to do this before
# sending any HTML output. # sending any HTML output.
# #
if (isset($_COOKIE["AURSID"])) { if (isset($_COOKIE["AURSID"])) {
$uid = uid_from_sid($_COOKIE['AURSID']);
delete_session_id($_COOKIE["AURSID"]); delete_session_id($_COOKIE["AURSID"]);
# setting expiration to 1 means '1 second after midnight January 1, 1970' # setting expiration to 1 means '1 second after midnight January 1, 1970'
setcookie("AURSID", "", 1, "/", null, !empty($_SERVER['HTTPS']), true); setcookie("AURSID", "", 1, "/", null, !empty($_SERVER['HTTPS']), true);
unset($_COOKIE['AURSID']); unset($_COOKIE['AURSID']);
clear_expired_sessions(); clear_expired_sessions();
# If the account is linked to an SSO account, disconnect the user from the SSO too.
if (isset($uid)) {
$dbh = DB::connect();
$sso_account_id = $dbh->query("SELECT SSOAccountID FROM Users WHERE ID = " . $dbh->quote($uid))
->fetchColumn();
if ($sso_account_id)
$redirect_uri = '/sso/logout';
}
} }
header('Location: /'); header("Location: $redirect_uri");
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment