Harden auth flows and add backend quality gate
This commit is contained in:
@@ -451,6 +451,10 @@ def _normalize_email(value: object) -> Optional[str]:
|
||||
return str(value).strip()
|
||||
|
||||
|
||||
def normalize_delivery_email(value: object) -> Optional[str]:
|
||||
return _normalize_email(value)
|
||||
|
||||
|
||||
def _normalize_display_text(value: object, fallback: str = "") -> str:
|
||||
if value is None:
|
||||
return fallback
|
||||
@@ -880,6 +884,9 @@ def render_invite_email_template(
|
||||
def resolve_user_delivery_email(user: Optional[Dict[str, Any]], invite: Optional[Dict[str, Any]] = None) -> Optional[str]:
|
||||
if not isinstance(user, dict):
|
||||
return _normalize_email(invite.get("recipient_email") if isinstance(invite, dict) else None)
|
||||
stored_email = _normalize_email(user.get("email"))
|
||||
if stored_email:
|
||||
return stored_email
|
||||
username_email = _normalize_email(user.get("username"))
|
||||
if username_email:
|
||||
return username_email
|
||||
|
||||
@@ -6,12 +6,15 @@ from ..clients.jellyfin import JellyfinClient
|
||||
from ..db import (
|
||||
create_user_if_missing,
|
||||
get_user_by_username,
|
||||
set_user_email,
|
||||
set_user_auth_provider,
|
||||
set_user_jellyseerr_id,
|
||||
)
|
||||
from ..runtime import get_runtime_settings
|
||||
from .user_cache import (
|
||||
build_jellyseerr_candidate_map,
|
||||
extract_jellyseerr_user_email,
|
||||
find_matching_jellyseerr_user,
|
||||
get_cached_jellyseerr_users,
|
||||
match_jellyseerr_user_id,
|
||||
save_jellyfin_users_cache,
|
||||
@@ -41,10 +44,13 @@ async def sync_jellyfin_users() -> int:
|
||||
if not name:
|
||||
continue
|
||||
matched_id = match_jellyseerr_user_id(name, candidate_map) if candidate_map else None
|
||||
matched_seerr_user = find_matching_jellyseerr_user(name, jellyseerr_users or [])
|
||||
matched_email = extract_jellyseerr_user_email(matched_seerr_user)
|
||||
created = create_user_if_missing(
|
||||
name,
|
||||
"jellyfin-user",
|
||||
role="user",
|
||||
email=matched_email,
|
||||
auth_provider="jellyfin",
|
||||
jellyseerr_user_id=matched_id,
|
||||
)
|
||||
@@ -60,6 +66,8 @@ async def sync_jellyfin_users() -> int:
|
||||
set_user_auth_provider(name, "jellyfin")
|
||||
if matched_id is not None:
|
||||
set_user_jellyseerr_id(name, matched_id)
|
||||
if matched_email:
|
||||
set_user_email(name, matched_email)
|
||||
return imported
|
||||
|
||||
|
||||
|
||||
@@ -112,6 +112,9 @@ async def _fetch_all_seerr_users() -> list[dict]:
|
||||
|
||||
def _resolve_seerr_user_email(seerr_user: Optional[dict], local_user: Optional[dict]) -> Optional[str]:
|
||||
if isinstance(local_user, dict):
|
||||
stored_email = str(local_user.get("email") or "").strip()
|
||||
if "@" in stored_email:
|
||||
return stored_email
|
||||
username = str(local_user.get("username") or "").strip()
|
||||
if "@" in username:
|
||||
return username
|
||||
|
||||
@@ -89,6 +89,33 @@ def build_jellyseerr_candidate_map(users: List[Dict[str, Any]]) -> Dict[str, int
|
||||
return candidate_to_id
|
||||
|
||||
|
||||
def find_matching_jellyseerr_user(
|
||||
identifier: str, users: List[Dict[str, Any]]
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
target_handles = set(_normalized_handles(identifier))
|
||||
if not target_handles:
|
||||
return None
|
||||
for user in users:
|
||||
if not isinstance(user, dict):
|
||||
continue
|
||||
for key in ("username", "email", "displayName", "name"):
|
||||
if target_handles.intersection(_normalized_handles(user.get(key))):
|
||||
return user
|
||||
return None
|
||||
|
||||
|
||||
def extract_jellyseerr_user_email(user: Optional[Dict[str, Any]]) -> Optional[str]:
|
||||
if not isinstance(user, dict):
|
||||
return None
|
||||
value = user.get("email")
|
||||
if not isinstance(value, str):
|
||||
return None
|
||||
candidate = value.strip()
|
||||
if not candidate or "@" not in candidate:
|
||||
return None
|
||||
return candidate
|
||||
|
||||
|
||||
def match_jellyseerr_user_id(
|
||||
username: str, candidate_map: Dict[str, int]
|
||||
) -> Optional[int]:
|
||||
|
||||
Reference in New Issue
Block a user