Repository: CTFd/CTFd
Pull request #388 (2017-09-13 15:57:50)

Fixing issues with loading /chals when unregistered
Add tests for seeing challenges while unregistered and also revert some changes to some of the challenge APIs. 


Patch:
diff --git a/CTFd/challenges.py b/CTFd/challenges.py
index 1a5252cd..981e28c4 100644
--- a/CTFd/challenges.py
+++ b/CTFd/challenges.py
@@ -107,19 +107,19 @@ def chals():
             else:
                 abort(403)
     if utils.user_can_view_challenges() and (utils.ctf_started() or utils.is_admin()):
+        teamid = session.get('id')
         chals = Challenges.query.filter(or_(Challenges.hidden != True, Challenges.hidden == None)).order_by(Challenges.value).all()
         json = {'game': []}
         for x in chals:
             tags = [tag.tag for tag in Tags.query.add_columns('tag').filter_by(chal=x.id).all()]
             files = [str(f.location) for f in Files.query.filter_by(chal=x.id).all()]
-            unlocked_hints = set([u.itemid for u in Unlocks.query.filter_by(model='hints', teamid=session['id'])])
+            unlocked_hints = set([u.itemid for u in Unlocks.query.filter_by(model='hints', teamid=teamid)])
             hints = []
             for hint in Hints.query.filter_by(chal=x.id).all():
                 if hint.id in unlocked_hints or utils.ctf_ended():
                     hints.append({'id': hint.id, 'cost': hint.cost, 'hint': hint.hint})
                 else:
                     hints.append({'id': hint.id, 'cost': hint.cost})
-            # hints = [{'id':hint.id, 'cost':hint.cost} for hint in Hints.query.filter_by(chal=x.id).all()]
             chal_type = get_chal_class(x.type)
             json['game'].append({
                 'id': x.id,
@@ -351,4 +351,4 @@ def chal(chalid):
         return jsonify({
             'status': -1,
             'message': "You must be logged in to solve a challenge"
-        }), 403
+        })


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
index efbf023e..684e739e 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -194,7 +194,9 @@ def test_ctftime_prevents_accessing_challenges_before_ctf():
                     "nonce": sess.get('nonce')
                 }
             r = client.post('/chal/{}'.format(chal_id), data=data)
-            assert r.status_code == 403
+            data = r.get_data(as_text=True)
+            data = json.loads(data)
+            assert data['status'] == -1
         solve_count = app.db.session.query(app.db.func.count(Solves.id)).first()[0]
         assert solve_count == 0
     destroy_ctfd(app)
diff --git a/tests/user/test_challenges.py b/tests/user/test_challenges.py
index 37aeb50e..035c0d5c 100644
--- a/tests/user/test_challenges.py
+++ b/tests/user/test_challenges.py
@@ -228,3 +228,41 @@ def test_unlocking_hint_for_unicode_challenge():
         output = json.loads(output)
         assert output.get('hint') == 'This is a hint'
     destroy_ctfd(app)
+
+
+def test_that_view_challenges_unregistered_works():
+    '''Test that view_challenges_unregistered works'''
+    app = create_ctfd()
+    with app.app_context():
+        chal = gen_challenge(app.db, name=text_type('🐺'))
+        chal_id = chal.id
+        hint = gen_hint(app.db, chal_id)
+
+        client = app.test_client()
+        r = client.get('/chals')
+        assert r.status_code == 403
+
+        config = set_config('view_challenges_unregistered', True)
+
+        client = app.test_client()
+        r = client.get('/chals')
+        data = r.get_data(as_text=True)
+        assert json.loads(data)
+
+        r = client.get('/chals/solves')
+        data = r.get_data(as_text=True)
+        assert json.loads(data) == {}
+
+        r = client.get('/chal/1/solves')
+        data = r.get_data(as_text=True)
+        assert json.loads(data)
+
+        with client.session_transaction() as sess:
+            data = {
+                "key": 'not_flag',
+                "nonce": sess.get('nonce')
+            }
+        r = client.post('/chal/{}'.format(chal_id), data=data)
+        data = r.get_data(as_text=True)
+        data = json.loads(data)
+        assert data['status'] == -1