Skip to content

Commit

Permalink
fix(api)!: use correct type for boolean and int
Browse files Browse the repository at this point in the history
  • Loading branch information
NicoFgrx committed Jan 15, 2025
1 parent 000af7b commit ee5b8de
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
22 changes: 17 additions & 5 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class DynamicIaCChallenge(DynamicChallenge):
)
mana_cost = db.Column(db.Integer, default=0)
until = db.Column(db.Text) # date
timeout = db.Column(db.Text) # duration
timeout = db.Column(db.Integer)
shared = db.Column(db.Boolean, default=False)
destroy_on_flag = db.Column(db.Boolean, default=False)

Expand Down Expand Up @@ -92,10 +92,10 @@ def create(cls, request):

# convert string value to boolean
if "shared" in data.keys():
data["shared"] = data["shared"] == "true"
data["shared"] = convert_to_boolean(data["shared"])

if "destroy_on_flag" in data.keys():
data["destroy_on_flag"] = data["destroy_on_flag"] == "true"
data["destroy_on_flag"] = convert_to_boolean(data["destroy_on_flag"])

if "scenario_id" not in data.keys():
logger.error("missing mandatory value in challenge creation")
Expand Down Expand Up @@ -181,7 +181,7 @@ def update(cls, challenge, request):
data = request.form or request.get_json()

if "shared" in data.keys():
data["shared"] = data["shared"] == "true" # convert string to boolean
data["shared"] = convert_to_boolean(data["shared"])

try:
r = get_challenge(challenge.id)
Expand Down Expand Up @@ -209,7 +209,7 @@ def update(cls, challenge, request):

# Update the destroy on flag boolean
if "destroy_on_flag" in data.keys():
data["destroy_on_flag"] = data["destroy_on_flag"] == "true" # convert string into boolean
data["destroy_on_flag"] = convert_to_boolean(data["destroy_on_flag"])

# Workaround
if "state" in data.keys() and len(data.keys()) == 1:
Expand Down Expand Up @@ -391,3 +391,15 @@ def attempt(cls, challenge, request):
return False, str(e)
logger.info(f"invalid submission for CTFd flag: challenge {challenge.id} source {sourceId}")
return False, "Incorrect"


def convert_to_boolean(value):
# Check if the value is a string and convert it to boolean if it matches "true" or "false" (case-insensitive)
if isinstance(value, str):
value_lower = value.strip().lower()
if value_lower == "true":
return True
elif value_lower == "false":
return False
# If the value is already a boolean or doesn't match a boolean string, return it as is
return value
6 changes: 3 additions & 3 deletions test/test_api_challenges.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

class Test_F_Challenges(unittest.TestCase):
def test_create_challenge_with_all_params(self):
chall_id = create_challenge(shared="true", destroy_on_flag="true", until="2222-02-22T21:22:00.000Z", timeout="2222")
chall_id = create_challenge(shared="true", destroy_on_flag="true", until="2222-02-22T21:22:00.000Z", timeout=2222)

r = requests.get(f"{config.ctfd_url}/api/v1/challenges/{chall_id}", headers=config.headers_admin)
a = json.loads(r.text)
Expand All @@ -40,7 +40,7 @@ def test_create_challenge_with_all_params(self):
self.assertEqual(a["data"]["shared"], True)
self.assertEqual(a["data"]["destroy_on_flag"], True)
self.assertEqual(a["data"]["until"], "2222-02-22T21:22:00.000Z")
self.assertEqual(a["data"]["timeout"], "2222")
self.assertEqual(a["data"]["timeout"], 2222)
self.assertEqual(a["data"]["scenario_id"], config.scenario_id)

delete_challenge(chall_id)
Expand Down Expand Up @@ -78,7 +78,7 @@ def test_create_challenge_with_mandatory_params(self):
self.assertEqual(a["data"]["shared"], True)
self.assertEqual(a["data"]["destroy_on_flag"], True)
self.assertEqual(a["data"]["until"], "2222-02-22T21:22:00.000Z")
self.assertEqual(a["data"]["timeout"], "2222")
self.assertEqual(a["data"]["timeout"], 2222)

# clean testing environment
delete_challenge(chall_id)
Expand Down

0 comments on commit ee5b8de

Please sign in to comment.