Moved to FastAPI. Awaiting auth

This commit is contained in:
tanshu 2020-05-04 00:50:52 +05:30
parent c3e7151aef
commit 545ccbc0f0
10 changed files with 107 additions and 91 deletions

6
.env Normal file
View File

@ -0,0 +1,6 @@
DEBUG=true
HOST=0.0.0.0
PORT=8000
API_URL_BASE=https://api.digitalocean.com/v2
API_TOKEN=""
HTPASSWD=.htpasswd

View File

@ -1,17 +1,2 @@
from crypt import crypt
import os
def htpasswd(username, password, request):
settings = request.registry.settings
file = settings['biforst.auth']
if not os.path.isfile(file):
return None
users = {}
with open(file) as f:
for line in f:
login, pwd = line.split(':')
users[login] = pwd.rstrip('\n')
if username in users and crypt(password, users[username]) == users[username]:
return [Authenticated]
return None

22
bifrost/auth.py Normal file
View File

@ -0,0 +1,22 @@
import os
from crypt import crypt
# def setup_auth(app):
# htpasswd: str = app.config.HTPASSWD
# print(htpasswd)
#
# @auth.verify_password
# def htpasswd(username, password):
# if not os.path.isfile(htpasswd):
# return None
# users = {}
# with open(htpasswd) as f:
# for line in f:
# login, pwd = line.split(':')
# users[login] = pwd.rstrip('\n')
# if username in users:
# return crypt(password, users[username]) == users[username]
# else:
# return False

14
bifrost/config.py Normal file
View File

@ -0,0 +1,14 @@
from environs import Env
env = Env()
env.read_env() # read .env file, if it exists
print("env reloaded")
class Settings:
debug: bool = env("DEBUG")
host: str = env("HOST")
port: int = env.int("PORT")
api_url_base: str = env("API_URL_BASE")
api_token: str = env("API_TOKEN")
htpasswd: str = env("HTPASSWD")

View File

@ -1,25 +1,27 @@
from sanic import Sanic
import uvicorn
from fastapi import FastAPI
from environs import Env
import bifrost.routers as routers
from .config import Settings as settings
from bifrost.settings import Settings
app = FastAPI()
app = Sanic(__name__, load_env='BIFROST_')
@app.get("/")
async def root():
return {"message": "Hello World"}
app.include_router(routers.router)
def init():
env = Env()
env.read_env()
uvicorn.run(app, host=settings.host, port=settings.port)
# app.add_route(update_view, '/update', methods=['GET'])
# # setup_auth(app)
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
)
# app.run(
# host=app.config.HOST,
# port=app.config.PORT,
# debug=app.config.DEBUG,
# access_log=app.config.ACCESS_LOG
# )

33
bifrost/routers.py Normal file
View File

@ -0,0 +1,33 @@
from functools import lru_cache
import logging as logger
from fastapi import APIRouter, Header, Request, Depends
from .digital_ocean import update_domain
from . import config
router = APIRouter()
@lru_cache()
def get_settings():
return config.Settings
@router.get("/update")
def update_view(domain: str, request: Request, ip: str = None, x_forwarded_for: str = Header(None), settings: config.Settings = Depends(get_settings)):
logger.info('Here is your log')
if ip is not None:
current_ip = ip
elif x_forwarded_for is not None:
current_ip = x_forwarded_for
else:
current_ip = request.ip
name, domain = domain.split('.', maxsplit=1)
update_domain(domain, name, current_ip, settings.api_url_base, settings.api_token, logger)
return {"domain": domain, "name": name, "current_ip": current_ip, "api_base": settings.api_url_base, "api_token": settings.api_token}
# @forbidden_view_config()
# def basic_challenge(request):
# response = HTTPUnauthorized()
# response.headers.update(forget(request))
# return response

View File

@ -1,9 +0,0 @@
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

View File

@ -1,28 +0,0 @@
from sanic.log import logger
from sanic.response import json
from bifrost.digital_ocean import update_domain
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.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

View File

@ -1,5 +1,4 @@
wheel
sanic
secure
fastapi
uvicorn
environs
sanic-envconfig
requests

View File

@ -3,20 +3,16 @@ import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
README = open(os.path.join(here, 'README.txt')).read()
CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
requires = [
'wheel',
'sanic',
'secure',
'environs',
'sanic-envconfig'
]
with open(os.path.join(here, 'README.txt'), "r") as r:
README = r.read()
with open(os.path.join(here, 'CHANGES.txt'), "r") as c:
CHANGES = c.read()
with open(os.path.join(here, 'requirements.txt'), "r") as r:
requires = r.read().splitlines()
setup(name='bifrost',
version='2.0',
description='bifrost',
description='Digital Ocean domain a record updater to use as dyndns',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
@ -26,16 +22,12 @@ setup(name='bifrost',
],
author='tanshu',
author_email='programming@tanshu.com',
url='https://git.tanshu.com/tanshu',
keywords='web pyramid pylons',
url='https://git.tanshu.com/tanshu/bifrost.git',
keywords='web sanic',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
install_requires=requires,
tests_require=requires,
test_suite="bifrost",
entry_points="""\
[paste.app_factory]
main = bifrost:main
""",
)