sprava uzivatelu

This commit is contained in:
JiriUhlir
2026-06-10 07:56:02 +02:00
parent 7dffff17c7
commit 9cec3d001f
7 changed files with 391 additions and 13 deletions
+21
View File
@@ -1,8 +1,29 @@
from app.db.database import get_connection
def _table_columns(con, table_name: str) -> set[str]:
rows = con.execute(f"PRAGMA table_info({table_name})").fetchall()
return {row["name"] for row in rows}
def ensure_user_columns(con) -> None:
columns = _table_columns(con, "users")
if not columns:
return
if "is_enabled" not in columns:
default_expression = "COALESCE(is_active, 1)" if "is_active" in columns else "1"
con.execute("ALTER TABLE users ADD COLUMN is_enabled INTEGER NOT NULL DEFAULT 1")
con.execute(f"UPDATE users SET is_enabled = {default_expression} WHERE is_enabled IS NULL OR is_enabled = 1")
if "updated_at" not in columns:
con.execute("ALTER TABLE users ADD COLUMN updated_at TEXT")
con.execute("UPDATE users SET updated_at = COALESCE(created_at, CURRENT_TIMESTAMP) WHERE updated_at IS NULL")
def run_migrations():
con = get_connection()
ensure_user_columns(con)
con.execute(
"""
+125
View File
@@ -0,0 +1,125 @@
from typing import Any
from app.db.database import get_connection
from app.db.migrations import run_migrations
ROLES = ("admin", "developer", "viewer")
def _table_columns(con, table_name: str) -> set[str]:
rows = con.execute(f"PRAGMA table_info({table_name})").fetchall()
return {row["name"] for row in rows}
def list_users() -> list[dict[str, Any]]:
run_migrations()
con = get_connection()
columns = _table_columns(con, "users")
last_login_select = "last_login_at" if "last_login_at" in columns else "NULL AS last_login_at"
rows = con.execute(
f"""
SELECT
id,
username,
display_name,
email,
role,
COALESCE(is_enabled, 1) AS is_enabled,
created_at,
updated_at,
{last_login_select}
FROM users
ORDER BY id
"""
).fetchall()
con.close()
return [dict(row) for row in rows]
def get_user(user_id: int) -> dict[str, Any] | None:
run_migrations()
con = get_connection()
columns = _table_columns(con, "users")
last_login_select = "last_login_at" if "last_login_at" in columns else "NULL AS last_login_at"
row = con.execute(
f"""
SELECT
id,
username,
display_name,
email,
role,
COALESCE(is_enabled, 1) AS is_enabled,
created_at,
updated_at,
{last_login_select}
FROM users
WHERE id = ?
""",
(user_id,),
).fetchone()
con.close()
return dict(row) if row else None
def count_enabled_admins(excluding_user_id: int | None = None) -> int:
run_migrations()
con = get_connection()
params: list[Any] = []
exclusion = ""
if excluding_user_id is not None:
exclusion = "AND id != ?"
params.append(excluding_user_id)
row = con.execute(
f"""
SELECT COUNT(*) AS count
FROM users
WHERE LOWER(COALESCE(role, '')) = 'admin'
AND COALESCE(is_enabled, 1) = 1
{exclusion}
""",
params,
).fetchone()
con.close()
return int(row["count"] or 0)
def update_user_role(user_id: int, role: str) -> None:
if role not in ROLES:
raise ValueError("Invalid user role")
run_migrations()
con = get_connection()
con.execute(
"""
UPDATE users
SET role = ?,
updated_at = CURRENT_TIMESTAMP
WHERE id = ?
""",
(role, user_id),
)
con.commit()
con.close()
def set_user_enabled(user_id: int, enabled: bool) -> None:
run_migrations()
con = get_connection()
con.execute(
"""
UPDATE users
SET is_enabled = ?,
updated_at = CURRENT_TIMESTAMP
WHERE id = ?
""",
(1 if enabled else 0, user_id),
)
con.commit()
con.close()