Skip to content

Commit fe2357e

Browse files
committed
Merge branch 'master' of github.com:CTFd/ctfcli
2 parents 08ea502 + 0d946b4 commit fe2357e

File tree

10 files changed

+588
-375
lines changed

10 files changed

+588
-375
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- name: Build package
3434
run: poetry build
3535

36-
- uses: actions/upload-artifact@v3
36+
- uses: actions/upload-artifact@v4
3737
with:
3838
path: |
3939
./dist/*.tar.gz

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99

1010
strategy:
1111
matrix:
12-
python-version: ['3.8', '3.9', '3.10', '3.11']
12+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
1313

1414
name: Testing
1515
steps:

ctfcli/__main__.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
from ctfcli.cli.pages import PagesCommand
1717
from ctfcli.cli.plugins import PluginsCommand
1818
from ctfcli.cli.templates import TemplatesCommand
19-
from ctfcli.core.exceptions import ProjectNotInitialized
19+
from ctfcli.core.exceptions import (
20+
MissingAPIKey,
21+
MissingInstanceURL,
22+
ProjectNotInitialized,
23+
)
2024
from ctfcli.core.plugins import load_plugins
2125
from ctfcli.utils.git import check_if_dir_is_inside_git_repo
2226

@@ -148,6 +152,14 @@ def main():
148152
if isinstance(ret, int):
149153
sys.exit(ret)
150154

155+
except MissingInstanceURL as e:
156+
click.secho(e, fg="red")
157+
sys.exit(1)
158+
159+
except MissingAPIKey as e:
160+
click.secho(e, fg="red")
161+
sys.exit(1)
162+
151163
except ProjectNotInitialized:
152164
if click.confirm(
153165
"Outside of a ctfcli project, would you like to start a new project in this directory?",

ctfcli/core/api.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@
33
from requests import Session
44

55
from ctfcli.core.config import Config
6+
from ctfcli.core.exceptions import MissingAPIKey, MissingInstanceURL
67

78

89
class API(Session):
910
def __init__(self):
1011
config = Config()
1112

1213
# Load required configuration values
13-
self.url = config["config"]["url"]
14-
self.access_token = config["config"]["access_token"]
14+
try:
15+
self.url = config["config"]["url"]
16+
except KeyError:
17+
raise MissingInstanceURL()
18+
19+
try:
20+
self.access_token = config["config"]["access_token"]
21+
except KeyError:
22+
raise MissingAPIKey()
1523

1624
# Handle SSL verification disabling
1725
try:

ctfcli/core/config.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010

1111

1212
class Config:
13+
_env_vars = {
14+
"CTFCLI_ACCESS_TOKEN": "access_token",
15+
"CTFCLI_URL": "url",
16+
}
17+
1318
def __init__(self):
1419
self.base_path = self.get_base_path()
1520
self.project_path = self.get_project_path()
@@ -26,6 +31,24 @@ def __init__(self):
2631
self.config = parser
2732
self.challenges = dict(self.config["challenges"])
2833

34+
# Load environment variables
35+
self._env_overrides()
36+
37+
def _env_overrides(self):
38+
"""
39+
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.
41+
"""
42+
for env_var, config_key in self._env_vars.items():
43+
env_value = os.getenv(env_var)
44+
if not env_value:
45+
continue
46+
47+
if not self.config.has_section("config"):
48+
self.config.add_section("config")
49+
50+
self.config["config"][config_key] = env_value
51+
2952
def __getitem__(self, key):
3053
return self.config[key]
3154

ctfcli/core/deployment/cloud.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from urllib.parse import urlparse
66

77
import click
8+
from slugify import slugify
89

910
from ctfcli.core.api import API
1011
from ctfcli.core.config import Config
@@ -118,7 +119,8 @@ def _get_or_create_service(self, image_location: str):
118119
return self.api.get(f"/api/v1/services/{service_data['id']}").json()["data"]
119120

120121
# Create the service if it doesn't exist
121-
return self.api.post("/api/v1/services", json={"name": self.image_name, "image": image_location}).json()["data"]
122+
image_name_slug = slugify(self.image_name)
123+
return self.api.post("/api/v1/services", json={"name": image_name_slug, "image": image_location}).json()["data"]
122124

123125
def _await_service_deployment(self, service_data, interval=10, timeout=180) -> Optional[Dict]:
124126
service_id = service_data["id"]

ctfcli/core/exceptions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@
33
import click
44

55

6+
class MissingAPIKey(Exception):
7+
def __str__(self):
8+
return (
9+
"Missing API key. "
10+
"Please set the API key in your configuration file or set the CTFCLI_ACCESS_TOKEN environment variable."
11+
)
12+
13+
14+
class MissingInstanceURL(Exception):
15+
def __str__(self):
16+
return (
17+
"Missing CTFd instance URL. "
18+
"Please set the instance URL in your configuration file or set the CTFCLI_URL environment variable."
19+
)
20+
21+
622
class ProjectNotInitialized(Exception):
723
pass
824

poetry.lock

Lines changed: 518 additions & 367 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

preprocess.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
def replace_symlinks():
5-
os.system("""find . -type l -exec sh -c 'target=$(readlink -f "$0"); rm "$0" && cp "$target" "$0"' {} \;""")
5+
os.system("""find . -type l -exec sh -c 'target=$(readlink -f "$0"); rm "$0" && cp "$target" "$0"' {} \\;""")
66

77

88
if __name__ == "__main__":

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ click = "^8.1.7"
2222
cookiecutter = "^2.3.0"
2323
appdirs = "^1.4.4"
2424
colorama = "^0.4.6"
25-
fire = "^0.5.0"
25+
fire = "^0.7.0"
2626
typing-extensions = "^4.7.1"
27+
python-slugify = "^8.0.4"
2728

2829
[tool.poetry.group.dev.dependencies]
2930
black = "^23.7.0"

0 commit comments

Comments
 (0)