cleanup http client a bit and add new functions
This commit is contained in:
parent
a731490af4
commit
4c19e55f1a
|
@ -48,12 +48,6 @@ class httpClient:
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
data = json.dumps(data)
|
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)
|
resp = self.client.request(method, url, headers=headers, body=data)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -83,7 +77,7 @@ class httpClient:
|
||||||
'''
|
'''
|
||||||
resp = self._fetch(*args, **kwargs)
|
resp = self._fetch(*args, **kwargs)
|
||||||
|
|
||||||
return resp.data.decode()
|
return resp.data.decode() if resp else None
|
||||||
|
|
||||||
|
|
||||||
def json(self, *args, **kwargs):
|
def json(self, *args, **kwargs):
|
||||||
|
@ -109,6 +103,29 @@ class httpClient:
|
||||||
return data
|
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'):
|
def SignHeaders(headers, keyid, privkey, url, method='GET'):
|
||||||
'''
|
'''
|
||||||
Signs headers and returns them with a signature header
|
Signs headers and returns them with a signature header
|
||||||
|
@ -140,7 +157,6 @@ def SignHeaders(headers, keyid, privkey, url, method='GET'):
|
||||||
return new_headers
|
return new_headers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def ValidateSignature(headers, method, path, client=None, agent=None):
|
def ValidateSignature(headers, method, path, client=None, agent=None):
|
||||||
'''
|
'''
|
||||||
Validates the signature header.
|
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
|
client = httpClient(agent=agent) if not client else client
|
||||||
headers = {k.lower(): v for k,v in headers.items()}
|
headers = {k.lower(): v for k,v in headers.items()}
|
||||||
|
|
||||||
try:
|
signature = ParseSig(headers)
|
||||||
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()
|
|
||||||
|
|
||||||
actor_data = client.json(signature['keyid'])
|
actor_data = client.json(signature['keyid'])
|
||||||
logging.debug(actor_data)
|
logging.debug(actor_data)
|
||||||
|
@ -194,11 +188,12 @@ def ValidateSignature(headers, method, path, client=None, agent=None):
|
||||||
if not valid:
|
if not valid:
|
||||||
if not isinstance(valid, tuple):
|
if not isinstance(valid, tuple):
|
||||||
logging.verbose('Signature validation failed for unknown actor')
|
logging.verbose('Signature validation failed for unknown actor')
|
||||||
|
logging.verbose(valid)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.verbose(f'Signature validation failed for actor: {valid[1]}')
|
logging.verbose(f'Signature validation failed for actor: {valid[1]}')
|
||||||
|
|
||||||
return json_error(401, 'signature check failed')
|
return
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
'''Miscellaneous functions'''
|
'''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.path import abspath, dirname, basename, isdir, isfile
|
||||||
from os import environ as env
|
from os import environ as env
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
from . import logging
|
from . import logging
|
||||||
|
|
||||||
|
@ -68,6 +69,31 @@ def config_dir(modpath=None):
|
||||||
return stor_path
|
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):
|
def sudo(cmd, password, user=None):
|
||||||
### Please don't pur your password in plain text in a script
|
### Please don't pur your password in plain text in a script
|
||||||
### Use a module like 'getpass' to get the password instead
|
### Use a module like 'getpass' to get the password instead
|
||||||
|
@ -87,6 +113,24 @@ def sudo(cmd, password, user=None):
|
||||||
return proc
|
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():
|
def merp():
|
||||||
log = logging.getLogger('merp-heck', {'level': 'merp', 'date': False})
|
log = logging.getLogger('merp-heck', {'level': 'merp', 'date': False})
|
||||||
log.merp('heck')
|
log.merp('heck')
|
||||||
|
|
|
@ -44,6 +44,9 @@ build_path_pairs = dict()
|
||||||
def addSearchPath(path):
|
def addSearchPath(path):
|
||||||
tplPath = abspath(path)
|
tplPath = abspath(path)
|
||||||
|
|
||||||
|
if not isdir(tplPath):
|
||||||
|
raise FileNotFoundError(f'Cannot find template directory: {tplPath}')
|
||||||
|
|
||||||
if tplPath not in search_path:
|
if tplPath not in search_path:
|
||||||
search_path.append(tplPath)
|
search_path.append(tplPath)
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ def addBuildPath(name, source, destination):
|
||||||
dest = abspath(destination)
|
dest = abspath(destination)
|
||||||
|
|
||||||
if not isdir(src):
|
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({
|
build_path_pairs.update({
|
||||||
name: {
|
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):
|
def sendResponse(template, request, context=dict(), status=200, ctype='text/html', headers=dict(), **kwargs):
|
||||||
context['request'] = request
|
context['request'] = request
|
||||||
html = renderTemplate(template, context=context, **kwargs)
|
html = renderTemplate(template, context, **kwargs)
|
||||||
|
|
||||||
if framework == 'sanic':
|
if framework == 'sanic':
|
||||||
return sanic.response.text(html, status=status, headers=headers, content_type=ctype)
|
return sanic.response.text(html, status=status, headers=headers, content_type=ctype)
|
||||||
|
@ -213,9 +216,8 @@ def templateWatcher():
|
||||||
|
|
||||||
for tplpath in watchPaths:
|
for tplpath in watchPaths:
|
||||||
logging.debug(f'Watching template dir for changes: {tplpath}')
|
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
|
return observer
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue