login.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. from typing import cast
  2. import flask_login
  3. from flask import request
  4. from flask_restful import Resource, reqparse
  5. import services
  6. from controllers.console import api
  7. from controllers.console.setup import setup_required
  8. from libs.helper import email, extract_remote_ip
  9. from libs.password import valid_password
  10. from models.account import Account
  11. from services.account_service import AccountService, TenantService
  12. class LoginApi(Resource):
  13. """Resource for user login."""
  14. @setup_required
  15. def post(self):
  16. """Authenticate user and login."""
  17. parser = reqparse.RequestParser()
  18. parser.add_argument("email", type=email, required=True, location="json")
  19. parser.add_argument("password", type=valid_password, required=True, location="json")
  20. parser.add_argument("remember_me", type=bool, required=False, default=False, location="json")
  21. args = parser.parse_args()
  22. # todo: Verify the recaptcha
  23. try:
  24. account = AccountService.authenticate(args["email"], args["password"])
  25. except services.errors.account.AccountLoginError as e:
  26. return {"code": "unauthorized", "message": str(e)}, 401
  27. # SELF_HOSTED only have one workspace
  28. tenants = TenantService.get_join_tenants(account)
  29. if len(tenants) == 0:
  30. return {
  31. "result": "fail",
  32. "data": "workspace not found, please contact system admin to invite you to join in a workspace",
  33. }
  34. token_pair = AccountService.login(account=account, ip_address=extract_remote_ip(request))
  35. return {"result": "success", "data": token_pair.model_dump()}
  36. class LogoutApi(Resource):
  37. @setup_required
  38. def get(self):
  39. account = cast(Account, flask_login.current_user)
  40. AccountService.logout(account=account)
  41. flask_login.logout_user()
  42. return {"result": "success"}
  43. class ResetPasswordApi(Resource):
  44. @setup_required
  45. def get(self):
  46. # parser = reqparse.RequestParser()
  47. # parser.add_argument('email', type=email, required=True, location='json')
  48. # args = parser.parse_args()
  49. # import mailchimp_transactional as MailchimpTransactional
  50. # from mailchimp_transactional.api_client import ApiClientError
  51. # account = {'email': args['email']}
  52. # account = AccountService.get_by_email(args['email'])
  53. # if account is None:
  54. # raise ValueError('Email not found')
  55. # new_password = AccountService.generate_password()
  56. # AccountService.update_password(account, new_password)
  57. # todo: Send email
  58. # MAILCHIMP_API_KEY = dify_config.MAILCHIMP_TRANSACTIONAL_API_KEY
  59. # mailchimp = MailchimpTransactional(MAILCHIMP_API_KEY)
  60. # message = {
  61. # 'from_email': 'noreply@example.com',
  62. # 'to': [{'email': account['email']}],
  63. # 'subject': 'Reset your Dify password',
  64. # 'html': """
  65. # <p>Dear User,</p>
  66. # <p>The Dify team has generated a new password for you, details as follows:</p>
  67. # <p><strong>{new_password}</strong></p>
  68. # <p>Please change your password to log in as soon as possible.</p>
  69. # <p>Regards,</p>
  70. # <p>The Dify Team</p>
  71. # """
  72. # }
  73. # response = mailchimp.messages.send({
  74. # 'message': message,
  75. # # required for transactional email
  76. # ' settings': {
  77. # 'sandbox_mode': dify_config.MAILCHIMP_SANDBOX_MODE,
  78. # },
  79. # })
  80. # Check if MSG was sent
  81. # if response.status_code != 200:
  82. # # handle error
  83. # pass
  84. return {"result": "success"}
  85. class RefreshTokenApi(Resource):
  86. def post(self):
  87. parser = reqparse.RequestParser()
  88. parser.add_argument("refresh_token", type=str, required=True, location="json")
  89. args = parser.parse_args()
  90. try:
  91. new_token_pair = AccountService.refresh_token(args["refresh_token"])
  92. return {"result": "success", "data": new_token_pair.model_dump()}
  93. except Exception as e:
  94. return {"result": "fail", "data": str(e)}, 401
  95. api.add_resource(LoginApi, "/login")
  96. api.add_resource(LogoutApi, "/logout")
  97. api.add_resource(RefreshTokenApi, "/refresh-token")