From 62854c95f5270953bd772aebbdb49b798eea20a8 Mon Sep 17 00:00:00 2001 From: rimu <3310831+rimu@users.noreply.github.com> Date: Fri, 3 Nov 2023 21:59:48 +1300 Subject: [PATCH] admin area for allow and block lists --- app/admin/forms.py | 12 ++++++++++ app/admin/routes.py | 44 ++++++++++++++++++++++++++++++++++- app/cli.py | 1 + app/templates/admin/home.html | 10 ++++++++ app/templates/base.html | 3 +++ app/utils.py | 17 +++++++++++++- 6 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 app/admin/forms.py create mode 100644 app/templates/admin/home.html diff --git a/app/admin/forms.py b/app/admin/forms.py new file mode 100644 index 00000000..0581f53f --- /dev/null +++ b/app/admin/forms.py @@ -0,0 +1,12 @@ +from flask_wtf import FlaskForm +from wtforms import StringField, PasswordField, SubmitField, HiddenField, BooleanField, TextAreaField +from wtforms.validators import ValidationError, DataRequired, Email, EqualTo, Length +from flask_babel import _, lazy_gettext as _l + + +class AdminForm(FlaskForm): + use_allowlist = BooleanField(_l('Allowlist instead of blocklist')) + allowlist = TextAreaField(_l('Allow federation with these instances')) + use_blocklist = BooleanField(_l('Blocklist instead of allowlist')) + blocklist = TextAreaField(_l('Deny federation with these instances')) + submit = SubmitField(_l('Save')) diff --git a/app/admin/routes.py b/app/admin/routes.py index 52c1dba0..66cf5bfe 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -1 +1,43 @@ -from app.utils import render_template \ No newline at end of file +from flask import request, flash +from flask_login import login_required, current_user +from flask_babel import _ +from sqlalchemy import text + +from app import db +from app.admin.forms import AdminForm +from app.models import AllowedInstances, BannedInstances +from app.utils import render_template, permission_required, set_setting, get_setting +from app.admin import bp + + +@bp.route('/', methods=['GET', 'POST']) +@login_required +@permission_required('change instance settings') +def admin_home(): + form = AdminForm() + if form.validate_on_submit(): + if form.use_allowlist.data: + set_setting('use_allowlist', True) + db.session.execute(text('DELETE FROM allowed_instances')) + for allow in form.allowlist.data.split('\n'): + if allow.strip(): + db.session.add(AllowedInstances(domain=allow.strip())) + if form.use_blocklist.data: + set_setting('use_allowlist', False) + db.session.execute(text('DELETE FROM banned_instances')) + for banned in form.blocklist.data.split('\n'): + if banned.strip(): + db.session.add(BannedInstances(domain=banned.strip())) + db.session.commit() + flash(_('Admin settings saved')) + + elif request.method == 'GET': + form.use_allowlist.data = get_setting('use_allowlist', False) + form.use_blocklist.data = not form.use_allowlist.data + instances = BannedInstances.query.all() + form.blocklist.data = '\n'.join([instance.domain for instance in instances]) + instances = AllowedInstances.query.all() + form.allowlist.data = '\n'.join([instance.domain for instance in instances]) + + return render_template('admin/home.html', title=_('Admin settings'), form=form) + diff --git a/app/cli.py b/app/cli.py index 8c88d5ed..7a3d960b 100644 --- a/app/cli.py +++ b/app/cli.py @@ -100,6 +100,7 @@ def register(app): admin_role.permissions.append(RolePermission(permission='change user roles')) admin_role.permissions.append(RolePermission(permission='ban users')) admin_role.permissions.append(RolePermission(permission='manage users')) + admin_role.permissions.append(RolePermission(permission='change instance settings')) db.session.add(admin_role) # Admin user diff --git a/app/templates/admin/home.html b/app/templates/admin/home.html new file mode 100644 index 00000000..c0abaaaf --- /dev/null +++ b/app/templates/admin/home.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} +{% from 'bootstrap/form.html' import render_form %} + +{% block app_content %} +
+
+ {{ render_form(form) }} +
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html index 6c6c162f..2a74c1b8 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -67,6 +67,9 @@ + {% if user_access('change instance settings', current_user.id) %} + + {% endif %} {% endif %} diff --git a/app/utils.py b/app/utils.py index 7e1996f2..79e82783 100644 --- a/app/utils.py +++ b/app/utils.py @@ -210,4 +210,19 @@ def validation_required(func): return func(*args, **kwargs) else: return redirect(url_for('auth.validation_required')) - return decorated_view \ No newline at end of file + return decorated_view + + +def permission_required(permission): + def decorator(func): + @wraps(func) + def decorated_view(*args, **kwargs): + if user_access(permission, current_user.id): + return func(*args, **kwargs) + else: + # Handle the case where the user doesn't have the required permission + return redirect(url_for('auth.permission_denied')) + + return decorated_view + + return decorator