feat: add email-based authentication
This commit is contained in:
+18
-8
@@ -2,14 +2,17 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from flask import Flask, abort, jsonify, request
|
||||
from flask import Flask, abort, jsonify, request, redirect, session
|
||||
from flask_login import current_user, logout_user
|
||||
|
||||
from .config import Config, DATA_DIR, ensure_dirs
|
||||
from .extensions import db, login_manager
|
||||
from .models import AppSetting, User
|
||||
from .migrations import upgrade_schema
|
||||
from .prediction import FEATURES, load_model
|
||||
from .security import csrf_token, validate_csrf_token
|
||||
from .time_utils import current_year_for_timezone, format_datetime_for_timezone
|
||||
from .time_utils import utc_now
|
||||
|
||||
|
||||
def create_app(config_object: type[Config] = Config, *, load_model_on_start: bool = True) -> Flask:
|
||||
@@ -34,7 +37,7 @@ def create_app(config_object: type[Config] = Config, *, load_model_on_start: boo
|
||||
app.register_blueprint(bp)
|
||||
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
upgrade_schema()
|
||||
init_admin_user(app)
|
||||
|
||||
if load_model_on_start:
|
||||
@@ -59,23 +62,26 @@ def configure_logging() -> None:
|
||||
def init_admin_user(app: Flask) -> None:
|
||||
admin_username = app.config["ADMIN_USERNAME"]
|
||||
admin_password = app.config["ADMIN_PASSWORD"]
|
||||
if admin_password:
|
||||
admin_email = app.config["ADMIN_EMAIL"]
|
||||
if admin_password and admin_email:
|
||||
admin = User.query.filter_by(username=admin_username).first()
|
||||
if admin is None:
|
||||
admin = User(username=admin_username, is_admin=True)
|
||||
admin = User(username=admin_username, email=admin_email, is_admin=True, is_active_account=True)
|
||||
admin.set_password(admin_password)
|
||||
db.session.add(admin)
|
||||
else:
|
||||
admin.is_admin = True
|
||||
if not admin.check_password(admin_password):
|
||||
admin.set_password(admin_password)
|
||||
if not admin.email:
|
||||
admin.email = admin_email
|
||||
admin.email_verified_at = utc_now()
|
||||
admin.is_active_account = True
|
||||
db.session.commit()
|
||||
elif not User.query.filter_by(is_admin=True).first():
|
||||
logging.warning("未设置 ADMIN_PASSWORD,跳过自动创建管理员账号。")
|
||||
logging.warning("未设置 ADMIN_PASSWORD 或 ADMIN_EMAIL,跳过自动创建管理员账号。")
|
||||
|
||||
default_admin = User.query.filter_by(username="admin", is_admin=True).first()
|
||||
if default_admin and default_admin.check_password("admin123"):
|
||||
logging.warning("检测到默认管理员密码 admin123,请立即通过 ADMIN_PASSWORD 更新。")
|
||||
logging.warning("检测到默认管理员密码 admin123,请通过账户安全页立即更新。")
|
||||
|
||||
|
||||
def register_app_hooks(app: Flask) -> None:
|
||||
@@ -114,6 +120,10 @@ def register_app_hooks(app: Flask) -> None:
|
||||
|
||||
@app.before_request
|
||||
def protect_csrf():
|
||||
if current_user.is_authenticated and session.get("auth_version") != current_user.auth_version:
|
||||
logout_user()
|
||||
session.clear()
|
||||
return redirect("/login")
|
||||
if request.method not in {"POST", "PUT", "PATCH", "DELETE"}:
|
||||
return None
|
||||
if validate_csrf_token():
|
||||
|
||||
Reference in New Issue
Block a user