instance allow list

This commit is contained in:
rimu 2023-11-03 20:32:12 +13:00
parent 6c706fe012
commit f118374f05
5 changed files with 73 additions and 5 deletions

View file

@ -5,7 +5,7 @@ When it matures enough, PyFedi will aim to work in a way consistent with the [Co
Please discuss your ideas in an issue at https://codeberg.org/rimu/pyfedi/issues before
starting any large pieces of work to ensure alignment with the roadmap, architecture and processes.
The general style and philosphy behind the way things have been constructed is well described by
The general style and philosophy behind the way things have been constructed is well described by
[The Grug Brained Developer](https://grugbrain.dev/). If that page resonates with you then you'll
probably enjoy your time here! The codebase needs to be simple enough that new developers of all
skill levels can easily understand what's going on and onboard quickly without a lot of upfront

View file

@ -5,7 +5,7 @@ from typing import Union, Tuple
from flask import current_app
from sqlalchemy import text
from app import db, cache
from app.models import User, Post, Community, BannedInstances, File, PostReply
from app.models import User, Post, Community, BannedInstances, File, PostReply, AllowedInstances
import time
import base64
import requests
@ -14,7 +14,7 @@ from cryptography.hazmat.primitives.asymmetric import padding
from app.constants import *
from urllib.parse import urlparse
from app.utils import get_request, allowlist_html, html_to_markdown
from app.utils import get_request, allowlist_html, html_to_markdown, get_setting
def public_key():
@ -184,6 +184,15 @@ def instance_blocked(host: str) -> bool:
return instance is not None
@cache.memoize(150)
def instance_allowed(host: str) -> bool:
host = host.lower()
if 'https://' in host or 'http://' in host:
host = urlparse(host).hostname
instance = AllowedInstances.query.filter_by(domain=host.strip()).first()
return instance is not None
def find_actor_or_create(actor: str) -> Union[User, Community, None]:
user = None
# actor parameter must be formatted as https://server/u/actor or https://server/c/actor
@ -197,8 +206,12 @@ def find_actor_or_create(actor: str) -> Union[User, Community, None]:
return None
elif actor.startswith('https://'):
server, address = extract_domain_and_actor(actor)
if instance_blocked(server):
return None
if get_setting('use_allowlist', False):
if not instance_allowed(server):
return None
else:
if instance_blocked(server):
return None
user = User.query.filter_by(
ap_profile_id=actor).first() # finds users formatted like https://kbin.social/u/tables
if user.banned:

View file

@ -451,6 +451,12 @@ class BannedInstances(db.Model):
created_at = db.Column(db.DateTime, default=datetime.utcnow)
class AllowedInstances(db.Model):
id = db.Column(db.Integer, primary_key=True)
domain = db.Column(db.String(256), index=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
class Instance(db.Model):
id = db.Column(db.Integer, primary_key=True)
domain = db.Column(db.String(256), index=True)

10
env.sample Normal file
View file

@ -0,0 +1,10 @@
SECRET_KEY=
SERVER_NAME='127.0.0.1:5000'
DATABASE_URL=postgresql+psycopg2://pyfedi:pyfedi@127.0.0.1/pyfedi
MAIL_SERVER=''
RECAPTCHA3_PUBLIC_KEY=''
RECAPTCHA3_PRIVATE_KEY=''
MODE='development'
FULL_AP_CONTEXT=True
CACHE_TYPE='FileSystemCache'
CACHE_DIR='/dev/shm/pyfedi'

View file

@ -0,0 +1,39 @@
"""allowed instances
Revision ID: 6a9bec0c492e
Revises: c88bbba381b5
Create Date: 2023-11-03 20:23:43.536572
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '6a9bec0c492e'
down_revision = 'c88bbba381b5'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('allowed_instances',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('domain', sa.String(length=256), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('allowed_instances', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_allowed_instances_domain'), ['domain'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('allowed_instances', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_allowed_instances_domain'))
op.drop_table('allowed_instances')
# ### end Alembic commands ###