From 610e46c4a84782c47ef97169212f0414eb133902 Mon Sep 17 00:00:00 2001 From: Kevin Hunter Kesling Date: Thu, 5 Dec 2024 11:09:35 -0500 Subject: [PATCH] Allow UEPs to restrict functions Update recent logic to only force UEPs to a certain function allow list iff the parent MEP has such a list. If the parent MEP is _not_ otherwise restricted, then let the UEP's configuration decide. This allows administrators to use Jinja logic to have different users restricted to different functions. --- .../endpoint/endpoint_manager.py | 4 +++- .../tests/unit/test_endpointmanager_unit.py | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/compute_endpoint/globus_compute_endpoint/endpoint/endpoint_manager.py b/compute_endpoint/globus_compute_endpoint/endpoint/endpoint_manager.py index 1e4d52c43..0f6af17ac 100644 --- a/compute_endpoint/globus_compute_endpoint/endpoint/endpoint_manager.py +++ b/compute_endpoint/globus_compute_endpoint/endpoint/endpoint_manager.py @@ -1073,10 +1073,12 @@ def cmd_start_endpoint( self._config, template_str, user_config_schema, user_opts, user_runtime ) stdin_data_dict = { - "allowed_functions": self._config.allowed_functions, "amqp_creds": kwargs.get("amqp_creds"), "config": user_config, } + if self._config.allowed_functions is not None: + stdin_data_dict["allowed_functions"] = self._config.allowed_functions + stdin_data = json.dumps(stdin_data_dict, separators=(",", ":")) exit_code += 1 diff --git a/compute_endpoint/tests/unit/test_endpointmanager_unit.py b/compute_endpoint/tests/unit/test_endpointmanager_unit.py index 4d3e5b392..52abfca46 100644 --- a/compute_endpoint/tests/unit/test_endpointmanager_unit.py +++ b/compute_endpoint/tests/unit/test_endpointmanager_unit.py @@ -2006,7 +2006,7 @@ def test_pipe_size_limit(mocker, mock_log, successful_exec_from_mocked_root, con conf_str = "v: " + "$" * (conf_size - 3) - stdin_data_size = conf_size + 56 # overhead for JSON dict keys, etc. + stdin_data_size = conf_size + 31 # overhead for JSON dict keys, etc. pipe_buffer_size = 512 # Subtract 256 for hard-coded buffer in-code is_valid = pipe_buffer_size - 256 - stdin_data_size >= 0 @@ -2038,6 +2038,26 @@ def _remove_user_config_template(*args, **kwargs): assert pyexc.value.code == _GOOD_EC, "Q&D: verify we exec'ed, based on '+= 1'" +def test_mep_not_restricted_uep_allowed_functions_not_overridden( + successful_exec_from_mocked_root, mock_conf_root +): + mock_os, *_, em = successful_exec_from_mocked_root + + m = mock.Mock() + mock_os.fdopen.return_value.__enter__.return_value = m + mock_conf_root.allowed_functions = None # just be explicit, despite default + with pytest.raises(SystemExit) as pyexc: + em._event_loop() + + assert pyexc.value.code == _GOOD_EC, "Q&D: verify we exec'ed, based on '+= 1'" + + (received_stdin,), _k = m.write.call_args + parsed_stdin = json.loads(received_stdin) + + # another test verifies when allowed_functions *is* set + assert "allowed_functions" not in parsed_stdin + + @pytest.mark.parametrize("fn_count", (0, 1, 2, 3, random.randint(4, 100))) def test_set_uep_allowed_functions( successful_exec_from_mocked_root, mock_conf_root, fn_count