Calibreweb login errors
This commit is contained in:
+22
-5
@@ -1,6 +1,6 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
import mimetypes
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
@@ -25,15 +25,25 @@ class CalibreClient:
|
|||||||
def _ensure_auth(self) -> None:
|
def _ensure_auth(self) -> None:
|
||||||
if self._authenticated:
|
if self._authenticated:
|
||||||
return
|
return
|
||||||
|
# Fetch login page first to get the CSRF token (Flask-WTF requirement)
|
||||||
|
login_url = f"{self._cfg.url}/login"
|
||||||
|
page = self._session.get(login_url, timeout=30)
|
||||||
|
page.raise_for_status()
|
||||||
|
csrf = _extract_csrf(page.text)
|
||||||
|
|
||||||
|
data = {"username": self._cfg.user, "password": self._cfg.password}
|
||||||
|
if csrf:
|
||||||
|
data["csrf_token"] = csrf
|
||||||
|
|
||||||
resp = self._session.post(
|
resp = self._session.post(
|
||||||
f"{self._cfg.url}/login",
|
login_url,
|
||||||
data={"username": self._cfg.user, "password": self._cfg.password},
|
data=data,
|
||||||
allow_redirects=True,
|
allow_redirects=True,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
# Calibre-Web redirects to / on success; a 200 on /login means bad creds
|
# Calibre-Web redirects to / on success; landing back on /login means bad creds
|
||||||
if resp.url.endswith("/login"):
|
if resp.url.rstrip("/").endswith("/login"):
|
||||||
raise RuntimeError("Calibre-Web authentication failed — check credentials")
|
raise RuntimeError("Calibre-Web authentication failed — check credentials")
|
||||||
self._authenticated = True
|
self._authenticated = True
|
||||||
log.info("Authenticated to Calibre-Web at %s", self._cfg.url)
|
log.info("Authenticated to Calibre-Web at %s", self._cfg.url)
|
||||||
@@ -75,6 +85,13 @@ def test_connection(cfg: CalibreConfig) -> tuple[bool, str]:
|
|||||||
return False, str(e)
|
return False, str(e)
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_csrf(html: str) -> str | None:
|
||||||
|
m = re.search(r'name="csrf_token"\s+value="([^"]+)"', html)
|
||||||
|
if not m:
|
||||||
|
m = re.search(r'value="([^"]+)"\s+name="csrf_token"', html)
|
||||||
|
return m.group(1) if m else None
|
||||||
|
|
||||||
|
|
||||||
def _sha256(path: Path) -> str:
|
def _sha256(path: Path) -> str:
|
||||||
h = hashlib.sha256()
|
h = hashlib.sha256()
|
||||||
with path.open("rb") as f:
|
with path.open("rb") as f:
|
||||||
|
|||||||
Reference in New Issue
Block a user