mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-17 14:04:20 +01:00
Preventing Hints from being unlocked after the end of a CTF (#439)
* Preventing Hints from being unlocked after the end of a CTF unless challenges can be viewed
This commit is contained in:
@@ -36,31 +36,27 @@ def hints_view(hintid):
|
|||||||
'cost': hint.cost
|
'cost': hint.cost
|
||||||
})
|
})
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
if not unlock and utils.ctftime():
|
if unlock is None: # The user does not have an unlock.
|
||||||
team = Teams.query.filter_by(id=session['id']).first()
|
if utils.ctftime() or (utils.ctf_ended() and utils.view_after_ctf()):
|
||||||
if team.score() < hint.cost:
|
# It's ctftime or the CTF has ended (but we allow views after)
|
||||||
return jsonify({'errors': 'Not enough points'})
|
team = Teams.query.filter_by(id=session['id']).first()
|
||||||
unlock = Unlocks(model='hints', teamid=session['id'], itemid=hint.id)
|
if team.score() < hint.cost:
|
||||||
award = Awards(teamid=session['id'], name=text_type('Hint for {}'.format(chal.name)), value=(-hint.cost))
|
return jsonify({'errors': 'Not enough points'})
|
||||||
db.session.add(unlock)
|
unlock = Unlocks(model='hints', teamid=session['id'], itemid=hint.id)
|
||||||
db.session.add(award)
|
award = Awards(teamid=session['id'], name=text_type('Hint for {}'.format(chal.name)), value=(-hint.cost))
|
||||||
db.session.commit()
|
db.session.add(unlock)
|
||||||
json_data = {
|
db.session.add(award)
|
||||||
'hint': hint.hint,
|
db.session.commit()
|
||||||
'chal': hint.chal,
|
json_data = {
|
||||||
'cost': hint.cost
|
'hint': hint.hint,
|
||||||
}
|
'chal': hint.chal,
|
||||||
db.session.close()
|
'cost': hint.cost
|
||||||
return jsonify(json_data)
|
}
|
||||||
elif utils.ctf_ended():
|
db.session.close()
|
||||||
json_data = {
|
return jsonify(json_data)
|
||||||
'hint': hint.hint,
|
elif utils.ctf_ended(): # The CTF has ended. No views after.
|
||||||
'chal': hint.chal,
|
abort(403)
|
||||||
'cost': hint.cost
|
else: # The user does have an unlock, we should give them their hint.
|
||||||
}
|
|
||||||
db.session.close()
|
|
||||||
return jsonify(json_data)
|
|
||||||
else:
|
|
||||||
json_data = {
|
json_data = {
|
||||||
'hint': hint.hint,
|
'hint': hint.hint,
|
||||||
'chal': hint.chal,
|
'chal': hint.chal,
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ def gen_challenge(db, name='chal_name', description='chal_description', value=10
|
|||||||
|
|
||||||
def gen_award(db, teamid, name="award_name", value=100):
|
def gen_award(db, teamid, name="award_name", value=100):
|
||||||
award = Awards(teamid, name, value)
|
award = Awards(teamid, name, value)
|
||||||
|
award.date = datetime.datetime.utcnow()
|
||||||
db.session.add(award)
|
db.session.add(award)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return award
|
return award
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ def test_submitting_flags_with_large_ips():
|
|||||||
|
|
||||||
|
|
||||||
def test_unlocking_hints_with_no_cost():
|
def test_unlocking_hints_with_no_cost():
|
||||||
'''Test that hints with no cost can be unlocked'''
|
"""Test that hints with no cost can be unlocked"""
|
||||||
app = create_ctfd()
|
app = create_ctfd()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
register_user(app)
|
register_user(app)
|
||||||
@@ -291,8 +291,110 @@ def test_unlocking_hints_with_no_cost():
|
|||||||
destroy_ctfd(app)
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unlocking_hints_with_cost_during_ctf_with_points():
|
||||||
|
"""Test that hints with a cost are unlocked if you have the points"""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
register_user(app)
|
||||||
|
chal = gen_challenge(app.db)
|
||||||
|
chal_id = chal.id
|
||||||
|
hint = gen_hint(app.db, chal_id, cost=10)
|
||||||
|
gen_award(app.db, teamid=2)
|
||||||
|
|
||||||
|
client = login_as_user(app)
|
||||||
|
with client.session_transaction() as sess:
|
||||||
|
data = {
|
||||||
|
"nonce": sess.get('nonce')
|
||||||
|
}
|
||||||
|
r = client.post('/hints/1', data=data)
|
||||||
|
output = r.get_data(as_text=True)
|
||||||
|
output = json.loads(output)
|
||||||
|
assert output.get('hint') == 'This is a hint'
|
||||||
|
user = Teams.query.filter_by(id=2).first()
|
||||||
|
assert user.score() == 90
|
||||||
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unlocking_hints_with_cost_during_ctf_without_points():
|
||||||
|
"""Test that hints with a cost are not unlocked if you don't have the points"""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
register_user(app)
|
||||||
|
chal = gen_challenge(app.db)
|
||||||
|
chal_id = chal.id
|
||||||
|
hint = gen_hint(app.db, chal_id, cost=10)
|
||||||
|
|
||||||
|
client = login_as_user(app)
|
||||||
|
with client.session_transaction() as sess:
|
||||||
|
data = {
|
||||||
|
"nonce": sess.get('nonce')
|
||||||
|
}
|
||||||
|
r = client.post('/hints/1', data=data)
|
||||||
|
output = r.get_data(as_text=True)
|
||||||
|
output = json.loads(output)
|
||||||
|
assert output.get('errors') == 'Not enough points'
|
||||||
|
user = Teams.query.filter_by(id=2).first()
|
||||||
|
assert user.score() == 0
|
||||||
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unlocking_hints_with_cost_during_ended_ctf():
|
||||||
|
"""Test that hints with a cost are not unlocked if the CTF has ended"""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
register_user(app)
|
||||||
|
chal = gen_challenge(app.db)
|
||||||
|
chal_id = chal.id
|
||||||
|
hint = gen_hint(app.db, chal_id, cost=10)
|
||||||
|
gen_award(app.db, teamid=2)
|
||||||
|
|
||||||
|
set_config('start', '1507089600') # Wednesday, October 4, 2017 12:00:00 AM GMT-04:00 DST
|
||||||
|
set_config('end', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||||
|
|
||||||
|
with freeze_time("2017-11-4"):
|
||||||
|
client = login_as_user(app)
|
||||||
|
with client.session_transaction() as sess:
|
||||||
|
data = {
|
||||||
|
"nonce": sess.get('nonce')
|
||||||
|
}
|
||||||
|
r = client.post('/hints/1', data=data)
|
||||||
|
assert r.status_code == 403
|
||||||
|
user = Teams.query.filter_by(id=2).first()
|
||||||
|
assert user.score() == 100
|
||||||
|
assert Unlocks.query.count() == 0
|
||||||
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
|
def test_unlocking_hints_with_cost_during_frozen_ctf():
|
||||||
|
"""Test that hints with a cost are unlocked if the CTF is frozen."""
|
||||||
|
app = create_ctfd()
|
||||||
|
with app.app_context():
|
||||||
|
set_config('freeze', '1507262400') # Friday, October 6, 2017 12:00:00 AM GMT-04:00 DST
|
||||||
|
with freeze_time("2017-10-4"):
|
||||||
|
register_user(app)
|
||||||
|
chal = gen_challenge(app.db)
|
||||||
|
chal_id = chal.id
|
||||||
|
hint = gen_hint(app.db, chal_id, cost=10)
|
||||||
|
gen_award(app.db, teamid=2)
|
||||||
|
|
||||||
|
with freeze_time("2017-10-8"):
|
||||||
|
client = login_as_user(app)
|
||||||
|
with client.session_transaction() as sess:
|
||||||
|
data = {
|
||||||
|
"nonce": sess.get('nonce')
|
||||||
|
}
|
||||||
|
|
||||||
|
r = client.post('/hints/1', data=data)
|
||||||
|
output = r.get_data(as_text=True)
|
||||||
|
output = json.loads(output)
|
||||||
|
assert output.get('hint') == 'This is a hint'
|
||||||
|
user = Teams.query.filter_by(id=2).first()
|
||||||
|
assert user.score() == 100
|
||||||
|
destroy_ctfd(app)
|
||||||
|
|
||||||
|
|
||||||
def test_unlocking_hint_for_unicode_challenge():
|
def test_unlocking_hint_for_unicode_challenge():
|
||||||
'''Test that hints for challenges with unicode names can be unlocked'''
|
"""Test that hints for challenges with unicode names can be unlocked"""
|
||||||
app = create_ctfd()
|
app = create_ctfd()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
register_user(app)
|
register_user(app)
|
||||||
|
|||||||
Reference in New Issue
Block a user