]> git.mar77i.info Git - hublib/blobdiff - hub/app.py
big cleanup and refactoring #2: scramble master ws uri again
[hublib] / hub / app.py
index 2f1b84936f1247f3832a4714b4dca3fc8982ffc4..5192a9187bf0ca5bbdbc879c0ec6c1abdc678ec7 100644 (file)
@@ -1,7 +1,10 @@
 import socket
 import sys
 from argparse import ArgumentParser
+from base64 import urlsafe_b64encode
+from hashlib import pbkdf2_hmac
 from pathlib import Path
+from secrets import token_urlsafe
 from subprocess import run
 from traceback import print_exception
 from urllib.parse import urlunsplit
@@ -9,28 +12,55 @@ from urllib.parse import urlunsplit
 from falcon.asgi import App as FalconApp
 from falcon.constants import MEDIA_HTML
 from jinja2 import Environment, FileSystemLoader, select_autoescape
+from redis.asyncio import StrictRedis
 from uvicorn import Config, Server
 
-from .hubapp import RootApp, HubApp
+from .static import HubApp, TemplateTreeFileApp
 
 
-class App(FalconApp):
-    def __init__(self, secret, **kwargs):
+class App(TemplateTreeFileApp, FalconApp):
+    @classmethod
+    def scan_files(cls, base_dir):
+        for path in base_dir.iterdir():
+            if not path.is_dir() and not cls.is_ignored_filename(path):
+                yield path
+
+    def scramble(self, value):
+        if isinstance(value, str):
+            value = value.encode()
+        secret = self.secret
+        if isinstance(secret, str):
+            secret = secret.encode()
+        return urlsafe_b64encode(
+            pbkdf2_hmac("sha512", value, secret, 221100)
+        ).rstrip(b"=").decode("ascii")
+
+    def uri_tail(self, path: Path) -> str:
+        return self.scramble(super().uri_tail(path))
+
+    def __init__(self, base_dir, secret, **kwargs):
+        from .utils import get_redis_pass
+
+        self.secret = secret or token_urlsafe(64)
         kwargs.setdefault("media_type", MEDIA_HTML)
-        super().__init__(**kwargs)
-        self.base_dir = Path(__file__).parents[1] / "webroot"
+        FalconApp.__init__(self, **kwargs)
+        TemplateTreeFileApp.__init__(
+            self, self, base_dir, "/derp", "root"
+        )
         self.env = Environment(
             loader=FileSystemLoader(self.base_dir),
             autoescape=select_autoescape(),
             extensions=["hub.utils.StaticTag"],
         )
-        self.hubapps = {"root": RootApp(self, self.base_dir, "/derp", secret)}
+        self.hubapps = {}
+        self.conn = StrictRedis(
+            username="default", password=get_redis_pass("/etc/redis/redis.conf")
+        )
         for base_dir in self.base_dir.iterdir():
-            if not base_dir.is_dir() or RootApp.is_ignored_filename(base_dir):
-                continue
-            self.hubapps[base_dir.name] = HubApp(
-                self, base_dir, base_uri=f"/derp/{base_dir.name}"
-            )
+            if base_dir.is_dir() and not self.is_ignored_filename(base_dir):
+                self.hubapps[base_dir.name] = HubApp(
+                    self, base_dir, base_uri=f"/derp/{base_dir.name}"
+                )
         self.add_error_handler(Exception, self.print_exception)
 
     async def print_exception(self, req, resp, ex, params):
@@ -44,7 +74,7 @@ class HubServer(Server):
 
     async def startup(self, sockets: list[socket.socket] | None = None) -> None:
         await super().startup(sockets)
-        root_app = self.config.loaded_app.app.hubapps["root"]
+        root_app = self.config.loaded_app.app
         print("Secret:", root_app.secret)
         for uri, file in root_app.files_per_uris.items():
             if file.name == "index.html":
@@ -65,8 +95,8 @@ async def main():
     ap.add_argument("--secret")
     ap.add_argument("--browser", default="xdg-open")
     args = ap.parse_args()
-    app = App(args.secret)
-    await app.hubapps["root"].setup()
+    app = App(Path(__file__).parents[1] / "webroot", args.secret)
+    await app.conn.set("client_id", 0)
     config = Config(app, port=5000, log_level="info")
     config.setup_event_loop()
     hs = HubServer(config, browser=args.browser)