diff --git a/.gitignore b/.gitignore index bc9f961..1972511 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ env .pydevproject */__pycache__/ .idea/ -*.egg-info/ \ No newline at end of file +*.egg-info/ +.htpasswd \ No newline at end of file diff --git a/bifrost/__init__.py b/bifrost/__init__.py index 1ae9386..5cac54f 100644 --- a/bifrost/__init__.py +++ b/bifrost/__init__.py @@ -1,17 +1,5 @@ from crypt import crypt import os -from pyramid.authentication import BasicAuthAuthenticationPolicy -from pyramid.authorization import ACLAuthorizationPolicy -from pyramid.config import Configurator -from pyramid.security import Authenticated, Allow, Everyone - - -def main(global_config, **settings): - config = Configurator(settings=settings, authentication_policy=BasicAuthAuthenticationPolicy(htpasswd), - authorization_policy=ACLAuthorizationPolicy(), root_factory='bifrost.RootFactory') - config.add_route('update', '/update') - config.scan() - return config.make_wsgi_app() def htpasswd(username, password, request): @@ -27,13 +15,3 @@ def htpasswd(username, password, request): if username in users and crypt(password, users[username]) == users[username]: return [Authenticated] return None - - -class RootFactory(object): - @property - def __acl__(self): - acl = [(Allow, Authenticated, Authenticated)] - return acl - - def __init__(self, request): - pass diff --git a/bifrost/__main__.py b/bifrost/__main__.py new file mode 100644 index 0000000..8ba0f4b --- /dev/null +++ b/bifrost/__main__.py @@ -0,0 +1,3 @@ +from bifrost.main import init + +init() diff --git a/bifrost/main.py b/bifrost/main.py new file mode 100644 index 0000000..5f2af20 --- /dev/null +++ b/bifrost/main.py @@ -0,0 +1,25 @@ +from sanic import Sanic + +from environs import Env + +from bifrost.settings import Settings + +app = Sanic(__name__, load_env='BIFROST_') + + +def init(): + env = Env() + env.read_env() + + app.config.from_object(Settings) + + from bifrost.views import update_view + app.add_route(update_view, '/update', methods=['GET']) + + app.run(host='0.0.0.0', port=8000, debug=True, access_log=True) + app.run( + host=app.config.HOST, + port=app.config.PORT, + debug=app.config.DEBUG, + access_log=app.config.ACCESS_LOG + ) diff --git a/bifrost/settings.py b/bifrost/settings.py new file mode 100644 index 0000000..2d4f448 --- /dev/null +++ b/bifrost/settings.py @@ -0,0 +1,9 @@ +from sanic_envconfig import EnvConfig + + +class Settings(EnvConfig): + DEBUG: bool = True + HOST: str = '0.0.0.0' + PORT: int = 8000 + API_URL_BASE: str = 'https://api.digitalocean.com/v2' + API_TOKEN: str = None diff --git a/bifrost/views.py b/bifrost/views.py index 4a5cb50..c5ac261 100644 --- a/bifrost/views.py +++ b/bifrost/views.py @@ -1,31 +1,28 @@ -import logging +from sanic.log import logger +from sanic.response import json -from pyramid.httpexceptions import HTTPUnauthorized -from pyramid.security import forget, Authenticated -from pyramid.view import view_config, forbidden_view_config from bifrost.digital_ocean import update_domain -log = logging.getLogger('bifrost.updater') -api_url_base = 'https://api.digitalocean.com/v2' -api_token = None - -@view_config(route_name='update', request_param='domain', renderer='json', permission=Authenticated) -def update_view(request): - current_ip = request.GET.get('ip', None) - if current_ip is None: +async def update_view(request): + logger.info('Here is your log') + if 'domain' not in request.args or len(request.args['domain']) != 1: + return json({"message": "Domain error"}) + domain = request.args['domain'][0] + if 'ip' in request.args and len(request.args['ip']) == 1: + current_ip = request.args['ip'][0] + else: if 'X-Forwarded-For' in request.headers: current_ip = request.headers['X-Forwarded-For'] else: - current_ip = request.remote_addr - - name, domain = request.GET['domain'].split('.', maxsplit=1) - update_domain(domain, name, current_ip, api_url_base, api_token, log) - return {} + current_ip = request.ip + name, domain = domain.split('.', maxsplit=1) + update_domain(domain, name, current_ip, request.app.config.API_URL_BASE, request.app.config.API_TOKEN, logger) + return json({"domain": domain, "name": name, "current_ip": current_ip, "api_base": request.app.config.API_URL_BASE, "api_token": request.app.config.API_TOKEN}) -@forbidden_view_config() -def basic_challenge(request): - response = HTTPUnauthorized() - response.headers.update(forget(request)) - return response +# @forbidden_view_config() +# def basic_challenge(request): +# response = HTTPUnauthorized() +# response.headers.update(forget(request)) +# return response diff --git a/development.ini b/development.ini deleted file mode 100644 index 4b800a7..0000000 --- a/development.ini +++ /dev/null @@ -1,63 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:bifrost - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -biforst.file = %(here)s/dns_info -biforst.auth = %(here)s/.htpasswd -webfaction.username = -webfaction.password = - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -host = 0.0.0.0 -port = 6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, bifrost, bifrost.updater - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_bifrost] -level = DEBUG -handlers = -qualname = bifrost - -[logger_bifrost.updater] -level = INFO -handlers = -qualname = bifrost.updater - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/production.ini b/production.ini deleted file mode 100644 index b229ecf..0000000 --- a/production.ini +++ /dev/null @@ -1,63 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:bifrost - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -biforst.file = %(here)s/dns_info -biforst.auth = %(here)s/.htpasswd -webfaction.username = -webfaction.password = - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -host = 0.0.0.0 -port = 6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, bifrost, bifrost.updater - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console - -[logger_bifrost] -level = WARN -handlers = -qualname = bifrost - -[logger_bifrost.updater] -level = INFO -handlers = -qualname = bifrost.updater - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/requirements.txt b/requirements.txt index ff4f41f..9b69927 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ -pyramid -waitress -requests +wheel +sanic +secure +environs +sanic-envconfig \ No newline at end of file diff --git a/setup.py b/setup.py index 23967fd..311d7b8 100644 --- a/setup.py +++ b/setup.py @@ -7,20 +7,22 @@ README = open(os.path.join(here, 'README.txt')).read() CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() requires = [ - 'pyramid', - 'waitress', - 'requests' + 'wheel', + 'sanic', + 'secure', + 'environs', + 'sanic-envconfig' ] setup(name='bifrost', - version='1.0', + version='2.0', description='bifrost', long_description=README + '\n\n' + CHANGES, classifiers=[ "Programming Language :: Python", "Framework :: Pyramid", "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + "Topic :: Internet :: WWW/HTTP :: ASGI :: Application", ], author='tanshu', author_email='programming@tanshu.com',