vishalbhat07/ctfd
0
1#!/usr/bin/env python2# -*- coding: utf-8 -*-3 4from freezegun import freeze_time5 6from CTFd.models import Unlocks, Users, db7from CTFd.utils import set_config, text_type8from tests.helpers import (9 create_ctfd,10 destroy_ctfd,11 gen_award,12 gen_challenge,13 gen_flag,14 gen_hint,15 login_as_user,16 register_user,17)18 19 20def test_user_cannot_unlock_hint():21 """Test that a user can't unlock a hint if they don't have enough points"""22 app = create_ctfd()23 with app.app_context():24 with app.test_client():25 register_user(app, name="user1", email="user1@examplectf.com")26 27 chal = gen_challenge(app.db, value=100)28 chal_id = chal.id29 30 gen_flag(app.db, challenge_id=chal.id, content="flag")31 32 hint = gen_hint(db, chal_id, cost=10)33 hint_id = hint.id34 35 client = login_as_user(app, name="user1", password="password")36 37 with client.session_transaction():38 r = client.get("/api/v1/hints/{}".format(hint_id))39 resp = r.get_json()40 assert resp["data"].get("content") is None41 assert resp["data"].get("cost") == 1042 destroy_ctfd(app)43 44 45def test_user_can_unlock_hint():46 """Test that a user can unlock a hint if they have enough points"""47 app = create_ctfd()48 with app.app_context():49 with app.test_client():50 register_user(app, name="user1", email="user1@examplectf.com")51 52 chal = gen_challenge(app.db, value=100)53 chal_id = chal.id54 55 gen_flag(app.db, challenge_id=chal.id, content="flag")56 57 hint = gen_hint(app.db, chal_id, cost=10)58 hint_id = hint.id59 60 gen_award(app.db, user_id=2, value=15)61 62 client = login_as_user(app, name="user1", password="password")63 64 user = Users.query.filter_by(name="user1").first()65 assert user.score == 1566 67 with client.session_transaction():68 r = client.get("/api/v1/hints/{}".format(hint_id))69 resp = r.get_json()70 assert resp["data"].get("content") is None71 72 params = {"target": hint_id, "type": "hints"}73 74 r = client.post("/api/v1/unlocks", json=params)75 resp = r.get_json()76 assert resp["success"] is True77 78 r = client.get("/api/v1/hints/{}".format(hint_id))79 resp = r.get_json()80 assert resp["data"].get("content") == "This is a hint"81 82 user = Users.query.filter_by(name="user1").first()83 assert user.score == 584 destroy_ctfd(app)85 86 87def test_unlocking_hints_with_no_cost():88 """Test that hints with no cost can be unlocked"""89 app = create_ctfd()90 with app.app_context():91 register_user(app)92 chal = gen_challenge(app.db)93 chal_id = chal.id94 gen_hint(app.db, chal_id)95 client = login_as_user(app)96 # Attempt to access hint97 r = client.get("/api/v1/hints/1")98 resp = r.get_json()["data"]99 100 # Hint does not provide content until an unlock is generated101 assert resp.get("content") is None102 103 # We generate an unlock for the free hint104 client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})105 106 # We should now be able to see content107 r = client.get("/api/v1/hints/1")108 resp = r.get_json()["data"]109 assert resp.get("content") == "This is a hint"110 destroy_ctfd(app)111 112 113def test_unlocking_hints_with_cost_during_ctf_with_points():114 """Test that hints with a cost are unlocked if you have the points"""115 app = create_ctfd()116 with app.app_context():117 register_user(app)118 chal = gen_challenge(app.db)119 chal_id = chal.id120 gen_hint(app.db, chal_id, cost=10)121 gen_award(app.db, user_id=2)122 123 client = login_as_user(app)124 r = client.get("/api/v1/hints/1")125 assert r.get_json()["data"].get("content") is None126 127 client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})128 129 r = client.get("/api/v1/hints/1")130 assert r.get_json()["data"].get("content") == "This is a hint"131 132 user = Users.query.filter_by(id=2).first()133 assert user.score == 90134 destroy_ctfd(app)135 136 137def test_unlocking_hints_with_cost_during_ctf_without_points():138 """Test that hints with a cost are not unlocked if you don't have the points"""139 app = create_ctfd()140 with app.app_context():141 register_user(app)142 chal = gen_challenge(app.db)143 chal_id = chal.id144 gen_hint(app.db, chal_id, cost=10)145 146 client = login_as_user(app)147 148 r = client.get("/api/v1/hints/1")149 assert r.get_json()["data"].get("content") is None150 151 r = client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})152 assert (153 r.get_json()["errors"]["score"]154 == "You do not have enough points to unlock this hint"155 )156 157 r = client.get("/api/v1/hints/1")158 assert r.get_json()["data"].get("content") is None159 160 user = Users.query.filter_by(id=2).first()161 assert user.score == 0162 destroy_ctfd(app)163 164 165def test_unlocking_hints_with_cost_before_ctf():166 """Test that hints are not unlocked if the CTF hasn't begun"""167 app = create_ctfd()168 with app.app_context():169 register_user(app)170 chal = gen_challenge(app.db)171 chal_id = chal.id172 gen_hint(app.db, chal_id)173 gen_award(app.db, user_id=2)174 175 set_config(176 "start", "1507089600"177 ) # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST178 set_config(179 "end", "1507262400"180 ) # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST181 182 with freeze_time("2017-10-1"):183 client = login_as_user(app)184 185 r = client.get("/api/v1/hints/1")186 assert r.status_code == 403187 assert r.get_json().get("data") is None188 189 r = client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})190 assert r.status_code == 403191 assert r.get_json().get("data") is None192 193 r = client.get("/api/v1/hints/1")194 assert r.get_json().get("data") is None195 assert r.status_code == 403196 197 user = Users.query.filter_by(id=2).first()198 199 assert user.score == 100200 assert Unlocks.query.count() == 0201 destroy_ctfd(app)202 203 204def test_unlocking_hints_with_cost_during_ended_ctf():205 """Test that hints with a cost are not unlocked if the CTF has ended"""206 app = create_ctfd()207 with app.app_context():208 register_user(app)209 chal = gen_challenge(app.db)210 chal_id = chal.id211 gen_hint(app.db, chal_id, cost=10)212 gen_award(app.db, user_id=2)213 214 set_config(215 "start", "1507089600"216 ) # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST217 set_config(218 "end", "1507262400"219 ) # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST220 221 with freeze_time("2017-11-4"):222 client = login_as_user(app)223 224 r = client.get("/api/v1/hints/1")225 assert r.get_json().get("data") is None226 assert r.status_code == 403227 228 r = client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})229 assert r.status_code == 403230 assert r.get_json()231 232 r = client.get("/api/v1/hints/1")233 assert r.status_code == 403234 235 user = Users.query.filter_by(id=2).first()236 assert user.score == 100237 assert Unlocks.query.count() == 0238 destroy_ctfd(app)239 240 241def test_unlocking_hints_with_cost_during_frozen_ctf():242 """Test that hints with a cost are unlocked if the CTF is frozen."""243 app = create_ctfd()244 with app.app_context():245 set_config(246 "freeze", "1507262400"247 ) # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST248 with freeze_time("2017-10-4"):249 register_user(app)250 chal = gen_challenge(app.db)251 chal_id = chal.id252 gen_hint(app.db, chal_id, cost=10)253 gen_award(app.db, user_id=2)254 255 with freeze_time("2017-10-8"):256 client = login_as_user(app)257 258 client.get("/api/v1/hints/1")259 260 client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})261 262 r = client.get("/api/v1/hints/1")263 264 resp = r.get_json()["data"]265 assert resp.get("content") == "This is a hint"266 267 user = Users.query.filter_by(id=2).first()268 assert user.score == 100269 destroy_ctfd(app)270 271 272def test_unlocking_hint_for_unicode_challenge():273 """Test that hints for challenges with unicode names can be unlocked"""274 app = create_ctfd()275 with app.app_context():276 register_user(app)277 chal = gen_challenge(app.db, name=text_type("๐บ"))278 chal_id = chal.id279 gen_hint(app.db, chal_id)280 281 client = login_as_user(app)282 283 # Generate an unlock for the free hint284 client.post("/api/v1/unlocks", json={"target": 1, "type": "hints"})285 r = client.get("/api/v1/hints/1")286 assert r.status_code == 200287 resp = r.get_json()["data"]288 assert resp.get("content") == "This is a hint"289 destroy_ctfd(app)290 