mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
temporary instance bans
This commit is contained in:
parent
95f7b226d2
commit
dd93048e96
6 changed files with 96 additions and 10 deletions
|
@ -892,7 +892,10 @@ def process_inbox_request(request_json, store_ap_json):
|
|||
if not blocked:
|
||||
log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Does not exist here')
|
||||
return
|
||||
block_from_ap_id = request_json['target']
|
||||
|
||||
# target = request_json['target'] # target is supposed to determine the scope - whether it is an instance-wide ban or just one community. Lemmy doesn't use it right though
|
||||
# community = find_actor_or_create(target, create_if_not_found=False, community_only=True)
|
||||
|
||||
remove_data = request_json['removeData'] if 'removeData' in request_json else False
|
||||
|
||||
# Lemmy currently only sends userbans for admins banning local users
|
||||
|
@ -902,15 +905,31 @@ def process_inbox_request(request_json, store_ap_json):
|
|||
log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_FAILURE, request_json if store_ap_json else None, 'Does not have permission')
|
||||
return
|
||||
|
||||
# request_json includes 'expires' and 'endTime' (same thing) but nowhere to record this and check in future for end in ban.
|
||||
if blocked.banned: # We may have already banned them - we don't want remote temp bans to over-ride our permanent bans
|
||||
return
|
||||
|
||||
if remove_data == True:
|
||||
if blocked.is_local(): # Sanity check
|
||||
current_app.logger.error('Attempt to ban local user: ' + str(request_json))
|
||||
return
|
||||
|
||||
blocked.banned = True
|
||||
db.session.commit()
|
||||
if 'expires' in request_json:
|
||||
blocked.banned_until = request_json['expires']
|
||||
elif 'endTime' in request_json:
|
||||
blocked.banned_until = request_json['endTime']
|
||||
try:
|
||||
db.session.commit()
|
||||
except: # I don't know the format of expires or endTime so let's see how this goes
|
||||
db.session.rollback()
|
||||
current_app.logger.error('could not save banned_until value: ' + str(request_json))
|
||||
|
||||
if remove_data:
|
||||
site_ban_remove_data(blocker.id, blocked)
|
||||
log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_SUCCESS, request_json if store_ap_json else None)
|
||||
else:
|
||||
#blocked.banned = True # uncommented until there's a mechanism for processing ban expiry date
|
||||
#db.session.commit()
|
||||
log_incoming_ap(announce_id, APLOG_USERBAN, APLOG_IGNORED, request_json if store_ap_json else None, 'Banned, but content retained')
|
||||
|
||||
return
|
||||
|
||||
if request_json['type'] == 'Undo':
|
||||
|
@ -1438,8 +1457,8 @@ def user_followers(actor):
|
|||
|
||||
@bp.route('/comment/<int:comment_id>', methods=['GET', 'HEAD'])
|
||||
def comment_ap(comment_id):
|
||||
reply = PostReply.query.get_or_404(comment_id)
|
||||
if is_activitypub_request():
|
||||
reply = PostReply.query.get_or_404(comment_id)
|
||||
reply_data = comment_model_to_json(reply) if request.method == 'GET' else []
|
||||
resp = jsonify(reply_data)
|
||||
resp.content_type = 'application/activity+json'
|
||||
|
@ -1447,7 +1466,6 @@ def comment_ap(comment_id):
|
|||
resp.headers.set('Link', f'<https://{current_app.config["SERVER_NAME"]}/comment/{reply.id}>; rel="alternate"; type="text/html"')
|
||||
return resp
|
||||
else:
|
||||
reply = PostReply.query.get_or_404(comment_id)
|
||||
return continue_discussion(reply.post.id, comment_id)
|
||||
|
||||
|
||||
|
|
|
@ -1453,7 +1453,6 @@ def site_ban_remove_data(blocker_id, blocked):
|
|||
if blocked.cover_id:
|
||||
blocked.cover.delete_from_disk()
|
||||
blocked.cover.source_url = ''
|
||||
# blocked.banned = True # uncommented until there's a mechanism for processing ban expiry date
|
||||
|
||||
db.session.commit()
|
||||
|
||||
|
|
|
@ -209,6 +209,11 @@ def register(app):
|
|||
db.session.execute(text('DELETE FROM "post_reply_vote" WHERE created_at < :cutoff'), {'cutoff': utcnow() - timedelta(days=28 * 6)})
|
||||
db.session.commit()
|
||||
|
||||
# Un-ban after ban expires
|
||||
db.session.execute(text('UPDATE "user" SET banned = false WHERE banned is true AND banned_until < :cutoff AND banned_until is not null'),
|
||||
{'cutoff': utcnow()})
|
||||
db.session.commit()
|
||||
|
||||
# Check for dormant or dead instances
|
||||
try:
|
||||
# Check for dormant or dead instances
|
||||
|
|
|
@ -135,12 +135,20 @@ class InstanceRole(db.Model):
|
|||
user = db.relationship('User', lazy='joined')
|
||||
|
||||
|
||||
# Instances that this user has blocked
|
||||
class InstanceBlock(db.Model):
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
|
||||
instance_id = db.Column(db.Integer, db.ForeignKey('instance.id'), primary_key=True)
|
||||
created_at = db.Column(db.DateTime, default=utcnow)
|
||||
|
||||
|
||||
# Instances that have banned this user
|
||||
class InstanceBan(db.Model):
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
|
||||
instance_id = db.Column(db.Integer, db.ForeignKey('instance.id'), primary_key=True)
|
||||
banned_until = db.Column(db.DateTime)
|
||||
|
||||
|
||||
class Conversation(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), index=True)
|
||||
|
@ -649,7 +657,8 @@ class User(UserMixin, db.Model):
|
|||
password_hash = db.Column(db.String(128))
|
||||
verified = db.Column(db.Boolean, default=False)
|
||||
verification_token = db.Column(db.String(16), index=True)
|
||||
banned = db.Column(db.Boolean, default=False)
|
||||
banned = db.Column(db.Boolean, default=False, index=True)
|
||||
banned_until = db.Column(db.DateTime) # null == permanent ban
|
||||
deleted = db.Column(db.Boolean, default=False)
|
||||
deleted_by = db.Column(db.Integer, index=True)
|
||||
about = db.Column(db.Text) # markdown
|
||||
|
@ -2010,6 +2019,7 @@ class CommunityBan(db.Model):
|
|||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True) # person who is banned, not the banner
|
||||
community_id = db.Column(db.Integer, db.ForeignKey('community.id'), primary_key=True)
|
||||
banned_by = db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||
banned_until = db.Column(db.DateTime)
|
||||
reason = db.Column(db.String(256))
|
||||
created_at = db.Column(db.DateTime, default=utcnow)
|
||||
ban_until = db.Column(db.DateTime)
|
||||
|
|
|
@ -470,8 +470,13 @@ def poll_vote(post_id):
|
|||
def continue_discussion(post_id, comment_id):
|
||||
post = Post.query.get_or_404(post_id)
|
||||
comment = PostReply.query.get_or_404(comment_id)
|
||||
|
||||
if post.community.banned or post.deleted or comment.deleted:
|
||||
abort(404)
|
||||
if current_user.is_anonymous or not (current_user.is_authenticated and (current_user.is_admin() or current_user.is_staff())):
|
||||
abort(404)
|
||||
else:
|
||||
flash(_('This comment has been deleted and is only visible to staff and admins.'), 'warning')
|
||||
|
||||
mods = post.community.moderators()
|
||||
is_moderator = current_user.is_authenticated and any(mod.user_id == current_user.id for mod in mods)
|
||||
if post.community.private_mods:
|
||||
|
|
49
migrations/versions/20a3bae71dd7_banned_until.py
Normal file
49
migrations/versions/20a3bae71dd7_banned_until.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
"""banned until
|
||||
|
||||
Revision ID: 20a3bae71dd7
|
||||
Revises: d88b49617de0
|
||||
Create Date: 2024-11-30 08:52:27.584637
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '20a3bae71dd7'
|
||||
down_revision = 'd88b49617de0'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('instance_ban',
|
||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||
sa.Column('instance_id', sa.Integer(), nullable=False),
|
||||
sa.Column('banned_until', sa.DateTime(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['instance_id'], ['instance.id'], ),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('user_id', 'instance_id')
|
||||
)
|
||||
with op.batch_alter_table('community_ban', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('banned_until', sa.DateTime(), nullable=True))
|
||||
|
||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||
batch_op.add_column(sa.Column('banned_until', sa.DateTime(), nullable=True))
|
||||
batch_op.create_index(batch_op.f('ix_user_banned'), ['banned'], unique=False)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_user_banned'))
|
||||
batch_op.drop_column('banned_until')
|
||||
|
||||
with op.batch_alter_table('community_ban', schema=None) as batch_op:
|
||||
batch_op.drop_column('banned_until')
|
||||
|
||||
op.drop_table('instance_ban')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in a new issue