diff --git a/invenio_config_tuw/auth/handlers.py b/invenio_config_tuw/auth/handlers.py index b2435b1318a98730a7c6d0041bc0bdaf4339ee65..e76ebf86bad510aad9411e57aa3b151e556bac2d 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 822b75dca26c8d279621df1af233a4e2fa212d4b..1c5be129c114533e33d8a4f11407562d371ff497 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 =