Repository: CTFd/CTFd

Issue:
Bootstrap Beta v3
https://getbootstrap.com/docs/4.0/migration/#beta-3-changes

See if anything needs to be changed to support Bootstrap Betav3. Supposedly there won't be breaking changes between v3 and Stable so this is a good issue to look into. 



Discussion:

Resolving patch:
diff --git a/CTFd/admin/challenges.py b/CTFd/admin/challenges.py
--- a/CTFd/admin/challenges.py
+++ b/CTFd/admin/challenges.py
@@ -31,22 +31,31 @@ def admin_chal_types():
 @admins_only
 def admin_chals():
     if request.method == 'POST':
-        chals = Challenges.query.add_columns('id', 'type', 'name', 'value', 'description', 'category', 'hidden', 'max_attempts').order_by(Challenges.value).all()
+        chals = Challenges.query.order_by(Challenges.value).all()
 
         json_data = {'game': []}
-        for x in chals:
-            type_class = CHALLENGE_CLASSES.get(x.type)
+        for chal in chals:
+            tags = [tag.tag for tag in Tags.query.add_columns('tag').filter_by(chal=chal.id).all()]
+            files = [str(f.location) for f in Files.query.filter_by(chal=chal.id).all()]
+            hints = []
+            for hint in Hints.query.filter_by(chal=chal.id).all():
+                hints.append({'id': hint.id, 'cost': hint.cost, 'hint': hint.hint})
+
+            type_class = CHALLENGE_CLASSES.get(chal.type)
             type_name = type_class.name if type_class else None
 
             json_data['game'].append({
-                'id': x.id,
-                'name': x.name,
-                'value': x.value,
-                'description': x.description,
-                'category': x.category,
-                'hidden': x.hidden,
-                'max_attempts': x.max_attempts,
-                'type': x.type,
+                'id': chal.id,
+                'name': chal.name,
+                'value': chal.value,
+                'description': chal.description,
+                'category': chal.category,
+                'files': files,
+                'tags': tags,
+                'hints': hints,
+                'hidden': chal.hidden,
+                'max_attempts': chal.max_attempts,
+                'type': chal.type,
                 'type_name': type_name,
                 'type_data': {
                     'id': type_class.id,
@@ -77,6 +86,17 @@ def admin_chal_detail(chalid):
             return jsonify({'status': 0, 'message': message})
     elif request.method == 'GET':
         obj, data = chal_class.read(chal)
+
+        tags = [tag.tag for tag in Tags.query.add_columns('tag').filter_by(chal=chal.id).all()]
+        files = [str(f.location) for f in Files.query.filter_by(chal=chal.id).all()]
+        hints = []
+        for hint in Hints.query.filter_by(chal=chal.id).all():
+            hints.append({'id': hint.id, 'cost': hint.cost, 'hint': hint.hint})
+
+        data['tags'] = tags
+        data['files'] = files
+        data['hints'] = hints
+
         return jsonify(data)
 
 


Test patch:
diff --git a/tests/admin/test_admin_facing.py b/tests/admin/test_admin_facing.py
--- a/tests/admin/test_admin_facing.py
+++ b/tests/admin/test_admin_facing.py
@@ -209,6 +209,10 @@ def test_admin_chal_detail_returns_proper_data():
         client = login_as_user(app, name="admin", password="password")
 
         chal = gen_challenge(app.db)
+        tag = gen_tag(app.db, chal.id, 'test-tag')
+        hint = gen_hint(app.db, chal.id, 'test-hint', 5)
+        f = gen_file(app.db, chal.id, '0bf1a55a5cd327c07af15df260979668/bird.swf')
+
         chal_class = get_chal_class(chal.type)
         data = {
             'id': chal.id,
@@ -216,6 +220,9 @@ def test_admin_chal_detail_returns_proper_data():
             'value': chal.value,
             'description': chal.description,
             'category': chal.category,
+            'files': ['0bf1a55a5cd327c07af15df260979668/bird.swf'],
+            'tags': ['test-tag'],
+            'hints': [{'id': 1, 'cost': 5, 'hint': 'test-hint'}],
             'hidden': chal.hidden,
             'max_attempts': chal.max_attempts,
             'type': chal.type,
diff --git a/tests/helpers.py b/tests/helpers.py
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -110,8 +110,11 @@ def gen_tag(db, chal, tag='tag_tag'):
     return tag
 
 
-def gen_file():
-    pass
+def gen_file(db, chal, location):
+    f = Files(chal, location)
+    db.session.add(f)
+    db.session.commit()
+    return f
 
 
 def gen_flag(db, chal, flag='flag', key_type='static'):