import gradio as gr from utils.logger import Logger from utils.database import get_db from data.repository.annotator_repo import AnnotatorRepo from data.repository.annotator_workload_repo import AnnotatorWorkloadRepo from utils.security import verify_password log = Logger() class AuthService: """ Authenticate users against DB and drive Gradio UI states. """ # ───────────── LOGIN ───────────── # @staticmethod def login(username: str, password: str, session: dict): """ خروجی‌ها (به همین ترتیب در LoginPage ثبت شده است): 0) message (Markdown داخل فرم لاگین) 1) login_container (پنهان/نمایان شدن فرم لاگین) 2) dashboard_container (نمایش داشبورد) 3) header_welcome (پیام خوش‌آمد در هدر) 4) items_state (لیست رکوردها) 5) idx_state (اندیس فعلی) 6-11) شش فیلد نمایشی (id, filename, sentence, ann_sentence, ann_at, validated) """ # ---------- اعتبارسنجی ---------- # log.info(f"Login attempt: username={username}") with get_db() as db: repo = AnnotatorRepo(db) annotator = repo.get_annotator_by_name(username) # ⬇️ توابع کمکی برای تولید خروجی خالی (درصورت خطا) def empty_dashboard_outputs(): return ( [], # items_state 0, # idx_state "", "", "", "", "", False, # شش فیلد ) # --- کاربر موجود نیست / غیر فعال if annotator is None or not annotator.is_active: log.warning("Failed login (not found / inactive)") return ( "❌ Wrong username or password!", gr.update(), gr.update(visible=False), gr.update(value=""), *empty_dashboard_outputs(), ) # --- رمز عبور اشتباه if not verify_password(password, annotator.password): log.warning("Failed login (bad password)") return ( "❌ Wrong username or password!", gr.update(), gr.update(visible=False), gr.update(value=""), *empty_dashboard_outputs(), ) # ---------- ورود موفق ---------- # session["user_id"] = annotator.id session["username"] = annotator.name # بارگذاری داده‌های داشبورد workload_repo = AnnotatorWorkloadRepo(db) raw_items = workload_repo.get_tts_data_with_annotations(username) dashboard_items = [ { "id": row["tts_data"].id, "filename": row["tts_data"].filename, "sentence": row["tts_data"].sentence, "annotated_sentence": ( row["annotation"].annotated_sentence if row["annotation"] else "" ), "annotated_at": ( row["annotation"].annotated_at.isoformat() if row["annotation"] and row["annotation"].annotated_at else "" ), "validated": ( row["annotation"].validated if row["annotation"] is not None else False ), } for row in raw_items ] session["dashboard_items"] = dashboard_items # مقداردهی فیلدهای رکورد اول (یا مقادیر تهی) if dashboard_items: first = dashboard_items[0] first_vals = ( first["id"], first["filename"], first["sentence"], first["annotated_sentence"], first["annotated_at"], first["validated"], ) else: first_vals = ("", "", "", "", "", False) log.info(f"User '{username}' logged in successfully.") # ---------- خروجی نهایی برای Gradio ---------- # return ( None, # 0: پیام خطا وجود ندارد gr.update(visible=False), # 1: فرم لاگین را مخفی کن gr.update(visible=True), # 2: داشبورد را نشان بده gr.update(value=f"👋 Welcome, {annotator.name}!"), # 3 dashboard_items, # 4: items_state 0, # 5: idx_state *first_vals, # 6-11: شش فیلد نخست ) # ───────────── LOGOUT ───────────── # @staticmethod def logout(session: dict): username = session.get("username", "unknown") session.clear() log.info(f"User '{username}' logged out.") return ( gr.update(visible=True), # لاگین فرم را دوباره نشان بده gr.update(visible=False), # داشبورد را پنهان کن gr.update(value=""), # پیام‌ها را پاک کن gr.update(value=""), # متن خوش‌آمد را پاک کن [], 0, "", "", "", "", "", False, # خروجی‌های داشبورد را ریست )