Revision d20914d0
Added by David Sorber over 7 years ago
| software/hbkif/conf/apache/hbkif.conf | ||
|---|---|---|
|
WSGIScriptAlias /hbkif /home/dsorber/Documents/repo/software/hbkif/hbkif.wsgi
|
||
|
<Directory /home/dsorber/Documents/repo/software/hbkif/>
|
||
|
WSGIApplicationGroup %{GLOBAL}
|
||
|
WSGIPassAuthorization On
|
||
|
Require all granted
|
||
|
</Directory>
|
||
|
|
||
|
#Alias "/docs/uspto/claims" "/ryftone/regression/uspto/claims/"
|
||
|
#<Directory /ryftone/regression/uspto/claims/>
|
||
|
# Options +Indexes
|
||
|
# Require all granted
|
||
|
#</Directory>
|
||
|
|
||
|
#Alias "/docs/uspto/parsed" "/ryftone/regression/uspto/split-parsed/"
|
||
|
#<Directory /ryftone/regression/uspto/split-parsed/>
|
||
|
# Options +Indexes
|
||
|
# Require all granted
|
||
|
#</Directory>
|
||
|
|
||
| software/hbkif/hbkif.wsgi | ||
|---|---|---|
|
import re
|
||
|
|
||
|
from hbkif.controllers.status import StatusController
|
||
|
from hbkif.controllers.version import VersionController
|
||
|
|
||
|
class Delegator(object):
|
||
|
|
||
|
def __init__(self):
|
||
|
pass
|
||
|
|
||
|
def __call__(self, environ, start_response):
|
||
|
path = environ['PATH_INFO']
|
||
|
|
||
|
if re.match('^/status(/)?$', path):
|
||
|
# Authenticate user
|
||
|
controller = StatusController(environ)
|
||
|
status, headers, body = controller.generate_response()
|
||
|
elif re.match('^/version(/)?$', path):
|
||
|
# All bookmarks page
|
||
|
controller = VersionController(environ)
|
||
|
status, headers, body = controller.generate_response()
|
||
|
else:
|
||
|
# User supplied an invalid URL
|
||
|
status = '200 OK'
|
||
|
body = 'hbkif is working!\n\nInvalid URL "{:s}"'.format(environ['PATH_INFO'])
|
||
|
body = body.encode()
|
||
|
headers = [('Content-Type', 'text/plain'),
|
||
|
('Content-Length', str(len(body)))]
|
||
|
|
||
|
# Send the status and response headers to the server
|
||
|
start_response(status, headers)
|
||
|
# Return the response body. (Notice it is wrapped in a list although it
|
||
|
# could be any iterable.)
|
||
|
return [body]
|
||
|
|
||
|
|
||
|
# Set the callable object
|
||
|
application = Delegator()
|
||
| software/hbkif/hbkif/config.py | ||
|---|---|---|
|
import logging
|
||
|
|
||
|
# Version information
|
||
|
VERSION_MAJOR = 0
|
||
|
VERSION_MINOR = 1
|
||
|
VERSION_BUGFIX = 0
|
||
|
|
||
|
VERSION_STR = '{:d}.{:d}.{:d}'.format(VERSION_MAJOR, VERSION_MINOR,
|
||
|
VERSION_BUGFIX)
|
||
|
|
||
|
# Logfile information
|
||
|
LOGFILE_PATH = '/var/log/hbkif/hbkif.log'
|
||
|
LOG_FORMAT_STR = '%(asctime)s|%(levelname)s|%(filename)s:%(lineno)s|%(message)s'
|
||
|
LOG_DATE_FORMAT_STR = '%a %b %d %H:%M:%S %Y'
|
||
|
DEFAULT_LOG_LEVEL = logging.DEBUG
|
||
|
|
||
|
|
||
| software/hbkif/hbkif/controllers/base.py | ||
|---|---|---|
|
import logging
|
||
|
|
||
|
from hbkif.config import LOGFILE_PATH, LOG_FORMAT_STR, LOG_DATE_FORMAT_STR, \
|
||
|
DEFAULT_LOG_LEVEL
|
||
|
|
||
|
|
||
|
def auth_with_jwt(func):
|
||
|
""" Method decorator for setting up JWT authorization for controllers that
|
||
|
require it.
|
||
|
"""
|
||
|
def func_wrapper(self, *args, **kwargs):
|
||
|
self.status = '403 Forbidden'
|
||
|
self.content = b''
|
||
|
|
||
|
http_auth = self.environ.get('HTTP_AUTHORIZATION', '')
|
||
|
logging.debug('HTTP_AUTHORIZATION: {:s}'.format(http_auth))
|
||
|
if http_auth.startswith('Bearer '):
|
||
|
logging.debug('Attempting to authorize JWT')
|
||
|
self.token_valid, self.token_expired, self.user_id = \
|
||
|
authorize_jwt(http_auth[7:])
|
||
|
|
||
|
if not self.token_expired:
|
||
|
# The token is not expired, so decide what to do next...
|
||
|
# For now we'll fully authorize if the token is valid (this
|
||
|
# can be changed in the future if fine-grained permissions are
|
||
|
# needed)
|
||
|
self.authorized = self.token_valid
|
||
|
else:
|
||
|
# TODO: handle expired...
|
||
|
logging.debug('JWT is expired')
|
||
|
return func(self, *args, **kwargs)
|
||
|
|
||
|
return func_wrapper
|
||
|
|
||
|
|
||
|
class BaseController(object):
|
||
|
|
||
|
def __init__(self, environ):
|
||
|
|
||
|
logging.basicConfig(format=LOG_FORMAT_STR,
|
||
|
datefmt=LOG_DATE_FORMAT_STR,
|
||
|
filename=LOGFILE_PATH, level=DEFAULT_LOG_LEVEL)
|
||
|
|
||
|
self.environ = environ
|
||
|
self.content = ''
|
||
|
|
||
|
# Override this as necessary
|
||
|
self.content_type = 'text/html; charset=utf-8'
|
||
|
|
||
|
# Unless overridden status should be 200 for success
|
||
|
self.status = '200 OK'
|
||
|
|
||
|
# Add custom headers as needed (formatted as tuple of: name, value)
|
||
|
self.custom_headers = []
|
||
|
|
||
|
# Used for token authorization
|
||
|
self.authorized = False
|
||
|
self.token_valid = False
|
||
|
self.token_expired = False
|
||
|
self.user_id = None
|
||
|
|
||
|
def build_content(self):
|
||
|
""" This method is used to build the content that is used to generate
|
||
|
the response. This method should populate the self.content dict.
|
||
|
|
||
|
Override this method with your own to make this controller actually
|
||
|
do stuff!
|
||
|
"""
|
||
|
return self.content.encode()
|
||
|
|
||
|
def generate_response(self):
|
||
|
""" This function generates the actual response which is made up of two
|
||
|
parts, the response headers and the response body. It then returns the
|
||
|
status along with the headers and body.
|
||
|
"""
|
||
|
body = self.build_content()
|
||
|
|
||
|
# Set the appropriate response headers
|
||
|
headers = [('Content-Type', self.content_type),
|
||
|
('Content-Length', str(len(body)))]
|
||
|
|
||
|
# Include any custom headers
|
||
|
if self.custom_headers:
|
||
|
headers.extend(self.custom_headers)
|
||
|
|
||
|
return self.status, headers, body
|
||
| software/hbkif/hbkif/controllers/status.py | ||
|---|---|---|
|
import datetime
|
||
|
import json
|
||
|
import logging
|
||
|
import subprocess
|
||
|
|
||
|
from hbkif.controllers.base import BaseController
|
||
|
from hbkif.config import VERSION_STR
|
||
|
|
||
|
pwd = 'admin'
|
||
|
|
||
|
class StatusController(BaseController):
|
||
|
|
||
|
def __init__(self, environ):
|
||
|
super(StatusController, self).__init__(environ)
|
||
|
|
||
|
# We return JSON
|
||
|
self.content_type = 'application/json'
|
||
|
|
||
|
def build_content(self):
|
||
|
logging.info('Handling /status request')
|
||
|
|
||
|
# Build command
|
||
|
cmd = 'ipmitool -I lanplus -U admin -P {:s} -H brutus-ipmi power status'
|
||
|
cmd = cmd.format(pwd)
|
||
|
proc = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE,
|
||
|
stderr=subprocess.STDOUT)
|
||
|
|
||
|
version_dict = {'returncode': proc.returncode,
|
||
|
'status': proc.stdout.decode('utf-8').strip()}
|
||
|
self.content = json.dumps(version_dict).encode()
|
||
|
return self.content
|
||
| software/hbkif/hbkif/controllers/version.py | ||
|---|---|---|
|
import datetime
|
||
|
import json
|
||
|
import logging
|
||
|
|
||
|
from hbkif.controllers.base import BaseController
|
||
|
from hbkif.config import VERSION_STR
|
||
|
|
||
|
class VersionController(BaseController):
|
||
|
|
||
|
def __init__(self, environ):
|
||
|
super(VersionController, self).__init__(environ)
|
||
|
|
||
|
# We return JSON
|
||
|
self.content_type = 'application/json'
|
||
|
|
||
|
def build_content(self):
|
||
|
logging.info('Handling /version request')
|
||
|
now = datetime.datetime.now()
|
||
|
version_dict = {'version': VERSION_STR,
|
||
|
'timestamp': now.strftime('%Y-%m-%d %H:%M:%S')}
|
||
|
self.content = json.dumps(version_dict).encode()
|
||
|
return self.content
|
||
| software/hbkif/setup.py | ||
|---|---|---|
|
from setuptools import setup, find_packages
|
||
|
|
||
|
# Use implicit ryft namespace package to keep things organized
|
||
|
setup(
|
||
|
name='hbkif',
|
||
|
version='0.1.0',
|
||
|
description='Handbrake web interface',
|
||
|
packages=['hbkif', 'hbkif.controllers'],
|
||
|
# ~ packages=find_packages('hbkif'),
|
||
|
# ~ entry_points = {
|
||
|
# ~ 'console_scripts': [
|
||
|
# ~ 'docsim_daemon = ryft.xrest.docsim_daemon:main',
|
||
|
# ~ ]
|
||
|
# ~ },
|
||
|
zip_safe=False,
|
||
|
)
|
||
Initial create of handbrake interface project.