Session-based firefox instance.

This commit is contained in:
sfigato 2019-08-01 00:29:28 +02:00 committed by blallo
parent 9abf1855d9
commit 5b3949e2ab
Signed by: blallo
GPG Key ID: 0CBE577C9B72DC3F
3 changed files with 59 additions and 11 deletions

View File

@ -0,0 +1,5 @@
# -*- encoding: utf-8 -*-
import os
# TODO: create config module and put this constant there.
BASE_URI = os.environ.get("BOTZ_BASE_URI", "http://localhost")

View File

@ -5,28 +5,45 @@ The application entrypoint.
"""
from aiohttp import web
import click
import base64
from cryptography import fernet
import logging
import os
import typing as T
import click
from aiohttp_session import setup, session_middleware
from aiohttp_session.cookie_storage import EncryptedCookieStorage
from bot_z.async_operator import AsyncOperator
from api.rest import routes
alog = logging.getLogger("api")
alog.setLevel(os.environ.get("BOTZ_LOGLEVEL", logging.INFO))
h = logging.StreamHandler()
f = logging.Formatter("%(levelname)s [%(name)s] -> %(message)s")
h.setFormatter(f)
alog.addHandler(h)
BASE_URI = os.environ.get("BOTZ_BASE_URI")
def setup_log() -> logging.Logger:
alog = logging.getLogger("api")
alog.setLevel(os.environ.get("BOTZ_LOGLEVEL", logging.INFO))
h = logging.StreamHandler()
f = logging.Formatter("%(levelname)s [%(name)s] -> %(message)s")
h.setFormatter(f)
alog.addHandler(h)
return alog
def init_secret() -> bytes:
fernet_key = fernet.Fernet.generate_key()
return base64.urlsafe_b64decode(fernet_key)
def setup_session(app: web.Application):
secret = init_secret()
setup(app, EncryptedCookieStorage(secret))
def run(address: T.Text, port: int) -> None:
"""Application entrypoint."""
alog = setup_log()
app = web.Application(logger=alog)
app["async_operator"] = AsyncOperator(BASE_URI, "test")
setup_session(app)
app.add_routes(routes)
web.run_app(app, host=address, port=port)

View File

@ -6,12 +6,31 @@ The REST endpoints.
from aiohttp import web
import logging
import typing as T
from aiohttp_session import get_session
from bot_z.async_operator import AsyncOperator
from api.async_bot import login, logout, checkin, checkout
from api import BASE_URI
alog = logging.getLogger("api")
routes = web.RouteTableDef()
OPERATORS = {}
async def get_set_operator(
request: web.Request, user: T.Text, password: T.Text
) -> AsyncOperator:
session = await get_session(request)
if "async_operator" in session:
op = OPERATORS[session["async_operator"]]
else:
op = AsyncOperator(BASE_URI, name=user)
session["async_operator"] = user
OPERATORS[user] = op
return op, session
@routes.post("/login")
@ -21,17 +40,24 @@ async def login_handler(request: web.Request) -> web.Response:
password = data.get("password")
if not user or not password:
return web.json_response({"error": "Missing username or password"}, status=404)
op = request.app["async_operator"]
op, session = await get_set_operator(request, user, password)
alog.debug("login - user: %s, password: %s", user, password)
res = await login(op, user, password)
alog.debug("login result: %s", res)
if not res:
session.invalidate()
alog.info("Login failed; session invalidated.")
return web.json_response({"logged_in": res}, status=200)
@routes.post("/logout")
async def logout_handler(request: web.Request) -> web.Response:
alog.debug("logout")
op = request.app["async_operator"]
session = await get_session(request)
op = OPERATORS.get(session.get("async_operator"))
if not op:
return web.json_response({"error": "No session"}, status=404)
res = await logout(op)
alog.debug("logout result: %s", res)
# FIX: assess if better to invalidate session and dump the browser session.
return web.json_response({"logged_in": res}, status=200)