File size: 3,995 Bytes
dde3265
 
 
3852cc4
dde3265
 
656590a
dde3265
3852cc4
 
 
 
 
dde3265
656590a
dde3265
 
 
656590a
 
 
 
dde3265
 
 
 
 
 
656590a
dde3265
 
 
 
 
 
 
 
656590a
dde3265
 
3852cc4
 
656590a
3852cc4
 
 
 
dde3265
 
 
 
 
 
 
 
 
 
 
656590a
dde3265
 
 
656590a
dde3265
 
 
 
 
 
 
 
 
 
 
656590a
dde3265
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656590a
dde3265
 
 
 
 
 
 
 
 
 
 
656590a
dde3265
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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}"