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 from aiohttp import web
import click import base64
from cryptography import fernet
import logging import logging
import os import os
import typing as T 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 bot_z.async_operator import AsyncOperator
from api.rest import routes from api.rest import routes
alog = logging.getLogger("api") def setup_log() -> logging.Logger:
alog.setLevel(os.environ.get("BOTZ_LOGLEVEL", logging.INFO)) alog = logging.getLogger("api")
h = logging.StreamHandler() alog.setLevel(os.environ.get("BOTZ_LOGLEVEL", logging.INFO))
f = logging.Formatter("%(levelname)s [%(name)s] -> %(message)s") h = logging.StreamHandler()
h.setFormatter(f) f = logging.Formatter("%(levelname)s [%(name)s] -> %(message)s")
alog.addHandler(h) h.setFormatter(f)
BASE_URI = os.environ.get("BOTZ_BASE_URI") 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: def run(address: T.Text, port: int) -> None:
"""Application entrypoint.""" """Application entrypoint."""
alog = setup_log()
app = web.Application(logger=alog) app = web.Application(logger=alog)
app["async_operator"] = AsyncOperator(BASE_URI, "test") setup_session(app)
app.add_routes(routes) app.add_routes(routes)
web.run_app(app, host=address, port=port) web.run_app(app, host=address, port=port)

View File

@ -6,12 +6,31 @@ The REST endpoints.
from aiohttp import web from aiohttp import web
import logging 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.async_bot import login, logout, checkin, checkout
from api import BASE_URI
alog = logging.getLogger("api") alog = logging.getLogger("api")
routes = web.RouteTableDef() 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") @routes.post("/login")
@ -21,17 +40,24 @@ async def login_handler(request: web.Request) -> web.Response:
password = data.get("password") password = data.get("password")
if not user or not password: if not user or not password:
return web.json_response({"error": "Missing username or password"}, status=404) 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) alog.debug("login - user: %s, password: %s", user, password)
res = await login(op, user, password) res = await login(op, user, password)
alog.debug("login result: %s", res) 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) return web.json_response({"logged_in": res}, status=200)
@routes.post("/logout") @routes.post("/logout")
async def logout_handler(request: web.Request) -> web.Response: async def logout_handler(request: web.Request) -> web.Response:
alog.debug("logout") 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) res = await logout(op)
alog.debug("logout result: %s", res) 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) return web.json_response({"logged_in": res}, status=200)