iunno tbh
This commit is contained in:
parent
7f76724806
commit
51cddac201
|
@ -6,3 +6,4 @@
|
|||
|
||||
envbash==1.2.0
|
||||
pyyaml==5.4.1
|
||||
pg8000=1.21.2
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
from izzylib import logging
|
||||
from izzylib.http_requests_client.signature import generate_rsa_key
|
||||
from izzylib.sql import SqlDatabase
|
||||
from izzylib.sql.generic import OperationalError
|
||||
from izzylib.http_urllib_client.signatures import generate_rsa_key
|
||||
from izzylib.sql import Database
|
||||
|
||||
from .base import Session, tables
|
||||
|
||||
from ..config import config, dbconfig
|
||||
|
||||
|
||||
db = SqlDatabase(
|
||||
db = Database(
|
||||
config.dbtype,
|
||||
tables = tables,
|
||||
session_class = Session,
|
||||
**dbconfig
|
||||
)
|
||||
|
@ -19,12 +17,12 @@ with db.session as s:
|
|||
try:
|
||||
version = s.get.config('version')
|
||||
|
||||
except OperationalError:
|
||||
except KeyError:
|
||||
version = 0
|
||||
|
||||
if version == 0:
|
||||
keys = generate_rsa_key()
|
||||
db.create_database()
|
||||
db.create_database(tables)
|
||||
s.put.config('version', config.version)
|
||||
s.put.config('pubkey', keys.pubkey)
|
||||
s.put.config('privkey', keys.privkey)
|
||||
|
|
|
@ -3,7 +3,6 @@ import json
|
|||
from datetime import datetime
|
||||
from functools import partial
|
||||
from izzylib import DotDict, boolean, logging
|
||||
from izzylib.http_requests_client.signature import generate_rsa_key
|
||||
from izzylib.sql import SqlDatabase, SqlSession
|
||||
from izzylib.sql import SqlColumn as Column
|
||||
from urllib.parse import urlparse
|
||||
|
@ -32,7 +31,8 @@ tables = {
|
|||
Column('msgid', 'text', nullable=False),
|
||||
Column('inboxid', 'integer', nullable=False, fkey='inbox.id'),
|
||||
Column('data', 'json', nullable=False),
|
||||
Column('headers', 'json')
|
||||
Column('headers', 'json'),
|
||||
Column('timestamp')
|
||||
],
|
||||
'user': [
|
||||
Column('id'),
|
||||
|
|
|
@ -1,35 +1,23 @@
|
|||
import json
|
||||
|
||||
from functools import wraps
|
||||
from izzylib import HttpRequestsClient, LruCache, logging
|
||||
from izzylib import LruCache, logging
|
||||
from izzylib.http_urllib_client import HttpUrllibClient
|
||||
|
||||
from . import __version__
|
||||
from .config import config
|
||||
from .database import db
|
||||
|
||||
|
||||
client = HttpRequestsClient(appagent=f'UnciaRelay/{__version__}; https://{config.host}')
|
||||
client = HttpUrllibClient(
|
||||
appagent = f'UnciaRelay/{__version__}; https://{config.host}',
|
||||
headers = {
|
||||
'accept': 'application/activity+json,application/json'
|
||||
}
|
||||
)
|
||||
|
||||
client.set_global()
|
||||
cache = LruCache()
|
||||
|
||||
|
||||
def cache_fetch(func):
|
||||
@wraps(func)
|
||||
def inner_func(url, *args, **kwargs):
|
||||
cached = cache.fetch(url)
|
||||
|
||||
if cached:
|
||||
return cached
|
||||
|
||||
response = func(url, *args, **kwargs)
|
||||
|
||||
if not response:
|
||||
return
|
||||
|
||||
cache.store(url, response)
|
||||
return response
|
||||
|
||||
return inner_func
|
||||
fetch_cache = LruCache()
|
||||
|
||||
|
||||
def fetch_actor(url):
|
||||
|
@ -40,15 +28,13 @@ def fetch_actor(url):
|
|||
return cached.data
|
||||
|
||||
try:
|
||||
response = client.json(url, activity=True)
|
||||
data = response.json
|
||||
data = fetch(url, cache=False)
|
||||
|
||||
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:
|
||||
data = fetch(url, sign=True, cache=False)
|
||||
|
||||
if not data:
|
||||
return
|
||||
|
@ -57,20 +43,39 @@ def fetch_actor(url):
|
|||
return data
|
||||
|
||||
|
||||
@cache_fetch
|
||||
def fetch_auth(url):
|
||||
with db.session as s:
|
||||
response = client.signed_request(
|
||||
s.get.config('privkey'),
|
||||
f'https://{config.host}/actor#main-key',
|
||||
url,
|
||||
headers = {'accept': 'application/activity+json'}
|
||||
)
|
||||
def fetch(url, sign=False, cache=True):
|
||||
cached_data = fetch_cache.fetch(url)
|
||||
|
||||
try:
|
||||
return response.json
|
||||
except json.decoder.JSONDecodeError:
|
||||
return {}
|
||||
if cached_data and cache:
|
||||
return cached_data
|
||||
|
||||
if sign:
|
||||
with db.session as s:
|
||||
response = client.request(url,
|
||||
privkey = s.get.config('privkey'),
|
||||
keyid = f'https://{config.host}/actor#main-key'
|
||||
)
|
||||
|
||||
else:
|
||||
response = client.request(url)
|
||||
|
||||
try:
|
||||
data = response.dict
|
||||
|
||||
except json.decoder.JSONDecodeError:
|
||||
return {}
|
||||
|
||||
if not data:
|
||||
return {}
|
||||
|
||||
if cache:
|
||||
fetch_cache.store(url, data)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def fetch_auth(url):
|
||||
return fetch(url, sign=True)
|
||||
|
||||
|
||||
def get_inbox(actor):
|
||||
|
@ -90,13 +95,12 @@ def push_message(inbox, message):
|
|||
f'https://{config.host}/actor#main-key',
|
||||
inbox,
|
||||
data = message.to_json(),
|
||||
method = 'post',
|
||||
headers = {'accept': 'application/json'}
|
||||
method = 'post'
|
||||
)
|
||||
|
||||
if response.status not in [200, 202]:
|
||||
try:
|
||||
body = response.json
|
||||
body = response.dict
|
||||
except:
|
||||
body = response.text
|
||||
|
||||
|
|
159
uncia/manage.py
159
uncia/manage.py
|
@ -1,10 +1,15 @@
|
|||
import json, sys, yaml
|
||||
import json, sys
|
||||
|
||||
from datetime import datetime
|
||||
from envbash import load_envbash
|
||||
from getpass import getuser
|
||||
from izzylib import DotDict, Path, boolean, logging, prompt
|
||||
from izzylib.sql import Database
|
||||
from os import environ as env
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from . import __version__
|
||||
from .config import dbconfig, config, write_config
|
||||
from .config import config, dbconfig, path, write_config
|
||||
from .database import db
|
||||
from .functions import fetch_actor, get_inbox
|
||||
from .messages import Message
|
||||
|
@ -253,7 +258,128 @@ python3 -m uncia.manage convert [pleroma or uncia]:
|
|||
|
||||
|
||||
def convert_uncia(self):
|
||||
pass
|
||||
cfg = load_old_uncia_config()
|
||||
pgdb = Database('postgresql', **cfg)
|
||||
|
||||
new_cfg = cfg.copy()
|
||||
new_cfg.pop('name', None)
|
||||
dbconfig.update(new_cfg)
|
||||
|
||||
with pgdb.session as s:
|
||||
oldcfg = DotDict({row.key: row.value for row in s.search('config')})
|
||||
inboxes = s.search('inboxes')
|
||||
requests = s.search('requests')
|
||||
retries = s.search('retries')
|
||||
users = s.search('users')
|
||||
whitelist = s.search('whitelist')
|
||||
domainbans = s.search('domainbans')
|
||||
userbans = s.search('userbans')
|
||||
actorkey = s.fetch('keys', actor='default')
|
||||
|
||||
config.host = oldcfg.host
|
||||
config.listen = oldcfg.address
|
||||
config.port = oldcfg.port
|
||||
|
||||
write_config()
|
||||
|
||||
with db.session as s:
|
||||
s.put.config('name', oldcfg.name)
|
||||
s.put.config('admin', oldcfg.admin)
|
||||
s.put.config('show_domain_bans', boolean(oldcfg.show_domainbans))
|
||||
s.put.config('show_user_bans', boolean(oldcfg.show_userbans))
|
||||
s.put.config('whitelist', boolean(oldcfg.whitelist))
|
||||
s.put.config('block_relays', boolean(oldcfg.block_relays))
|
||||
s.put.config('require_approval', boolean(oldcfg.require_approval))
|
||||
s.put.config('privkey', actorkey.privkey)
|
||||
s.put.config('pubkey', actorkey.pubkey)
|
||||
|
||||
for inbox in [*inboxes, *requests]:
|
||||
try:
|
||||
timestamp = datetime.fromtimestamp(inbox.timestamp)
|
||||
except:
|
||||
timestamp = datetime.now()
|
||||
|
||||
s.insert('inbox',
|
||||
actor = inbox.actor,
|
||||
inbox = inbox.inbox,
|
||||
domain = inbox.domain,
|
||||
followid = inbox.get('followid'),
|
||||
timestamp = timestamp
|
||||
)
|
||||
|
||||
for retry in retries:
|
||||
try:
|
||||
timestamp = datetime.fromtimestamp(retry.timestamp)
|
||||
except:
|
||||
timestamp = datetime.now()
|
||||
|
||||
instance = s.fetch('inbox', inbox=retry.inbox)
|
||||
|
||||
if not instance:
|
||||
continue
|
||||
|
||||
s.insert('retry',
|
||||
inboxid = instance.id,
|
||||
msgid = retry.msgid,
|
||||
headers = json.loads(retry.headers),
|
||||
data = json.loads(retry.data),
|
||||
timestamp = timestamp
|
||||
)
|
||||
|
||||
for user in users:
|
||||
try:
|
||||
timestamp = datetime.fromtimestamp(user.timestamp)
|
||||
except:
|
||||
timestamp = datetime.now()
|
||||
|
||||
s.insert('user',
|
||||
handle = user.handle,
|
||||
username = user.username,
|
||||
hash = user.password,
|
||||
level = 30,
|
||||
timestamp = timestamp
|
||||
)
|
||||
|
||||
for instance in whitelist:
|
||||
try:
|
||||
timestamp = datetime.fromtimestamp(instance.timestamp)
|
||||
except:
|
||||
timestamp = datetime.now()
|
||||
|
||||
s.insert('whitelist',
|
||||
domain = instance.domain,
|
||||
timestamp = timestamp
|
||||
)
|
||||
|
||||
for row in [*domainbans, *userbans]:
|
||||
try:
|
||||
timestamp = datetime.fromtimestamp(row.timestamp)
|
||||
except:
|
||||
timestamp = datetime.now()
|
||||
|
||||
s.insert('ban',
|
||||
handle = row.get('username'),
|
||||
domain = None if row.domain.lower() == 'any' else row.domain,
|
||||
reason = row.reason,
|
||||
timestamp = timestamp
|
||||
)
|
||||
|
||||
pgdb.close()
|
||||
|
||||
delete_old = prompt('Config and database successfully converted. Delete old files and drop the old database?', default='no', valtype=boolean, options=['yes', 'no'])
|
||||
|
||||
if delete_old:
|
||||
path.data.join('production.env').delete()
|
||||
|
||||
pgdb._connect_args[0]['name'] = 'postgres'
|
||||
pgdb.open()
|
||||
|
||||
with pgdb.session as s:
|
||||
s.execute(f'DROP DATABASE {cfg.name}')
|
||||
|
||||
pgdb.close()
|
||||
|
||||
return f'Successfully dropped database: {cfg.name}'
|
||||
|
||||
|
||||
def convert_pleroma(self):
|
||||
|
@ -294,6 +420,33 @@ python3 -m uncia.manage convert [pleroma or uncia]:
|
|||
pl_cfg.db.delete()
|
||||
|
||||
|
||||
def load_old_uncia_config():
|
||||
try:
|
||||
load_envbash(path.config.join('production.env'))
|
||||
|
||||
except FileNotFoundError as e:
|
||||
pass
|
||||
|
||||
cfg = DotDict(
|
||||
host = env.get('DBHOST'),
|
||||
port = int(env.get('DBPORT', 5432)),
|
||||
user = env.get('DBUSER', getuser()),
|
||||
password = env.get('DBPASS'),
|
||||
name = env.get('DBNAME', 'uncia'),
|
||||
maxconnections = int(env.get('DBCONNUM', 15))
|
||||
)
|
||||
|
||||
#for k,v in cfg.items():
|
||||
#if v == None:
|
||||
#del cfg[k]
|
||||
|
||||
#if k == 'host' and Path(v).exists():
|
||||
#cfg['unix_socket'] = v
|
||||
#del cfg[k]
|
||||
|
||||
return cfg
|
||||
|
||||
|
||||
def load_pleroma_relay_config():
|
||||
with open('relay.yaml') as f:
|
||||
yaml_file = yaml.load(f, Loader=yaml.FullLoader)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from izzylib import logging
|
||||
from izzylib.http_requests_client import parse_signature, verify_request
|
||||
from izzylib.http_urllib_client import parse_signature, verify_request
|
||||
from izzylib.http_server import MiddlewareBase
|
||||
|
||||
from .database import db
|
||||
|
|
|
@ -5,7 +5,7 @@ from tldextract import extract
|
|||
from urllib.parse import urlparse
|
||||
|
||||
from .database import db
|
||||
from .functions import fetch_actor, fetch_auth, get_inbox, push_message
|
||||
from .functions import fetch, fetch_actor, get_inbox, push_message
|
||||
from .messages import Message
|
||||
|
||||
|
||||
|
@ -76,7 +76,7 @@ class ProcessData:
|
|||
if self.actor.type.lower() != 'application':
|
||||
return
|
||||
|
||||
object = fetch_auth(self.data.object) if isinstance(self.data.object, str) else self.data.object
|
||||
object = fetch(self.data.object, sign=True) if isinstance(self.data.object, str) else self.data.object
|
||||
|
||||
if object.type != 'Follow':
|
||||
return
|
||||
|
@ -87,14 +87,23 @@ class ProcessData:
|
|||
|
||||
|
||||
def cmd_announce(self):
|
||||
object = fetch_auth(self.data.object) if isinstance(self.data.object, str) else self.data.object
|
||||
obj_actor = fetch_auth(object.attributedTo)
|
||||
if isinstance(self.data.object, dict):
|
||||
object = self.data.object
|
||||
object_id = self.data.object.id
|
||||
|
||||
if not obj_actor:
|
||||
logging.verbose('Failed to fetch actor:', obj_actor)
|
||||
else:
|
||||
object = fetch(self.data.object, sign=True)
|
||||
object_id = self.data.object
|
||||
|
||||
if not object:
|
||||
obj_actor = None
|
||||
logging.verbose('Failed to fetch object:', object_id)
|
||||
|
||||
else:
|
||||
obj_actor = fetch(object.attributedTo, sign=True)
|
||||
|
||||
# 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
|
||||
#obj_actor = fetch(object.attributedTo, sign=True) if isinstance(object.attributedTo, str) else object.attributedTo
|
||||
|
||||
if object.id in relayed_objects:
|
||||
logging.verbose('Already relayed object:', object.id)
|
||||
|
@ -120,4 +129,4 @@ class ProcessData:
|
|||
logging.debug(f'Server error {response.status}: {response.text}')
|
||||
|
||||
else:
|
||||
logging.verbose(f'Send "{object.id}" to {instance.domain}')
|
||||
logging.verbose(f'Sent "{object.id}" to {instance.domain}')
|
||||
|
|
Loading…
Reference in a new issue