85 lines
2.3 KiB
Python
85 lines
2.3 KiB
Python
from functools import wraps
|
|
|
|
from flask import jsonify, session
|
|
from werkzeug.security import check_password_hash, generate_password_hash
|
|
|
|
from .db import get_db, now_iso
|
|
|
|
|
|
def get_current_user():
|
|
user_id = session.get("user_id")
|
|
if not user_id:
|
|
return None
|
|
conn = get_db()
|
|
try:
|
|
row = conn.execute("SELECT * FROM users WHERE id = ?", (user_id,)).fetchone()
|
|
if row is None or not row["is_active"]:
|
|
session.clear()
|
|
return None
|
|
return dict(row)
|
|
finally:
|
|
conn.close()
|
|
|
|
|
|
def login_required(view):
|
|
@wraps(view)
|
|
def wrapped(*args, **kwargs):
|
|
user = get_current_user()
|
|
if user is None:
|
|
return jsonify({"error": "请先登录"}), 401
|
|
return view(user=user, *args, **kwargs)
|
|
|
|
return wrapped
|
|
|
|
|
|
def admin_required(view):
|
|
@wraps(view)
|
|
def wrapped(*args, **kwargs):
|
|
user = get_current_user()
|
|
if user is None:
|
|
return jsonify({"error": "请先登录"}), 401
|
|
if not user["is_admin"]:
|
|
return jsonify({"error": "无管理员权限"}), 403
|
|
return view(user=user, *args, **kwargs)
|
|
|
|
return wrapped
|
|
|
|
|
|
def create_user(username, password, display_name, is_admin=False, is_active=True):
|
|
conn = get_db()
|
|
try:
|
|
conn.execute(
|
|
"""
|
|
INSERT INTO users (username, password_hash, display_name, is_admin, is_active, created_at)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
""",
|
|
(
|
|
username,
|
|
generate_password_hash(password),
|
|
display_name,
|
|
1 if is_admin else 0,
|
|
1 if is_active else 0,
|
|
now_iso(),
|
|
),
|
|
)
|
|
conn.commit()
|
|
return conn.execute(
|
|
"SELECT id, username, display_name, is_admin, is_active, created_at FROM users WHERE username = ?",
|
|
(username,),
|
|
).fetchone()
|
|
finally:
|
|
conn.close()
|
|
|
|
|
|
def authenticate(username, password):
|
|
conn = get_db()
|
|
try:
|
|
row = conn.execute("SELECT * FROM users WHERE username = ?", (username,)).fetchone()
|
|
if row is None or not check_password_hash(row["password_hash"], password):
|
|
return None
|
|
if not row["is_active"]:
|
|
return {"disabled": True}
|
|
return dict(row)
|
|
finally:
|
|
conn.close()
|