diff --git a/outlook_web/app.py b/outlook_web/app.py index 2286554..c820980 100644 --- a/outlook_web/app.py +++ b/outlook_web/app.py @@ -97,7 +97,7 @@ def create_app(*, autostart_scheduler: Optional[bool] = None): app.register_blueprint(tags.create_blueprint()) app.register_blueprint(accounts.create_blueprint()) app.register_blueprint(emails.create_blueprint()) - app.register_blueprint(temp_emails.create_blueprint()) + app.register_blueprint(temp_emails.create_blueprint(csrf_exempt=csrf_exempt)) app.register_blueprint(oauth.create_blueprint()) app.register_blueprint(settings.create_blueprint()) app.register_blueprint(scheduler.create_blueprint()) diff --git a/outlook_web/routes/temp_emails.py b/outlook_web/routes/temp_emails.py index 0436de2..b8fed9a 100644 --- a/outlook_web/routes/temp_emails.py +++ b/outlook_web/routes/temp_emails.py @@ -5,24 +5,26 @@ from flask import Blueprint from outlook_web.controllers import temp_emails as temp_emails_controller -def create_blueprint() -> Blueprint: - """创建 temp_emails Blueprint""" +def create_blueprint(csrf_exempt=None) -> Blueprint: + """创建 temp_emails Blueprint(支持 CSRF 豁免)""" bp = Blueprint("temp_emails", __name__) - bp.add_url_rule("/api/temp-emails", view_func=temp_emails_controller.api_get_temp_emails, methods=["GET"]) - bp.add_url_rule("/api/temp-emails/generate", view_func=temp_emails_controller.api_generate_temp_email, methods=["POST"]) - bp.add_url_rule("/api/temp-emails/", view_func=temp_emails_controller.api_delete_temp_email, methods=["DELETE"]) - bp.add_url_rule("/api/temp-emails//messages", view_func=temp_emails_controller.api_get_temp_email_messages, methods=["GET"]) - bp.add_url_rule( - "/api/temp-emails//messages/", - view_func=temp_emails_controller.api_get_temp_email_message_detail, - methods=["GET"], - ) - bp.add_url_rule( - "/api/temp-emails//messages/", - view_func=temp_emails_controller.api_delete_temp_email_message, - methods=["DELETE"], - ) - bp.add_url_rule("/api/temp-emails//clear", view_func=temp_emails_controller.api_clear_temp_email_messages, methods=["DELETE"]) - bp.add_url_rule("/api/temp-emails//refresh", view_func=temp_emails_controller.api_refresh_temp_email_messages, methods=["POST"]) + + # 定义路由处理函数 + handlers = [ + ("/api/temp-emails", temp_emails_controller.api_get_temp_emails, ["GET"]), + ("/api/temp-emails/generate", temp_emails_controller.api_generate_temp_email, ["POST"]), + ("/api/temp-emails/", temp_emails_controller.api_delete_temp_email, ["DELETE"]), + ("/api/temp-emails//messages", temp_emails_controller.api_get_temp_email_messages, ["GET"]), + ("/api/temp-emails//messages/", temp_emails_controller.api_get_temp_email_message_detail, ["GET"]), + ("/api/temp-emails//messages/", temp_emails_controller.api_delete_temp_email_message, ["DELETE"]), + ("/api/temp-emails//clear", temp_emails_controller.api_clear_temp_email_messages, ["DELETE"]), + ("/api/temp-emails//refresh", temp_emails_controller.api_refresh_temp_email_messages, ["POST"]), + ] + + # 注册路由,如果提供了 csrf_exempt 则应用到所有路由 + for path, handler, methods in handlers: + view_func = csrf_exempt(handler) if csrf_exempt else handler + bp.add_url_rule(path, view_func=view_func, methods=methods) + return bp diff --git a/outlook_web/security/csrf.py b/outlook_web/security/csrf.py index 0a9e220..541d716 100644 --- a/outlook_web/security/csrf.py +++ b/outlook_web/security/csrf.py @@ -14,6 +14,13 @@ except ImportError: # pragma: no cover print("Warning: flask-wtf not installed. CSRF protection is disabled. Install with: pip install flask-wtf") +def generate_csrf(): + """生成 CSRF token(模块级别导出)""" + if _generate_csrf is not None: + return _generate_csrf() + return None + + def init_csrf(app) -> Tuple[Optional[object], Callable, Optional[Callable]]: """ 初始化 CSRF 保护(如果可用)