a lot of changes

This commit is contained in:
Izalia Mae 2021-09-14 11:34:57 -04:00
parent c2796a5075
commit 24ae540ea5
10 changed files with 54 additions and 16 deletions

View file

@ -87,7 +87,7 @@ class Application(sanic.Sanic):
def add_middleware(self, middleware):
mw = middleware(self)
self.register_middleware(mw.handler, mw.attach)
self.register_middleware(mw, mw.attach)
def get_menu_item(self, name):

View file

@ -14,9 +14,11 @@ class UserLevel(IntEnum):
AUTH = 1000
# Note: sub-classing the Request class breaks things for some reason
class Config(DotDict):
defaults = dict(
name = 'IzzyLib Http Server',
title = None,
version = '0.0.1',
git_repo = 'https://git.barkshark.xyz/izaliamae/izzylib',
listen = 'localhost',
@ -50,6 +52,9 @@ class Config(DotDict):
if kwargs.get('host') and not kwargs.get('web_host'):
self.web_host = self.host
if self.name and not self.title:
self.title = self.name
def __setitem__(self, key, value):
if key not in self.defaults.keys():

View file

@ -30,6 +30,9 @@ class GenericError:
traceback.print_exc()
try:
if 'json' in request.headers.get('accept', ''):
return response.json(msg, status=status)
return response.error(msg, status, pprint=True)
except Exception as e:

View file

@ -1,7 +1,7 @@
<!DOCTYPE html>
%html
%head
%title << {{cfg.name}}: {{page}}
%title << {{cfg.title}}: {{page}}
%link(rel='stylesheet' type='text/css' href='/framework/style.css')
%link(rel='manifest' href='/framework/manifest.json')
%meta(charset='UTF-8')
@ -13,10 +13,10 @@
#header.flex-container
-if menu_left
#btn.section
.page-title.section -> %a.title(href='/') << {{cfg.name}}
.page-title.section -> %a.title(href='/') << {{cfg.title}}
-else
.page-title.section -> %a.title(href='/') << {{cfg.name}}
.page-title.section -> %a.title(href='/') << {{cfg.title}}
#btn.section
-if message

View file

@ -4,6 +4,7 @@ from datetime import datetime, timedelta, timezone
from izzylib import izzylog as logging, logging as applog
from . import start_time
from .response import Response
cache_types = [
@ -42,7 +43,14 @@ class MiddlewareBase:
self.cfg = app.cfg
async def handler(self, request):
async def __call__(self, request, response=None):
if not response:
response = Response(self.app, request)
return await self.handler(request, response)
async def handler(self, request, response):
pass

View file

@ -1,3 +1,5 @@
import json
from izzylib import LowerDotDict
@ -29,3 +31,11 @@ class Headers(LowerDotDict):
def getall(self, key, default=[]):
return self.get(key.lower(), default)
def to_json(self, indent=None):
return json.dumps(self.to_dict(), indent=indent)
def to_dict(self):
return {k: self.getone(k) for k in self}

View file

@ -1,6 +1,7 @@
import sanic
from izzylib import DotDict
from urllib.parse import parse_qsl
from .misc import Headers

View file

@ -62,11 +62,11 @@ class Response:
def __str__(self):
return self.body
return str(self.body)
def __bytes__(self):
return self.body.encode('utf-8')
return self.body if isinstance(self.body, bytes) else self.body.encode('utf-8')
def __repr__(self):

View file

@ -11,7 +11,7 @@ from izzylib.exceptions import HttpFileDownloadedError
from ssl import SSLCertVerificationError
from urllib.parse import urlparse
from .signature import sign_request
from .signature import sign_request, set_client
Client = None
@ -111,7 +111,7 @@ class HttpRequestsClient(object):
class HttpRequestsRequest(object):
def __init__(self, client, url, data=None, headers={}, query={}, method='get'):
def __init__(self, client, url, data=b'', headers={}, query={}, method='get'):
parsed = urlparse(url)
self.args = [url]
self.kwargs = DotDict({'params': query})
@ -119,6 +119,7 @@ class HttpRequestsRequest(object):
self.client = client
self.path = parsed.path
self.host = parsed.netloc
self.body = data
new_headers = client.headers.copy()
new_headers.update(headers)
@ -129,7 +130,6 @@ class HttpRequestsRequest(object):
parsed_headers['user-agent'] = client.agent
self.kwargs['headers'] = DotDict(new_headers)
self.kwargs['data'] = data
if client.proxy.enabled:
self.kwargs['proxies'] = DotDict({self.proxy.ptype: f'{self.proxy.ptype}://{self.proxy.host}:{self.proxy.port}'})
@ -142,7 +142,7 @@ class HttpRequestsRequest(object):
@body.setter
def body(self, data):
self.kwargs.data = data
self.kwargs.data = data.encode('utf-8') if isinstance(data, str) else data
@property
@ -224,3 +224,4 @@ class HttpRequestsResponse(object):
def set_requests_client(client=None):
global Client
Client = client or RequestsClient()
set_client(Client)

View file

@ -6,6 +6,7 @@ from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from base64 import b64decode, b64encode
from datetime import datetime
from functools import lru_cache
from izzylib import DefaultDotDict, DotDict
from izzylib import izzylog as logging
@ -13,6 +14,15 @@ from tldextract import extract
from urllib.parse import urlparse
Client = None
def set_client(client):
global Client
Client = client
@lru_cache(maxsize=512)
def fetch_actor(url):
if not Client:
@ -126,6 +136,7 @@ def parse_signature(signature: str):
sig.headers = sig.headers.split()
sig.domain = urlparse(sig.keyid).netloc
sig.top_domain = '.'.join(extract(sig.domain)[1:])
sig.actor = sig.keyid.split('#')[0]
return sig
@ -152,7 +163,6 @@ def verify_headers(headers: dict, method: str, path: str, actor: dict=None, body
if not actor:
actor = fetch_actor(signature.keyid)
print(actor)
## Add digest header to missing headers list if it doesn't exist
if method.lower() == 'post' and not digest:
@ -181,9 +191,7 @@ async def verify_request(request, actor: dict=None):
actor: A dictionary containing the activitypub actor and the link to the pubkey used for verification
'''
body = (await request.body) if request.body else None
headers = {k.lower(): v[0] for k,v in request.headers.items()}
return verify_headers(headers, request.method, request.path, actor, body)
return verify_headers(request.Headers.to_dict(), request.method, request.path, actor, request.body)
@ -223,6 +231,8 @@ def sign_pkcs_headers(key: str, headers: dict, sig=None):
def sign_request(request, privkey, keyid):
assert isinstance(request.body, bytes)
request.add_header('(request-target)', f'{request.method.lower()} {request.path}')
request.add_header('host', request.host)
request.add_header('date', datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'))
@ -230,7 +240,7 @@ def sign_request(request, privkey, keyid):
if request.body:
body_hash = b64encode(SHA256.new(request.body).digest()).decode("UTF-8")
request.add_header('digest', f'SHA-256={body_hash}')
request.add_header('content-length', len(request.body))
request.add_header('content-length', str(len(request.body)))
sig = {
'keyId': keyid,