mirror of
https://gitlab.com/SIGBUS/nyaa.git
synced 2024-12-22 04:00:01 +00:00
Read-only maintenance mode setting for config.py (#356)
Disables all POSTs, optionally allowing users to log in (without updating last login date) Blocked POSTs will redirect to the GET endpoint if possible, otherwise to referrer or in last case, home page. API requests will get a plaintext message with 405 status code.
This commit is contained in:
parent
5e93d7ec6d
commit
c5d705210d
|
@ -1,7 +1,13 @@
|
|||
import os
|
||||
|
||||
|
||||
DEBUG = True
|
||||
# A read-only maintenance mode, in which the database is not modified
|
||||
MAINTENANCE_MODE = True
|
||||
# A maintenance message (used in layout.html template)
|
||||
MAINTENANCE_MODE_MESSAGE = 'Site is currently in read-only maintenance mode.'
|
||||
# Allow logging in during maintenance (without updating last login date)
|
||||
MAINTENANCE_MODE_LOGINS = True
|
||||
|
||||
USE_RECAPTCHA = False
|
||||
USE_EMAIL_VERIFICATION = False
|
||||
USE_MYSQL = True
|
||||
|
|
|
@ -312,6 +312,12 @@
|
|||
|
||||
<div class="container">
|
||||
{% include "flashes.html" %}
|
||||
{% if config.MAINTENANCE_MODE and config.MAINTENANCE_MODE_MESSAGE %}
|
||||
<div class="alert alert-dismissable alert-warning" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
{{ config.MAINTENANCE_MODE_MESSAGE | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% block body %}{% endblock %}
|
||||
</div> <!-- /container -->
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import flask
|
||||
|
||||
from nyaa.views import ( # isort:skip
|
||||
account,
|
||||
admin,
|
||||
|
@ -8,8 +10,37 @@ from nyaa.views import ( # isort:skip
|
|||
)
|
||||
|
||||
|
||||
def _maintenance_mode_hook():
|
||||
''' Blocks POSTs, unless MAINTENANCE_MODE_LOGINS is True and the POST is for a login. '''
|
||||
if flask.request.method == 'POST':
|
||||
allow_logins = flask.current_app.config['MAINTENANCE_MODE_LOGINS']
|
||||
endpoint = flask.request.endpoint
|
||||
|
||||
if not (allow_logins and endpoint == 'account.login'):
|
||||
message = 'Site is currently in maintenance mode.'
|
||||
|
||||
# In case of an API request, return a plaintext error message
|
||||
if endpoint.startswith('api.'):
|
||||
resp = flask.make_response(message, 405)
|
||||
resp.headers['Content-Type'] = 'text/plain'
|
||||
return resp
|
||||
else:
|
||||
# Otherwise redirect to the target page and flash a message
|
||||
flask.flash(flask.Markup(message), 'danger')
|
||||
try:
|
||||
target_url = flask.url_for(endpoint)
|
||||
except:
|
||||
# Non-GET-able endpoint, try referrer or default to home page
|
||||
target_url = flask.request.referrer or flask.url_for('main.home')
|
||||
return flask.redirect(target_url)
|
||||
|
||||
|
||||
def register_views(flask_app):
|
||||
""" Register the blueprints using the flask_app object """
|
||||
# Add our POST blocker first
|
||||
if flask_app.config['MAINTENANCE_MODE']:
|
||||
flask_app.before_request(_maintenance_mode_hook)
|
||||
|
||||
flask_app.register_blueprint(account.bp)
|
||||
flask_app.register_blueprint(admin.bp)
|
||||
flask_app.register_blueprint(main.bp)
|
||||
|
|
|
@ -21,6 +21,10 @@ def login():
|
|||
|
||||
form = forms.LoginForm(flask.request.form)
|
||||
if flask.request.method == 'POST' and form.validate():
|
||||
if app.config['MAINTENANCE_MODE'] and not app.config['MAINTENANCE_MODE_LOGINS']:
|
||||
flask.flash(flask.Markup('<strong>Logins are currently disabled.</strong>'), 'danger')
|
||||
return flask.redirect(flask.url_for('account.login'))
|
||||
|
||||
username = form.username.data.strip()
|
||||
password = form.password.data
|
||||
user = models.User.by_username(username)
|
||||
|
@ -40,8 +44,9 @@ def login():
|
|||
|
||||
user.last_login_date = datetime.utcnow()
|
||||
user.last_login_ip = ip_address(flask.request.remote_addr).packed
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
if not app.config['MAINTENANCE_MODE']:
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
flask.g.user = user
|
||||
flask.session['user_id'] = user.id
|
||||
|
|
|
@ -41,11 +41,12 @@ def before_request():
|
|||
flask.session.permanent = True
|
||||
flask.session.modified = True
|
||||
|
||||
ip = ip_address(flask.request.remote_addr)
|
||||
if user.last_login_ip != ip:
|
||||
user.last_login_ip = ip.packed
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
if not app.config['MAINTENANCE_MODE']:
|
||||
ip = ip_address(flask.request.remote_addr)
|
||||
if user.last_login_ip != ip:
|
||||
user.last_login_ip = ip.packed
|
||||
db.session.add(user)
|
||||
db.session.commit()
|
||||
|
||||
# Check if user is banned on POST
|
||||
if flask.request.method == 'POST':
|
||||
|
|
|
@ -190,6 +190,10 @@ def view_user(user_name):
|
|||
|
||||
@bp.route('/user/activate/<payload>')
|
||||
def activate_user(payload):
|
||||
if app.config['MAINTENANCE_MODE']:
|
||||
flask.flash(flask.Markup('<strong>Activations are currently disabled.</strong>'), 'danger')
|
||||
return flask.redirect(flask.url_for('main.home'))
|
||||
|
||||
s = get_serializer()
|
||||
try:
|
||||
user_id = s.loads(payload)
|
||||
|
|
Loading…
Reference in a new issue