diff --git a/perun/proxygui/gui/gui.py b/perun/proxygui/gui/gui.py index 188c6240c9015261094a43a638d9bea6bc319711..7adf52b13ec5e54fdcb96f2b43e9e96773b8dfae 100644 --- a/perun/proxygui/gui/gui.py +++ b/perun/proxygui/gui/gui.py @@ -24,7 +24,7 @@ from perun.proxygui.api.heuristic_api import AuthEventLoggingQueries from perun.proxygui.jwt import SingletonJWTServiceProvider from perun.proxygui.logout_manager import LogoutManager from perun.proxygui.user_manager import UserManager -from perun.utils.CustomExceptions import InvalidJWTError +from perun.utils.CustomExceptions import InvalidJWTError, UserNotExistsException from perun.utils.Notification import NotificationType from perun.utils.consent_framework.consent_manager import ConsentManager @@ -611,6 +611,7 @@ def construct_gui_blueprint(cfg, auth: OIDCAuthentication): "HeuristicData.html", redirect_url=REDIRECT_URL, selected=False, + user_not_exists=False, ) try: @@ -621,13 +622,25 @@ def construct_gui_blueprint(cfg, auth: OIDCAuthentication): f"integer" ), HTTPStatus.BAD_REQUEST - name = user_manager.get_user_name(user_id) + try: + name = user_manager.get_user_name(user_id) + except UserNotExistsException: + user_not_exists_message = f"User with ID {user_id} does not exist." + return render_template( + "HeuristicData.html", + redirect_url=REDIRECT_URL, + selected=False, + user_not_exists=True, + user_not_exists_message=user_not_exists_message, + ) + auth_event.get_auth_logs(user_id) return render_template( "HeuristicData.html", redirect_url=REDIRECT_URL, selected=True, + user_not_exists=False, user=user_id, name=name, last_n_times=auth_event.get_last_n_times(), diff --git a/perun/proxygui/gui/templates/HeuristicData.html b/perun/proxygui/gui/templates/HeuristicData.html index 06541b3f3df0e0aa9320fbcc080a3edeb2d680c1..266a4a30485b13d4bbf18efb1d152626d7e0f863 100644 --- a/perun/proxygui/gui/templates/HeuristicData.html +++ b/perun/proxygui/gui/templates/HeuristicData.html @@ -3,7 +3,8 @@ {% block contentwrapper %} <div class="window {% if cfg.css_framework == 'MUNI' %}framework_muni{% else %}framework_bootstrap5 bg-light{% endif %}"> <div id="content"> - <div class="wrap{% if not cfg.css_framework == 'MUNI' %} container{% endif %}"> + <div class="box-bg{% if not cfg.css_framework == 'MUNI' %} container{% + endif %}"> {% block content %} {% if selected %} <div class="content"> @@ -126,7 +127,22 @@ <br/> <h3><span>{{ _("Specify a Perun user ID to gather data:") }}</span></h3> <form action="{{ url_for('gui.heuristics') }}" method="get"> - <input type="number" id="user_id" name="user_id" min="1" required placeholder="User ID"> + <div class="u-pb-30"> + <input type="number" id="user_id" name="user_id" min="1" required placeholder="User ID"> + </div> + {% if user_not_exists %} + {% if not cfg.css_framework == 'MUNI' %} + <div class="bd-callout bd-callout-danger"> + {{ user_not_exists_message }} + </div> + {% else %} + <div class="message message--common message--common-error" + role="alert"> + <span class="message__icon icon icon-exclamation-triangle"></span> + <p class="message__desc">{{ user_not_exists_message }}</p> + </div> + {% endif %} + {% endif %} <p class="btn-wrap"> <button class="btn btn-primary btn-s btn-accept" type="submit" name="submit"> diff --git a/perun/proxygui/user_manager.py b/perun/proxygui/user_manager.py index e3520707af9bd26f5c3975a3a2553c03c72ca031..c2a185bb0e024bc5a4856da8bf2b9b1515421369 100644 --- a/perun/proxygui/user_manager.py +++ b/perun/proxygui/user_manager.py @@ -6,6 +6,7 @@ from typing import Optional from perun.connector import AdaptersManager from perun.connector import Logger +from perun.connector.adapters.AdaptersManager import AdaptersManagerNotExistsException from sqlalchemy import MetaData, delete, select, update from sqlalchemy.engine import Engine from sqlalchemy.orm.session import Session @@ -13,6 +14,7 @@ from sqlalchemy.orm.session import Session from perun.proxygui import jwt from perun.proxygui.jwt import SingletonJWTServiceProvider from perun.utils.ConfigStore import ConfigStore +from perun.utils.CustomExceptions import UserNotExistsException from perun.utils.DatabaseService import DatabaseService from perun.utils.EmailService import EmailService from perun.utils.Notification import NotificationType @@ -26,6 +28,7 @@ class UserManager: ) ADAPTERS_MANAGER_CFG = GLOBAL_CONFIG["adapters_manager"] ATTRS_MAP = ConfigStore.get_attributes_map(GLOBAL_CONFIG["attrs_cfg_path"]) + self.USER_NOT_EXISTS_EXCEPTION_NAME = "UserNotExistsException" self._ADAPTERS_MANAGER = AdaptersManager(ADAPTERS_MANAGER_CFG, ATTRS_MAP) self._SUBJECT_ATTRIBUTE = USER_MANAGER_CFG.get( @@ -62,8 +65,17 @@ class UserManager: return attr_value def extract_user_attribute(self, attr_name: str, user_id: int) -> Any: - user_attrs = self._ADAPTERS_MANAGER.get_user_attributes(user_id, [attr_name]) - return user_attrs.get(attr_name) + try: + user_attrs = self._ADAPTERS_MANAGER.get_user_attributes( + user_id, [attr_name] + ) + return user_attrs.get(attr_name) + except AdaptersManagerNotExistsException as e: + # Wrap an exception to deal with it in the GUI + if self.USER_NOT_EXISTS_EXCEPTION_NAME in e.message: + raise UserNotExistsException(e.message) + + raise e def _revoke_ssp_sessions( self, diff --git a/perun/utils/CustomExceptions.py b/perun/utils/CustomExceptions.py index a68104b44124ff92f48de51a66e14b71dfe93715..e23ef02509bb1ab69b246f15533ee1792c22164f 100644 --- a/perun/utils/CustomExceptions.py +++ b/perun/utils/CustomExceptions.py @@ -1,2 +1,6 @@ class InvalidJWTError(Exception): pass + + +class UserNotExistsException(Exception): + pass