Archived
Remove account-based DynDNS onboarding
This commit is contained in:
1 parent
86060d6bdc
commit
148918b283
8 files changed
+67
-599
No files matched your search
@@ -3,13 +3,11 @@ from __future__ import annotations
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import re
|
||||
import secrets
|
||||
import time
|
||||
from datetime import UTC, datetime
|
||||
from ipaddress import ip_address, ip_network
|
||||
|
||||
from fastapi import HTTPException, Request, Response
|
||||
from fastapi import HTTPException, Request
|
||||
|
||||
from .ddns_models import DdnsSettings
|
||||
|
||||
@@ -46,49 +44,8 @@ def hash_lookup_token(token: str) -> str:
|
||||
return hashlib.sha256(token.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def normalize_email(value: str) -> str:
|
||||
email = value.strip().lower()
|
||||
if not re.fullmatch(r"[^@\s]+@[^@\s]+\.[^@\s]+", email):
|
||||
return ""
|
||||
return email
|
||||
|
||||
|
||||
def make_session_cookie(user_id: int, secret: str) -> str:
|
||||
timestamp = str(int(time.time()))
|
||||
payload = f"{user_id}:{timestamp}"
|
||||
signature = _session_signature(payload, secret)
|
||||
return base64.urlsafe_b64encode(f"{payload}:{signature}".encode()).decode("ascii")
|
||||
|
||||
|
||||
def verify_session_cookie(value: str | None, secret: str, max_age_seconds: int = 60 * 60 * 24 * 30) -> int | None:
|
||||
if not value or not secret:
|
||||
return None
|
||||
try:
|
||||
decoded = base64.urlsafe_b64decode(value.encode("ascii")).decode("utf-8")
|
||||
user_id, timestamp, signature = decoded.split(":", 2)
|
||||
except Exception:
|
||||
return None
|
||||
payload = f"{user_id}:{timestamp}"
|
||||
if not hmac.compare_digest(signature, _session_signature(payload, secret)):
|
||||
return None
|
||||
if int(time.time()) - int(timestamp) > max_age_seconds:
|
||||
return None
|
||||
return int(user_id)
|
||||
|
||||
|
||||
def set_session_cookie(response: Response, settings: DdnsSettings, user_id: int) -> None:
|
||||
response.set_cookie(
|
||||
"ddns_session",
|
||||
make_session_cookie(user_id, settings.session_secret),
|
||||
max_age=60 * 60 * 24 * 30,
|
||||
httponly=True,
|
||||
secure=settings.public_base_url.startswith("https://"),
|
||||
samesite="strict",
|
||||
)
|
||||
|
||||
|
||||
def admin_csrf_token(settings: DdnsSettings) -> str:
|
||||
secret = settings.admin_password or settings.shared_secret or settings.session_secret
|
||||
secret = settings.admin_password or settings.shared_secret
|
||||
day = datetime.now(UTC).strftime("%Y-%m-%d")
|
||||
return hmac.new(secret.encode("utf-8"), f"admin:{day}".encode(), hashlib.sha256).hexdigest()
|
||||
|
||||
@@ -109,8 +66,6 @@ def client_ip(request: Request, settings: DdnsSettings | None = None) -> str:
|
||||
def is_rate_limited_path(path: str) -> bool:
|
||||
limited_paths = {
|
||||
"/magic",
|
||||
"/login",
|
||||
"/register",
|
||||
"/accounts",
|
||||
"/request-domain",
|
||||
"/verify-domain",
|
||||
@@ -121,10 +76,6 @@ def is_rate_limited_path(path: str) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def _session_signature(payload: str, secret: str) -> str:
|
||||
return hmac.new(secret.encode("utf-8"), payload.encode("utf-8"), hashlib.sha256).hexdigest()
|
||||
|
||||
|
||||
def _trusted_proxy(peer: str, trusted: set[str]) -> bool:
|
||||
if not trusted:
|
||||
return False
|
||||
|
||||
Reference in new issue
Block a user