feat: add auth subsystem with WebAuthn passkeys support
New modules: lib/auth, lib/auth_users, lib/db, lib/db_sqlite, lib/password, lib/webauthn, daemon/handlers/auth, scripts/bootstrap_auth, tests/test_auth Frontend: webui/api/auth, hoover/components/auth, pages/login, passkeys, users Updates: daemon/iface and server, lib/common and nginx, pyproject.toml deps, install script, server.py, app.js, and websocket/api clients
This commit is contained in:
+1
-26
@@ -14,7 +14,7 @@ from typing import Any
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
from lib.acme import find_cert_dir
|
||||
from lib.common import ensure_dirs, load_json, save_json
|
||||
from lib.common import _hash_password, ensure_dirs, load_json, save_json
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -50,10 +50,6 @@ DEFAULT_SSL: dict[str, Any] = {
|
||||
WEBUI_BACKEND: dict[str, Any] = {
|
||||
"label": "Vacuum Wall WebUI",
|
||||
"builtin": True,
|
||||
"auth": {
|
||||
"user": "admin",
|
||||
"htpasswd": str(HTPASSWD_FILE),
|
||||
},
|
||||
"paths": {
|
||||
"/": {
|
||||
"backend": {"host": "127.0.0.1", "port": 9090, "proto": "http"},
|
||||
@@ -120,13 +116,6 @@ def _ensure_webui_backend(raw: dict[str, Any]) -> None:
|
||||
return
|
||||
backends["webui"] = deepcopy(WEBUI_BACKEND)
|
||||
backends["webui"]["_migrated"] = True
|
||||
# Harvest auth from legacy path-level auth if present
|
||||
for dom in raw.get("domains", {}).values():
|
||||
paths = dom.get("paths", {})
|
||||
root = paths.get("/", {})
|
||||
if root.get("auth"):
|
||||
backends["webui"]["auth"] = root["auth"]
|
||||
break
|
||||
|
||||
|
||||
def _migrate_mgmt_domains(raw: dict[str, Any]) -> None:
|
||||
@@ -577,20 +566,6 @@ def write_htpasswd(user: str, password: str) -> None:
|
||||
os.replace(tmp, HTPASSWD_FILE)
|
||||
|
||||
|
||||
def _hash_password(password: str) -> str:
|
||||
"""Hash *password* using SHA-256 crypt (``$5$`` format) via passlib.
|
||||
|
||||
Args:
|
||||
password: Plain-text password to hash.
|
||||
|
||||
Returns:
|
||||
The hashed password string suitable for ``.htpasswd`` (e.g. ``$5$rounds=…$…``).
|
||||
"""
|
||||
from passlib.hash import sha256_crypt
|
||||
|
||||
return sha256_crypt.hash(password)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"WEBUI_BACKEND",
|
||||
"_ensure_webui_backend",
|
||||
|
||||
Reference in New Issue
Block a user