Skip to content

Commit

Permalink
Closes #252
Browse files Browse the repository at this point in the history
  • Loading branch information
jdabtieu committed Sep 13, 2024
1 parent 0a16295 commit d23b7aa
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 20 deletions.
4 changes: 3 additions & 1 deletion src/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ def check_for_maintenance():
return

if not check_perm(["ADMIN", "SUPERADMIN"]):
return render_template("error/maintenance.html"), 503
with open('maintenance_mode', 'r') as f:
msg = f.read()
return render_template("error/maintenance.html", msg=msg), 503
else:
flash("Maintenance mode is enabled", "maintenance")

Expand Down
18 changes: 14 additions & 4 deletions src/templates/admin/console.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,22 @@ <h5 class="card-title">Manage Homepage</h5>
Maintenance mode prevents non-admin users from interacting with the site. Admins can still log
in and perform changes as required. Use this for site upgrades and for other situations as
needed. If CTFOJ or its server is rebooted, maintenance mode will remain on. To disable it,
log in as an admin account and navigate back to this page or remove the 'maintenance_mode' file
on the server.
log in as an admin account and navigate back to this page.
</p>
<form action="/admin/maintenance" method="POST">
{% if maintenance_mode %}
<form action="/admin/maintenance/disable" method="POST">
<input type="submit" class="btn btn-danger mb-3" value="Disable Maintenance Mode">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
</form>
{% endif %}
<form action="/admin/maintenance/enable" method="POST">
<textarea class="form-control mb-3"
name="message"
id="maintenance-message"
rows="4"
placeholder="Maintenance message (optional)">{{ maintenance_msg }}</textarea>
{% if maintenance_mode %}
<input type="submit" class="btn btn-danger" value="Disable Maintenance Mode">
<input type="submit" class="btn btn-secondary" value="Update Message">
{% else %}
<input type="submit" class="btn btn-danger" value="Enable Maintenance Mode">
{% endif %}
Expand Down
1 change: 1 addition & 0 deletions src/templates/error/maintenance.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ <h1>Under Maintenance</h1>
We are currently undergoing scheduled maintenance. We will be back soon.
Thank you for your patience.
</p>
<p>{{ msg }}</p>
</main>
<footer>
<hr>
Expand Down
11 changes: 7 additions & 4 deletions src/tests/test_emaintenance.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,26 @@ def test_emaintenance(client, database):
'password': 'CTFOJadmin'
}, follow_redirects=True)

result = client.post('/admin/maintenance', follow_redirects=True)
result = client.post('/admin/maintenance/enable', follow_redirects=True)
assert result.status_code == 200
assert b'Enabled' in result.data

result = client.get('/', follow_redirects=True)
assert result.status_code == 200
assert b'maintenance' not in result.data

result = client.post('/admin/maintenance', follow_redirects=True)
result = client.post('/admin/maintenance/disable', follow_redirects=True)
assert result.status_code == 200
assert b'Disabled' in result.data

client.post('/admin/maintenance', follow_redirects=True)
client.post('/admin/maintenance/enable', data={
'message': 'maintenance message'
})

result = client.get('/logout', follow_redirects=True)
assert result.status_code == 503
assert b'maintenance' in result.data
assert b'maintenance message' in result.data

result = client.get('/api', follow_redirects=True)
assert result.status_code == 503
Expand All @@ -43,6 +46,6 @@ def test_emaintenance(client, database):
'username': 'admin',
'password': 'CTFOJadmin'
}, follow_redirects=True)
result = client.post('/admin/maintenance', follow_redirects=True)
result = client.post('/admin/maintenance/disable', follow_redirects=True)
assert result.status_code == 200
assert b'Disabled' in result.data # disable mode for other tests
34 changes: 23 additions & 11 deletions src/views/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@
@api.route("/console")
@perm_required(["ADMIN", "SUPERADMIN", "PROBLEM_MANAGER", "CONTENT_MANAGER"])
def admin_console():
maintenance_mode = os.path.exists('maintenance_mode')
if maintenance_mode:
msg = read_file('maintenance_mode')
else:
msg = ""
return render_template("admin/console.html", ver="v4.2.3",
maintenance_mode=os.path.exists('maintenance_mode'))
maintenance_mode=maintenance_mode, maintenance_msg=msg)


@api.route("/submissions")
Expand Down Expand Up @@ -344,19 +349,26 @@ def editannouncement(aid):
return redirect("/")


@api.route("/maintenance", methods=["POST"])
@api.route("/maintenance/enable", methods=["POST"])
@admin_required
def maintenance():
maintenance_mode = os.path.exists('maintenance_mode')
def enable_maintenance():
msg = request.form.get("message") or ""
write_file('maintenance_mode', msg)
flash("Enabled maintenance mode", "success")

msg = "Disabled" if maintenance_mode else "Enabled"
if maintenance_mode:
os.remove('maintenance_mode')
else:
write_file('maintenance_mode', '')
flash(msg + " maintenance mode", "success")
logger.info(("Enabled maintenance mode by "
f"user #{session['user_id']} ({session['username']})"),
extra={"section": "misc"})
return redirect('/admin/console')


@api.route("/maintenance/disable", methods=["POST"])
@admin_required
def disable_maintenance():
os.remove('maintenance_mode')
flash("Disabled maintenance mode", "success")

logger.info((f"{msg} maintenance mode by "
logger.info(("Disabled maintenance mode by "
f"user #{session['user_id']} ({session['username']})"),
extra={"section": "misc"})
return redirect('/admin/console')
Expand Down

0 comments on commit d23b7aa

Please sign in to comment.