diff --git a/IzzyLib/http.py b/IzzyLib/http.py index eaaf515..559fb87 100644 --- a/IzzyLib/http.py +++ b/IzzyLib/http.py @@ -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 diff --git a/IzzyLib/misc.py b/IzzyLib/misc.py index 36729fb..b96e8cb 100644 --- a/IzzyLib/misc.py +++ b/IzzyLib/misc.py @@ -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') diff --git a/IzzyLib/template.py b/IzzyLib/template.py index c0a4b22..747fac9 100644 --- a/IzzyLib/template.py +++ b/IzzyLib/template.py @@ -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