From 997e228e35ba35b61c4968eea27c212ba72201fc Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Sun, 4 May 2025 17:22:32 -0400 Subject: [PATCH 1/2] Add support for hint titles released in CTFd 3.7.7 --- ctfcli/core/challenge.py | 2 ++ ctfcli/spec/challenge-example.yml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/ctfcli/core/challenge.py b/ctfcli/core/challenge.py index 517f550..77a9f22 100644 --- a/ctfcli/core/challenge.py +++ b/ctfcli/core/challenge.py @@ -398,12 +398,14 @@ def _create_hints(self): if type(hint) == str: hint_payload = { "content": hint, + "title": "", "cost": 0, "challenge_id": self.challenge_id, } else: hint_payload = { "content": hint["content"], + "title": hint.get("title", ""), "cost": hint["cost"], "challenge_id": self.challenge_id, } diff --git a/ctfcli/spec/challenge-example.yml b/ctfcli/spec/challenge-example.yml index 4c73f13..f8fe07c 100644 --- a/ctfcli/spec/challenge-example.yml +++ b/ctfcli/spec/challenge-example.yml @@ -107,6 +107,9 @@ hints: cost: 10 } - This hint is free + - title: Titled Hint + content: This hint has a title and costs points + cost: 10 # Requirements are used to make a challenge require another challenge to be # solved before being available. From d13a0c783ceca87dadfd630371923a1c2c9746d0 Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Sun, 4 May 2025 17:33:46 -0400 Subject: [PATCH 2/2] Fix tests --- tests/core/test_challenge.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/core/test_challenge.py b/tests/core/test_challenge.py index cbc404d..22c4b5f 100644 --- a/tests/core/test_challenge.py +++ b/tests/core/test_challenge.py @@ -699,9 +699,9 @@ def test_updates_hints(self, mock_api_constructor: MagicMock, *args, **kwargs): mock_api.post.assert_has_calls( [ - call("/api/v1/hints", json={"content": "free hint", "cost": 0, "challenge_id": 1}), + call("/api/v1/hints", json={"content": "free hint", "title": "", "cost": 0, "challenge_id": 1}), call().raise_for_status(), - call("/api/v1/hints", json={"content": "paid hint", "cost": 100, "challenge_id": 1}), + call("/api/v1/hints", json={"content": "paid hint", "title": "", "cost": 100, "challenge_id": 1}), call().raise_for_status(), ] ) @@ -1029,7 +1029,7 @@ def test_updates_multiple_attributes_at_once(self, mock_api_constructor: MagicMo call().raise_for_status(), call("/api/v1/files", files=ANY, data={"challenge_id": 1, "type": "challenge"}), call().raise_for_status(), - call("/api/v1/hints", json={"content": "free hint", "cost": 0, "challenge_id": 1}), + call("/api/v1/hints", json={"title": "", "content": "free hint", "cost": 0, "challenge_id": 1}), call().raise_for_status(), ] ) @@ -1237,8 +1237,8 @@ def mock_post(*args, **kwargs): # files call("/api/v1/files", files=ANY, data={"challenge_id": 3, "type": "challenge"}), # hints - call("/api/v1/hints", json={"content": "free hint", "cost": 0, "challenge_id": 3}), - call("/api/v1/hints", json={"content": "paid hint", "cost": 100, "challenge_id": 3}), + call("/api/v1/hints", json={"title": "", "content": "free hint", "cost": 0, "challenge_id": 3}), + call("/api/v1/hints", json={"title": "", "content": "paid hint", "cost": 100, "challenge_id": 3}), ] )