diff options
| -rw-r--r-- | CHANGELOG.md | 9 | ||||
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | setup.cfg | 4 | ||||
| -rw-r--r-- | src/etoolkit/__init__.py | 2 | ||||
| -rw-r--r-- | src/etoolkit/etoolkit.py | 18 | ||||
| -rw-r--r-- | tests/conftest.py | 5 | ||||
| -rw-r--r-- | tests/test_envtoolkit_instance.py | 4 |
7 files changed, 39 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index aca6068..916a9a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
| @@ -1,5 +1,14 @@ | |||
| 1 | # Changelog | 1 | # Changelog |
| 2 | 2 | ||
| 3 | ## [2.1.0](https://github.com/blackm0re/etoolkit/tree/2.1.0) (2024-12-26) | ||
| 4 | |||
| 5 | [Full Changelog](https://github.com/blackm0re/etoolkit/compare/2.0.0...2.1.0) | ||
| 6 | |||
| 7 | **Changes:** | ||
| 8 | |||
| 9 | - add encrypted values to *ETOOLKIT_SENSITIVE* implicitly | ||
| 10 | |||
| 11 | |||
| 3 | ## [2.0.0](https://github.com/blackm0re/etoolkit/tree/2.0.0) (2024-05-13) | 12 | ## [2.0.0](https://github.com/blackm0re/etoolkit/tree/2.0.0) (2024-05-13) |
| 4 | 13 | ||
| 5 | [Full Changelog](https://github.com/blackm0re/etoolkit/compare/1.2.0...2.0.0) | 14 | [Full Changelog](https://github.com/blackm0re/etoolkit/compare/1.2.0...2.0.0) |
| @@ -297,6 +297,10 @@ will prompt for the current master password, then for a new master password | |||
| 297 | (with confirmation) and finally the new config file (if "all") or instance | 297 | (with confirmation) and finally the new config file (if "all") or instance |
| 298 | contents will be displayed. | 298 | contents will be displayed. |
| 299 | 299 | ||
| 300 | The values of variables listed in *ETOOLKIT_SENSITIVE* will not be displayed | ||
| 301 | when an instance is loaded. The keys of encrypted values will be be added to | ||
| 302 | *ETOOLKIT_SENSITIVE* implicitly. | ||
| 303 | |||
| 300 | Contact the author for questions and suggestions! :) | 304 | Contact the author for questions and suggestions! :) |
| 301 | 305 | ||
| 302 | 306 | ||
| @@ -15,12 +15,12 @@ classifiers = | |||
| 15 | Intended Audience :: System Administrators | 15 | Intended Audience :: System Administrators |
| 16 | License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) | 16 | License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) |
| 17 | Programming Language :: Python :: 3 | 17 | Programming Language :: Python :: 3 |
| 18 | Programming Language :: Python :: 3.8 | ||
| 19 | Programming Language :: Python :: 3.9 | 18 | Programming Language :: Python :: 3.9 |
| 20 | Programming Language :: Python :: 3.10 | 19 | Programming Language :: Python :: 3.10 |
| 21 | Programming Language :: Python :: 3.11 | 20 | Programming Language :: Python :: 3.11 |
| 22 | Programming Language :: Python :: 3.12 | 21 | Programming Language :: Python :: 3.12 |
| 23 | Programming Language :: Python :: 3.13 | 22 | Programming Language :: Python :: 3.13 |
| 23 | Programming Language :: Python :: 3.14 | ||
| 24 | Operating System :: POSIX | 24 | Operating System :: POSIX |
| 25 | Topic :: Security :: Cryptography | 25 | Topic :: Security :: Cryptography |
| 26 | 26 | ||
| @@ -32,7 +32,7 @@ project_urls = | |||
| 32 | package_dir = | 32 | package_dir = |
| 33 | = src | 33 | = src |
| 34 | packages = find: | 34 | packages = find: |
| 35 | python_requires = >=3.8 | 35 | python_requires = >=3.9 |
| 36 | 36 | ||
| 37 | install_requires = | 37 | install_requires = |
| 38 | cryptography>=3.2 | 38 | cryptography>=3.2 |
diff --git a/src/etoolkit/__init__.py b/src/etoolkit/__init__.py index 711c6ae..4cf5d6e 100644 --- a/src/etoolkit/__init__.py +++ b/src/etoolkit/__init__.py | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | from .etoolkit import EtoolkitInstance, EtoolkitInstanceError | 18 | from .etoolkit import EtoolkitInstance, EtoolkitInstanceError |
| 19 | 19 | ||
| 20 | __author__ = 'Simeon Simeonov' | 20 | __author__ = 'Simeon Simeonov' |
| 21 | __version__ = '2.0.0' | 21 | __version__ = '2.1.0' |
| 22 | __license__ = 'GPL3' | 22 | __license__ = 'GPL3' |
| 23 | 23 | ||
| 24 | 24 | ||
diff --git a/src/etoolkit/etoolkit.py b/src/etoolkit/etoolkit.py index 9a1b47e..a933a01 100644 --- a/src/etoolkit/etoolkit.py +++ b/src/etoolkit/etoolkit.py | |||
| @@ -43,6 +43,7 @@ class EtoolkitInstance: | |||
| 43 | """ | 43 | """ |
| 44 | self._name = name | 44 | self._name = name |
| 45 | self._parent = None | 45 | self._parent = None |
| 46 | self._env = None | ||
| 46 | self._raw_env_variables = {} | 47 | self._raw_env_variables = {} |
| 47 | self._sensitive_env_variables = [] | 48 | self._sensitive_env_variables = [] |
| 48 | self._master_password = None | 49 | self._master_password = None |
| @@ -57,9 +58,6 @@ class EtoolkitInstance: | |||
| 57 | self._instance_data['ETOOLKIT_PARENT'], data | 58 | self._instance_data['ETOOLKIT_PARENT'], data |
| 58 | ) | 59 | ) |
| 59 | self._raw_env_variables.update(self._parent.raw_env_variables) | 60 | self._raw_env_variables.update(self._parent.raw_env_variables) |
| 60 | self._sensitive_env_variables.extend( | ||
| 61 | self._parent.sensitive_env_variables | ||
| 62 | ) | ||
| 63 | if self._instance_data.get('ETOOLKIT_SENSITIVE'): | 61 | if self._instance_data.get('ETOOLKIT_SENSITIVE'): |
| 64 | if not isinstance(self._instance_data['ETOOLKIT_SENSITIVE'], list): | 62 | if not isinstance(self._instance_data['ETOOLKIT_SENSITIVE'], list): |
| 65 | raise EtoolkitInstanceError( | 63 | raise EtoolkitInstanceError( |
| @@ -399,6 +397,9 @@ class EtoolkitInstance: | |||
| 399 | :return: New environment dict with all macros replaced by their values | 397 | :return: New environment dict with all macros replaced by their values |
| 400 | :rtype: dict | 398 | :rtype: dict |
| 401 | """ | 399 | """ |
| 400 | if self._env is not None: | ||
| 401 | return self._env | ||
| 402 | |||
| 402 | macros = { | 403 | macros = { |
| 403 | '%h': os.path.expanduser('~'), | 404 | '%h': os.path.expanduser('~'), |
| 404 | '%i': self.name, | 405 | '%i': self.name, |
| @@ -419,6 +420,8 @@ class EtoolkitInstance: | |||
| 419 | ) | 420 | ) |
| 420 | if isinstance(value, str) and value.startswith('enc-val$'): | 421 | if isinstance(value, str) and value.startswith('enc-val$'): |
| 421 | value = self._decrypt_value(value) | 422 | value = self._decrypt_value(value) |
| 423 | if key not in self._sensitive_env_variables: | ||
| 424 | self._sensitive_env_variables.append(key) | ||
| 422 | if isinstance(value, str) and value.endswith(':'): | 425 | if isinstance(value, str) and value.endswith(':'): |
| 423 | # if 'value' ends with ':', append the existing value of | 426 | # if 'value' ends with ':', append the existing value of |
| 424 | # os.environ[key] after the value of 'value' | 427 | # os.environ[key] after the value of 'value' |
| @@ -434,6 +437,15 @@ class EtoolkitInstance: | |||
| 434 | else: | 437 | else: |
| 435 | # completely overwrite the existing value of os.environ[key] | 438 | # completely overwrite the existing value of os.environ[key] |
| 436 | new_env[key] = self.parse_value(value, macros) | 439 | new_env[key] = self.parse_value(value, macros) |
| 440 | |||
| 441 | # add the sensitive variables list of the parent (if any) | ||
| 442 | if self._parent is not None: | ||
| 443 | self._sensitive_env_variables.extend( | ||
| 444 | self._parent.sensitive_env_variables | ||
| 445 | ) | ||
| 446 | |||
| 447 | self._env = new_env | ||
| 448 | |||
| 437 | return new_env | 449 | return new_env |
| 438 | 450 | ||
| 439 | def get_full_name(self, delimiter: str = '') -> str: | 451 | def get_full_name(self, delimiter: str = '') -> str: |
diff --git a/tests/conftest.py b/tests/conftest.py index 37dd184..a4463fd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py | |||
| @@ -49,6 +49,11 @@ def config_data(): | |||
| 49 | '+YYrZbwTBuG0Pl+WMQrvxLUtq5j8qYuQqz' | 49 | '+YYrZbwTBuG0Pl+WMQrvxLUtq5j8qYuQqz' |
| 50 | 'oIwgoGt7AaWZCJz+E7qoDeg3wke70ST8U=' | 50 | 'oIwgoGt7AaWZCJz+E7qoDeg3wke70ST8U=' |
| 51 | ), | 51 | ), |
| 52 | 'ETOOLKIT_TEST_PASSWORD2': ( | ||
| 53 | 'enc-val$2$RCSZqq9pWrRDoCVYVHopyu1LzaJGfv8roVviqrLTBxM=$' | ||
| 54 | '+YYrZbwTBuG0Pl+WMQrvxLUtq5j8qYuQqz' | ||
| 55 | 'oIwgoGt7AaWZCJz+E7qoDeg3wke70ST8U=' | ||
| 56 | ), | ||
| 52 | }, | 57 | }, |
| 53 | }, | 58 | }, |
| 54 | } | 59 | } |
diff --git a/tests/test_envtoolkit_instance.py b/tests/test_envtoolkit_instance.py index 9873d57..f555f81 100644 --- a/tests/test_envtoolkit_instance.py +++ b/tests/test_envtoolkit_instance.py | |||
| @@ -31,7 +31,8 @@ def test_instantiation(config_data): | |||
| 31 | instance = etoolkit.EtoolkitInstance('secret', config_data) | 31 | instance = etoolkit.EtoolkitInstance('secret', config_data) |
| 32 | assert 'ETOOLKIT_PARENT' not in instance.raw_env_variables | 32 | assert 'ETOOLKIT_PARENT' not in instance.raw_env_variables |
| 33 | assert 'ETOOLKIT_SENSITIVE' not in instance.raw_env_variables | 33 | assert 'ETOOLKIT_SENSITIVE' not in instance.raw_env_variables |
| 34 | assert 'DB_CONNECTION' not in instance.sensitive_env_variables | 34 | assert 'GNUPGHOME' not in instance.sensitive_env_variables |
| 35 | assert 'ETOOLKIT_TEST_PASSWORD2' not in instance.sensitive_env_variables | ||
| 35 | assert 'ETOOLKIT_TEST_PASSWORD' in instance.sensitive_env_variables | 36 | assert 'ETOOLKIT_TEST_PASSWORD' in instance.sensitive_env_variables |
| 36 | assert instance.name == 'secret' | 37 | assert instance.name == 'secret' |
| 37 | assert ( | 38 | assert ( |
| @@ -64,6 +65,7 @@ def test_get_environ( | |||
| 64 | env = instance.get_environ() | 65 | env = instance.get_environ() |
| 65 | assert isinstance(env, dict) | 66 | assert isinstance(env, dict) |
| 66 | assert env['ETOOLKIT_TEST_PASSWORD'] == short_value | 67 | assert env['ETOOLKIT_TEST_PASSWORD'] == short_value |
| 68 | assert 'ETOOLKIT_TEST_PASSWORD2' in instance.sensitive_env_variables | ||
| 67 | 69 | ||
| 68 | 70 | ||
| 69 | def test_get_full_name(config_data): | 71 | def test_get_full_name(config_data): |
