Implement complete WebDAV file serving compatible with various clients from Windows File Explorer to more specialized sync tools. The old control WebSocket has been updated to part-DAV, part REST API instead. Implemented user:pass BASIC auth. Added UI and backend for creating tokens that avoid the need to use actual username and password for requests from CLI or DAV.
48 lines
1.1 KiB
Python
48 lines
1.1 KiB
Python
from time import time
|
|
|
|
import jwt
|
|
|
|
from cista.config import derived_secret
|
|
|
|
|
|
def session_secret():
|
|
return derived_secret("session")
|
|
|
|
|
|
max_age = 365 * 86400 # Seconds since last login
|
|
|
|
|
|
def get(request):
|
|
try:
|
|
return jwt.decode(request.cookies.s, session_secret(), algorithms=["HS256"])
|
|
except Exception:
|
|
return False if "s" in request.cookies else None
|
|
|
|
|
|
def create(res, username, *, secure: bool = True, **kwargs):
|
|
data = {
|
|
"exp": int(time()) + max_age,
|
|
"username": username,
|
|
**kwargs,
|
|
}
|
|
s = jwt.encode(data, session_secret())
|
|
res.cookies.add_cookie("s", s, httponly=True, max_age=max_age, secure=secure)
|
|
|
|
|
|
def update(res, s, *, secure: bool = True, **kwargs):
|
|
s.update(kwargs)
|
|
s = jwt.encode(s, session_secret())
|
|
max_age = max(1, s["exp"] - int(time())) # type: ignore
|
|
res.cookies.add_cookie("s", s, httponly=True, max_age=max_age, secure=secure)
|
|
|
|
|
|
def delete(res):
|
|
res.cookies.delete_cookie("s")
|
|
|
|
|
|
def flash(res, message: str | None):
|
|
if message is None:
|
|
res.cookies.delete_cookie("message")
|
|
else:
|
|
res.cookies.add_cookie("message", message, max_age=5)
|