diff --git a/CHANGELOG.md b/CHANGELOG.md index f895332..f8aeab2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Contact: [ghantoos@ghantoos.org](mailto:ghantoos@ghantoos.org) [https://github.com/ghantoos/lshell](https://github.com/ghantoos/lshell) +### v0.10.2 24/10/2024 +- Make env_path have precedence over the OS path ($env_path:$PATH) +- Test auto-release via Pypi + ### v0.10.1 24/10/2024 - Add the ability to write and execute a lshell script (`#!/usr/bin/lshell`) - Added Pypi package diff --git a/etc/lshell.conf b/etc/lshell.conf index ee687c2..b443cd1 100644 --- a/etc/lshell.conf +++ b/etc/lshell.conf @@ -88,7 +88,7 @@ aliases : {'ll':'ls -l'} #home_path : '/home/bla/' ## update the environment variable $PATH of the user -#env_path : ':/usr/local/bin:/usr/sbin' +#env_path : '/usr/local/bin:/usr/sbin' ## a list of path; all executable files inside these path will be allowed #allowed_cmd_path: ['/home/bla/bin','/home/bla/stuff/libexec'] diff --git a/lshell/checkconfig.py b/lshell/checkconfig.py index 53dc745..af38935 100644 --- a/lshell/checkconfig.py +++ b/lshell/checkconfig.py @@ -601,7 +601,17 @@ def get_config_user(self): f"{self.conf['home_path']}/{self.conf['history_file']}" ) - os.environ["PATH"] = os.environ["PATH"] + self.conf["env_path"] + if self.conf["env_path"]: + new_path = f"{self.conf['env_path']}:{os.environ['PATH']}" + + # Check if the new path is valid + if all( + c in string.ascii_letters + string.digits + "/:-_." for c in new_path + ) and not new_path.startswith(":"): + os.environ["PATH"] = new_path + else: + print(f"CONF: env_path must be a valid $PATH: {self.conf['env_path']}") + sys.exit(1) # append default commands to allowed list self.conf["allowed"] += list(set(variables.builtins_list) - set(["export"])) diff --git a/lshell/variables.py b/lshell/variables.py index 8aa9e3f..9c8df3d 100644 --- a/lshell/variables.py +++ b/lshell/variables.py @@ -3,7 +3,7 @@ import sys import os -__version__ = "0.10.1" +__version__ = "0.10.2" # Required config variable list per user required_config = ["allowed", "forbidden", "warning_counter"] diff --git a/man/lshell.1 b/man/lshell.1 index d44c9af..7f540d1 100644 --- a/man/lshell.1 +++ b/man/lshell.1 @@ -1,7 +1,7 @@ .\" .\" Man page for the Limited Shell (lshell) project. .\" -.TH lshell 1 "October, 2024" "v0.10.1" +.TH lshell 1 "October, 2024" "v0.10.2" .SH NAME lshell \- Limited Shell diff --git a/test/test_unit.py b/test/test_unit.py index e3c1611..570c05d 100644 --- a/test/test_unit.py +++ b/test/test_unit.py @@ -3,6 +3,7 @@ import os import unittest from getpass import getuser +from unittest.mock import patch # import lshell specifics from lshell.shellcmd import ShellCmd @@ -229,3 +230,60 @@ def test_28_checksecure_quoted_command(self): """U28 | quoted command should be parsed""" input_command = "echo'/1.sh'" return self.assertEqual(sec.check_secure(input_command, self.userconf)[0], 1) + + def test_29_env_path_updates_path_variable(self): + """Test that --env_path updates the PATH environment variable.""" + # store the original $PATH + original_path = os.environ["PATH"] + + # Simulate passing the --env_path argument + random_path = "/usr/random:/this_is_a_test" + args = self.args + [ + f"--env_path='{random_path}'", + ] + CheckConfig(args).returnconf() + + # Verify that the $PATH has been updated correctly + expected_path = f"{random_path}:{original_path}" + + # Assuming CheckConfig sets the environment variable + self.assertEqual(os.environ["PATH"], expected_path) + + # Reset the PATH environment variable + os.environ["PATH"] = original_path + + @patch("sys.exit") # Mock sys.exit to prevent exiting the test on failure + def test_invalid_new_path(self, mock_exit): + """Test that an invalid new PATH triggers an error and sys.exit.""" + original_path = os.environ["PATH"] + random_path = "/usr/random:/invalid$path" + args = self.args + [ + f"--env_path='{random_path}'", + ] + + # Simulate passing the --env_path argument + CheckConfig(args).returnconf() + + # Check that sys.exit was called due to invalid path + mock_exit.assert_called_once_with(1) + + # The PATH should not have been changed + self.assertEqual(os.environ["PATH"], original_path) + + @patch("sys.exit") + def test_new_path_starts_with_colon(self, mock_exit): + """Test that a new PATH starting with a colon triggers an error.""" + original_path = os.environ["PATH"] + random_path = ":/usr/random:/this_is_a_test" + args = self.args + [ + f"--env_path='{random_path}'", + ] + + # Simulate passing the --env_path argument + CheckConfig(args).returnconf() + + # Check that sys.exit was called due to invalid path + mock_exit.assert_called_once() + + # The PATH should not have been changed + self.assertEqual(os.environ["PATH"], original_path)