Skip to content

Commit 1a9e080

Browse files
authored
Don't write envvar configs to disk (#221)
1 parent a103e68 commit 1a9e080

2 files changed

Lines changed: 32 additions & 9 deletions

File tree

‎ctfcli/core/config.py‎

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@
99
from ctfcli.core.exceptions import ProjectNotInitialized
1010

1111

12+
class EnvConfigParser(configparser.ConfigParser):
13+
"""
14+
ConfigParser that reads environment variable overrides from the "config" section
15+
without storing them, so they are never written to disk.
16+
"""
17+
18+
env_overrides = {}
19+
20+
def get(self, section, option, **kwargs):
21+
if section == "config" and option in self.env_overrides:
22+
return self.env_overrides[option]
23+
return super().get(section, option, **kwargs)
24+
25+
def has_option(self, section, option):
26+
if section == "config" and option in self.env_overrides:
27+
return True
28+
return super().has_option(section, option)
29+
30+
1231
class Config:
1332
_env_vars = {
1433
"CTFCLI_ACCESS_TOKEN": "access_token",
@@ -24,7 +43,7 @@ def __init__(self):
2443
self.pages_path = self.get_pages_path()
2544
self.plugins_path = self.get_plugins_path()
2645

27-
parser = configparser.ConfigParser()
46+
parser = EnvConfigParser()
2847
parser.optionxform = str
2948
parser.read(self.config_path)
3049

@@ -37,17 +56,18 @@ def __init__(self):
3756
def _env_overrides(self):
3857
"""
3958
For each environment variable specified in _env_vars, check if it exists
40-
and if so, add it to the config under the "config" section.
59+
and if so, set it as an override for the "config" section.
4160
"""
61+
overrides = {}
4262
for env_var, config_key in self._env_vars.items():
4363
env_value = os.getenv(env_var)
44-
if not env_value:
45-
continue
64+
if env_value:
65+
overrides[config_key] = env_value
4666

47-
if not self.config.has_section("config"):
48-
self.config.add_section("config")
67+
if overrides and not self.config.has_section("config"):
68+
self.config.add_section("config")
4969

50-
self.config["config"][config_key] = env_value
70+
self.config.env_overrides = overrides
5171

5272
def __getitem__(self, key):
5373
return self.config[key]
@@ -65,6 +85,9 @@ def as_json(self, pretty=False) -> str:
6585
for k, v in self.config.items(section):
6686
data[section][k] = v
6787

88+
for k, v in self.config.env_overrides.items():
89+
data["config"][k] = v
90+
6891
if pretty:
6992
return json.dumps(data, sort_keys=True, indent=4)
7093

‎tests/core/test_config.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ def test_determines_config_path(self, *args, **kwargs):
4242
self.assertEqual(expected_config_path, config.get_config_path())
4343

4444
@mock.patch("ctfcli.core.config.Path.cwd", return_value=minimal_challenge_cwd)
45-
@mock.patch("ctfcli.core.config.configparser.ConfigParser")
45+
@mock.patch("ctfcli.core.config.EnvConfigParser")
4646
def test_reads_config(self, mock_configparser: MagicMock, *args, **kwargs):
4747
Config()
4848
expected_config_path = BASE_DIR / "fixtures" / "challenges" / ".ctf" / "config"
4949
mock_configparser.return_value.read.assert_called_once_with(expected_config_path)
5050

5151
@mock.patch("ctfcli.core.config.Path.cwd", return_value=minimal_challenge_cwd)
52-
@mock.patch("ctfcli.core.config.configparser.ConfigParser")
52+
@mock.patch("ctfcli.core.config.EnvConfigParser")
5353
def test_writes_config(self, mock_configparser: MagicMock, *args, **kwargs):
5454
config = Config()
5555

0 commit comments

Comments
 (0)