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