admins can set permissions for staff role #21

This commit is contained in:
rimu 2024-07-16 21:29:06 +08:00
parent 0309cbded9
commit 3643526706
7 changed files with 95 additions and 10 deletions

View file

@ -431,14 +431,17 @@ def shared_inbox():
actor = find_actor_or_create(request_json['actor']) if 'actor' in request_json else None
if actor is not None:
if HttpSignature.verify_request(request, actor.public_key, skip_date=True):
if current_app.debug:
process_inbox_request(request_json, activity_log.id, ip_address())
try:
if HttpSignature.verify_request(request, actor.public_key, skip_date=True):
if current_app.debug:
process_inbox_request(request_json, activity_log.id, ip_address())
else:
process_inbox_request.delay(request_json, activity_log.id, ip_address())
return ''
else:
process_inbox_request.delay(request_json, activity_log.id, ip_address())
return ''
else:
activity_log.exception_message = 'Could not verify signature'
activity_log.exception_message = 'Could not verify signature'
except VerificationError as e:
activity_log.exception_message = 'Could not verify signature: ' + str(e)
else:
actor_name = request_json['actor'] if 'actor' in request_json else ''
activity_log.exception_message = f'Actor could not be found: {actor_name}'

View file

@ -22,7 +22,7 @@ from app.community.util import save_icon_file, save_banner_file
from app.constants import REPORT_STATE_NEW, REPORT_STATE_ESCALATED
from app.email import send_welcome_email
from app.models import AllowedInstances, BannedInstances, ActivityPubLog, utcnow, Site, Community, CommunityMember, \
User, Instance, File, Report, Topic, UserRegistration, Role, Post, PostReply, Language
User, Instance, File, Report, Topic, UserRegistration, Role, Post, PostReply, Language, RolePermission
from app.utils import render_template, permission_required, set_setting, get_setting, gibberish, markdown_to_html, \
moderating_communities, joined_communities, finalize_user_setup, theme_list, blocked_phrases, blocked_referrers, \
topic_tree, languages_for_form, menu_topics, ensure_directory_exists, add_to_modlog
@ -923,3 +923,31 @@ def newsletter():
menu_topics=menu_topics(),
site=g.site
)
@bp.route('/permissions', methods=['GET', 'POST'])
@login_required
@permission_required('change instance settings')
def admin_permissions():
if request.method == 'POST':
permissions = db.session.execute(text('SELECT DISTINCT permission FROM "role_permission"')).fetchall()
db.session.execute(text('DELETE FROM "role_permission"'))
roles = [3, 4] # 3 = Staff, 4 = Admin
for permission in permissions:
for role in roles:
if request.form.get(f'role_{role}_{permission[0]}'):
db.session.add(RolePermission(role_id=role, permission=permission[0]))
db.session.commit()
flash(_('Settings saved'))
roles = Role.query.filter(Role.id > 2).order_by(Role.weight).all()
permissions = db.session.execute(text('SELECT DISTINCT permission FROM "role_permission"')).fetchall()
return render_template('admin/permissions.html', title=_('Role permissions'), roles=roles,
permissions=permissions,
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),
menu_topics=menu_topics(),
site=g.site
)

View file

@ -13,5 +13,6 @@
<a href="{{ url_for('admin.admin_reports') }}">{{ _('Moderation') }}</a> |
<a href="{{ url_for('admin.admin_federation') }}">{{ _('Federation') }}</a> |
<a href="{{ url_for('admin.newsletter') }}">{{ _('Newsletter') }}</a> |
<a href="{{ url_for('admin.admin_permissions') }}">{{ _('Permissions') }}</a> |
<a href="{{ url_for('admin.admin_activities') }}">{{ _('Activities') }}</a>
</nav>

View file

@ -0,0 +1,45 @@
{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') %}
{% extends 'themes/' + theme() + '/base.html' %}
{% else %}
{% extends "base.html" %}
{% endif %} %}
{% from 'bootstrap/form.html' import render_form %}
{% set active_child = 'admin_permissions' %}
{% block app_content %}
<div class="row">
<div class="col">
<h1>{{ _('Permissions') }}</h1>
<form method="post">
{{ form_csrf_token }}
<table class="table table-striped" style="max-width: 500px;">
<tr>
<th> </th>
<th class="text-center">{{ _('Staff') }}</th>
<th class="text-center">{{ _('Admin') }}</th>
</tr>
{% for permission in permissions -%}
<tr>
<th>{{ permission[0] }}</th>
<td class="text-center">
<input type="checkbox" name="role_3_{{ permission[0] }}" {{ 'checked' if role_access(permission[0], 3) else '' }}>
</td>
<td class="text-center">
<input type="checkbox" name="role_4_{{ permission[0] }}" {{ 'checked' if role_access(permission[0], 4) else '' }}>
</td>
</tr>
{% endfor -%}
</table>
<input type="submit" class="btn btn-primary" value="{{ _('Save') }}">
</form>
</div>
</div>
<hr />
<div class="row">
<div class="col">
{% include 'admin/_nav.html' %}
</div>
</div>
<hr />
{% endblock %}

View file

@ -233,9 +233,9 @@
<li><a class="dropdown-item{{ ' active' if active_child == 'admin_federation' }}" href="{{ url_for('admin.admin_federation') }}">{{ _('Federation') }}</a></li>
<li><a class="dropdown-item{{ ' active' if active_child == 'admin_newsletter' }}" href="{{ url_for('admin.newsletter') }}">{{ _('Newsletter') }}</a></li>
<li><a class="dropdown-item{{ ' active' if active_child == 'admin_activities' }}" href="{{ url_for('admin.admin_activities') }}">{{ _('Activities') }}</a></li>
<li><a class="dropdown-item{{ ' active' if active_child == 'admin_permissions' }}" href="{{ url_for('admin.admin_permissions') }}">{{ _('Permissions') }}</a></li>
</ul>
</li>
{% endif %}
<li class="nav-item"><a class="nav-link" href="/auth/logout">{{ _('Log out') }}</a></li>
<li class="nav-item d-none d-md-inline-block">

View file

@ -407,6 +407,13 @@ def user_access(permission: str, user_id: int) -> bool:
return has_access is not None
def role_access(permission: str, role_id: int) -> bool:
has_access = db.session.execute(text('SELECT * FROM "role_permission" as rp ' +
'WHERE rp.role_id = :role_id AND rp.permission = :permission'),
{'role_id': role_id, 'permission': permission}).first()
return has_access is not None
@cache.memoize(timeout=10)
def community_membership(user: User, community: Community) -> int:
if community is None:

View file

@ -13,7 +13,7 @@ from app.constants import POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_ARTICLE, PO
from app.models import Site
from app.utils import getmtime, gibberish, shorten_string, shorten_url, digits, user_access, community_membership, \
can_create_post, can_upvote, can_downvote, shorten_number, ap_datetime, current_theme, community_link_to_href, \
in_sorted_list
in_sorted_list, role_access
app = create_app()
cli.register(app)
@ -42,6 +42,7 @@ with app.app_context():
app.jinja_env.globals['community_membership'] = community_membership
app.jinja_env.globals['json_loads'] = json.loads
app.jinja_env.globals['user_access'] = user_access
app.jinja_env.globals['role_access'] = role_access
app.jinja_env.globals['ap_datetime'] = ap_datetime
app.jinja_env.globals['can_create'] = can_create_post
app.jinja_env.globals['can_upvote'] = can_upvote