from http.server import HTTPServer, BaseHTTPRequestHandler from urllib.parse import urlparse import json from pathlib import Path from lane_common.device_id import derive_device_id from lane_common.policy import lane_policy from .model import AccountStore from .auth import SessionManager SESSION_MANAGER = SessionManager() class AccountsHandler(BaseHTTPRequestHandler): store = None def _json(self, status: int, payload: dict) -> None: body = json.dumps({**payload, **lane_policy()}, sort_keys=True).encode("utf-8") self.send_response(status) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def do_POST(self) -> None: parsed = urlparse(self.path) length = int(self.headers.get("Content-Length", "0")) body = self.rfile.read(length) data = json.loads(body or b"{}") if parsed.path == "/accounts/create": username = data.get("username") password = data.get("password") device_info = data.get("device_info", {}) if not username or not password: self._json(400, {"error": "missing_credentials"}) return acc_id = self.store.create_account(username, password) device_id = derive_device_id(device_info) self.store.bind_device(acc_id, device_id) account = {"id": acc_id, "username": username} token = SESSION_MANAGER.create_session(account, device_id) self._json(200, {"session": token, "account_id": acc_id}) return if parsed.path == "/accounts/login": username = data.get("username") password = data.get("password") device_info = data.get("device_info", {}) account = self.store.authenticate(username, password) if account is None: self._json(401, {"error": "invalid_credentials"}) return device_id = derive_device_id(device_info) token = SESSION_MANAGER.create_session(account, device_id) self._json(200, {"session": token, "account_id": account["id"]}) return self._json(404, {"error": "not_found"}) def run() -> None: base = Path("/lane-estate/accounts.db") store = AccountStore(base) AccountsHandler.store = store server = HTTPServer(("0.0.0.0", 8081), AccountsHandler) server.serve_forever()