From e72946e568e24bf006a1a86066a86f562ddb9db5 Mon Sep 17 00:00:00 2001
From: Sotiris Tsepelakis <sotirios.tsepelakis@tuwien.ac.at>
Date: Mon, 18 Mar 2024 13:51:26 +0100
Subject: [PATCH] Handlers: set affiliation from remote account
---
invenio_config_tuw/auth/handlers.py | 40 ++++++++++++++++++++++++++---
setup.cfg | 3 ++-
2 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/invenio_config_tuw/auth/handlers.py b/invenio_config_tuw/auth/handlers.py
index b2435b1..e76ebf8 100644
--- a/invenio_config_tuw/auth/handlers.py
+++ b/invenio_config_tuw/auth/handlers.py
@@ -1,12 +1,13 @@
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2020-2023 TU Wien.
+# Copyright (C) 2020-2024 TU Wien.
#
# Invenio Config TUW is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.
"""Custom handlers for the Keycloak integration."""
+import jwt
from flask import current_app, redirect, render_template, request, session, url_for
from flask_login import current_user
@@ -41,6 +42,7 @@ from invenio_oauthclient.utils import (
oauth_get_user,
oauth_register,
)
+from saml2.mdstore import MetadataStore
from .utils import auto_trust_user, create_username_from_info, get_user_by_username
@@ -217,9 +219,39 @@ def base_authorized_signup_handler(resp, remote, *args, **kwargs):
if new_full_name and new_full_name != user.user_profile["full_name"]:
user.user_profile = {"full_name": new_full_name, **old_profile}
- # Hard code the affiliation to TU Wien, since we are currently
- # not accepting any externals. It is set on every login.
- user.user_profile = {**user.user_profile, "affiliations": "TU Wien"}
+ # We are now accepting logins from several trusted external universities/organizations,
+ # so we're setting the affiliation for the most common ones
+ def _translate_affiliation(affiliation_list):
+ metadata_url = "https://eduid.at/md/aconet-registered.xml"
+
+ mds = MetadataStore(None, None)
+ mds.load("remote", url=metadata_url, check_validity=True)
+ # scope to check email
+ # return display name in english
+ for idp_id in mds.identity_providers():
+ idp_descr = mds[idp_id]["idpsso_descriptor"][0]
+ for ext_elem in idp_descr["extensions"]["extension_elements"]:
+ for display_name in ext_elem.get("display_name", []):
+ if display_name["lang"] == "en":
+ if any(
+ affiliation.endswith(
+ idp_descr["extensions"]["extension_elements"][0][
+ "text"
+ ]
+ )
+ for affiliation in affiliation_list
+ ):
+ return display_name["text"]
+ return "None"
+
+ decoded_token = jwt.decode(
+ user.remote_accounts[0].remote_tokens[0].access_token,
+ options={"verify_signature": False},
+ )
+ user.user_profile = {
+ **user.user_profile,
+ "affiliations": _translate_affiliation(decoded_token.get("affiliation")),
+ }
# Link account
# ------------
diff --git a/setup.cfg b/setup.cfg
index 822b75d..1c5be12 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2020-2022 TU Wien.
+# Copyright (C) 2020-2024 TU Wien.
#
# Invenio-Config-TUW is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.
@@ -37,6 +37,7 @@ install_requires =
Flask-BabelEx>=0.9.4
invenio-app-rdm>=11.0.0
invenio-mail>=1.0.2,<1.1.0
+ pysaml2
[options.extras_require]
tests =
--
GitLab