diff --git a/app/community/routes.py b/app/community/routes.py index 2284912c..ce09ad64 100644 --- a/app/community/routes.py +++ b/app/community/routes.py @@ -852,3 +852,59 @@ def community_notification(community_id: int): db.session.commit() return render_template('community/_notification_toggle.html', community=community) + + +@bp.route('//moderate', methods=['GET']) +@login_required +def community_moderate(actor): + community = actor_to_community(actor) + + if community is not None: + if community.is_moderator() or current_user.is_admin(): + + page = request.args.get('page', 1, type=int) + search = request.args.get('search', '') + local_remote = request.args.get('local_remote', '') + + reports = Report.query.filter_by(status=0, in_community_id=community.id) + if local_remote == 'local': + reports = reports.filter_by(ap_id=None) + if local_remote == 'remote': + reports = reports.filter(Report.ap_id != None) + reports = reports.order_by(desc(Report.created_at)).paginate(page=page, per_page=1000, error_out=False) + + next_url = url_for('admin.admin_reports', page=reports.next_num) if reports.has_next else None + prev_url = url_for('admin.admin_reports', page=reports.prev_num) if reports.has_prev and page != 1 else None + + return render_template('community/community_moderate.html', title=_('Moderation of %(community)s', community=community.display_name()), + community=community, reports=reports, current='reports', + next_url=next_url, prev_url=prev_url, + moderating_communities=moderating_communities(current_user.get_id()), + joined_communities=joined_communities(current_user.get_id()), + inoculation=inoculation[randint(0, len(inoculation) - 1)] + ) + else: + abort(401) + else: + abort(404) + + +@bp.route('//moderate/banned', methods=['GET']) +@login_required +def community_moderate_banned(actor): + community = actor_to_community(actor) + + if community is not None: + if community.is_moderator() or current_user.is_admin(): + banned_people = User.query.join(CommunityBan, CommunityBan.user_id == User.id).filter(CommunityBan.community_id == community.id).all() + return render_template('community/community_moderate_banned.html', + title=_('People banned from of %(community)s', community=community.display_name()), + community=community, banned_people=banned_people, current='banned', + moderating_communities=moderating_communities(current_user.get_id()), + joined_communities=joined_communities(current_user.get_id()), + inoculation=inoculation[randint(0, len(inoculation) - 1)] + ) + else: + abort(401) + else: + abort(404) \ No newline at end of file diff --git a/app/models.py b/app/models.py index 9ce75226..10f792b2 100644 --- a/app/models.py +++ b/app/models.py @@ -1120,11 +1120,12 @@ class Report(db.Model): status = db.Column(db.Integer, default=0) type = db.Column(db.Integer, default=0) # 0 = user, 1 = post, 2 = reply, 3 = community, 4 = conversation reporter_id = db.Column(db.Integer, db.ForeignKey('user.id')) - suspect_community_id = db.Column(db.Integer, db.ForeignKey('user.id')) + suspect_community_id = db.Column(db.Integer, db.ForeignKey('community.id')) suspect_user_id = db.Column(db.Integer, db.ForeignKey('user.id')) suspect_post_id = db.Column(db.Integer, db.ForeignKey('post.id')) suspect_post_reply_id = db.Column(db.Integer, db.ForeignKey('post_reply.id')) suspect_conversation_id = db.Column(db.Integer, db.ForeignKey('conversation.id')) + in_community_id = db.Column(db.Integer, db.ForeignKey('community.id')) created_at = db.Column(db.DateTime, default=utcnow) updated = db.Column(db.DateTime, default=utcnow) diff --git a/app/post/routes.py b/app/post/routes.py index 993400cb..568a4518 100644 --- a/app/post/routes.py +++ b/app/post/routes.py @@ -795,7 +795,7 @@ def post_report(post_id: int): if form.validate_on_submit(): report = Report(reasons=form.reasons_to_string(form.reasons.data), description=form.description.data, type=1, reporter_id=current_user.id, suspect_user_id=post.author.id, suspect_post_id=post.id, - suspect_community_id=post.community.id) + suspect_community_id=post.community.id, in_community_id=post.community.id) db.session.add(report) # Notify moderators diff --git a/app/templates/community/_community_moderation_nav.html b/app/templates/community/_community_moderation_nav.html new file mode 100644 index 00000000..51dea95d --- /dev/null +++ b/app/templates/community/_community_moderation_nav.html @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/app/templates/community/community.html b/app/templates/community/community.html index be31617b..24252648 100644 --- a/app/templates/community/community.html +++ b/app/templates/community/community.html @@ -175,7 +175,9 @@

{{ _('Community Settings') }}

-

{{ _('Moderate') }}

+ {% if is_moderator or is_owner or is_admin %} +

{{ _('Moderate') }}

+ {% endif %} {% if is_owner or is_admin %}

{{ _('Settings') }}

{% endif %} diff --git a/app/templates/community/community_moderate.html b/app/templates/community/community_moderate.html new file mode 100644 index 00000000..38bcf75c --- /dev/null +++ b/app/templates/community/community_moderate.html @@ -0,0 +1,84 @@ +{% 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_field %} + +{% block app_content %} +
+
+ +
+
+

{{ _('Moderation of %(community)s', community=community.display_name()) }}

+
+
+ +
+
+ {% include "community/_community_moderation_nav.html" %} +

{{ _('Reports') }}

+ {% if reports.items %} +
+ + + + +
+ + + + + + + + + + {% for report in reports.items %} + + + + + + + + + {% endfor %} +
Local/RemoteReasonsDescriptionTypeCreatedActions
{{ 'Local' if report.is_local() else 'Remote' }}{{ report.reasons }}{{ report.description }}{{ report.type_text() }}{{ moment(report.created_at).fromNow() }} + {% if report.suspect_conversation_id %} + View + {% elif report.suspect_post_reply_id %} + View + {% elif report.suspect_post_id %} + View + {% elif report.suspect_user_id %} + View + {% elif report.suspect_community_id %} + View + {% endif %} +
+ + {% else %} +

{{ _('No reports yet') }}

+ {% endif %} +
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/community/community_moderate_banned.html b/app/templates/community/community_moderate_banned.html new file mode 100644 index 00000000..3ce5a8f2 --- /dev/null +++ b/app/templates/community/community_moderate_banned.html @@ -0,0 +1,65 @@ +{% 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_field %} + +{% block app_content %} +
+
+ +
+
+

{{ _('Moderation of %(community)s', community=community.display_name()) }}

+
+
+ +
+
+ {% include "community/_community_moderation_nav.html" %} +

{{ _('Banned people') }}

+ {% if banned_people %} +
+ + + + +
+ + + + + + + + + {% for user in banned_people %} + + + + + + + + {% endfor %} +
NameLocal/RemoteReportsIPActions
+ {{ user.display_name() }}{{ 'Local' if user.is_local() else 'Remote' }}{{ user.reports if user.reports > 0 }} {{ user.ip_address if user.ip_address }} {% if user.is_local() %} + View local + {% else %} + View remote + {% endif %} + | {{ _('Un ban') }} +
+ {% else %} +

{{ _('No banned people yet') }}

+ {% endif %} +
+
+{% endblock %} \ No newline at end of file diff --git a/migrations/versions/81175e11c083_report_in_community.py b/migrations/versions/81175e11c083_report_in_community.py new file mode 100644 index 00000000..7258b495 --- /dev/null +++ b/migrations/versions/81175e11c083_report_in_community.py @@ -0,0 +1,38 @@ +"""report in community + +Revision ID: 81175e11c083 +Revises: e72aa356e4d0 +Create Date: 2024-03-18 20:37:43.216482 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '81175e11c083' +down_revision = 'e72aa356e4d0' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('report', schema=None) as batch_op: + batch_op.add_column(sa.Column('in_community_id', sa.Integer(), nullable=True)) + batch_op.drop_constraint('report_suspect_community_id_fkey', type_='foreignkey') + batch_op.create_foreign_key(None, 'community', ['suspect_community_id'], ['id']) + batch_op.create_foreign_key(None, 'community', ['in_community_id'], ['id']) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('report', schema=None) as batch_op: + batch_op.drop_constraint(None, type_='foreignkey') + batch_op.drop_constraint(None, type_='foreignkey') + batch_op.create_foreign_key('report_suspect_community_id_fkey', 'user', ['suspect_community_id'], ['id']) + batch_op.drop_column('in_community_id') + + # ### end Alembic commands ###