75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
# auth.py - Authentication and User Management
|
|
|
|
import functools
|
|
from flask import session, redirect, url_for, request, jsonify
|
|
from db import get_db_connection
|
|
|
|
|
|
def init_users_table():
|
|
"""Create users table and default admin user."""
|
|
with get_db_connection() as conn:
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute('''
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT NOT NULL UNIQUE,
|
|
password TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'user',
|
|
is_active INTEGER NOT NULL DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
last_login TIMESTAMP
|
|
)
|
|
''')
|
|
|
|
# Create default admin if no users exist
|
|
cursor.execute('SELECT COUNT(*) as count FROM users')
|
|
if cursor.fetchone()['count'] == 0:
|
|
cursor.execute('''
|
|
INSERT INTO users (username, password, role, is_active)
|
|
VALUES (?, ?, ?, ?)
|
|
''', ('admin', 'admin123', 'admin', 1))
|
|
print("✅ Default admin user created (username: admin, password: admin123)")
|
|
|
|
conn.commit()
|
|
|
|
|
|
def login_required(f):
|
|
"""Decorator to require login for routes."""
|
|
@functools.wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
if 'user_id' not in session:
|
|
# Check if it's an API request
|
|
if request.path.startswith('/api/'):
|
|
return jsonify({'error': 'Authentication required'}), 401
|
|
return redirect(url_for('auth.login_page'))
|
|
return f(*args, **kwargs)
|
|
return decorated_function
|
|
|
|
|
|
def admin_required(f):
|
|
"""Decorator to require admin role for routes."""
|
|
@functools.wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
if 'user_id' not in session:
|
|
if request.path.startswith('/api/'):
|
|
return jsonify({'error': 'Authentication required'}), 401
|
|
return redirect(url_for('auth.login_page'))
|
|
if session.get('user_role') != 'admin':
|
|
if request.path.startswith('/api/'):
|
|
return jsonify({'error': 'Admin access required'}), 403
|
|
return redirect(url_for('main.index'))
|
|
return f(*args, **kwargs)
|
|
return decorated_function
|
|
|
|
|
|
def get_current_user():
|
|
"""Get current logged-in user info from session."""
|
|
if 'user_id' not in session:
|
|
return None
|
|
return {
|
|
'id': session.get('user_id'),
|
|
'username': session.get('username'),
|
|
'role': session.get('user_role')
|
|
}
|