Build 2602261717: master invite policy and self-service invite controls
This commit is contained in:
@@ -172,6 +172,7 @@ def init_db() -> None:
|
||||
last_login_at TEXT,
|
||||
is_blocked INTEGER NOT NULL DEFAULT 0,
|
||||
auto_search_enabled INTEGER NOT NULL DEFAULT 1,
|
||||
invite_management_enabled INTEGER NOT NULL DEFAULT 0,
|
||||
profile_id INTEGER,
|
||||
expires_at TEXT,
|
||||
invited_by_code TEXT,
|
||||
@@ -341,6 +342,10 @@ def init_db() -> None:
|
||||
conn.execute("ALTER TABLE users ADD COLUMN auto_search_enabled INTEGER NOT NULL DEFAULT 1")
|
||||
except sqlite3.OperationalError:
|
||||
pass
|
||||
try:
|
||||
conn.execute("ALTER TABLE users ADD COLUMN invite_management_enabled INTEGER NOT NULL DEFAULT 0")
|
||||
except sqlite3.OperationalError:
|
||||
pass
|
||||
try:
|
||||
conn.execute("ALTER TABLE users ADD COLUMN profile_id INTEGER")
|
||||
except sqlite3.OperationalError:
|
||||
@@ -498,6 +503,7 @@ def create_user(
|
||||
auth_provider: str = "local",
|
||||
jellyseerr_user_id: Optional[int] = None,
|
||||
auto_search_enabled: bool = True,
|
||||
invite_management_enabled: bool = False,
|
||||
profile_id: Optional[int] = None,
|
||||
expires_at: Optional[str] = None,
|
||||
invited_by_code: Optional[str] = None,
|
||||
@@ -515,6 +521,7 @@ def create_user(
|
||||
jellyseerr_user_id,
|
||||
created_at,
|
||||
auto_search_enabled,
|
||||
invite_management_enabled,
|
||||
profile_id,
|
||||
expires_at,
|
||||
invited_by_code,
|
||||
@@ -530,6 +537,7 @@ def create_user(
|
||||
jellyseerr_user_id,
|
||||
created_at,
|
||||
1 if auto_search_enabled else 0,
|
||||
1 if invite_management_enabled else 0,
|
||||
profile_id,
|
||||
expires_at,
|
||||
invited_by_code,
|
||||
@@ -545,6 +553,7 @@ def create_user_if_missing(
|
||||
auth_provider: str = "local",
|
||||
jellyseerr_user_id: Optional[int] = None,
|
||||
auto_search_enabled: bool = True,
|
||||
invite_management_enabled: bool = False,
|
||||
profile_id: Optional[int] = None,
|
||||
expires_at: Optional[str] = None,
|
||||
invited_by_code: Optional[str] = None,
|
||||
@@ -562,6 +571,7 @@ def create_user_if_missing(
|
||||
jellyseerr_user_id,
|
||||
created_at,
|
||||
auto_search_enabled,
|
||||
invite_management_enabled,
|
||||
profile_id,
|
||||
expires_at,
|
||||
invited_by_code,
|
||||
@@ -577,6 +587,7 @@ def create_user_if_missing(
|
||||
jellyseerr_user_id,
|
||||
created_at,
|
||||
1 if auto_search_enabled else 0,
|
||||
1 if invite_management_enabled else 0,
|
||||
profile_id,
|
||||
expires_at,
|
||||
invited_by_code,
|
||||
@@ -592,7 +603,7 @@ def get_user_by_username(username: str) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
SELECT id, username, password_hash, role, auth_provider, jellyseerr_user_id,
|
||||
created_at, last_login_at, is_blocked, auto_search_enabled,
|
||||
profile_id, expires_at, invited_by_code, invited_at,
|
||||
invite_management_enabled, profile_id, expires_at, invited_by_code, invited_at,
|
||||
jellyfin_password_hash, last_jellyfin_auth_at
|
||||
FROM users
|
||||
WHERE username = ? COLLATE NOCASE
|
||||
@@ -612,13 +623,14 @@ def get_user_by_username(username: str) -> Optional[Dict[str, Any]]:
|
||||
"last_login_at": row[7],
|
||||
"is_blocked": bool(row[8]),
|
||||
"auto_search_enabled": bool(row[9]),
|
||||
"profile_id": row[10],
|
||||
"expires_at": row[11],
|
||||
"invited_by_code": row[12],
|
||||
"invited_at": row[13],
|
||||
"is_expired": _is_datetime_in_past(row[11]),
|
||||
"jellyfin_password_hash": row[14],
|
||||
"last_jellyfin_auth_at": row[15],
|
||||
"invite_management_enabled": bool(row[10]),
|
||||
"profile_id": row[11],
|
||||
"expires_at": row[12],
|
||||
"invited_by_code": row[13],
|
||||
"invited_at": row[14],
|
||||
"is_expired": _is_datetime_in_past(row[12]),
|
||||
"jellyfin_password_hash": row[15],
|
||||
"last_jellyfin_auth_at": row[16],
|
||||
}
|
||||
|
||||
|
||||
@@ -628,7 +640,7 @@ def get_user_by_id(user_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
SELECT id, username, password_hash, role, auth_provider, jellyseerr_user_id,
|
||||
created_at, last_login_at, is_blocked, auto_search_enabled,
|
||||
profile_id, expires_at, invited_by_code, invited_at,
|
||||
invite_management_enabled, profile_id, expires_at, invited_by_code, invited_at,
|
||||
jellyfin_password_hash, last_jellyfin_auth_at
|
||||
FROM users
|
||||
WHERE id = ?
|
||||
@@ -648,13 +660,14 @@ def get_user_by_id(user_id: int) -> Optional[Dict[str, Any]]:
|
||||
"last_login_at": row[7],
|
||||
"is_blocked": bool(row[8]),
|
||||
"auto_search_enabled": bool(row[9]),
|
||||
"profile_id": row[10],
|
||||
"expires_at": row[11],
|
||||
"invited_by_code": row[12],
|
||||
"invited_at": row[13],
|
||||
"is_expired": _is_datetime_in_past(row[11]),
|
||||
"jellyfin_password_hash": row[14],
|
||||
"last_jellyfin_auth_at": row[15],
|
||||
"invite_management_enabled": bool(row[10]),
|
||||
"profile_id": row[11],
|
||||
"expires_at": row[12],
|
||||
"invited_by_code": row[13],
|
||||
"invited_at": row[14],
|
||||
"is_expired": _is_datetime_in_past(row[12]),
|
||||
"jellyfin_password_hash": row[15],
|
||||
"last_jellyfin_auth_at": row[16],
|
||||
}
|
||||
|
||||
def get_all_users() -> list[Dict[str, Any]]:
|
||||
@@ -662,8 +675,8 @@ def get_all_users() -> list[Dict[str, Any]]:
|
||||
rows = conn.execute(
|
||||
"""
|
||||
SELECT id, username, role, auth_provider, jellyseerr_user_id, created_at,
|
||||
last_login_at, is_blocked, auto_search_enabled, profile_id, expires_at,
|
||||
invited_by_code, invited_at
|
||||
last_login_at, is_blocked, auto_search_enabled, invite_management_enabled,
|
||||
profile_id, expires_at, invited_by_code, invited_at
|
||||
FROM users
|
||||
ORDER BY username COLLATE NOCASE
|
||||
"""
|
||||
@@ -681,11 +694,12 @@ def get_all_users() -> list[Dict[str, Any]]:
|
||||
"last_login_at": row[6],
|
||||
"is_blocked": bool(row[7]),
|
||||
"auto_search_enabled": bool(row[8]),
|
||||
"profile_id": row[9],
|
||||
"expires_at": row[10],
|
||||
"invited_by_code": row[11],
|
||||
"invited_at": row[12],
|
||||
"is_expired": _is_datetime_in_past(row[10]),
|
||||
"invite_management_enabled": bool(row[9]),
|
||||
"profile_id": row[10],
|
||||
"expires_at": row[11],
|
||||
"invited_by_code": row[12],
|
||||
"invited_at": row[13],
|
||||
"is_expired": _is_datetime_in_past(row[11]),
|
||||
}
|
||||
)
|
||||
return results
|
||||
@@ -788,6 +802,16 @@ def set_user_auto_search_enabled(username: str, enabled: bool) -> None:
|
||||
)
|
||||
|
||||
|
||||
def set_user_invite_management_enabled(username: str, enabled: bool) -> None:
|
||||
with _connect() as conn:
|
||||
conn.execute(
|
||||
"""
|
||||
UPDATE users SET invite_management_enabled = ? WHERE username = ? COLLATE NOCASE
|
||||
""",
|
||||
(1 if enabled else 0, username),
|
||||
)
|
||||
|
||||
|
||||
def set_auto_search_enabled_for_non_admin_users(enabled: bool) -> int:
|
||||
with _connect() as conn:
|
||||
cursor = conn.execute(
|
||||
@@ -799,6 +823,17 @@ def set_auto_search_enabled_for_non_admin_users(enabled: bool) -> int:
|
||||
return cursor.rowcount
|
||||
|
||||
|
||||
def set_invite_management_enabled_for_non_admin_users(enabled: bool) -> int:
|
||||
with _connect() as conn:
|
||||
cursor = conn.execute(
|
||||
"""
|
||||
UPDATE users SET invite_management_enabled = ? WHERE role != 'admin'
|
||||
""",
|
||||
(1 if enabled else 0,),
|
||||
)
|
||||
return cursor.rowcount
|
||||
|
||||
|
||||
def set_user_profile_id(username: str, profile_id: Optional[int]) -> None:
|
||||
with _connect() as conn:
|
||||
conn.execute(
|
||||
|
||||
Reference in New Issue
Block a user