From c24a0ce6d5a32db5d577b7dfc00d8c644c5a1b9a Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Fri, 6 May 2022 16:10:34 -0400 Subject: [PATCH 1/3] fix actor unfollowing and simplify (un)following --- relay/manage.py | 52 +++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/relay/manage.py b/relay/manage.py index b07652c..e72a852 100644 --- a/relay/manage.py +++ b/relay/manage.py @@ -65,7 +65,20 @@ def cli_inbox_list(): def cli_inbox_follow(actor): 'Follow an actor (Relay must be running)' - run_in_loop(handle_follow_actor, actor) + config = app['config'] + database = app['database'] + + if config.is_banned(actor): + return click.echo(f'Error: Refusing to follow banned actor: {actor}') + + if not actor.startswith('http'): + actor = f'https://{actor}/actor' + + if database.get_inbox(actor): + return click.echo(f'Error: Already following actor: {actor}') + + run_in_loop(follow_remote_actor, actor) + click.echo(f'Sent follow message to: {actor}') @cli_inbox.command('unfollow') @@ -73,7 +86,16 @@ def cli_inbox_follow(actor): def cli_inbox_unfollow(actor): 'Unfollow an actor (Relay must be running)' - run_in_loop(handle_unfollow_actor(actor)) + database = app['database'] + + if not actor.startswith('http'): + actor = f'https://{actor}/actor' + + if not database.get_inbox(actor): + return click.echo(f'Error: Not following actor: {actor}') + + run_in_loop(unfollow_remote_actor, actor) + click.echo(f'Sent unfollow message to: {actor}') @cli_inbox.command('add') @@ -376,32 +398,6 @@ def run_in_loop(func, *args, **kwargs): return loop.run_until_complete(func(*args, **kwargs)) -async def handle_follow_actor(app, target): - config = app['config'] - - if not target.startswith('http'): - target = f'https://{target}/actor' - - if config.is_banned(target): - return click.echo(f'Error: Refusing to follow banned actor: {target}') - - await follow_remote_actor(target) - click.echo(f'Sent follow message to: {target}') - - -async def handle_unfollow_actor(app, target): - database = app['database'] - - if not target.startswith('http'): - target = f'https://{target}/actor' - - if not database.get_inbox(target): - return click.echo(f'Error: Not following actor: {target}') - - await unfollow_remote_actor(target) - click.echo(f'Sent unfollow message to: {target}') - - async def handle_start_webserver(): config = app['config'] runner = AppRunner(app, access_log_format='%{X-Forwarded-For}i "%r" %s %b "%{Referer}i" "%{User-Agent}i"') From 1c3b1b39e657e62333636a2eecd2068d9d359212 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Fri, 6 May 2022 17:23:44 -0400 Subject: [PATCH 2/3] docs: don't assume activityrelay is in PATH --- docs/commands.md | 4 ++++ docs/configuration.md | 2 +- docs/installation.md | 10 +++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index a92e784..6e7da54 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -5,6 +5,10 @@ any category or command to get help on that specific option (ex. `activityrelay Note: Unless specified, it is recommended to run any commands while the relay is shutdown. +Note 2: `activityrelay` is only available via pip or pipx if `~/.local/bin` is in `$PATH`. If it +isn't, use `python3 -m relay` if installed via pip or `~/.local/bin/activityrelay` if installed +via pipx + ## Run diff --git a/docs/configuration.md b/docs/configuration.md index b76b931..ecadac3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -75,7 +75,7 @@ the block list, it will be removed from the inbox list on startup. ### Blocked Software A list of ActivityPub software which cannot follow your relay. This list is empty by default, but -setting this to the above list will block all other relays and prevent relay chains +setting this to the below list will block all other relays and prevent relay chains blocked_software: - activityrelay diff --git a/docs/installation.md b/docs/installation.md index 7445f58..2e93904 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -24,14 +24,14 @@ Or from a cloned git repo. Once finished, you can set up the relay via the setup command. It will ask a few questions to fill out config options for your relay - activityrelay setup + ~/.local/bin/activityrelay setup Finally start it up with the run command. - activityrelay run + ~/.local/bin/activityrelay run Note: Pipx requires python 3.7+. If your distro doesn't have a compatible version of python, it can -be installed via +be installed via [pyenv](https://github.com/pyenv/pyenv). ## Pip @@ -47,11 +47,11 @@ or a cloned git repo. Now run the configuration wizard - activityrelay setup + python3 -m relay setup And start the relay when finished - activityrelay run + python3 -m relay run ## Docker From d005ff8f48e3ae581e4b363b10ebd9c982365a5b Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Fri, 6 May 2022 18:08:55 -0400 Subject: [PATCH 3/3] add/remove inbox on cli inbox (un)follow --- relay/database.py | 10 ++++++---- relay/manage.py | 24 ++++++++++++++++++------ relay/misc.py | 2 -- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/relay/database.py b/relay/database.py index 3582360..6e71f56 100644 --- a/relay/database.py +++ b/relay/database.py @@ -109,13 +109,15 @@ class RelayDatabase: def add_inbox(self, inbox): assert inbox.startswith('https') - assert inbox not in self.inboxes + assert not self.get_inbox(inbox) self.data['relay-list'].append(inbox) - def del_inbox(self, inbox): - if inbox not in self.inboxes: - raise KeyError(inbox) + def del_inbox(self, inbox_url): + inbox = self.get_inbox(inbox_url) + + if not inbox: + raise KeyError(inbox_url) self.data['relay-list'].remove(inbox) diff --git a/relay/manage.py b/relay/manage.py index e72a852..4aae7c7 100644 --- a/relay/manage.py +++ b/relay/manage.py @@ -9,10 +9,9 @@ import platform from aiohttp.web import AppRunner, TCPSite from cachetools import LRUCache -from . import app, views, __version__ +from . import app, misc, views, __version__ from .config import DotDict, RelayConfig, relay_software_names from .database import RelayDatabase -from .misc import check_open_port, follow_remote_actor, unfollow_remote_actor @click.group('cli', context_settings={'show_default': True}, invoke_without_command=True) @@ -77,8 +76,18 @@ def cli_inbox_follow(actor): if database.get_inbox(actor): return click.echo(f'Error: Already following actor: {actor}') - run_in_loop(follow_remote_actor, actor) - click.echo(f'Sent follow message to: {actor}') + actor_data = run_in_loop(misc.request, actor, sign_headers=True) + + if not actor_data: + return click.echo(f'Error: Failed to fetch actor: {actor}') + + inbox = misc.get_actor_inbox(actor_data) + + database.add_inbox(inbox) + database.save() + + run_in_loop(misc.follow_remote_actor, actor) + click.echo(f'Sent follow message to actor: {actor}') @cli_inbox.command('unfollow') @@ -94,7 +103,10 @@ def cli_inbox_unfollow(actor): if not database.get_inbox(actor): return click.echo(f'Error: Not following actor: {actor}') - run_in_loop(unfollow_remote_actor, actor) + database.del_inbox(actor) + database.save() + + run_in_loop(misc.unfollow_remote_actor, actor) click.echo(f'Sent unfollow message to: {actor}') @@ -370,7 +382,7 @@ def relay_run(): click.echo('Warning: PyCrypto is old and should be replaced with pycryptodome') return click.echo(pip_command) - if not check_open_port(config.listen, config.port): + if not misc.check_open_port(config.listen, config.port): return click.echo(f'Error: A server is already running on port {config.port}') # web pages diff --git a/relay/misc.py b/relay/misc.py index 184f577..91f6f3f 100644 --- a/relay/misc.py +++ b/relay/misc.py @@ -160,7 +160,6 @@ async def fetch_nodeinfo(domain): async def follow_remote_actor(actor_uri): config = app['config'] - database = app['database'] actor = await request(actor_uri) inbox = get_actor_inbox(actor) @@ -185,7 +184,6 @@ async def follow_remote_actor(actor_uri): async def unfollow_remote_actor(actor_uri): config = app['config'] - database = app['database'] actor = await request(actor_uri)