changes in auth logic
This commit is contained in:
@@ -65,6 +65,22 @@ def uses_external_provider() -> bool:
|
||||
return enabled() and provider() in {"proxy", "tinyauth"}
|
||||
|
||||
|
||||
def external_auth_summary() -> dict[str, Any]:
|
||||
# Note: Exposes safe auth-mode facts for the Users panel without leaking secrets.
|
||||
return {
|
||||
"enabled": enabled(),
|
||||
"provider": provider(),
|
||||
"external": uses_external_provider(),
|
||||
"auto_create": bool(AUTH_PROXY_AUTO_CREATE) if uses_external_provider() else False,
|
||||
"auto_create_role": AUTH_PROXY_AUTO_CREATE_ROLE,
|
||||
"auto_create_permission": AUTH_PROXY_AUTO_CREATE_PERMISSION,
|
||||
"bypass_enabled": bool(AUTH_BYPASS_HOSTS),
|
||||
"bypass_hosts": sorted(AUTH_BYPASS_HOSTS),
|
||||
"bypass_user": AUTH_BYPASS_USER,
|
||||
"password_editable": not uses_external_provider(),
|
||||
}
|
||||
|
||||
|
||||
def password_hash(password: str) -> str:
|
||||
return generate_password_hash(password or "")
|
||||
|
||||
@@ -465,6 +481,7 @@ def save_user(data: dict[str, Any], user_id: int | None = None) -> dict[str, Any
|
||||
username = str(data.get("username") or "").strip()
|
||||
role = "admin" if data.get("role") == "admin" else "user"
|
||||
is_active = 1 if data.get("is_active", True) else 0
|
||||
password_editable = not uses_external_provider()
|
||||
if not username:
|
||||
raise ValueError("Username is required")
|
||||
with connect() as conn:
|
||||
@@ -477,12 +494,15 @@ def save_user(data: dict[str, Any], user_id: int | None = None) -> dict[str, Any
|
||||
(username, str(data.get("email") or "").strip() or None, str(data.get("display_name") or "").strip() or None, role, is_active, now, user_id),
|
||||
)
|
||||
else:
|
||||
initial_password_hash = password_hash(str(data.get("password") or username)) if password_editable else None
|
||||
# Note: TinyAuth/proxy users are passwordless in pyTorrent; credentials stay with the auth provider.
|
||||
cur = conn.execute(
|
||||
"INSERT INTO users(username,password_hash,email,display_name,role,is_active,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?)",
|
||||
(username, password_hash(str(data.get("password") or username)), str(data.get("email") or "").strip() or None, str(data.get("display_name") or "").strip() or None, role, is_active, now, now),
|
||||
(username, initial_password_hash, str(data.get("email") or "").strip() or None, str(data.get("display_name") or "").strip() or None, role, is_active, now, now),
|
||||
)
|
||||
user_id = int(cur.lastrowid)
|
||||
if data.get("password"):
|
||||
if data.get("password") and password_editable:
|
||||
# Note: Password changes are intentionally disabled for external auth providers.
|
||||
conn.execute("UPDATE users SET password_hash=?, updated_at=? WHERE id=?", (password_hash(str(data.get("password"))), now, user_id))
|
||||
if role != "admin":
|
||||
conn.execute("DELETE FROM user_profile_permissions WHERE user_id=?", (user_id,))
|
||||
@@ -558,7 +578,7 @@ def list_api_tokens(user_id: int) -> list[dict[str, Any]]:
|
||||
abort(403)
|
||||
with connect() as conn:
|
||||
rows = conn.execute(
|
||||
"SELECT id,user_id,name,token_prefix,last_used_at,created_at,updated_at,revoked_at FROM api_tokens WHERE user_id=? ORDER BY created_at DESC",
|
||||
"SELECT id,user_id,name,token_prefix,last_used_at,created_at,updated_at,revoked_at FROM api_tokens WHERE user_id=? AND revoked_at IS NULL ORDER BY created_at DESC",
|
||||
(uid,),
|
||||
).fetchall()
|
||||
return [_token_response(row) for row in rows]
|
||||
@@ -602,10 +622,13 @@ def revoke_api_token(user_id: int, token_id: int) -> None:
|
||||
abort(403)
|
||||
now = utcnow()
|
||||
with connect() as conn:
|
||||
conn.execute(
|
||||
"UPDATE api_tokens SET revoked_at=COALESCE(revoked_at, ?), updated_at=? WHERE id=? AND user_id=?",
|
||||
# Note: Report missing/already revoked tokens instead of showing a false success in the UI.
|
||||
cur = conn.execute(
|
||||
"UPDATE api_tokens SET revoked_at=COALESCE(revoked_at, ?), updated_at=? WHERE id=? AND user_id=? AND revoked_at IS NULL",
|
||||
(now, now, tid, uid),
|
||||
)
|
||||
if cur.rowcount <= 0:
|
||||
raise ValueError("Active API token not found")
|
||||
|
||||
|
||||
def authenticate_api_token(token: str) -> dict[str, Any] | None:
|
||||
|
||||
Reference in New Issue
Block a user