finish basic relay functions
This commit is contained in:
parent
6ea8a4bcd9
commit
8bb5d7c2cf
2
Makefile
2
Makefile
|
@ -28,7 +28,7 @@ setupdev:
|
|||
update-deps:
|
||||
git reset HEAD --hard
|
||||
git pull
|
||||
$(PYTHON) -m pip install -r requirements.txt
|
||||
$(PYTHON) -m pip install -U -r requirements.txt
|
||||
|
||||
run:
|
||||
$(PYTHON) -m uncia
|
||||
|
|
|
@ -6,8 +6,7 @@ from izzylib import DotDict, Path, boolean, izzylog, logging
|
|||
from os import environ as env
|
||||
|
||||
|
||||
izzylog.set_config('level', 'VERBOSE')
|
||||
logging.set_config('level', 'DEBUG')
|
||||
logging.set_config('level', env.get('LOG_LEVEL', 'INFO'))
|
||||
|
||||
|
||||
scriptpath = Path(__file__).resolve.parent
|
||||
|
|
|
@ -49,13 +49,19 @@ tables = {
|
|||
],
|
||||
'whitelist': [
|
||||
Column('id'),
|
||||
Column('actor', 'text', nullable=False, unique=True)
|
||||
Column('domain', 'text', nullable=False, unique=True)
|
||||
],
|
||||
'ban': [
|
||||
Column('id'),
|
||||
Column('handle', 'text'),
|
||||
Column('domain', 'text'),
|
||||
Column('reason', 'text')
|
||||
],
|
||||
'actor_cache': [
|
||||
Column('id'),
|
||||
Column('url', 'text', nullable=False, unique=True),
|
||||
Column('data', 'json', nullable=False),
|
||||
Column('timestamp')
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from izzylib import logging
|
||||
|
||||
|
||||
def cmd_inbox(self, data):
|
||||
instance = self.get.inbox(data)
|
||||
def cmd_instance(self, data):
|
||||
instance = self.get.instance(data)
|
||||
|
||||
if not instance:
|
||||
logging.debug(f'db.get.inbox: instance does not exist: {data}')
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
from izzylib import DotDict
|
||||
from izzylib import DotDict, logging
|
||||
|
||||
|
||||
def cmd_actor(self, url):
|
||||
cache = self.cache.actor_cache.fetch(url)
|
||||
|
||||
if cache:
|
||||
return cache
|
||||
|
||||
row = self.fetch('actor_cache', url=url)
|
||||
|
||||
if not row:
|
||||
return
|
||||
|
||||
self.cache.actor_cache.store(url, row)
|
||||
return row
|
||||
|
||||
|
||||
def cmd_ban_list(self, types='domain'):
|
||||
|
@ -61,15 +76,17 @@ def cmd_config_all(self):
|
|||
return data
|
||||
|
||||
|
||||
def cmd_inbox(self, data):
|
||||
for line in ['domain', 'inbox', 'actor']:
|
||||
row = self.fetch('inbox', **{line: data})
|
||||
def cmd_instance(self, data):
|
||||
for field in ['domain', 'inbox', 'actor']:
|
||||
row = self.fetch('inbox', **{field: data})
|
||||
|
||||
if row:
|
||||
return row
|
||||
break
|
||||
|
||||
return row
|
||||
|
||||
|
||||
def cmd_inbox_list(self, value=None):
|
||||
def cmd_instance_list(self, value=None):
|
||||
data = []
|
||||
|
||||
if value not in [None, 'domain', 'inbox', 'actor']:
|
||||
|
@ -86,11 +103,11 @@ def cmd_inbox_list(self, value=None):
|
|||
return data
|
||||
|
||||
|
||||
def cmd_instance(self, data):
|
||||
for field in ['domain', 'inbox', 'actor']:
|
||||
row = self.fetch('inbox', **{field: data})
|
||||
def cmd_inbox(*args, **kwargs):
|
||||
logging.warning('DeprecationWarning: session.get.inbox')
|
||||
return cmd_instance(*args, **kwargs)
|
||||
|
||||
if row:
|
||||
break
|
||||
|
||||
return row
|
||||
def cmd_inbox_list(*args, **kwargs):
|
||||
logging.warning('DeprecationWarning: session.get.inbox_list')
|
||||
return cmd_instance_list(*args, **kwargs)
|
||||
|
|
|
@ -3,6 +3,29 @@ from izzylib import logging
|
|||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
def cmd_actor(self, url, actor):
|
||||
row = self.get.actor(url)
|
||||
|
||||
if row:
|
||||
row = self.update(
|
||||
row = row,
|
||||
data = actor,
|
||||
timestamp = datetime.now(),
|
||||
return_row = True
|
||||
)
|
||||
|
||||
else:
|
||||
row = self.insert('actor_cache',
|
||||
url = url,
|
||||
data = actor,
|
||||
timestamp = datetime.now(),
|
||||
return_row = True
|
||||
)
|
||||
|
||||
self.cache.actor_cache.store(url, row)
|
||||
return row
|
||||
|
||||
|
||||
def cmd_config(self, key, value):
|
||||
row = self.fetch('config', key=key)
|
||||
|
||||
|
|
|
@ -30,9 +30,29 @@ def cache_fetch(func):
|
|||
return inner_func
|
||||
|
||||
|
||||
@cache_fetch
|
||||
def fetch_actor(url):
|
||||
return client.json(url, activity=True).json
|
||||
with db.session as s:
|
||||
cached = s.get.actor(url)
|
||||
|
||||
if cached:
|
||||
return cached.data
|
||||
|
||||
try:
|
||||
response = client.json(url, activity=True)
|
||||
data = response.json
|
||||
|
||||
except:
|
||||
data = None
|
||||
|
||||
if response.status not in [200, 202]:
|
||||
logging.verbose(f'Signing headers to fetch actor: {url}')
|
||||
data = fetch_auth(url)
|
||||
|
||||
if not data:
|
||||
return
|
||||
|
||||
s.put.actor(url, data)
|
||||
return data
|
||||
|
||||
|
||||
@cache_fetch
|
||||
|
@ -45,7 +65,7 @@ def fetch_auth(url):
|
|||
headers = {'accept': 'application/activity+json'}
|
||||
)
|
||||
|
||||
return response.json()
|
||||
return response.json
|
||||
|
||||
|
||||
def get_inbox(actor):
|
||||
|
|
|
@ -4,6 +4,7 @@ from izzylib import logging
|
|||
|
||||
from . import __version__
|
||||
from .database import db
|
||||
from .messages import Message
|
||||
|
||||
|
||||
exe = f'{sys.executable} -m uncia.manage'
|
||||
|
@ -21,7 +22,10 @@ class Command:
|
|||
|
||||
args = arguments[1:] if len(arguments) > 1 else []
|
||||
|
||||
self.result = self[cmd](*args)
|
||||
try:
|
||||
self.result = self[cmd](*args)
|
||||
except InvalidCommandError:
|
||||
self.result = f'Not a valid command: {cmd}'
|
||||
|
||||
|
||||
def __getitem__(self, key):
|
||||
|
@ -67,15 +71,58 @@ python3 -m uncia.manage config [key] [value]:
|
|||
return self.cmd_config(key, ' '.join(value))
|
||||
|
||||
|
||||
def cmd_request(self, action=None, url=None):
|
||||
with db.session as s:
|
||||
if not action:
|
||||
instances = []
|
||||
|
||||
for row in s.search('inbox'):
|
||||
if row.followid:
|
||||
instances.append(row.domain)
|
||||
|
||||
text = 'Awaiting Requests:\n'
|
||||
text += '\n'.join([f'- {domain}' for domain in instances])
|
||||
return text
|
||||
|
||||
else:
|
||||
instance = s.get.instance(url)
|
||||
|
||||
if instance.followid:
|
||||
if action == 'accept':
|
||||
s.update(row=instance, followid=None)
|
||||
text = f'Accepted {url}'
|
||||
|
||||
elif action == 'reject':
|
||||
s.remove(row=instance)
|
||||
text = f'Rejected {url}'
|
||||
|
||||
else:
|
||||
return f'Not a valid request action: {action}'
|
||||
|
||||
Message('accept', instance.followid, instance.actor).send(instance.inbox)
|
||||
return text
|
||||
|
||||
|
||||
def cmd_accept(self, url):
|
||||
cmd_request('accept', url)
|
||||
|
||||
def cmd_reject(self, url):
|
||||
cmd_request('reject', url)
|
||||
|
||||
|
||||
def cmd_remove(self, data):
|
||||
with db.session as s:
|
||||
if s.delete.inbox(data):
|
||||
if s.delete.instance(data):
|
||||
return f'Instance removed: {data}'
|
||||
|
||||
else:
|
||||
return f'Instance does not exist: {data}'
|
||||
|
||||
|
||||
class InvalidCommandError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:] if len(sys.argv) > 1 else []
|
||||
cmd = Command(args)
|
||||
|
|
|
@ -3,62 +3,92 @@ from urllib.parse import urlparse
|
|||
from uuid import uuid4
|
||||
|
||||
from .config import config
|
||||
from .functions import push_message
|
||||
|
||||
|
||||
def accept(followid, instance):
|
||||
message = DotDict({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'type': 'Accept',
|
||||
'to': [instance.actor],
|
||||
'actor': f'https://{config.host}/actor',
|
||||
|
||||
'object': {
|
||||
'type': 'Follow',
|
||||
'id': followid,
|
||||
'object': f'https://{config.host}/actor',
|
||||
'actor': instance.actor
|
||||
},
|
||||
|
||||
'id': f'https://{config.host}/activities/{str(uuid4())}',
|
||||
})
|
||||
|
||||
return message
|
||||
class Message:
|
||||
def __init__(self, name, *args):
|
||||
self.message = getattr(self, name)(*args)
|
||||
|
||||
|
||||
def announce(object_id, inbox):
|
||||
data = DotDict({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'type': 'Announce',
|
||||
'to': [f'https://{config.host}/followers'],
|
||||
'actor': f'https://{config.host}/actor',
|
||||
'object': object_id,
|
||||
'id': f'https://{config.host}/activities/{str(uuid4())}'
|
||||
})
|
||||
|
||||
return data
|
||||
def send(self, inbox):
|
||||
return push_message(inbox, self.message)
|
||||
|
||||
|
||||
def note(user_handle, user_inbox, user_actor, actor, message):
|
||||
actor_domain = urlparse(actor).netloc
|
||||
user_domain = urlparse(user_inbox).netloc
|
||||
data = DotDict({
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": f"https://{config.host}/activities/{str(uuid4())}",
|
||||
"type": "Create",
|
||||
"actor": f"https://{config.host}/actor",
|
||||
"object": {
|
||||
def accept(self, followid, actor):
|
||||
message = DotDict({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'type': 'Accept',
|
||||
'to': [actor],
|
||||
'actor': f'https://{config.host}/actor',
|
||||
|
||||
'object': {
|
||||
'type': 'Follow',
|
||||
'id': followid,
|
||||
'object': f'https://{config.host}/actor',
|
||||
'actor': actor
|
||||
},
|
||||
|
||||
'id': f'https://{config.host}/activities/{str(uuid4())}',
|
||||
})
|
||||
|
||||
return message
|
||||
|
||||
|
||||
def reject(self, followid, actor):
|
||||
message = DotDict({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'type': 'Reject',
|
||||
'to': [actor],
|
||||
'actor': f'https://{config.host}/actor',
|
||||
|
||||
'object': {
|
||||
'type': 'Follow',
|
||||
'id': followid,
|
||||
'object': f'https://{config.host}/actor',
|
||||
'actor': actor
|
||||
},
|
||||
|
||||
'id': f'https://{config.host}/activities/{str(uuid4())}',
|
||||
})
|
||||
|
||||
return message
|
||||
|
||||
|
||||
def announce(self, object_id):
|
||||
data = DotDict({
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
'type': 'Announce',
|
||||
'to': [f'https://{config.host}/followers'],
|
||||
'actor': f'https://{config.host}/actor',
|
||||
'object': object_id,
|
||||
'id': f'https://{config.host}/activities/{str(uuid4())}'
|
||||
})
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def note(self, user_handle, user_inbox, user_actor, actor, message):
|
||||
actor_domain = urlparse(actor).netloc
|
||||
user_domain = urlparse(user_inbox).netloc
|
||||
data = DotDict({
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": f"https://{config.host}/activities/{str(uuid4())}",
|
||||
"type": "Note",
|
||||
"published": ap_date(),
|
||||
"attributedTo": f"https://{config.host}/actor",
|
||||
"content": message,
|
||||
'to': [user_inbox],
|
||||
'tag': [{
|
||||
'type': 'Mention',
|
||||
'href': user_actor,
|
||||
'name': f'@{user_handle}@{user_domain}'
|
||||
}],
|
||||
}
|
||||
})
|
||||
"type": "Create",
|
||||
"actor": f"https://{config.host}/actor",
|
||||
"object": {
|
||||
"id": f"https://{config.host}/activities/{str(uuid4())}",
|
||||
"type": "Note",
|
||||
"published": ap_date(),
|
||||
"attributedTo": f"https://{config.host}/actor",
|
||||
"content": message,
|
||||
'to': [user_inbox],
|
||||
'tag': [{
|
||||
'type': 'Mention',
|
||||
'href': user_actor,
|
||||
'name': f'@{user_handle}@{user_domain}'
|
||||
}],
|
||||
}
|
||||
})
|
||||
|
||||
return data
|
||||
return data
|
||||
|
|
|
@ -3,6 +3,7 @@ from izzylib.http_requests_client import parse_signature, verify_request
|
|||
from izzylib.http_server import MiddlewareBase
|
||||
|
||||
from .database import db
|
||||
from .functions import fetch_actor
|
||||
|
||||
|
||||
auth_paths = [
|
||||
|
@ -11,6 +12,25 @@ auth_paths = [
|
|||
'/admin'
|
||||
]
|
||||
|
||||
# Instances that just shouldn't exist and/or are known to harass others
|
||||
blocked_instances = [
|
||||
'kiwifarms.cc',
|
||||
'neckbeard.xyz',
|
||||
'gameliberty.club',
|
||||
'shitposter.club',
|
||||
'freespeechextremist.com',
|
||||
'smuglo.li',
|
||||
'yggdrasil.social',
|
||||
'gleasonator.com',
|
||||
'ligma.pro',
|
||||
'fedi.absturztau.be',
|
||||
'blob.cat',
|
||||
'social.i2p.rocks',
|
||||
'lolicon.rocks',
|
||||
'pawoo.net',
|
||||
'baraag.net'
|
||||
]
|
||||
|
||||
|
||||
class AuthCheck(MiddlewareBase):
|
||||
attach = 'request'
|
||||
|
@ -27,12 +47,16 @@ class AuthCheck(MiddlewareBase):
|
|||
request.ctx.instance = None
|
||||
|
||||
if request.ctx.signature:
|
||||
if any([s.get.ban(domain=request.ctx.signature.domain), s.get.ban(domain=request.ctx.signature.top_domain)]):
|
||||
return response.text(f'BEGONE!', status=403)
|
||||
if request.ctx.signature.top_domain in blocked_instances:
|
||||
return response.text(f'This teapot kills fascists', status=418)
|
||||
|
||||
request.ctx.instance = s.get.inbox(request.ctx.signature.domain)
|
||||
if any(map(s.get.ban, [None], [request.ctx.signature.domain, request.ctx.signature.top_domain])):
|
||||
return response.text(f'no', status=403)
|
||||
|
||||
if request.path == '/inbox' and request.method.lower() == 'post':
|
||||
request.ctx.instance = s.get.instance(request.ctx.signature.domain)
|
||||
request.ctx.actor = fetch_actor(request.ctx.signature.actor)
|
||||
|
||||
if request.path in ['/inbox', '/actor'] and request.method.lower() == 'post':
|
||||
try:
|
||||
data = request.data.json
|
||||
|
||||
|
@ -41,7 +65,7 @@ class AuthCheck(MiddlewareBase):
|
|||
return response.text(f'Invalid data', status=400)
|
||||
|
||||
try:
|
||||
validated = await verify_request(request)
|
||||
validated = await verify_request(request, actor=request.ctx.actor)
|
||||
|
||||
except AssertionError as e:
|
||||
logging.debug(f'Failed sig check: {e}')
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
from izzylib import logging
|
||||
import json
|
||||
|
||||
from izzylib import logging
|
||||
from tldextract import extract
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from . import messages
|
||||
from .database import db
|
||||
from .functions import fetch_actor, get_inbox, push_message
|
||||
from .functions import fetch_actor, fetch_auth, get_inbox, push_message
|
||||
from .messages import Message
|
||||
|
||||
|
||||
relayed_objects = []
|
||||
|
||||
|
||||
class ProcessData:
|
||||
|
@ -13,48 +20,104 @@ class ProcessData:
|
|||
self.instance = request.ctx.instance
|
||||
self.type = data.type.lower()
|
||||
self.data = data
|
||||
self.actor = fetch_actor(data.actor)
|
||||
|
||||
try:
|
||||
self.actor = fetch_actor(self.signature.actor)
|
||||
except json.decoder.JSONDecodeError:
|
||||
self.actor = None
|
||||
|
||||
#print(self.request.Headers.to_json(4))
|
||||
#print(self.request.data.json.to_json(4))
|
||||
|
||||
if not self.actor:
|
||||
logging.verbose(f'Failed to fetch actor on instance follow: {actor.data}')
|
||||
self.new_response = response.json('Failed to fetch actor.', status=400)
|
||||
logging.verbose(f'Failed to fetch actor: {data.actor}')
|
||||
self.new_response = response.json('Failed to fetch actor.', status=401)
|
||||
return
|
||||
|
||||
self.new_response = getattr(self, f'cmd_{self.type}')()
|
||||
|
||||
|
||||
def cmd_follow(self):
|
||||
if self.instance and not self.instance.followid:
|
||||
return
|
||||
if self.actor.type.lower() != 'application':
|
||||
#return self.response.json('No', status=403)
|
||||
|
||||
data = [
|
||||
get_inbox(self.actor),
|
||||
self.actor.id
|
||||
]
|
||||
Message('reject', self.data.id, self.actor.id).send(self.actor.inbox)
|
||||
logging.debug(f'Rejected non-application actor: {self.actor.id}')
|
||||
return
|
||||
|
||||
with db.session as s:
|
||||
req_app = s.get.config('require_approval')
|
||||
|
||||
if req_app:
|
||||
data.append(self.data.id)
|
||||
if not (self.instance and not self.instance.followid):
|
||||
data = [
|
||||
get_inbox(self.actor),
|
||||
self.actor.id
|
||||
]
|
||||
|
||||
instance = s.put.instance(*data)
|
||||
if req_app:
|
||||
data.append(self.data.id)
|
||||
|
||||
if not instance:
|
||||
logging.error(f'Something messed up when inserting "{self.signature.domain}" into the database')
|
||||
return self.response.json('Internal error', status=500)
|
||||
self.instance = s.put.instance(*data)
|
||||
|
||||
if not req_app:
|
||||
accept_msg = messages.accept(self.data.id, instance)
|
||||
resp = push_message(instance.inbox, accept_msg)
|
||||
if not self.instance:
|
||||
logging.error(f'Something messed up when inserting "{self.signature.domain}" into the database')
|
||||
return self.response.json('Internal error', status=500)
|
||||
|
||||
if resp.status not in [200, 202]:
|
||||
raise ValueError(f'Error when pushing to "{instance.inbox}"')
|
||||
message = Message('accept', self.data.id, self.instance.actor)
|
||||
resp = message.send(self.instance.inbox)
|
||||
|
||||
if resp.status not in [200, 202]:
|
||||
raise ValueError(f'Error when pushing to "{self.instance.inbox}"')
|
||||
|
||||
logging.verbose(f'Instance joined the relay: {self.instance.domain}')
|
||||
|
||||
|
||||
def cmd_undo(self):
|
||||
pass
|
||||
if self.actor.type.lower() != 'application':
|
||||
return
|
||||
|
||||
object = fetch_auth(self.data.object) if isinstance(self.data.object, str) else self.data.object
|
||||
|
||||
if object.type != 'Follow':
|
||||
return
|
||||
|
||||
with db.session as s:
|
||||
s.delete.instance(self.signature.actor)
|
||||
logging.debug(f'Removed instance from relay: {self.instance.domain}')
|
||||
|
||||
|
||||
def cmd_announce(self):
|
||||
pass
|
||||
object = fetch_auth(self.data.object) if isinstance(self.data.object, str) else self.data.object
|
||||
obj_actor = fetch_auth(object.attributedTo)
|
||||
|
||||
if not obj_actor:
|
||||
logging.verbose('Failed to fetch actor:', obj_actor)
|
||||
|
||||
# I'm pretty sure object.attributedTo is a string, but leaving this here just in case
|
||||
#obj_actor = fetch_auth(object.attributedTo) if isinstance(object.attributedTo, str) else object.attributedTo
|
||||
|
||||
if object.id in relayed_objects:
|
||||
logging.verbose('Already relayed object:', object.id)
|
||||
return
|
||||
|
||||
if obj_actor:
|
||||
obj_handle = obj_actor.preferredUsername
|
||||
obj_domain = urlparse(object.id).netloc
|
||||
obj_domain_top = extract(obj_domain).registered_domain
|
||||
|
||||
with db.session as s:
|
||||
if any(map(s.get.ban, [None], [obj_domain, obj_domain_top])) or s.get.ban(obj_handle, obj_domain):
|
||||
logging.verbose('Refusing to relay object from banned domain or user:', object.id)
|
||||
return
|
||||
|
||||
msg = Message('announce', object.id)
|
||||
|
||||
for instance in [row for row in s.get.instance_list() if row.domain not in [obj_domain, self.instance.domain]]:
|
||||
response = msg.send(instance.inbox)
|
||||
|
||||
if response.status not in [200, 202]:
|
||||
logging.verbose(f'Failed to send object announce to {instance.domain}: {object.id}')
|
||||
logging.debug(f'Server error {response.status}: {response.text}')
|
||||
|
||||
else:
|
||||
logging.verbose(f'Send "{object.id}" to {instance.domain}')
|
||||
|
|
|
@ -19,13 +19,10 @@ def template_context(context):
|
|||
return context
|
||||
|
||||
|
||||
def HttpRequest(Request):
|
||||
pass
|
||||
|
||||
|
||||
with db.session as s:
|
||||
app = Application(
|
||||
name = s.get.config('name'),
|
||||
title = s.get.config('name'),
|
||||
name = 'UnciaRelay',
|
||||
version = __version__,
|
||||
listen = config.listen,
|
||||
port = config.port,
|
||||
|
@ -33,7 +30,6 @@ with db.session as s:
|
|||
workers = config.workers,
|
||||
git_repo = 'https://git.barkshark.xyz/izaliamae/uncia',
|
||||
proto = 'https',
|
||||
#request_class = HttpRequest,
|
||||
tpl_search = [path.frontend],
|
||||
tpl_context = template_context,
|
||||
class_views = [getattr(views, view) for view in dir(views) if view.startswith('Uncia')]
|
||||
|
|
|
@ -16,7 +16,7 @@ class UnciaHome(View):
|
|||
instances = []
|
||||
|
||||
with db.session as s:
|
||||
for row in s.get.inbox_list():
|
||||
for row in s.get.instance_list():
|
||||
if not row.followid:
|
||||
instances.append({
|
||||
'domain': row.domain,
|
||||
|
@ -106,24 +106,24 @@ class UnciaActor(View):
|
|||
'https://www.w3.org/ns/activitystreams',
|
||||
{'manuallyApprovesFollowers': 'as:manuallyApprovesFollowers'},
|
||||
],
|
||||
'id': f'https://{config.host}/actor',
|
||||
#'followers': f'https://{host}/followers',
|
||||
#'following': f'https://{host}/following',
|
||||
'name': cfg.name,
|
||||
'summary': cfg.description,
|
||||
'preferredUsername': 'relay',
|
||||
'type': 'Application',
|
||||
'inbox': f'https://{config.host}/inbox',
|
||||
'url': f'https://{config.host}/actor',
|
||||
'manuallyApprovesFollowers': cfg.require_approval,
|
||||
'endpoints': {
|
||||
'sharedInbox': f"https://{config.host}/inbox"
|
||||
},
|
||||
#'followers': f'https://{host}/followers',
|
||||
#'following': f'https://{host}/following',
|
||||
'inbox': f'https://{config.host}/inbox',
|
||||
'name': cfg.name,
|
||||
'type': 'Application',
|
||||
'id': f'https://{config.host}/actor',
|
||||
'manuallyApprovesFollowers': cfg.require_approval,
|
||||
'publicKey': {
|
||||
'id': f'https://{config.host}/actor#main-key',
|
||||
'owner': f'https://{config.host}/actor',
|
||||
'publicKeyPem': cfg.pubkey
|
||||
},
|
||||
'summary': 'Relay Actor',
|
||||
'preferredUsername': 'relay',
|
||||
'url': f'https://{config.host}/actor'
|
||||
}
|
||||
}
|
||||
|
||||
return response.json(data)
|
||||
|
@ -142,7 +142,7 @@ class UnciaNodeinfo(View):
|
|||
|
||||
async def get(self, request, response):
|
||||
with db.session as s:
|
||||
instances = s.get.inbox_list('domain')
|
||||
instances = s.get.instance_list('domain')
|
||||
domainbans = [row.domain for row in s.get.ban_list('domain')]
|
||||
userbans = [f"{row.handle}@{row.domain}" for row in s.get.ban_list('user')]
|
||||
|
||||
|
|
Loading…
Reference in a new issue