Protect founder account and add attendance badge levels
This commit is contained in:
+28
-7
@@ -78,12 +78,14 @@ INITIAL_ADMIN_EMAIL = os.environ.get("INITIAL_ADMIN_EMAIL")
|
||||
|
||||
BADGE_DEFINITIONS = (
|
||||
("founder", "Gründer", "⚔️", None, "Von Anfang an dabei und Pingu Concerts mit aufgebaut", "special"),
|
||||
("admin", "Admin", "🛡️", None, "Verantwortung für Pingu Concerts", "special"),
|
||||
("admin", "Admin", "🏴☠️", None, "Verantwortung für Pingu Concerts", "special"),
|
||||
("beta_tester", "Beta Tester", "🧪", None, "In der Beta dabei", "beta"),
|
||||
("first_gig", "Erster Gig", "🎸", 1, "Dein erstes besuchtes Konzert", "attendance"),
|
||||
("regular", "Stammgast", "🤘", 5, "5 Konzerte besucht", "attendance"),
|
||||
("ten_gigs", "Zehnerrunde", "🔥", 10, "10 Konzerte besucht", "attendance"),
|
||||
("tour_veteran", "Tourveteran", "⚡", 25, "25 Konzerte besucht", "attendance"),
|
||||
("fifty_gigs", "Fünfzig Konzerte", "💀", 50, "50 Konzerte besucht", "attendance"),
|
||||
("hundred_gigs", "Hunderterclub", "👑", 100, "100 Konzerte besucht", "attendance"),
|
||||
)
|
||||
ATTENDANCE_BADGE_CODES = tuple(
|
||||
badge_code
|
||||
@@ -119,6 +121,11 @@ def ensure_schema():
|
||||
ADD COLUMN IF NOT EXISTS is_admin BOOLEAN NOT NULL DEFAULT FALSE
|
||||
""",
|
||||
"""
|
||||
UPDATE users
|
||||
SET is_admin = TRUE
|
||||
WHERE LOWER(username) = 'kai'
|
||||
""",
|
||||
"""
|
||||
ALTER TABLE users
|
||||
ADD COLUMN IF NOT EXISTS avatar_path TEXT
|
||||
""",
|
||||
@@ -1107,11 +1114,13 @@ def grant_earned_badges(user_id: int, attended_count: int, registered_at):
|
||||
(user_id,),
|
||||
)
|
||||
|
||||
# Konzert-Patches sind eine Level-Leiste: immer nur die höchste
|
||||
# erreichte Stufe anzeigen (ältere Stufen werden ersetzt).
|
||||
cursor.execute(
|
||||
"DELETE FROM user_badges WHERE user_id = %s AND badge_code = ANY(%s)",
|
||||
(user_id, list(ATTENDANCE_BADGE_CODES)),
|
||||
)
|
||||
if highest_attendance_badge:
|
||||
cursor.execute(
|
||||
"DELETE FROM user_badges WHERE user_id = %s AND badge_code = ANY(%s)",
|
||||
(user_id, list(ATTENDANCE_BADGE_CODES)),
|
||||
)
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO user_badges (user_id, badge_code)
|
||||
@@ -1685,6 +1694,13 @@ def update_user_role(
|
||||
|
||||
with get_db_connection() as connection:
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("SELECT username FROM users WHERE id = %s", (user_id,))
|
||||
target_user = cursor.fetchone()
|
||||
if target_user and (target_user[0] or "").casefold() == "kai" and role != "admin":
|
||||
return HTMLResponse(
|
||||
"<h1>Der Gründer Kai muss Admin bleiben.</h1>",
|
||||
status_code=400,
|
||||
)
|
||||
cursor.execute(
|
||||
"UPDATE users SET is_admin = %s WHERE id = %s",
|
||||
(role == "admin", user_id),
|
||||
@@ -1708,15 +1724,20 @@ def delete_user(request: Request, user_id: int):
|
||||
|
||||
with get_db_connection() as connection:
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("SELECT avatar_path FROM users WHERE id = %s", (user_id,))
|
||||
cursor.execute("SELECT username, avatar_path FROM users WHERE id = %s", (user_id,))
|
||||
target_user = cursor.fetchone()
|
||||
if target_user and (target_user[0] or "").casefold() == "kai":
|
||||
return HTMLResponse(
|
||||
"<h1>Der Gründer Kai kann nicht gelöscht werden.</h1>",
|
||||
status_code=400,
|
||||
)
|
||||
cursor.execute("SELECT path FROM concert_photos WHERE user_id = %s", (user_id,))
|
||||
photo_paths = [row[0] for row in cursor.fetchall()]
|
||||
cursor.execute("DELETE FROM users WHERE id = %s", (user_id,))
|
||||
connection.commit()
|
||||
|
||||
if target_user:
|
||||
remove_uploaded_file(target_user[0], AVATAR_DIR, "/static/uploads/avatars/")
|
||||
remove_uploaded_file(target_user[1], AVATAR_DIR, "/static/uploads/avatars/")
|
||||
for photo_path in photo_paths:
|
||||
remove_uploaded_file(photo_path, PHOTO_DIR, "/static/uploads/photos/")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user