From 5b953d849b5da251faa28ab00d0ee546b9cbb5ec Mon Sep 17 00:00:00 2001 From: Jonas Bardino Date: Tue, 4 Nov 2025 11:47:14 +0100 Subject: [PATCH] Force Show Peers date to display on same format as the date picker by wrapping it in a dummy input field without border. Limit date picker UI and backend accepted date range to dates between 7 days from today and ~10 years in the future, with fallback to default 365 days if an invalid value is given. Highlight the fallback in output. The end date value is automatically interpreted as until midnight and the defaults are now read from mig/shared/defaults.py both for UI and backend. --- mig/assets/css/V3/style.css | 5 +++++ mig/shared/defaults.py | 4 ++++ mig/shared/functionality/peers.py | 14 +++++++++++--- mig/shared/functionality/peersaction.py | 23 +++++++++++++---------- mig/shared/output.py | 5 +++++ 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/mig/assets/css/V3/style.css b/mig/assets/css/V3/style.css index 10ea2b48b..c5b14d738 100644 --- a/mig/assets/css/V3/style.css +++ b/mig/assets/css/V3/style.css @@ -816,3 +816,8 @@ var, sampl, code { border: 1px solid #ff9900; margin-bottom: 20px; } + +/* Disable border on e.g. input elements if specifically requested */ +.noborder { + border: 0; +} diff --git a/mig/shared/defaults.py b/mig/shared/defaults.py index 2ad3c5905..cf9e34c76 100644 --- a/mig/shared/defaults.py +++ b/mig/shared/defaults.py @@ -208,6 +208,10 @@ # Number of days before expire that auto extend attempts kick in # NOTE: must be lower than all X_auto_extend_days values to avoid hammering attempt_auto_extend_days = 10 +# Enforce peers expire value (End date) to default/min/max days in the future +peers_expire_default_days = generic_valid_days +peers_expire_min_days = 7 +peers_expire_max_days = 3652 # Strictly ordered list of account status values to enable use of filemarks # for caching account status using integer timestamps outside user DB. diff --git a/mig/shared/functionality/peers.py b/mig/shared/functionality/peers.py index f24f01f4e..ce0b6cd60 100755 --- a/mig/shared/functionality/peers.py +++ b/mig/shared/functionality/peers.py @@ -4,7 +4,7 @@ # --- BEGIN_HEADER --- # # peers - manage external collaboration partners, etc. -# Copyright (C) 2003-2021 The MiG Project lead by Brian Vinter +# Copyright (C) 2003-2025 The MiG Project by the Science HPC Center at UCPH # # This file is part of MiG. # @@ -41,7 +41,8 @@ from mig.shared.base import pretty_format_user, fill_distinguished_name, \ client_id_dir, force_native_str_rec from mig.shared.defaults import csrf_field, peers_filename, \ - pending_peers_filename, peers_fields, peer_kinds, default_pager_entries + pending_peers_filename, peers_fields, peer_kinds, default_pager_entries, \ + peers_expire_min_days, peers_expire_max_days from mig.shared.functional import validate_input_and_cert from mig.shared.handlers import get_csrf_limit, make_csrf_token from mig.shared.htmlgen import man_base_js, man_base_html, html_post_helper @@ -217,6 +218,12 @@ def main(client_id, user_arguments_dict): 'csrf_field': csrf_field, 'csrf_limit': csrf_limit, 'target_op': target_op, 'csrf_token': csrf_token, 'expire_help': expire_help, + # NOTE: allow select expire N days or more from now + 'min_peers_expire': datetime.date.today() + \ + datetime.timedelta(days=peers_expire_min_days), + # NOTE: allow up to N days in the future + 'max_peers_expire': datetime.date.today() + \ + datetime.timedelta(days=peers_expire_max_days), 'csv_header': csv_sep.join([i for i in peers_fields])} form_prefix_html = '''
+ min="%(min_peers_expire)s" max="%(max_peers_expire)s" + title="Access expiry date"/> ''' diff --git a/mig/shared/functionality/peersaction.py b/mig/shared/functionality/peersaction.py index 5bc3574d0..bf27c3870 100644 --- a/mig/shared/functionality/peersaction.py +++ b/mig/shared/functionality/peersaction.py @@ -4,7 +4,7 @@ # --- BEGIN_HEADER --- # # peersaction - handle management of peers -# Copyright (C) 2003-2023 The MiG Project lead by Brian Vinter +# Copyright (C) 2003-2025 The MiG Project by the Science HPC Center at UCPH # # This file is part of MiG. # @@ -41,7 +41,8 @@ from mig.shared.base import client_id_dir, fill_distinguished_name, \ extract_field from mig.shared.defaults import peers_filename, peer_kinds, peers_fields, \ - keyword_auto, csrf_field + keyword_auto, csrf_field, peers_expire_default_days, \ + peers_expire_min_days, peers_expire_max_days from mig.shared.functional import validate_input, REJECT_UNSET from mig.shared.handlers import safe_handler, get_csrf_limit from mig.shared.htmlgen import html_post_helper @@ -51,7 +52,6 @@ from mig.shared.url import urlencode from mig.shared.useradm import get_full_user_map -default_expire_days = 7 peer_actions = ['import', 'add', 'remove', 'update', 'accept', 'reject'] @@ -155,17 +155,20 @@ def main(client_id, user_arguments_dict): expire = now else: expire = datetime.datetime.strptime(raw_expire, '%Y-%m-%d') - if now > expire: - raise ValueError("specified expire value is in the past!") + if now + datetime.timedelta(days=peers_expire_min_days) > expire: + raise ValueError("specified expire is in the past!") + if now + datetime.timedelta(days=peers_expire_max_days) < expire: + raise ValueError("specified expire is too far in the future!") except Exception as exc: - logger.error("expire %r could not be parsed into a (future) date" % + logger.error("expire %r could not be parsed into a valid date" % raw_expire) output_objects.append( - {'object_type': 'text', 'text': - 'No valid expire provided - using default: %d days' % - default_expire_days}) + {'object_type': 'warning', 'text': + 'End date must be %d - %d days from now - using default %d days' % + (peers_expire_min_days, peers_expire_max_days, + peers_expire_default_days)}) expire = now - expire += datetime.timedelta(days=default_expire_days) + expire += datetime.timedelta(days=peers_expire_default_days) expire = expire.date().isoformat() peers_path = os.path.join(configuration.user_settings, client_dir, diff --git a/mig/shared/output.py b/mig/shared/output.py index 74517410f..bd96c5fbc 100644 --- a/mig/shared/output.py +++ b/mig/shared/output.py @@ -1560,6 +1560,11 @@ def html_format(configuration, ret_val, ret_msg, out_obj): single_peer['state'] = single_peer.get('state', '') if not single_peer['state']: single_peer['state'] = 'NA' + single_peer['expire'] = single_peer.get('expire', '') + if single_peer['expire']: + # Make a dummy input field to force consistent date format + single_peer['expire'] = "" % single_peer lines.append(''' %(full_name)s%(organization)s%(email)s %(country)s%(state)s%(kind)s%(label)s%(expire)s