aboutsummaryrefslogtreecommitdiff
path: root/labbot/addons/dashboard/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'labbot/addons/dashboard/__init__.py')
-rw-r--r--labbot/addons/dashboard/__init__.py121
1 files changed, 109 insertions, 12 deletions
diff --git a/labbot/addons/dashboard/__init__.py b/labbot/addons/dashboard/__init__.py
index 9e63cbc..d1c08c2 100644
--- a/labbot/addons/dashboard/__init__.py
+++ b/labbot/addons/dashboard/__init__.py
@@ -4,48 +4,124 @@ a web dashboard for lab-bot
import os
import logging
import json
+import time
+from functools import wraps
import aiohttp
import jinja2
import aiohttp_jinja2 # type: ignore
+from itsdangerous.url_safe import URLSafeSerializer
+from itsdangerous.exc import BadSignature
from labbot import __version__ as labbot_version
from labbot.config import Config
log = logging.getLogger(__name__)
+config = Config(__name__)
+config.set_global_data(
+ accounts={
+ "admin":"admin"
+ },
+ secret="secret",
+ salt="salt123"
+)
+
class BufferHandler(logging.Handler):
- def __init__(self, dashboard, lines=-1):
+ def __init__(self, lines=-1):
super().__init__(level=logging.DEBUG)
- self.dashboard = dashboard
+ self.log_buffer = []
self.lines = lines
def emit(self, record):
try:
msg = self.format(record)
- return self.dashboard.log_buffer.append(msg)
+ return self.log_buffer.append(msg)
finally:
if self.lines > 0:
- while len(self.dashboard.log_buffer) > self.lines:
- self.dashboard.log_buffer.remove(0)
+ while len(self.log_buffer) > self.lines:
+ self.log_buffer.remove(0)
+
+auth_s = URLSafeSerializer(config["secret"], config["salt"])
+def check_auth():
+ def decorator(func):
+ @wraps(func)
+ async def wrapper(*args, **kwargs):
+ full_kwargs = kwargs.copy()
+ full_kwargs.update(zip(func.__code__.co_varnames, args))
+ try:
+ request = full_kwargs["coro"]
+ except KeyError:
+ try:
+ request = full_kwargs["args"]
+ except KeyError:
+ request = full_kwargs["request"]
+
+ try:
+ session = request.cookies["session"]
+ data = auth_s.loads(session)
+ return await func(*args, **kwargs)
+ except (KeyError, BadSignature):
+ resp = aiohttp.web.HTTPFound(
+ location='/login',
+ headers=request.headers
+ )
+ resp.del_cookie("session")
+ raise resp
+
+
+ return wrapper
+ return decorator
+
+def set_auth():
+ def decorator(func):
+ @wraps(func)
+ async def wrapper(*args, **kwargs):
+ full_kwargs = kwargs.copy()
+ full_kwargs.update(zip(func.__code__.co_varnames, args))
+ try:
+ request = full_kwargs["coro"]
+ except KeyError:
+ try:
+ request = full_kwargs["args"]
+ except KeyError:
+ request = full_kwargs["request"]
+
+ if request.method == "POST":
+ data = await request.post()
+ try:
+ username = data["username"]
+ password = data["password"]
+ if config["accounts"].get(username, "") == password:
+ resp = aiohttp.web.HTTPFound(
+ location='/',
+ headers=request.headers
+ )
+ resp.set_cookie("session", auth_s.dumps({"time": time.time(), "username": username}), max_age=300)
+ raise resp
+ except KeyError:
+ pass
+ return await func(*args, **kwargs)
+
+ return wrapper
+ return decorator
class Dashboard:
def __init__(self, bot):
self.bot = bot
self.app = self.bot.instance.app
- self.log_buffer = []
formatter = logging.Formatter(
"[{asctime}] [{levelname}] {name}: {message}", datefmt="%Y-%m-%d %H:%M:%S", style="{"
)
- buffer_handler = BufferHandler(self)
- buffer_handler.setFormatter(formatter)
+ self.buffer_handler = BufferHandler()
+ self.buffer_handler.setFormatter(formatter)
root_logger = logging.getLogger()
- root_logger.addHandler(buffer_handler)
+ root_logger.addHandler(self.buffer_handler)
del root_logger
dashboard_dir = os.path.join(os.path.dirname(__file__), "templates")
@@ -58,7 +134,6 @@ class Dashboard:
["/", self.dashboard],
["/log", self.log],
["/settings", self.settings],
- ["/settings/dashboard", self.addon_settings("dashboard")],
]
for addon in self.bot.addons:
@@ -67,21 +142,27 @@ class Dashboard:
for page in self.pages:
endpoint, func = page
self.app.router.add_get(endpoint, func)
+ self.app.router.add_get("/login", self.login)
+ self.app.router.add_post("/login", self.login)
+ self.app.router.add_get("/logout", self.logout)
+ @check_auth()
@aiohttp_jinja2.template('index.html')
async def dashboard(self, request: aiohttp.web.Request) -> dict:
return {}
+ @check_auth()
@aiohttp_jinja2.template('log.html')
async def log(self, request: aiohttp.web.Request) -> dict:
return {}
+ @check_auth()
@aiohttp_jinja2.template('settings.html')
async def settings(self, request: aiohttp.web.Request) -> dict:
return {}
def addon_settings(self, addon):
-
+ @check_auth()
@aiohttp_jinja2.template('addon_settings.html')
async def _settings(request: aiohttp.web.Request) -> dict:
c = Config(addon, self.bot.name)
@@ -91,6 +172,20 @@ class Dashboard:
return _settings
+ @set_auth()
+ @aiohttp_jinja2.template('login.html')
+ async def login(self, request: aiohttp.web.Request) -> dict:
+ return {}
+
+ @check_auth()
+ async def logout(self, request: aiohttp.web.Request):
+ resp = aiohttp.web.HTTPFound(
+ location='/login',
+ headers=request.headers
+ )
+ resp.del_cookie("session")
+ return resp
+
async def processor(self, request) -> dict:
return {
"bot": {
@@ -99,7 +194,7 @@ class Dashboard:
"addons": self.bot.addons,
"config": self.bot.config,
- "log": "\n".join(self.log_buffer)
+ "log": "\n".join(self.buffer_handler.log_buffer)
}
}
@@ -107,4 +202,6 @@ class Dashboard:
self.event_counter += 1
def setup(bot):
+ config.setup(__name__, bot.name)
+ config.save()
Dashboard(bot)