cleanup http client a bit and add new functions

This commit is contained in:
Izalia Mae 2020-06-06 06:34:27 -04:00
parent a731490af4
commit 4c19e55f1a
3 changed files with 78 additions and 37 deletions

View file

@ -48,12 +48,6 @@ class httpClient:
if isinstance(data, dict):
data = json.dumps(data)
elif not isinstance(data, bytes):
try:
data = bytes(data)
except:
raise TypeError('Post data cannot be turned into bytes')
resp = self.client.request(method, url, headers=headers, body=data)
else:
@ -83,7 +77,7 @@ class httpClient:
'''
resp = self._fetch(*args, **kwargs)
return resp.data.decode()
return resp.data.decode() if resp else None
def json(self, *args, **kwargs):
@ -109,6 +103,29 @@ class httpClient:
return data
def ParseSig(headers):
sig_header = headers.get('signature')
if not sig_header:
logging.verbose('Missing signature header')
return
split_sig = sig_header.split(',')
signature = {}
for part in split_sig:
key, value = part.split('=', 1)
signature[key.lower()] = value.replace('"', '')
if not signature.get('headers'):
logging.verbose('Missing headers section in signature')
return
signature['headers'] = signature['headers'].split()
return signature
def SignHeaders(headers, keyid, privkey, url, method='GET'):
'''
Signs headers and returns them with a signature header
@ -140,7 +157,6 @@ def SignHeaders(headers, keyid, privkey, url, method='GET'):
return new_headers
def ValidateSignature(headers, method, path, client=None, agent=None):
'''
Validates the signature header.
@ -155,29 +171,7 @@ def ValidateSignature(headers, method, path, client=None, agent=None):
client = httpClient(agent=agent) if not client else client
headers = {k.lower(): v for k,v in headers.items()}
try:
sig_header = headers.get('signature')
except Exception as e:
logging.error(e)
return
if not sig_header:
logging.error('Missing signature header')
return
split_sig = sig_header.split(',')
signature = {}
for part in split_sig:
key, value = part.split('=', 1)
signature[key.lower()] = value.replace('"', '')
if not signature.get('headers'):
logging.verbose('Missing headers section in signature')
return
signature['headers'] = signature['headers'].split()
signature = ParseSig(headers)
actor_data = client.json(signature['keyid'])
logging.debug(actor_data)
@ -194,11 +188,12 @@ def ValidateSignature(headers, method, path, client=None, agent=None):
if not valid:
if not isinstance(valid, tuple):
logging.verbose('Signature validation failed for unknown actor')
logging.verbose(valid)
else:
logging.verbose(f'Signature validation failed for actor: {valid[1]}')
return json_error(401, 'signature check failed')
return
else:
return True

View file

@ -1,9 +1,10 @@
'''Miscellaneous functions'''
import random, string, sys, os, shlex, subprocess
import random, string, sys, os, shlex, subprocess, socket, traceback
from os.path import abspath, dirname, basename, isdir, isfile
from os import environ as env
from datetime import datetime
from collections import namedtuple
from . import logging
@ -68,6 +69,31 @@ def config_dir(modpath=None):
return stor_path
def getBin(filename):
for pathdir in env['PATH'].split(':'):
fullpath = os.path.join(pathdir, filename)
if os.path.isfile(fullpath):
return fullpath
raise FileNotFoundError(f'Cannot find {filename} in path.')
def Try(funct, *args, **kwargs):
Result = namedtuple('Result', 'result exception')
out = None
exc = None
try:
out = funct(*args, **kwargs)
except Exception as e:
traceback.print_exc()
exc = e
return Result(out, exc)
def sudo(cmd, password, user=None):
### Please don't pur your password in plain text in a script
### Use a module like 'getpass' to get the password instead
@ -87,6 +113,24 @@ def sudo(cmd, password, user=None):
return proc
def getip():
# Get the main IP address of the machine
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(('10.255.255.255', 1))
data = s.getsockname()
ip = data[0]
except Exception:
ip = '127.0.0.1'
finally:
s.close()
return ip
def merp():
log = logging.getLogger('merp-heck', {'level': 'merp', 'date': False})
log.merp('heck')

View file

@ -44,6 +44,9 @@ build_path_pairs = dict()
def addSearchPath(path):
tplPath = abspath(path)
if not isdir(tplPath):
raise FileNotFoundError(f'Cannot find template directory: {tplPath}')
if tplPath not in search_path:
search_path.append(tplPath)
@ -60,7 +63,7 @@ def addBuildPath(name, source, destination):
dest = abspath(destination)
if not isdir(src):
raise FileNotFoundError('Source path doesn\'t exist: {src}')
raise FileNotFoundError(f'Source path doesn\'t exist: {src}')
build_path_pairs.update({
name: {
@ -132,7 +135,7 @@ def renderTemplate(tplfile, context, request=None, headers=dict(), cookies=dict(
def sendResponse(template, request, context=dict(), status=200, ctype='text/html', headers=dict(), **kwargs):
context['request'] = request
html = renderTemplate(template, context=context, **kwargs)
html = renderTemplate(template, context, **kwargs)
if framework == 'sanic':
return sanic.response.text(html, status=status, headers=headers, content_type=ctype)
@ -213,9 +216,8 @@ def templateWatcher():
for tplpath in watchPaths:
logging.debug(f'Watching template dir for changes: {tplpath}')
observer.schedule(templateWatchHandler(), tplpath, recursive=False)
observer.schedule(templateWatchHandler(), tplpath, recursive=True)
observer.start()
return observer