import sqlite3 import hashlib import db_logger DB_FILE = db_logger.DB_FILE # Default users to seed (User bawaan) DEFAULT_USERS = { "free": {"password": "free", "role": "free"}, "premium": {"password": "premium", "role": "premium"}, "dev": {"password": "dev", "role": "developer"} } def hash_password(password): """Mengenkripsi password menggunakan SHA-256.""" return hashlib.sha256(password.encode()).hexdigest() def seed_users(): """ Memasukkan user default ke database jika belum ada. Password akan otomatis di-hash. """ conn = sqlite3.connect(DB_FILE) c = conn.cursor() for username, data in DEFAULT_USERS.items(): try: hashed_pw = hash_password(data['password']) # INSERT OR IGNORE akan melewati jika username sudah ada (karena constraint UNIQUE) c.execute("INSERT OR IGNORE INTO users (username, password, role) VALUES (?, ?, ?)", (username, hashed_pw, data['role'])) except Exception as e: print(f"Error seeding user {username}: {e}") conn.commit() conn.close() # Jalankan seeding saat modul diimpor seed_users() def authenticate(username, password): """ Memvalidasi kredensial login user. Returns: (is_valid, role, message) """ username = username.strip() try: conn = sqlite3.connect(DB_FILE) c = conn.cursor() c.execute("SELECT password, role FROM users WHERE username = ?", (username,)) result = c.fetchone() conn.close() if result: stored_password_hash, role = result input_password_hash = hash_password(password) # Cek Kompatibilitas: Jika password di DB bukan hash (misal sisa versi lama) if len(stored_password_hash) != 64 and stored_password_hash == password: return True, role, f"✅ Welcome, {username} ({role})" # Cek Hash if stored_password_hash == input_password_hash: return True, role, f"✅ Welcome, {username} ({role})" else: return False, None, "❌ Invalid password" else: return False, None, "❌ User not found" except Exception as e: return False, None, f"❌ System Error: {e}" def add_user(username, password, role): """Menambahkan user baru ke database dengan password terenkripsi.""" username = username.strip() if not username or not password or not role: return False, "All fields are required." try: conn = sqlite3.connect(DB_FILE) c = conn.cursor() hashed_pw = hash_password(password) c.execute("INSERT INTO users (username, password, role) VALUES (?, ?, ?)", (username, hashed_pw, role)) conn.commit() conn.close() return True, f"User '{username}' created successfully." except sqlite3.IntegrityError: return False, f"User '{username}' already exists." except Exception as e: return False, f"Error: {e}" def list_users(): """Menampilkan daftar semua user (tanpa password) dalam bentuk DataFrame.""" try: conn = sqlite3.connect(DB_FILE) import pandas as pd df = pd.read_sql_query("SELECT id, username, role FROM users", conn) conn.close() return df except Exception as e: print(f"Error listing users: {e}") return None def delete_user(username): """Menghapus user berdasarkan username.""" try: conn = sqlite3.connect(DB_FILE) c = conn.cursor() c.execute("DELETE FROM users WHERE username = ?", (username,)) conn.commit() rows = c.rowcount conn.close() if rows > 0: return True, f"User '{username}' deleted." else: return False, f"User '{username}' not found." except Exception as e: return False, f"Error: {e}"