#!/usr/bin/env python2 import os import random import sys import yaml import bottle import cliapp import distixapi class AuthenticationPlugin(object): name = 'AuthenticationPlugin' def __init__(self, users): self._users = users def apply(self, callback, route): def authorize(*args, **kwargs): try: scopes = distixapi.get_scopes(self._users, bottle.request) except distixapi.AuthenticationError: return bottle.abort(401, 'Unauthorized') if route['method'].lower() not in scopes: return bottle.abort(401, 'Unauthorized') return callback(*args, **kwargs) return authorize class API(object): def __init__(self, users): self.app = bottle.Bottle() self.app.install(AuthenticationPlugin(users)) self.app.route('/version', method='GET', callback=self.version) def run(self, port): self.app.run(port=port) def version(self): return { 'version': '1.0' } class DistixBackend(cliapp.Application): def add_settings(self): self.settings.integer( ['port'], 'listen on PORT', metavar='PORT') self.settings.string( ['port-file'], 'pick random ports, write to FILE', metavar='FILE') self.settings.string( ['pid-file'], 'write pid to FILE', metavar='FILE') self.settings.string( ['users-file'], 'read users list from FILE', metavar='FILE') def process_args(self, args): users = self.read_user_file() if self.settings['port']: port = self.settings['port'] else: port = self.pick_random_port() self.write_pid_file() api = API(users) api.run(port) def read_user_file(self): filename = self.settings['users-file'] if os.path.exists(filename): with open(filename) as f: return yaml.safe_load(f) def pick_random_port(self): port = random.randint(1025, 32767) with open(self.settings['port-file'], 'w') as f: f.write('{}\n'.format(port)) return port def write_pid_file(self): filename = self.settings['pid-file'] if filename: with open(filename, 'w') as f: f.write('{}\n'.format(os.getpid())) DistixBackend(version=distixapi.__version__).run()