admin area for allow and block lists

This commit is contained in:
rimu 2023-11-03 21:59:48 +13:00
parent f118374f05
commit 62854c95f5
6 changed files with 85 additions and 2 deletions

12
app/admin/forms.py Normal file
View file

@ -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'))

View file

@ -1 +1,43 @@
from app.utils import render_template
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)

View file

@ -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

View file

@ -0,0 +1,10 @@
{% extends "base.html" %}
{% from 'bootstrap/form.html' import render_form %}
{% block app_content %}
<div class="row">
<div class="col">
{{ render_form(form) }}
</div>
</div>
{% endblock %}

View file

@ -67,6 +67,9 @@
<li class="nav-item"><a class="nav-link" href="/">{{ _('Home') }}</a></li>
<li class="nav-item"><a class="nav-link" href="/communities">{{ _('Communities') }}</a></li>
<li class="nav-item"><a class="nav-link" href="/u/{{ current_user.user_name }}">{{ current_user.user_name }}</a></li>
{% if user_access('change instance settings', current_user.id) %}
<li class="nav-item"><a class="nav-link" href="/admin/">{{ _('Admin') }}</a></li>
{% endif %}
<li class="nav-item"><a class="nav-link" href="/auth/logout">{{ _('Log out') }}</a></li>
{% endif %}
</ul>

View file

@ -211,3 +211,18 @@ def validation_required(func):
else:
return redirect(url_for('auth.validation_required'))
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