diff --git a/alembic/versions/2022_07_31_0815-50d26a370a65_add_is_blocked_attribute_on_actors.py b/alembic/versions/2022_07_31_0815-50d26a370a65_add_is_blocked_attribute_on_actors.py new file mode 100644 index 0000000..81ce1f6 --- /dev/null +++ b/alembic/versions/2022_07_31_0815-50d26a370a65_add_is_blocked_attribute_on_actors.py @@ -0,0 +1,32 @@ +"""Add is_blocked attribute on actors + +Revision ID: 50d26a370a65 +Revises: f5717d82b3ff +Create Date: 2022-07-31 08:15:27.226340+00:00 + +""" +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision = '50d26a370a65' +down_revision = 'f5717d82b3ff' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('actor', schema=None) as batch_op: + batch_op.add_column(sa.Column('is_blocked', sa.Boolean(), server_default='0', nullable=False)) + + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('actor', schema=None) as batch_op: + batch_op.drop_column('is_blocked') + + # ### end Alembic commands ### diff --git a/app/admin.py b/app/admin.py index 97f9036..a1e78d1 100644 --- a/app/admin.py +++ b/app/admin.py @@ -563,11 +563,41 @@ async def admin_actions_follow( csrf_check: None = Depends(verify_csrf_token), db_session: AsyncSession = Depends(get_db_session), ) -> RedirectResponse: - print(f"Following {ap_actor_id}") + logger.info(f"Following {ap_actor_id}") await send_follow(db_session, ap_actor_id) return RedirectResponse(redirect_url, status_code=302) +@router.post("/actions/block") +async def admin_actions_block( + request: Request, + ap_actor_id: str = Form(), + redirect_url: str = Form(), + csrf_check: None = Depends(verify_csrf_token), + db_session: AsyncSession = Depends(get_db_session), +) -> RedirectResponse: + logger.info(f"Blocking {ap_actor_id}") + actor = await fetch_actor(db_session, ap_actor_id) + actor.is_blocked = True + await db_session.commit() + return RedirectResponse(redirect_url, status_code=302) + + +@router.post("/actions/unblock") +async def admin_actions_unblock( + request: Request, + ap_actor_id: str = Form(), + redirect_url: str = Form(), + csrf_check: None = Depends(verify_csrf_token), + db_session: AsyncSession = Depends(get_db_session), +) -> RedirectResponse: + logger.info(f"Unblocking {ap_actor_id}") + actor = await fetch_actor(db_session, ap_actor_id) + actor.is_blocked = False + await db_session.commit() + return RedirectResponse(redirect_url, status_code=302) + + @router.post("/actions/delete") async def admin_actions_delete( request: Request, diff --git a/app/boxes.py b/app/boxes.py index c59a5fb..5a140ca 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -1271,6 +1271,10 @@ async def save_to_inbox( await _process_transient_object(db_session, raw_object, actor) return None + if actor.is_blocked: + logger.warning("Actor {actor.ap_id} is blocked, ignoring object") + return None + raw_object_id = ap.get_id(raw_object) forwarded_by_actor = None diff --git a/app/models.py b/app/models.py index 152d5b8..5d23245 100644 --- a/app/models.py +++ b/app/models.py @@ -51,6 +51,8 @@ class Actor(Base, BaseActor): handle = Column(String, nullable=True, index=True) + is_blocked = Column(Boolean, nullable=False, default=False, server_default="0") + @property def is_from_db(self) -> bool: return True diff --git a/app/templates/utils.html b/app/templates/utils.html index ba93ed2..5ba2ba5 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -6,6 +6,24 @@ {% endmacro %} +{% macro admin_block_button(actor) %} +
+{% endmacro %} + +{% macro admin_unblock_button(actor) %} + +{% endmacro %} + {% macro admin_follow_button(actor) %}