From 4626bbb00978d4f1ec48edcb406d0d56c0efcb66 Mon Sep 17 00:00:00 2001 From: VaiTon <eyadlorenzo@gmail.com> Date: Mon, 7 Apr 2025 22:14:44 +0200 Subject: [PATCH 1/4] feat: allow specifying access_token as an env var --- ctfcli/__main__.py | 6 +++++- ctfcli/core/api.py | 7 ++++++- ctfcli/core/config.py | 22 ++++++++++++++++++++++ ctfcli/core/exceptions.py | 7 +++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/ctfcli/__main__.py b/ctfcli/__main__.py index dcbf0a5..032618c 100644 --- a/ctfcli/__main__.py +++ b/ctfcli/__main__.py @@ -16,7 +16,7 @@ from ctfcli.cli.pages import PagesCommand from ctfcli.cli.plugins import PluginsCommand from ctfcli.cli.templates import TemplatesCommand -from ctfcli.core.exceptions import ProjectNotInitialized +from ctfcli.core.exceptions import MissingAPIKey, ProjectNotInitialized from ctfcli.core.plugins import load_plugins from ctfcli.utils.git import check_if_dir_is_inside_git_repo @@ -148,6 +148,10 @@ def main(): if isinstance(ret, int): sys.exit(ret) + except MissingAPIKey as e: + click.secho(e, fg="red") + sys.exit(1) + except ProjectNotInitialized: if click.confirm( "Outside of a ctfcli project, would you like to start a new project in this directory?", diff --git a/ctfcli/core/api.py b/ctfcli/core/api.py index 5487642..c9c62c5 100644 --- a/ctfcli/core/api.py +++ b/ctfcli/core/api.py @@ -3,6 +3,7 @@ from requests import Session from ctfcli.core.config import Config +from ctfcli.core.exceptions import MissingAPIKey class API(Session): @@ -11,7 +12,11 @@ def __init__(self): # Load required configuration values self.url = config["config"]["url"] - self.access_token = config["config"]["access_token"] + + try: + self.access_token = config["config"]["access_token"] + except KeyError: + raise MissingAPIKey() # Handle SSL verification disabling try: diff --git a/ctfcli/core/config.py b/ctfcli/core/config.py index 3e68d67..66103ff 100644 --- a/ctfcli/core/config.py +++ b/ctfcli/core/config.py @@ -10,6 +10,10 @@ class Config: + _env_vars = { + "CTFD_TOKEN": "access_token", + } + def __init__(self): self.base_path = self.get_base_path() self.project_path = self.get_project_path() @@ -26,6 +30,24 @@ def __init__(self): self.config = parser self.challenges = dict(self.config["challenges"]) + # Load environment variables + self._env_overrides() + + def _env_overrides(self): + """ + For each environment variable specified in _env_vars, check if it exists + and if so, add it to the config under the "config" section. + """ + for env_var, config_key in self._env_vars.items(): + env_value = os.getenv(env_var) + if not env_value: + continue + + if not self.config.has_section("config"): + self.config.add_section("config") + + self.config["config"][config_key] = env_value + def __getitem__(self, key): return self.config[key] diff --git a/ctfcli/core/exceptions.py b/ctfcli/core/exceptions.py index bb5e4a4..fb6fa8c 100644 --- a/ctfcli/core/exceptions.py +++ b/ctfcli/core/exceptions.py @@ -3,6 +3,13 @@ import click +class MissingAPIKey(Exception): + def __str__(self): + return ( + "Missing API key. Please set the API key in your configuration file or set CTFD_TOKEN environment variable." + ) + + class ProjectNotInitialized(Exception): pass From e251135b3c1ad7935f9e68be1efcf7052727de9d Mon Sep 17 00:00:00 2001 From: Kevin Chung <kchung@ctfd.io> Date: Fri, 25 Apr 2025 02:13:23 -0400 Subject: [PATCH 2/4] Allow specifying URL via envvar update token envvar name --- ctfcli/core/config.py | 3 ++- ctfcli/core/exceptions.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ctfcli/core/config.py b/ctfcli/core/config.py index 66103ff..028a7a0 100644 --- a/ctfcli/core/config.py +++ b/ctfcli/core/config.py @@ -11,7 +11,8 @@ class Config: _env_vars = { - "CTFD_TOKEN": "access_token", + "CTFCLI_ACCESS_TOKEN": "access_token", + "CTFCLI_URL": "url", } def __init__(self): diff --git a/ctfcli/core/exceptions.py b/ctfcli/core/exceptions.py index fb6fa8c..ab69d7d 100644 --- a/ctfcli/core/exceptions.py +++ b/ctfcli/core/exceptions.py @@ -6,7 +6,7 @@ class MissingAPIKey(Exception): def __str__(self): return ( - "Missing API key. Please set the API key in your configuration file or set CTFD_TOKEN environment variable." + "Missing API key. Please set the API key in your configuration file or set CTFCLI_ACCESS_TOKEN environment variable." ) From 15a5009ed9c10a48a6a10f7ad331e6c4800b5982 Mon Sep 17 00:00:00 2001 From: Kevin Chung <kchung@ctfd.io> Date: Fri, 25 Apr 2025 02:21:27 -0400 Subject: [PATCH 3/4] Show error if instance URL not configured --- ctfcli/__main__.py | 10 +++++++++- ctfcli/core/api.py | 7 +++++-- ctfcli/core/exceptions.py | 11 ++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/ctfcli/__main__.py b/ctfcli/__main__.py index 032618c..d4467eb 100644 --- a/ctfcli/__main__.py +++ b/ctfcli/__main__.py @@ -16,7 +16,11 @@ from ctfcli.cli.pages import PagesCommand from ctfcli.cli.plugins import PluginsCommand from ctfcli.cli.templates import TemplatesCommand -from ctfcli.core.exceptions import MissingAPIKey, ProjectNotInitialized +from ctfcli.core.exceptions import ( + MissingAPIKey, + MissingInstanceURL, + ProjectNotInitialized, +) from ctfcli.core.plugins import load_plugins from ctfcli.utils.git import check_if_dir_is_inside_git_repo @@ -148,6 +152,10 @@ def main(): if isinstance(ret, int): sys.exit(ret) + except MissingInstanceURL as e: + click.secho(e, fg="red") + sys.exit(1) + except MissingAPIKey as e: click.secho(e, fg="red") sys.exit(1) diff --git a/ctfcli/core/api.py b/ctfcli/core/api.py index c9c62c5..f3b797a 100644 --- a/ctfcli/core/api.py +++ b/ctfcli/core/api.py @@ -3,7 +3,7 @@ from requests import Session from ctfcli.core.config import Config -from ctfcli.core.exceptions import MissingAPIKey +from ctfcli.core.exceptions import MissingAPIKey, MissingInstanceURL class API(Session): @@ -11,7 +11,10 @@ def __init__(self): config = Config() # Load required configuration values - self.url = config["config"]["url"] + try: + self.url = config["config"]["url"] + except KeyError: + raise MissingInstanceURL() try: self.access_token = config["config"]["access_token"] diff --git a/ctfcli/core/exceptions.py b/ctfcli/core/exceptions.py index ab69d7d..5c49d2d 100644 --- a/ctfcli/core/exceptions.py +++ b/ctfcli/core/exceptions.py @@ -6,7 +6,16 @@ class MissingAPIKey(Exception): def __str__(self): return ( - "Missing API key. Please set the API key in your configuration file or set CTFCLI_ACCESS_TOKEN environment variable." + "Missing API key. " + "Please set the API key in your configuration file or set the CTFCLI_ACCESS_TOKEN environment variable." + ) + + +class MissingInstanceURL(Exception): + def __str__(self): + return ( + "Missing CTFd instance URL. " + "Please set the instance URL in your configuration file or set the CTFCLI_URL environment variable." ) From ea158a2084e82779d5b7a63327d7e497705f574d Mon Sep 17 00:00:00 2001 From: Kevin Chung <kchung@ctfd.io> Date: Fri, 25 Apr 2025 02:32:27 -0400 Subject: [PATCH 4/4] update upload-artifact version --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bfe617c..cddca22 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: - name: Build package run: poetry build - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: | ./dist/*.tar.gz