| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | # | 
					
						
							|  |  |  |  | #  Copyright 2024 The InfiniFlow Authors. All Rights Reserved. | 
					
						
							|  |  |  |  | # | 
					
						
							|  |  |  |  | #  Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  | #  you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  | #  You may obtain a copy of the License at | 
					
						
							|  |  |  |  | # | 
					
						
							|  |  |  |  | #      http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  |  | # | 
					
						
							|  |  |  |  | #  Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  | #  distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  | #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  | #  See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  | #  limitations under the License. | 
					
						
							|  |  |  |  | # | 
					
						
							| 
									
										
										
										
											2024-11-14 17:13:48 +08:00
										 |  |  |  | import logging | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | import json | 
					
						
							|  |  |  |  | import re | 
					
						
							|  |  |  |  | from datetime import datetime | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | from flask import request, session, redirect | 
					
						
							|  |  |  |  | from werkzeug.security import generate_password_hash, check_password_hash | 
					
						
							|  |  |  |  | from flask_login import login_required, current_user, login_user, logout_user | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | from api.db.db_models import TenantLLM | 
					
						
							|  |  |  |  | from api.db.services.llm_service import TenantLLMService, LLMService | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  | from api.utils.api_utils import ( | 
					
						
							|  |  |  |  |     server_error_response, | 
					
						
							|  |  |  |  |     validate_request, | 
					
						
							|  |  |  |  |     get_data_error_result, | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | from api.utils import ( | 
					
						
							|  |  |  |  |     get_uuid, | 
					
						
							|  |  |  |  |     get_format_time, | 
					
						
							|  |  |  |  |     decrypt, | 
					
						
							|  |  |  |  |     download_img, | 
					
						
							|  |  |  |  |     current_timestamp, | 
					
						
							|  |  |  |  |     datetime_format, | 
					
						
							|  |  |  |  | ) | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  | from api.db import UserTenantRole, FileType | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  | from api import settings | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | from api.db.services.user_service import UserService, TenantService, UserTenantService | 
					
						
							|  |  |  |  | from api.db.services.file_service import FileService | 
					
						
							| 
									
										
										
										
											2024-08-15 19:51:09 +08:00
										 |  |  |  | from api.utils.api_utils import get_json_result, construct_response | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/login", methods=["POST", "GET"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | def login(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     User login endpoint. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - User | 
					
						
							|  |  |  |  |     parameters: | 
					
						
							|  |  |  |  |       - in: body | 
					
						
							|  |  |  |  |         name: body | 
					
						
							|  |  |  |  |         description: Login credentials. | 
					
						
							|  |  |  |  |         required: true | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |           properties: | 
					
						
							|  |  |  |  |             email: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User email. | 
					
						
							|  |  |  |  |             password: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User password. | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Login successful. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |       401: | 
					
						
							|  |  |  |  |         description: Authentication failed. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     if not request.json: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return get_json_result( | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             data=False, code=settings.RetCode.AUTHENTICATION_ERROR, message="Unauthorized!" | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     email = request.json.get("email", "") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     users = UserService.query(email=email) | 
					
						
							|  |  |  |  |     if not users: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return get_json_result( | 
					
						
							|  |  |  |  |             data=False, | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             code=settings.RetCode.AUTHENTICATION_ERROR, | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |             message=f"Email: {email} is not registered!", | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     password = request.json.get("password") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     try: | 
					
						
							|  |  |  |  |         password = decrypt(password) | 
					
						
							|  |  |  |  |     except BaseException: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return get_json_result( | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             data=False, code=settings.RetCode.SERVER_ERROR, message="Fail to crypt password" | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     user = UserService.query_user(email, password) | 
					
						
							|  |  |  |  |     if user: | 
					
						
							|  |  |  |  |         response_data = user.to_json() | 
					
						
							|  |  |  |  |         user.access_token = get_uuid() | 
					
						
							|  |  |  |  |         login_user(user) | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         user.update_time = (current_timestamp(),) | 
					
						
							|  |  |  |  |         user.update_date = (datetime_format(datetime.now()),) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         user.save() | 
					
						
							|  |  |  |  |         msg = "Welcome back!" | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |         return construct_response(data=response_data, auth=user.get_id(), message=msg) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return get_json_result( | 
					
						
							|  |  |  |  |             data=False, | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             code=settings.RetCode.AUTHENTICATION_ERROR, | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |             message="Email and password do not match!", | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/github_callback", methods=["GET"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | def github_callback(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     GitHub OAuth callback endpoint. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - OAuth | 
					
						
							|  |  |  |  |     parameters: | 
					
						
							|  |  |  |  |       - in: query | 
					
						
							|  |  |  |  |         name: code | 
					
						
							|  |  |  |  |         type: string | 
					
						
							|  |  |  |  |         required: true | 
					
						
							|  |  |  |  |         description: Authorization code from GitHub. | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Authentication successful. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     import requests | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     res = requests.post( | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |         settings.GITHUB_OAUTH.get("url"), | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         data={ | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             "client_id": settings.GITHUB_OAUTH.get("client_id"), | 
					
						
							|  |  |  |  |             "client_secret": settings.GITHUB_OAUTH.get("secret_key"), | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             "code": request.args.get("code"), | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         headers={"Accept": "application/json"}, | 
					
						
							|  |  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     res = res.json() | 
					
						
							|  |  |  |  |     if "error" in res: | 
					
						
							|  |  |  |  |         return redirect("/?error=%s" % res["error_description"]) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if "user:email" not in res["scope"].split(","): | 
					
						
							|  |  |  |  |         return redirect("/?error=user:email not in scope") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     session["access_token"] = res["access_token"] | 
					
						
							|  |  |  |  |     session["access_token_from"] = "github" | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  |     user_info = user_info_from_github(session["access_token"]) | 
					
						
							|  |  |  |  |     email_address = user_info["email"] | 
					
						
							|  |  |  |  |     users = UserService.query(email=email_address) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user_id = get_uuid() | 
					
						
							|  |  |  |  |     if not users: | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  |         # User isn't try to register | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         try: | 
					
						
							|  |  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  |                 avatar = download_img(user_info["avatar_url"]) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             except Exception as e: | 
					
						
							| 
									
										
										
										
											2024-11-14 17:13:48 +08:00
										 |  |  |  |                 logging.exception(e) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |                 avatar = "" | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             users = user_register( | 
					
						
							|  |  |  |  |                 user_id, | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     "access_token": session["access_token"], | 
					
						
							|  |  |  |  |                     "email": email_address, | 
					
						
							|  |  |  |  |                     "avatar": avatar, | 
					
						
							|  |  |  |  |                     "nickname": user_info["login"], | 
					
						
							|  |  |  |  |                     "login_channel": "github", | 
					
						
							|  |  |  |  |                     "last_login_time": get_format_time(), | 
					
						
							|  |  |  |  |                     "is_superuser": False, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             if not users: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |                 raise Exception(f"Fail to register {email_address}.") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             if len(users) > 1: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |                 raise Exception(f"Same email: {email_address} exists!") | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             # Try to log in | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             user = users[0] | 
					
						
							|  |  |  |  |             login_user(user) | 
					
						
							|  |  |  |  |             return redirect("/?auth=%s" % user.get_id()) | 
					
						
							|  |  |  |  |         except Exception as e: | 
					
						
							|  |  |  |  |             rollback_user_registration(user_id) | 
					
						
							| 
									
										
										
										
											2024-11-14 17:13:48 +08:00
										 |  |  |  |             logging.exception(e) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             return redirect("/?error=%s" % str(e)) | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # User has already registered, try to log in | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user = users[0] | 
					
						
							|  |  |  |  |     user.access_token = get_uuid() | 
					
						
							|  |  |  |  |     login_user(user) | 
					
						
							|  |  |  |  |     user.save() | 
					
						
							|  |  |  |  |     return redirect("/?auth=%s" % user.get_id()) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/feishu_callback", methods=["GET"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | def feishu_callback(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     Feishu OAuth callback endpoint. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - OAuth | 
					
						
							|  |  |  |  |     parameters: | 
					
						
							|  |  |  |  |       - in: query | 
					
						
							|  |  |  |  |         name: code | 
					
						
							|  |  |  |  |         type: string | 
					
						
							|  |  |  |  |         required: true | 
					
						
							|  |  |  |  |         description: Authorization code from Feishu. | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Authentication successful. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     import requests | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     app_access_token_res = requests.post( | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |         settings.FEISHU_OAUTH.get("app_access_token_url"), | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         data=json.dumps( | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |                 "app_id": settings.FEISHU_OAUTH.get("app_id"), | 
					
						
							|  |  |  |  |                 "app_secret": settings.FEISHU_OAUTH.get("app_secret"), | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  |         ), | 
					
						
							|  |  |  |  |         headers={"Content-Type": "application/json; charset=utf-8"}, | 
					
						
							|  |  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     app_access_token_res = app_access_token_res.json() | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     if app_access_token_res["code"] != 0: | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         return redirect("/?error=%s" % app_access_token_res) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     res = requests.post( | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |         settings.FEISHU_OAUTH.get("user_access_token_url"), | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         data=json.dumps( | 
					
						
							|  |  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |                 "grant_type": settings.FEISHU_OAUTH.get("grant_type"), | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |                 "code": request.args.get("code"), | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         ), | 
					
						
							|  |  |  |  |         headers={ | 
					
						
							|  |  |  |  |             "Content-Type": "application/json; charset=utf-8", | 
					
						
							|  |  |  |  |             "Authorization": f"Bearer {app_access_token_res['app_access_token']}", | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     res = res.json() | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     if res["code"] != 0: | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         return redirect("/?error=%s" % res["message"]) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-28 13:00:38 +08:00
										 |  |  |  |     if "contact:user.email:readonly" not in res["data"]["scope"].split(): | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         return redirect("/?error=contact:user.email:readonly not in scope") | 
					
						
							|  |  |  |  |     session["access_token"] = res["data"]["access_token"] | 
					
						
							|  |  |  |  |     session["access_token_from"] = "feishu" | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  |     user_info = user_info_from_feishu(session["access_token"]) | 
					
						
							|  |  |  |  |     email_address = user_info["email"] | 
					
						
							|  |  |  |  |     users = UserService.query(email=email_address) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user_id = get_uuid() | 
					
						
							|  |  |  |  |     if not users: | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  |         # User isn't try to register | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         try: | 
					
						
							|  |  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  |                 avatar = download_img(user_info["avatar_url"]) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             except Exception as e: | 
					
						
							| 
									
										
										
										
											2024-11-14 17:13:48 +08:00
										 |  |  |  |                 logging.exception(e) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |                 avatar = "" | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             users = user_register( | 
					
						
							|  |  |  |  |                 user_id, | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     "access_token": session["access_token"], | 
					
						
							|  |  |  |  |                     "email": email_address, | 
					
						
							|  |  |  |  |                     "avatar": avatar, | 
					
						
							|  |  |  |  |                     "nickname": user_info["en_name"], | 
					
						
							|  |  |  |  |                     "login_channel": "feishu", | 
					
						
							|  |  |  |  |                     "last_login_time": get_format_time(), | 
					
						
							|  |  |  |  |                     "is_superuser": False, | 
					
						
							|  |  |  |  |                 }, | 
					
						
							|  |  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             if not users: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |                 raise Exception(f"Fail to register {email_address}.") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             if len(users) > 1: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |                 raise Exception(f"Same email: {email_address} exists!") | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             # Try to log in | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             user = users[0] | 
					
						
							|  |  |  |  |             login_user(user) | 
					
						
							|  |  |  |  |             return redirect("/?auth=%s" % user.get_id()) | 
					
						
							|  |  |  |  |         except Exception as e: | 
					
						
							|  |  |  |  |             rollback_user_registration(user_id) | 
					
						
							| 
									
										
										
										
											2024-11-14 17:13:48 +08:00
										 |  |  |  |             logging.exception(e) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             return redirect("/?error=%s" % str(e)) | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     # User has already registered, try to log in | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user = users[0] | 
					
						
							|  |  |  |  |     user.access_token = get_uuid() | 
					
						
							|  |  |  |  |     login_user(user) | 
					
						
							|  |  |  |  |     user.save() | 
					
						
							|  |  |  |  |     return redirect("/?auth=%s" % user.get_id()) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | def user_info_from_feishu(access_token): | 
					
						
							|  |  |  |  |     import requests | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     headers = { | 
					
						
							|  |  |  |  |         "Content-Type": "application/json; charset=utf-8", | 
					
						
							|  |  |  |  |         "Authorization": f"Bearer {access_token}", | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     res = requests.get( | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |         "https://open.feishu.cn/open-apis/authen/v1/user_info", headers=headers | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user_info = res.json()["data"] | 
					
						
							|  |  |  |  |     user_info["email"] = None if user_info.get("email") == "" else user_info["email"] | 
					
						
							|  |  |  |  |     return user_info | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | def user_info_from_github(access_token): | 
					
						
							|  |  |  |  |     import requests | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     headers = {"Accept": "application/json", "Authorization": f"token {access_token}"} | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     res = requests.get( | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         f"https://api.github.com/user?access_token={access_token}", headers=headers | 
					
						
							|  |  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user_info = res.json() | 
					
						
							|  |  |  |  |     email_info = requests.get( | 
					
						
							|  |  |  |  |         f"https://api.github.com/user/emails?access_token={access_token}", | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         headers=headers, | 
					
						
							|  |  |  |  |     ).json() | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user_info["email"] = next( | 
					
						
							| 
									
										
										
										
											2024-12-08 14:21:12 +08:00
										 |  |  |  |         (email for email in email_info if email["primary"]), None | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     )["email"] | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     return user_info | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/logout", methods=["GET"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | @login_required | 
					
						
							|  |  |  |  | def log_out(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     User logout endpoint. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - User | 
					
						
							|  |  |  |  |     security: | 
					
						
							|  |  |  |  |       - ApiKeyAuth: [] | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Logout successful. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     current_user.access_token = "" | 
					
						
							|  |  |  |  |     current_user.save() | 
					
						
							|  |  |  |  |     logout_user() | 
					
						
							|  |  |  |  |     return get_json_result(data=True) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/setting", methods=["POST"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | @login_required | 
					
						
							|  |  |  |  | def setting_user(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     Update user settings. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - User | 
					
						
							|  |  |  |  |     security: | 
					
						
							|  |  |  |  |       - ApiKeyAuth: [] | 
					
						
							|  |  |  |  |     parameters: | 
					
						
							|  |  |  |  |       - in: body | 
					
						
							|  |  |  |  |         name: body | 
					
						
							|  |  |  |  |         description: User settings to update. | 
					
						
							|  |  |  |  |         required: true | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |           properties: | 
					
						
							|  |  |  |  |             nickname: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: New nickname. | 
					
						
							|  |  |  |  |             email: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: New email. | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Settings updated successfully. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     update_dict = {} | 
					
						
							|  |  |  |  |     request_data = request.json | 
					
						
							|  |  |  |  |     if request_data.get("password"): | 
					
						
							|  |  |  |  |         new_password = request_data.get("new_password") | 
					
						
							|  |  |  |  |         if not check_password_hash( | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |                 current_user.password, decrypt(request_data["password"]) | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ): | 
					
						
							|  |  |  |  |             return get_json_result( | 
					
						
							|  |  |  |  |                 data=False, | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |                 code=settings.RetCode.AUTHENTICATION_ERROR, | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |                 message="Password error!", | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         if new_password: | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  |             update_dict["password"] = generate_password_hash(decrypt(new_password)) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     for k in request_data.keys(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         if k in [ | 
					
						
							|  |  |  |  |             "password", | 
					
						
							|  |  |  |  |             "new_password", | 
					
						
							|  |  |  |  |             "email", | 
					
						
							|  |  |  |  |             "status", | 
					
						
							|  |  |  |  |             "is_superuser", | 
					
						
							|  |  |  |  |             "login_channel", | 
					
						
							|  |  |  |  |             "is_anonymous", | 
					
						
							|  |  |  |  |             "is_active", | 
					
						
							|  |  |  |  |             "is_authenticated", | 
					
						
							|  |  |  |  |             "last_login_time", | 
					
						
							|  |  |  |  |         ]: | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |             continue | 
					
						
							|  |  |  |  |         update_dict[k] = request_data[k] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     try: | 
					
						
							|  |  |  |  |         UserService.update_by_id(current_user.id, update_dict) | 
					
						
							|  |  |  |  |         return get_json_result(data=True) | 
					
						
							|  |  |  |  |     except Exception as e: | 
					
						
							| 
									
										
										
										
											2024-11-14 17:13:48 +08:00
										 |  |  |  |         logging.exception(e) | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return get_json_result( | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             data=False, message="Update failure!", code=settings.RetCode.EXCEPTION_ERROR | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/info", methods=["GET"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | @login_required | 
					
						
							| 
									
										
										
										
											2024-08-16 08:43:26 +08:00
										 |  |  |  | def user_profile(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     Get user profile information. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - User | 
					
						
							|  |  |  |  |     security: | 
					
						
							|  |  |  |  |       - ApiKeyAuth: [] | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: User profile retrieved successfully. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |           properties: | 
					
						
							|  |  |  |  |             id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User ID. | 
					
						
							|  |  |  |  |             nickname: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User nickname. | 
					
						
							|  |  |  |  |             email: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User email. | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     return get_json_result(data=current_user.to_dict()) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | def rollback_user_registration(user_id): | 
					
						
							|  |  |  |  |     try: | 
					
						
							|  |  |  |  |         UserService.delete_by_id(user_id) | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |     except Exception: | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         pass | 
					
						
							|  |  |  |  |     try: | 
					
						
							|  |  |  |  |         TenantService.delete_by_id(user_id) | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |     except Exception: | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         pass | 
					
						
							|  |  |  |  |     try: | 
					
						
							|  |  |  |  |         u = UserTenantService.query(tenant_id=user_id) | 
					
						
							|  |  |  |  |         if u: | 
					
						
							|  |  |  |  |             UserTenantService.delete_by_id(u[0].id) | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |     except Exception: | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         pass | 
					
						
							|  |  |  |  |     try: | 
					
						
							|  |  |  |  |         TenantLLM.delete().where(TenantLLM.tenant_id == user_id).execute() | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |     except Exception: | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         pass | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | def user_register(user_id, user): | 
					
						
							|  |  |  |  |     user["id"] = user_id | 
					
						
							|  |  |  |  |     tenant = { | 
					
						
							|  |  |  |  |         "id": user_id, | 
					
						
							|  |  |  |  |         "name": user["nickname"] + "‘s Kingdom", | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |         "llm_id": settings.CHAT_MDL, | 
					
						
							|  |  |  |  |         "embd_id": settings.EMBEDDING_MDL, | 
					
						
							|  |  |  |  |         "asr_id": settings.ASR_MDL, | 
					
						
							|  |  |  |  |         "parser_ids": settings.PARSERS, | 
					
						
							|  |  |  |  |         "img2txt_id": settings.IMAGE2TEXT_MDL, | 
					
						
							|  |  |  |  |         "rerank_id": settings.RERANK_MDL, | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     usr_tenant = { | 
					
						
							|  |  |  |  |         "tenant_id": user_id, | 
					
						
							|  |  |  |  |         "user_id": user_id, | 
					
						
							|  |  |  |  |         "invited_by": user_id, | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         "role": UserTenantRole.OWNER, | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     file_id = get_uuid() | 
					
						
							|  |  |  |  |     file = { | 
					
						
							|  |  |  |  |         "id": file_id, | 
					
						
							|  |  |  |  |         "parent_id": file_id, | 
					
						
							|  |  |  |  |         "tenant_id": user_id, | 
					
						
							|  |  |  |  |         "created_by": user_id, | 
					
						
							|  |  |  |  |         "name": "/", | 
					
						
							|  |  |  |  |         "type": FileType.FOLDER.value, | 
					
						
							|  |  |  |  |         "size": 0, | 
					
						
							|  |  |  |  |         "location": "", | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     tenant_llm = [] | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |     for llm in LLMService.query(fid=settings.LLM_FACTORY): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         tenant_llm.append( | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 "tenant_id": user_id, | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |                 "llm_factory": settings.LLM_FACTORY, | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |                 "llm_name": llm.llm_name, | 
					
						
							|  |  |  |  |                 "model_type": llm.model_type, | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |                 "api_key": settings.API_KEY, | 
					
						
							| 
									
										
										
										
											2024-11-22 12:25:42 +08:00
										 |  |  |  |                 "api_base": settings.LLM_BASE_URL, | 
					
						
							|  |  |  |  |                 "max_tokens": llm.max_tokens if llm.max_tokens else 8192 | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if not UserService.save(**user): | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     TenantService.insert(**tenant) | 
					
						
							|  |  |  |  |     UserTenantService.insert(**usr_tenant) | 
					
						
							|  |  |  |  |     TenantLLMService.insert_many(tenant_llm) | 
					
						
							|  |  |  |  |     FileService.insert(file) | 
					
						
							|  |  |  |  |     return UserService.query(email=user["email"]) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/register", methods=["POST"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | @validate_request("nickname", "email", "password") | 
					
						
							|  |  |  |  | def user_add(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     Register a new user. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - User | 
					
						
							|  |  |  |  |     parameters: | 
					
						
							|  |  |  |  |       - in: body | 
					
						
							|  |  |  |  |         name: body | 
					
						
							|  |  |  |  |         description: Registration details. | 
					
						
							|  |  |  |  |         required: true | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |           properties: | 
					
						
							|  |  |  |  |             nickname: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User nickname. | 
					
						
							|  |  |  |  |             email: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User email. | 
					
						
							|  |  |  |  |             password: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: User password. | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Registration successful. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2025-03-21 09:38:15 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     if not settings.REGISTER_ENABLED: | 
					
						
							|  |  |  |  |         return get_json_result( | 
					
						
							|  |  |  |  |             data=False, | 
					
						
							|  |  |  |  |             message="User registration is disabled!", | 
					
						
							|  |  |  |  |             code=settings.RetCode.OPERATING_ERROR, | 
					
						
							|  |  |  |  |         ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     req = request.json | 
					
						
							| 
									
										
										
										
											2024-08-15 19:25:51 +08:00
										 |  |  |  |     email_address = req["email"] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # Validate the email address | 
					
						
							| 
									
										
										
										
											2025-03-03 13:55:10 +11:00
										 |  |  |  |     if not re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,}$", email_address): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return get_json_result( | 
					
						
							|  |  |  |  |             data=False, | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |             message=f"Invalid email address: {email_address}!", | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             code=settings.RetCode.OPERATING_ERROR, | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 19:25:51 +08:00
										 |  |  |  |     # Check if the email address is already used | 
					
						
							|  |  |  |  |     if UserService.query(email=email_address): | 
					
						
							|  |  |  |  |         return get_json_result( | 
					
						
							|  |  |  |  |             data=False, | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |             message=f"Email: {email_address} has already registered!", | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             code=settings.RetCode.OPERATING_ERROR, | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 19:25:51 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-15 19:51:09 +08:00
										 |  |  |  |     # Construct user info data | 
					
						
							|  |  |  |  |     nickname = req["nickname"] | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     user_dict = { | 
					
						
							|  |  |  |  |         "access_token": get_uuid(), | 
					
						
							| 
									
										
										
										
											2024-08-15 19:25:51 +08:00
										 |  |  |  |         "email": email_address, | 
					
						
							| 
									
										
										
										
											2024-08-15 19:51:09 +08:00
										 |  |  |  |         "nickname": nickname, | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         "password": decrypt(req["password"]), | 
					
						
							|  |  |  |  |         "login_channel": "password", | 
					
						
							|  |  |  |  |         "last_login_time": get_format_time(), | 
					
						
							|  |  |  |  |         "is_superuser": False, | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     user_id = get_uuid() | 
					
						
							|  |  |  |  |     try: | 
					
						
							|  |  |  |  |         users = user_register(user_id, user_dict) | 
					
						
							|  |  |  |  |         if not users: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             raise Exception(f"Fail to register {email_address}.") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         if len(users) > 1: | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |             raise Exception(f"Same email: {email_address} exists!") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         user = users[0] | 
					
						
							|  |  |  |  |         login_user(user) | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return construct_response( | 
					
						
							|  |  |  |  |             data=user.to_json(), | 
					
						
							|  |  |  |  |             auth=user.get_id(), | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |             message=f"{nickname}, welcome aboard!", | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     except Exception as e: | 
					
						
							|  |  |  |  |         rollback_user_registration(user_id) | 
					
						
							| 
									
										
										
										
											2024-11-14 17:13:48 +08:00
										 |  |  |  |         logging.exception(e) | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         return get_json_result( | 
					
						
							|  |  |  |  |             data=False, | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |             message=f"User registration failure, error: {str(e)}", | 
					
						
							| 
									
										
										
										
											2024-11-15 17:30:56 +08:00
										 |  |  |  |             code=settings.RetCode.EXCEPTION_ERROR, | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/tenant_info", methods=["GET"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | @login_required | 
					
						
							|  |  |  |  | def tenant_info(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     Get tenant information. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - Tenant | 
					
						
							|  |  |  |  |     security: | 
					
						
							|  |  |  |  |       - ApiKeyAuth: [] | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Tenant information retrieved successfully. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |           properties: | 
					
						
							|  |  |  |  |             tenant_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: Tenant ID. | 
					
						
							|  |  |  |  |             name: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: Tenant name. | 
					
						
							|  |  |  |  |             llm_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: LLM ID. | 
					
						
							|  |  |  |  |             embd_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: Embedding model ID. | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-10-16 16:10:24 +08:00
										 |  |  |  |         tenants = TenantService.get_info_by(current_user.id) | 
					
						
							|  |  |  |  |         if not tenants: | 
					
						
							| 
									
										
										
										
											2024-11-05 11:02:31 +08:00
										 |  |  |  |             return get_data_error_result(message="Tenant not found!") | 
					
						
							| 
									
										
										
										
											2024-10-16 16:10:24 +08:00
										 |  |  |  |         return get_json_result(data=tenants[0]) | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     except Exception as e: | 
					
						
							|  |  |  |  |         return server_error_response(e) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 21:23:51 +08:00
										 |  |  |  | @manager.route("/set_tenant_info", methods=["POST"])  # noqa: F821 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | @login_required | 
					
						
							| 
									
										
										
										
											2024-08-26 18:06:50 +08:00
										 |  |  |  | @validate_request("tenant_id", "asr_id", "embd_id", "img2txt_id", "llm_id") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  | def set_tenant_info(): | 
					
						
							| 
									
										
										
										
											2024-11-04 08:35:36 +01:00
										 |  |  |  |     """
 | 
					
						
							|  |  |  |  |     Update tenant information. | 
					
						
							|  |  |  |  |     --- | 
					
						
							|  |  |  |  |     tags: | 
					
						
							|  |  |  |  |       - Tenant | 
					
						
							|  |  |  |  |     security: | 
					
						
							|  |  |  |  |       - ApiKeyAuth: [] | 
					
						
							|  |  |  |  |     parameters: | 
					
						
							|  |  |  |  |       - in: body | 
					
						
							|  |  |  |  |         name: body | 
					
						
							|  |  |  |  |         description: Tenant information to update. | 
					
						
							|  |  |  |  |         required: true | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |           properties: | 
					
						
							|  |  |  |  |             tenant_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: Tenant ID. | 
					
						
							|  |  |  |  |             llm_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: LLM ID. | 
					
						
							|  |  |  |  |             embd_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: Embedding model ID. | 
					
						
							|  |  |  |  |             asr_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: ASR model ID. | 
					
						
							|  |  |  |  |             img2txt_id: | 
					
						
							|  |  |  |  |               type: string | 
					
						
							|  |  |  |  |               description: Image to Text model ID. | 
					
						
							|  |  |  |  |     responses: | 
					
						
							|  |  |  |  |       200: | 
					
						
							|  |  |  |  |         description: Tenant information updated successfully. | 
					
						
							|  |  |  |  |         schema: | 
					
						
							|  |  |  |  |           type: object | 
					
						
							|  |  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |     req = request.json | 
					
						
							|  |  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-11-19 14:15:25 +08:00
										 |  |  |  |         tid = req.pop("tenant_id") | 
					
						
							| 
									
										
										
										
											2024-08-15 09:17:36 +08:00
										 |  |  |  |         TenantService.update_by_id(tid, req) | 
					
						
							|  |  |  |  |         return get_json_result(data=True) | 
					
						
							|  |  |  |  |     except Exception as e: | 
					
						
							|  |  |  |  |         return server_error_response(e) |