Add user feature permissions and unified account management
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
from ..feature_access import permissions, update_permissions
|
||||
from typing import Any, Dict, List, Optional
|
||||
from datetime import datetime, timedelta, timezone
|
||||
import asyncio
|
||||
@@ -1199,7 +1200,7 @@ async def list_users_summary() -> Dict[str, Any]:
|
||||
username = user.get("username") or ""
|
||||
username_norm = _normalize_username(username) if username else ""
|
||||
stats = get_user_request_stats(username_norm, user.get("jellyseerr_user_id"))
|
||||
results.append({**user, "stats": stats})
|
||||
results.append({**user, "features": permissions(user), "stats": stats})
|
||||
return {"users": results}
|
||||
|
||||
@router.get("/users/{username}")
|
||||
@@ -1209,7 +1210,7 @@ async def get_user_summary(username: str) -> Dict[str, Any]:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
username_norm = _normalize_username(user.get("username") or "")
|
||||
stats = get_user_request_stats(username_norm, user.get("jellyseerr_user_id"))
|
||||
return {"user": user, "stats": stats, "lineage": _user_inviter_details(user)}
|
||||
return {"user": {**user, "features": permissions(user)}, "stats": stats, "lineage": _user_inviter_details(user)}
|
||||
|
||||
|
||||
@router.get("/users/id/{user_id}")
|
||||
@@ -1219,7 +1220,7 @@ async def get_user_summary_by_id(user_id: int) -> Dict[str, Any]:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
username_norm = _normalize_username(user.get("username") or "")
|
||||
stats = get_user_request_stats(username_norm, user.get("jellyseerr_user_id"))
|
||||
return {"user": user, "stats": stats, "lineage": _user_inviter_details(user)}
|
||||
return {"user": {**user, "features": permissions(user)}, "stats": stats, "lineage": _user_inviter_details(user)}
|
||||
|
||||
|
||||
@router.post("/users/{username}/block")
|
||||
@@ -2122,3 +2123,26 @@ async def remove_invite(invite_id: int) -> Dict[str, Any]:
|
||||
raise HTTPException(status_code=404, detail="Invite not found")
|
||||
logger.warning("Admin deleted invite: invite_id=%s", invite_id)
|
||||
return {"status": "ok", "deleted": True, "invite_id": invite_id}
|
||||
|
||||
|
||||
@router.put("/users/features/bulk")
|
||||
async def bulk_feature_permissions(payload: Dict[str, Any]) -> dict:
|
||||
try:
|
||||
updated = update_permissions(payload)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
return {"updated": updated, "scope": "non-admin-users"}
|
||||
|
||||
|
||||
@router.put("/users/{username}/features")
|
||||
async def user_feature_permissions(username: str, payload: Dict[str, Any]) -> dict:
|
||||
user = get_user_by_username(username)
|
||||
if not user:
|
||||
raise HTTPException(status_code=404, detail="User not found")
|
||||
if user.get("role") == "admin":
|
||||
raise HTTPException(status_code=400, detail="Administrators always have all features")
|
||||
try:
|
||||
update_permissions(payload, username)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
return {"features": permissions(get_user_by_username(username))}
|
||||
|
||||
Reference in New Issue
Block a user