Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

ext_login.py 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import json
  2. import flask_login # type: ignore
  3. from flask import Response, request
  4. from flask_login import user_loaded_from_request, user_logged_in
  5. from werkzeug.exceptions import NotFound, Unauthorized
  6. import contexts
  7. from configs import dify_config
  8. from dify_app import DifyApp
  9. from extensions.ext_database import db
  10. from libs.passport import PassportService
  11. from models.account import Account, Tenant, TenantAccountJoin
  12. from models.model import EndUser
  13. from services.account_service import AccountService
  14. login_manager = flask_login.LoginManager()
  15. # Flask-Login configuration
  16. @login_manager.request_loader
  17. def load_user_from_request(request_from_flask_login):
  18. """Load user based on the request."""
  19. auth_header = request.headers.get("Authorization", "")
  20. auth_token: str | None = None
  21. if auth_header:
  22. if " " not in auth_header:
  23. raise Unauthorized("Invalid Authorization header format. Expected 'Bearer <api-key>' format.")
  24. auth_scheme, auth_token = auth_header.split(maxsplit=1)
  25. auth_scheme = auth_scheme.lower()
  26. if auth_scheme != "bearer":
  27. raise Unauthorized("Invalid Authorization header format. Expected 'Bearer <api-key>' format.")
  28. else:
  29. auth_token = request.args.get("_token")
  30. # Check for admin API key authentication first
  31. if dify_config.ADMIN_API_KEY_ENABLE and auth_header:
  32. admin_api_key = dify_config.ADMIN_API_KEY
  33. if admin_api_key and admin_api_key == auth_token:
  34. workspace_id = request.headers.get("X-WORKSPACE-ID")
  35. if workspace_id:
  36. tenant_account_join = (
  37. db.session.query(Tenant, TenantAccountJoin)
  38. .filter(Tenant.id == workspace_id)
  39. .filter(TenantAccountJoin.tenant_id == Tenant.id)
  40. .filter(TenantAccountJoin.role == "owner")
  41. .one_or_none()
  42. )
  43. if tenant_account_join:
  44. tenant, ta = tenant_account_join
  45. account = db.session.query(Account).filter_by(id=ta.account_id).first()
  46. if account:
  47. account.current_tenant = tenant
  48. return account
  49. if request.blueprint in {"console", "inner_api"}:
  50. if not auth_token:
  51. raise Unauthorized("Invalid Authorization token.")
  52. decoded = PassportService().verify(auth_token)
  53. user_id = decoded.get("user_id")
  54. if not user_id:
  55. raise Unauthorized("Invalid Authorization token.")
  56. logged_in_account = AccountService.load_logged_in_account(account_id=user_id)
  57. return logged_in_account
  58. elif request.blueprint == "web":
  59. decoded = PassportService().verify(auth_token)
  60. end_user_id = decoded.get("end_user_id")
  61. if not end_user_id:
  62. raise Unauthorized("Invalid Authorization token.")
  63. end_user = db.session.query(EndUser).filter(EndUser.id == decoded["end_user_id"]).first()
  64. if not end_user:
  65. raise NotFound("End user not found.")
  66. return end_user
  67. @user_logged_in.connect
  68. @user_loaded_from_request.connect
  69. def on_user_logged_in(_sender, user):
  70. """Called when a user logged in.
  71. Note: AccountService.load_logged_in_account will populate user.current_tenant_id
  72. through the load_user method, which calls account.set_tenant_id().
  73. """
  74. if user and isinstance(user, Account) and user.current_tenant_id:
  75. contexts.tenant_id.set(user.current_tenant_id)
  76. @login_manager.unauthorized_handler
  77. def unauthorized_handler():
  78. """Handle unauthorized requests."""
  79. return Response(
  80. json.dumps({"code": "unauthorized", "message": "Unauthorized."}),
  81. status=401,
  82. content_type="application/json",
  83. )
  84. def init_app(app: DifyApp):
  85. login_manager.init_app(app)