| 
									
										
										
										
											2024-02-20 12:44:00 +08:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2024-04-03 00:18:36 +08:00
										 |  |  | import uuid | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  | import time | 
					
						
							|  |  |  | import datetime | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | import logging | 
					
						
							| 
									
										
										
										
											2024-12-08 11:57:57 +08:00
										 |  |  | from aiohttp import ClientSession | 
					
						
							| 
									
										
										
										
											2024-05-02 10:02:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-10 16:54:13 +08:00
										 |  |  | from open_webui.models.auths import ( | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  |     AddUserForm, | 
					
						
							|  |  |  |     ApiKey, | 
					
						
							|  |  |  |     Auths, | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |     Token, | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     LdapForm, | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  |     SigninForm, | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  |     SigninResponse, | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  |     SignupForm, | 
					
						
							| 
									
										
										
										
											2023-12-29 16:12:30 +08:00
										 |  |  |     UpdatePasswordForm, | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  |     UpdateProfileForm, | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  |     UserResponse, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2024-12-10 16:54:13 +08:00
										 |  |  | from open_webui.models.users import Users | 
					
						
							| 
									
										
										
										
											2024-11-20 04:17:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-04 22:54:48 +08:00
										 |  |  | from open_webui.constants import ERROR_MESSAGES, WEBHOOK_MESSAGES | 
					
						
							|  |  |  | from open_webui.env import ( | 
					
						
							| 
									
										
										
										
											2024-11-19 22:14:52 +08:00
										 |  |  |     WEBUI_AUTH, | 
					
						
							| 
									
										
										
										
											2024-09-04 22:54:48 +08:00
										 |  |  |     WEBUI_AUTH_TRUSTED_EMAIL_HEADER, | 
					
						
							|  |  |  |     WEBUI_AUTH_TRUSTED_NAME_HEADER, | 
					
						
							| 
									
										
										
										
											2025-01-23 22:16:50 +08:00
										 |  |  |     WEBUI_AUTH_COOKIE_SAME_SITE, | 
					
						
							|  |  |  |     WEBUI_AUTH_COOKIE_SECURE, | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     SRC_LOG_LEVELS, | 
					
						
							| 
									
										
										
										
											2024-09-04 22:54:48 +08:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  | from fastapi import APIRouter, Depends, HTTPException, Request, status | 
					
						
							| 
									
										
										
										
											2024-12-07 20:49:12 +08:00
										 |  |  | from fastapi.responses import RedirectResponse, Response | 
					
						
							| 
									
										
										
										
											2025-02-27 14:18:18 +08:00
										 |  |  | from open_webui.config import OPENID_PROVIDER_URL, ENABLE_OAUTH_SIGNUP, ENABLE_LDAP | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  | from pydantic import BaseModel | 
					
						
							| 
									
										
										
										
											2024-09-04 22:54:48 +08:00
										 |  |  | from open_webui.utils.misc import parse_duration, validate_email_format | 
					
						
							| 
									
										
										
										
											2024-12-09 08:01:56 +08:00
										 |  |  | from open_webui.utils.auth import ( | 
					
						
							| 
									
										
										
										
											2024-04-03 00:18:36 +08:00
										 |  |  |     create_api_key, | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  |     create_token, | 
					
						
							|  |  |  |     get_admin_user, | 
					
						
							| 
									
										
										
										
											2024-10-11 03:51:00 +08:00
										 |  |  |     get_verified_user, | 
					
						
							| 
									
										
										
										
											2024-08-28 06:10:27 +08:00
										 |  |  |     get_current_user, | 
					
						
							|  |  |  |     get_password_hash, | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2024-09-04 22:54:48 +08:00
										 |  |  | from open_webui.utils.webhook import post_webhook | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  | from open_webui.utils.access_control import get_permissions | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | from typing import Optional, List | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from ssl import CERT_REQUIRED, PROTOCOL_TLS | 
					
						
							| 
									
										
										
										
											2025-02-26 00:07:53 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | if ENABLE_LDAP.value: | 
					
						
							|  |  |  |     from ldap3 import Server, Connection, NONE, Tls | 
					
						
							|  |  |  |     from ldap3.utils.conv import escape_filter_chars | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 16:13:59 +08:00
										 |  |  | router = APIRouter() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | log = logging.getLogger(__name__) | 
					
						
							|  |  |  | log.setLevel(SRC_LOG_LEVELS["MAIN"]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | # GetSessionUser | 
					
						
							|  |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  | class SessionUserResponse(Token, UserResponse): | 
					
						
							|  |  |  |     expires_at: Optional[int] = None | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     permissions: Optional[dict] = None | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @router.get("/", response_model=SessionUserResponse) | 
					
						
							| 
									
										
										
										
											2024-06-20 05:38:09 +08:00
										 |  |  | async def get_session_user( | 
					
						
							|  |  |  |     request: Request, response: Response, user=Depends(get_current_user) | 
					
						
							|  |  |  | ): | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |     expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) | 
					
						
							|  |  |  |     expires_at = None | 
					
						
							|  |  |  |     if expires_delta: | 
					
						
							|  |  |  |         expires_at = int(time.time()) + int(expires_delta.total_seconds()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-20 05:38:09 +08:00
										 |  |  |     token = create_token( | 
					
						
							|  |  |  |         data={"id": user.id}, | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |         expires_delta=expires_delta, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-15 17:51:08 +08:00
										 |  |  |     datetime_expires_at = ( | 
					
						
							|  |  |  |         datetime.datetime.fromtimestamp(expires_at, datetime.timezone.utc) | 
					
						
							|  |  |  |         if expires_at | 
					
						
							|  |  |  |         else None | 
					
						
							| 
									
										
										
										
											2024-06-20 05:38:09 +08:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Set the cookie token | 
					
						
							|  |  |  |     response.set_cookie( | 
					
						
							|  |  |  |         key="token", | 
					
						
							|  |  |  |         value=token, | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |         expires=datetime_expires_at, | 
					
						
							| 
									
										
										
										
											2024-06-20 05:38:09 +08:00
										 |  |  |         httponly=True,  # Ensures the cookie is not accessible via JavaScript | 
					
						
							| 
									
										
										
										
											2025-01-23 22:16:50 +08:00
										 |  |  |         samesite=WEBUI_AUTH_COOKIE_SAME_SITE, | 
					
						
							|  |  |  |         secure=WEBUI_AUTH_COOKIE_SECURE, | 
					
						
							| 
									
										
										
										
											2024-06-20 05:38:09 +08:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     user_permissions = get_permissions( | 
					
						
							|  |  |  |         user.id, request.app.state.config.USER_PERMISSIONS | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-30 18:53:33 +08:00
										 |  |  |     return { | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |         "token": token, | 
					
						
							|  |  |  |         "token_type": "Bearer", | 
					
						
							|  |  |  |         "expires_at": expires_at, | 
					
						
							| 
									
										
										
										
											2023-12-30 18:53:33 +08:00
										 |  |  |         "id": user.id, | 
					
						
							|  |  |  |         "email": user.email, | 
					
						
							|  |  |  |         "name": user.name, | 
					
						
							|  |  |  |         "role": user.role, | 
					
						
							|  |  |  |         "profile_image_url": user.profile_image_url, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         "permissions": user_permissions, | 
					
						
							| 
									
										
										
										
											2023-12-30 18:53:33 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  | ############################ | 
					
						
							| 
									
										
										
										
											2024-01-27 13:22:25 +08:00
										 |  |  | # Update Profile | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @router.post("/update/profile", response_model=UserResponse) | 
					
						
							| 
									
										
										
										
											2024-01-27 13:22:25 +08:00
										 |  |  | async def update_profile( | 
					
						
							| 
									
										
										
										
											2024-10-11 03:51:00 +08:00
										 |  |  |     form_data: UpdateProfileForm, session_user=Depends(get_verified_user) | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  | ): | 
					
						
							|  |  |  |     if session_user: | 
					
						
							| 
									
										
										
										
											2024-01-27 13:22:25 +08:00
										 |  |  |         user = Users.update_user_by_id( | 
					
						
							|  |  |  |             session_user.id, | 
					
						
							|  |  |  |             {"profile_image_url": form_data.profile_image_url, "name": form_data.name}, | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  |         if user: | 
					
						
							|  |  |  |             return user | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise HTTPException(400, detail=ERROR_MESSAGES.DEFAULT()) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-29 16:12:30 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | # Update Password | 
					
						
							|  |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 16:55:50 +08:00
										 |  |  | @router.post("/update/password", response_model=bool) | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  | async def update_password( | 
					
						
							|  |  |  |     form_data: UpdatePasswordForm, session_user=Depends(get_current_user) | 
					
						
							|  |  |  | ): | 
					
						
							| 
									
										
										
										
											2024-03-27 05:30:53 +08:00
										 |  |  |     if WEBUI_AUTH_TRUSTED_EMAIL_HEADER: | 
					
						
							|  |  |  |         raise HTTPException(400, detail=ERROR_MESSAGES.ACTION_PROHIBITED) | 
					
						
							| 
									
										
										
										
											2023-12-29 16:26:47 +08:00
										 |  |  |     if session_user: | 
					
						
							|  |  |  |         user = Auths.authenticate_user(session_user.email, form_data.password) | 
					
						
							| 
									
										
										
										
											2023-12-29 16:12:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-29 16:26:47 +08:00
										 |  |  |         if user: | 
					
						
							|  |  |  |             hashed = get_password_hash(form_data.new_password) | 
					
						
							| 
									
										
										
										
											2023-12-29 16:29:18 +08:00
										 |  |  |             return Auths.update_user_password_by_id(user.id, hashed) | 
					
						
							| 
									
										
										
										
											2023-12-29 16:26:47 +08:00
										 |  |  |         else: | 
					
						
							|  |  |  |             raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_PASSWORD) | 
					
						
							| 
									
										
										
										
											2023-12-29 16:12:30 +08:00
										 |  |  |     else: | 
					
						
							|  |  |  |         raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | # LDAP Authentication | 
					
						
							|  |  |  | ############################ | 
					
						
							| 
									
										
										
										
											2025-01-28 22:51:21 +08:00
										 |  |  | @router.post("/ldap", response_model=SessionUserResponse) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | async def ldap_auth(request: Request, response: Response, form_data: LdapForm): | 
					
						
							|  |  |  |     ENABLE_LDAP = request.app.state.config.ENABLE_LDAP | 
					
						
							|  |  |  |     LDAP_SERVER_LABEL = request.app.state.config.LDAP_SERVER_LABEL | 
					
						
							|  |  |  |     LDAP_SERVER_HOST = request.app.state.config.LDAP_SERVER_HOST | 
					
						
							|  |  |  |     LDAP_SERVER_PORT = request.app.state.config.LDAP_SERVER_PORT | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |     LDAP_ATTRIBUTE_FOR_MAIL = request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     LDAP_ATTRIBUTE_FOR_USERNAME = request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME | 
					
						
							|  |  |  |     LDAP_SEARCH_BASE = request.app.state.config.LDAP_SEARCH_BASE | 
					
						
							|  |  |  |     LDAP_SEARCH_FILTERS = request.app.state.config.LDAP_SEARCH_FILTERS | 
					
						
							|  |  |  |     LDAP_APP_DN = request.app.state.config.LDAP_APP_DN | 
					
						
							|  |  |  |     LDAP_APP_PASSWORD = request.app.state.config.LDAP_APP_PASSWORD | 
					
						
							|  |  |  |     LDAP_USE_TLS = request.app.state.config.LDAP_USE_TLS | 
					
						
							|  |  |  |     LDAP_CA_CERT_FILE = request.app.state.config.LDAP_CA_CERT_FILE | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     LDAP_CIPHERS = ( | 
					
						
							|  |  |  |         request.app.state.config.LDAP_CIPHERS | 
					
						
							|  |  |  |         if request.app.state.config.LDAP_CIPHERS | 
					
						
							|  |  |  |         else "ALL" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not ENABLE_LDAP: | 
					
						
							|  |  |  |         raise HTTPException(400, detail="LDAP authentication is not enabled") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         tls = Tls( | 
					
						
							|  |  |  |             validate=CERT_REQUIRED, | 
					
						
							|  |  |  |             version=PROTOCOL_TLS, | 
					
						
							|  |  |  |             ca_certs_file=LDAP_CA_CERT_FILE, | 
					
						
							|  |  |  |             ciphers=LDAP_CIPHERS, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     except Exception as e: | 
					
						
							|  |  |  |         log.error(f"An error occurred on TLS: {str(e)}") | 
					
						
							|  |  |  |         raise HTTPException(400, detail=str(e)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         server = Server( | 
					
						
							|  |  |  |             host=LDAP_SERVER_HOST, | 
					
						
							|  |  |  |             port=LDAP_SERVER_PORT, | 
					
						
							| 
									
										
										
										
											2025-01-07 14:13:18 +08:00
										 |  |  |             get_info=NONE, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |             use_ssl=LDAP_USE_TLS, | 
					
						
							|  |  |  |             tls=tls, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         connection_app = Connection( | 
					
						
							|  |  |  |             server, | 
					
						
							|  |  |  |             LDAP_APP_DN, | 
					
						
							|  |  |  |             LDAP_APP_PASSWORD, | 
					
						
							|  |  |  |             auto_bind="NONE", | 
					
						
							|  |  |  |             authentication="SIMPLE", | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |         if not connection_app.bind(): | 
					
						
							|  |  |  |             raise HTTPException(400, detail="Application account bind failed") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         search_success = connection_app.search( | 
					
						
							|  |  |  |             search_base=LDAP_SEARCH_BASE, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |             search_filter=f"(&({LDAP_ATTRIBUTE_FOR_USERNAME}={escape_filter_chars(form_data.user.lower())}){LDAP_SEARCH_FILTERS})", | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |             attributes=[ | 
					
						
							|  |  |  |                 f"{LDAP_ATTRIBUTE_FOR_USERNAME}", | 
					
						
							|  |  |  |                 f"{LDAP_ATTRIBUTE_FOR_MAIL}", | 
					
						
							|  |  |  |                 "cn", | 
					
						
							|  |  |  |             ], | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if not search_success: | 
					
						
							|  |  |  |             raise HTTPException(400, detail="User not found in the LDAP server") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         entry = connection_app.entries[0] | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         username = str(entry[f"{LDAP_ATTRIBUTE_FOR_USERNAME}"]).lower() | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |         mail = str(entry[f"{LDAP_ATTRIBUTE_FOR_MAIL}"]) | 
					
						
							|  |  |  |         if not mail or mail == "" or mail == "[]": | 
					
						
							|  |  |  |             raise HTTPException(400, f"User {form_data.user} does not have mail.") | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         cn = str(entry["cn"]) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |         user_dn = entry.entry_dn | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if username == form_data.user.lower(): | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |             connection_user = Connection( | 
					
						
							|  |  |  |                 server, | 
					
						
							|  |  |  |                 user_dn, | 
					
						
							|  |  |  |                 form_data.password, | 
					
						
							|  |  |  |                 auto_bind="NONE", | 
					
						
							|  |  |  |                 authentication="SIMPLE", | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |             if not connection_user.bind(): | 
					
						
							|  |  |  |                 raise HTTPException(400, f"Authentication failed for {form_data.user}") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             user = Users.get_user_by_email(mail) | 
					
						
							|  |  |  |             if not user: | 
					
						
							|  |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2025-02-16 16:11:18 +08:00
										 |  |  |                     user_count = Users.get_num_users() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-21 21:05:02 +08:00
										 |  |  |                     role = ( | 
					
						
							|  |  |  |                         "admin" | 
					
						
							| 
									
										
										
										
											2025-02-16 16:11:18 +08:00
										 |  |  |                         if user_count == 0 | 
					
						
							| 
									
										
										
										
											2024-11-21 21:05:02 +08:00
										 |  |  |                         else request.app.state.config.DEFAULT_USER_ROLE | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     user = Auths.insert_new_auth( | 
					
						
							| 
									
										
										
										
											2024-11-23 11:22:35 +08:00
										 |  |  |                         email=mail, password=str(uuid.uuid4()), name=cn, role=role | 
					
						
							| 
									
										
										
										
											2024-11-21 21:05:02 +08:00
										 |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     if not user: | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |                         raise HTTPException( | 
					
						
							|  |  |  |                             500, detail=ERROR_MESSAGES.CREATE_USER_ERROR | 
					
						
							|  |  |  |                         ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 except HTTPException: | 
					
						
							|  |  |  |                     raise | 
					
						
							|  |  |  |                 except Exception as err: | 
					
						
							|  |  |  |                     raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-21 21:05:02 +08:00
										 |  |  |             user = Auths.authenticate_user_by_trusted_header(mail) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if user: | 
					
						
							|  |  |  |                 token = create_token( | 
					
						
							|  |  |  |                     data={"id": user.id}, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |                     expires_delta=parse_duration( | 
					
						
							|  |  |  |                         request.app.state.config.JWT_EXPIRES_IN | 
					
						
							|  |  |  |                     ), | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # Set the cookie token | 
					
						
							|  |  |  |                 response.set_cookie( | 
					
						
							|  |  |  |                     key="token", | 
					
						
							|  |  |  |                     value=token, | 
					
						
							|  |  |  |                     httponly=True,  # Ensures the cookie is not accessible via JavaScript | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-28 22:51:21 +08:00
										 |  |  |                 user_permissions = get_permissions( | 
					
						
							|  |  |  |                     user.id, request.app.state.config.USER_PERMISSIONS | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |                 return { | 
					
						
							|  |  |  |                     "token": token, | 
					
						
							|  |  |  |                     "token_type": "Bearer", | 
					
						
							|  |  |  |                     "id": user.id, | 
					
						
							|  |  |  |                     "email": user.email, | 
					
						
							|  |  |  |                     "name": user.name, | 
					
						
							|  |  |  |                     "role": user.role, | 
					
						
							|  |  |  |                     "profile_image_url": user.profile_image_url, | 
					
						
							| 
									
										
										
										
											2025-01-28 22:51:21 +08:00
										 |  |  |                     "permissions": user_permissions, | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |                 } | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |             raise HTTPException( | 
					
						
							|  |  |  |                 400, | 
					
						
							|  |  |  |                 f"User {form_data.user} does not match the record. Search result: {str(entry[f'{LDAP_ATTRIBUTE_FOR_USERNAME}'])}", | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     except Exception as e: | 
					
						
							|  |  |  |         raise HTTPException(400, detail=str(e)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | # SignIn | 
					
						
							|  |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  | @router.post("/signin", response_model=SessionUserResponse) | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  | async def signin(request: Request, response: Response, form_data: SigninForm): | 
					
						
							| 
									
										
										
										
											2024-03-27 05:30:53 +08:00
										 |  |  |     if WEBUI_AUTH_TRUSTED_EMAIL_HEADER: | 
					
						
							|  |  |  |         if WEBUI_AUTH_TRUSTED_EMAIL_HEADER not in request.headers: | 
					
						
							| 
									
										
										
										
											2024-03-30 04:06:18 +08:00
										 |  |  |             raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_TRUSTED_HEADER) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 18:34:57 +08:00
										 |  |  |         trusted_email = request.headers[WEBUI_AUTH_TRUSTED_EMAIL_HEADER].lower() | 
					
						
							| 
									
										
										
										
											2024-06-16 04:04:11 +08:00
										 |  |  |         trusted_name = trusted_email | 
					
						
							|  |  |  |         if WEBUI_AUTH_TRUSTED_NAME_HEADER: | 
					
						
							| 
									
										
										
										
											2024-06-17 12:55:08 +08:00
										 |  |  |             trusted_name = request.headers.get( | 
					
						
							|  |  |  |                 WEBUI_AUTH_TRUSTED_NAME_HEADER, trusted_email | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-03-28 18:34:57 +08:00
										 |  |  |         if not Users.get_user_by_email(trusted_email.lower()): | 
					
						
							| 
									
										
										
										
											2024-03-30 04:06:18 +08:00
										 |  |  |             await signup( | 
					
						
							|  |  |  |                 request, | 
					
						
							| 
									
										
										
										
											2024-06-28 12:43:19 +08:00
										 |  |  |                 response, | 
					
						
							| 
									
										
										
										
											2024-03-30 04:06:18 +08:00
										 |  |  |                 SignupForm( | 
					
						
							| 
									
										
										
										
											2024-06-16 04:04:11 +08:00
										 |  |  |                     email=trusted_email, password=str(uuid.uuid4()), name=trusted_name | 
					
						
							| 
									
										
										
										
											2024-03-30 04:06:18 +08:00
										 |  |  |                 ), | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-03-27 05:30:53 +08:00
										 |  |  |         user = Auths.authenticate_user_by_trusted_header(trusted_email) | 
					
						
							| 
									
										
										
										
											2024-05-09 08:17:21 +08:00
										 |  |  |     elif WEBUI_AUTH == False: | 
					
						
							|  |  |  |         admin_email = "admin@localhost" | 
					
						
							|  |  |  |         admin_password = "admin" | 
					
						
							| 
									
										
										
										
											2024-05-09 07:19:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-09 08:17:21 +08:00
										 |  |  |         if Users.get_user_by_email(admin_email.lower()): | 
					
						
							|  |  |  |             user = Auths.authenticate_user(admin_email.lower(), admin_password) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             if Users.get_num_users() != 0: | 
					
						
							|  |  |  |                 raise HTTPException(400, detail=ERROR_MESSAGES.EXISTING_USERS) | 
					
						
							| 
									
										
										
										
											2024-05-09 08:15:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-09 08:17:21 +08:00
										 |  |  |             await signup( | 
					
						
							|  |  |  |                 request, | 
					
						
							| 
									
										
										
										
											2024-06-28 12:44:35 +08:00
										 |  |  |                 response, | 
					
						
							| 
									
										
										
										
											2024-05-09 08:17:21 +08:00
										 |  |  |                 SignupForm(email=admin_email, password=admin_password, name="User"), | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-05-09 07:42:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-09 08:17:21 +08:00
										 |  |  |             user = Auths.authenticate_user(admin_email.lower(), admin_password) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         user = Auths.authenticate_user(form_data.email.lower(), form_data.password) | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if user: | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) | 
					
						
							|  |  |  |         expires_at = None | 
					
						
							|  |  |  |         if expires_delta: | 
					
						
							|  |  |  |             expires_at = int(time.time()) + int(expires_delta.total_seconds()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 12:44:00 +08:00
										 |  |  |         token = create_token( | 
					
						
							|  |  |  |             data={"id": user.id}, | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |             expires_delta=expires_delta, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-15 17:51:08 +08:00
										 |  |  |         datetime_expires_at = ( | 
					
						
							|  |  |  |             datetime.datetime.fromtimestamp(expires_at, datetime.timezone.utc) | 
					
						
							|  |  |  |             if expires_at | 
					
						
							|  |  |  |             else None | 
					
						
							| 
									
										
										
										
											2024-02-20 12:44:00 +08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  |         # Set the cookie token | 
					
						
							|  |  |  |         response.set_cookie( | 
					
						
							|  |  |  |             key="token", | 
					
						
							|  |  |  |             value=token, | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |             expires=datetime_expires_at, | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  |             httponly=True,  # Ensures the cookie is not accessible via JavaScript | 
					
						
							| 
									
										
										
										
											2025-01-23 22:16:50 +08:00
										 |  |  |             samesite=WEBUI_AUTH_COOKIE_SAME_SITE, | 
					
						
							|  |  |  |             secure=WEBUI_AUTH_COOKIE_SECURE, | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         user_permissions = get_permissions( | 
					
						
							|  |  |  |             user.id, request.app.state.config.USER_PERMISSIONS | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  |         return { | 
					
						
							|  |  |  |             "token": token, | 
					
						
							|  |  |  |             "token_type": "Bearer", | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |             "expires_at": expires_at, | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  |             "id": user.id, | 
					
						
							|  |  |  |             "email": user.email, | 
					
						
							|  |  |  |             "name": user.name, | 
					
						
							|  |  |  |             "role": user.role, | 
					
						
							| 
									
										
										
										
											2023-11-19 13:41:43 +08:00
										 |  |  |             "profile_image_url": user.profile_image_url, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |             "permissions": user_permissions, | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2023-11-19 13:41:43 +08:00
										 |  |  |         raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) | 
					
						
							| 
									
										
										
										
											2023-11-19 08:47:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ############################ | 
					
						
							|  |  |  | # SignUp | 
					
						
							|  |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  | @router.post("/signup", response_model=SessionUserResponse) | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  | async def signup(request: Request, response: Response, form_data: SignupForm): | 
					
						
							| 
									
										
										
										
											2025-02-16 16:11:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-21 21:35:35 +08:00
										 |  |  |     if WEBUI_AUTH: | 
					
						
							| 
									
										
										
										
											2024-09-21 21:33:34 +08:00
										 |  |  |         if ( | 
					
						
							|  |  |  |             not request.app.state.config.ENABLE_SIGNUP | 
					
						
							|  |  |  |             or not request.app.state.config.ENABLE_LOGIN_FORM | 
					
						
							|  |  |  |         ): | 
					
						
							|  |  |  |             raise HTTPException( | 
					
						
							|  |  |  |                 status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-09-21 21:35:35 +08:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2025-02-18 11:29:28 +08:00
										 |  |  |         if Users.get_num_users() != 0: | 
					
						
							| 
									
										
										
										
											2024-09-21 21:35:35 +08:00
										 |  |  |             raise HTTPException( | 
					
						
							|  |  |  |                 status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-18 11:29:28 +08:00
										 |  |  |     user_count = Users.get_num_users() | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |     if not validate_email_format(form_data.email.lower()): | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  |         raise HTTPException( | 
					
						
							|  |  |  |             status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |     if Users.get_user_by_email(form_data.email.lower()): | 
					
						
							|  |  |  |         raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  |         role = ( | 
					
						
							| 
									
										
										
										
											2025-02-16 16:11:18 +08:00
										 |  |  |             "admin" if user_count == 0 else request.app.state.config.DEFAULT_USER_ROLE | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-11-03 17:25:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-16 16:11:18 +08:00
										 |  |  |         if user_count == 0: | 
					
						
							| 
									
										
										
										
											2024-11-03 17:25:41 +08:00
										 |  |  |             # Disable signup after the first user is created | 
					
						
							|  |  |  |             request.app.state.config.ENABLE_SIGNUP = False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |         hashed = get_password_hash(form_data.password) | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  |         user = Auths.insert_new_auth( | 
					
						
							| 
									
										
										
										
											2024-04-04 16:10:51 +08:00
										 |  |  |             form_data.email.lower(), | 
					
						
							|  |  |  |             hashed, | 
					
						
							|  |  |  |             form_data.name, | 
					
						
							|  |  |  |             form_data.profile_image_url, | 
					
						
							|  |  |  |             role, | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-01-02 04:32:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |         if user: | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |             expires_delta = parse_duration(request.app.state.config.JWT_EXPIRES_IN) | 
					
						
							|  |  |  |             expires_at = None | 
					
						
							|  |  |  |             if expires_delta: | 
					
						
							|  |  |  |                 expires_at = int(time.time()) + int(expires_delta.total_seconds()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 12:44:00 +08:00
										 |  |  |             token = create_token( | 
					
						
							|  |  |  |                 data={"id": user.id}, | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |                 expires_delta=expires_delta, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-15 17:51:08 +08:00
										 |  |  |             datetime_expires_at = ( | 
					
						
							|  |  |  |                 datetime.datetime.fromtimestamp(expires_at, datetime.timezone.utc) | 
					
						
							|  |  |  |                 if expires_at | 
					
						
							|  |  |  |                 else None | 
					
						
							| 
									
										
										
										
											2024-02-20 12:44:00 +08:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  |             # Set the cookie token | 
					
						
							|  |  |  |             response.set_cookie( | 
					
						
							|  |  |  |                 key="token", | 
					
						
							|  |  |  |                 value=token, | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |                 expires=datetime_expires_at, | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  |                 httponly=True,  # Ensures the cookie is not accessible via JavaScript | 
					
						
							| 
									
										
										
										
											2025-01-23 22:16:50 +08:00
										 |  |  |                 samesite=WEBUI_AUTH_COOKIE_SAME_SITE, | 
					
						
							|  |  |  |                 secure=WEBUI_AUTH_COOKIE_SECURE, | 
					
						
							| 
									
										
										
										
											2024-06-21 04:14:58 +08:00
										 |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-10 15:03:24 +08:00
										 |  |  |             if request.app.state.config.WEBHOOK_URL: | 
					
						
							| 
									
										
										
										
											2024-03-21 09:35:02 +08:00
										 |  |  |                 post_webhook( | 
					
						
							| 
									
										
										
										
											2025-02-16 16:11:18 +08:00
										 |  |  |                     request.app.state.WEBUI_NAME, | 
					
						
							| 
									
										
										
										
											2024-05-10 15:03:24 +08:00
										 |  |  |                     request.app.state.config.WEBHOOK_URL, | 
					
						
							| 
									
										
										
										
											2024-03-21 09:47:13 +08:00
										 |  |  |                     WEBHOOK_MESSAGES.USER_SIGNUP(user.name), | 
					
						
							| 
									
										
										
										
											2024-03-21 09:35:02 +08:00
										 |  |  |                     { | 
					
						
							|  |  |  |                         "action": "signup", | 
					
						
							|  |  |  |                         "message": WEBHOOK_MESSAGES.USER_SIGNUP(user.name), | 
					
						
							|  |  |  |                         "user": user.model_dump_json(exclude_none=True), | 
					
						
							|  |  |  |                     }, | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |             user_permissions = get_permissions( | 
					
						
							|  |  |  |                 user.id, request.app.state.config.USER_PERMISSIONS | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |             return { | 
					
						
							|  |  |  |                 "token": token, | 
					
						
							|  |  |  |                 "token_type": "Bearer", | 
					
						
							| 
									
										
										
										
											2024-10-15 17:48:41 +08:00
										 |  |  |                 "expires_at": expires_at, | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |                 "id": user.id, | 
					
						
							|  |  |  |                 "email": user.email, | 
					
						
							|  |  |  |                 "name": user.name, | 
					
						
							|  |  |  |                 "role": user.role, | 
					
						
							|  |  |  |                 "profile_image_url": user.profile_image_url, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |                 "permissions": user_permissions, | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |             } | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  |             raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) | 
					
						
							| 
									
										
										
										
											2024-05-02 08:55:18 +08:00
										 |  |  |     except Exception as err: | 
					
						
							|  |  |  |         raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 04:35:29 +08:00
										 |  |  | @router.get("/signout") | 
					
						
							| 
									
										
										
										
											2024-12-07 20:49:12 +08:00
										 |  |  | async def signout(request: Request, response: Response): | 
					
						
							| 
									
										
										
										
											2024-10-25 04:35:29 +08:00
										 |  |  |     response.delete_cookie("token") | 
					
						
							| 
									
										
										
										
											2024-12-07 22:13:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-07 22:21:05 +08:00
										 |  |  |     if ENABLE_OAUTH_SIGNUP.value: | 
					
						
							| 
									
										
										
										
											2024-12-10 08:25:56 +08:00
										 |  |  |         oauth_id_token = request.cookies.get("oauth_id_token") | 
					
						
							|  |  |  |         if oauth_id_token: | 
					
						
							| 
									
										
										
										
											2024-12-08 11:57:57 +08:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 async with ClientSession() as session: | 
					
						
							|  |  |  |                     async with session.get(OPENID_PROVIDER_URL.value) as resp: | 
					
						
							|  |  |  |                         if resp.status == 200: | 
					
						
							|  |  |  |                             openid_data = await resp.json() | 
					
						
							|  |  |  |                             logout_url = openid_data.get("end_session_endpoint") | 
					
						
							|  |  |  |                             if logout_url: | 
					
						
							| 
									
										
										
										
											2024-12-10 08:25:56 +08:00
										 |  |  |                                 response.delete_cookie("oauth_id_token") | 
					
						
							|  |  |  |                                 return RedirectResponse( | 
					
						
							| 
									
										
										
										
											2025-02-09 13:37:24 +08:00
										 |  |  |                                     headers=response.headers, | 
					
						
							| 
									
										
										
										
											2025-02-20 17:01:29 +08:00
										 |  |  |                                     url=f"{logout_url}?id_token_hint={oauth_id_token}", | 
					
						
							| 
									
										
										
										
											2024-12-10 08:25:56 +08:00
										 |  |  |                                 ) | 
					
						
							| 
									
										
										
										
											2024-12-08 11:57:57 +08:00
										 |  |  |                         else: | 
					
						
							|  |  |  |                             raise HTTPException( | 
					
						
							|  |  |  |                                 status_code=resp.status, | 
					
						
							| 
									
										
										
										
											2024-12-10 08:25:56 +08:00
										 |  |  |                                 detail="Failed to fetch OpenID configuration", | 
					
						
							| 
									
										
										
										
											2024-12-08 11:57:57 +08:00
										 |  |  |                             ) | 
					
						
							|  |  |  |             except Exception as e: | 
					
						
							|  |  |  |                 raise HTTPException(status_code=500, detail=str(e)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 04:35:29 +08:00
										 |  |  |     return {"status": True} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 08:55:18 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | # AddUser | 
					
						
							|  |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @router.post("/add", response_model=SigninResponse) | 
					
						
							| 
									
										
										
										
											2024-05-02 10:02:25 +08:00
										 |  |  | async def add_user(form_data: AddUserForm, user=Depends(get_admin_user)): | 
					
						
							| 
									
										
										
										
											2024-05-02 08:55:18 +08:00
										 |  |  |     if not validate_email_format(form_data.email.lower()): | 
					
						
							|  |  |  |         raise HTTPException( | 
					
						
							|  |  |  |             status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if Users.get_user_by_email(form_data.email.lower()): | 
					
						
							|  |  |  |         raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         hashed = get_password_hash(form_data.password) | 
					
						
							|  |  |  |         user = Auths.insert_new_auth( | 
					
						
							|  |  |  |             form_data.email.lower(), | 
					
						
							|  |  |  |             hashed, | 
					
						
							|  |  |  |             form_data.name, | 
					
						
							|  |  |  |             form_data.profile_image_url, | 
					
						
							| 
									
										
										
										
											2024-05-02 09:06:02 +08:00
										 |  |  |             form_data.role, | 
					
						
							| 
									
										
										
										
											2024-05-02 08:55:18 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if user: | 
					
						
							|  |  |  |             token = create_token(data={"id": user.id}) | 
					
						
							|  |  |  |             return { | 
					
						
							|  |  |  |                 "token": token, | 
					
						
							|  |  |  |                 "token_type": "Bearer", | 
					
						
							|  |  |  |                 "id": user.id, | 
					
						
							|  |  |  |                 "email": user.email, | 
					
						
							|  |  |  |                 "name": user.name, | 
					
						
							|  |  |  |                 "role": user.role, | 
					
						
							|  |  |  |                 "profile_image_url": user.profile_image_url, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) | 
					
						
							| 
									
										
										
										
											2024-01-20 22:54:53 +08:00
										 |  |  |     except Exception as err: | 
					
						
							| 
									
										
										
										
											2024-01-27 12:27:45 +08:00
										 |  |  |         raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-02 04:32:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ############################ | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  | # GetAdminDetails | 
					
						
							| 
									
										
										
										
											2024-01-02 04:32:28 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  | @router.get("/admin/details") | 
					
						
							|  |  |  | async def get_admin_details(request: Request, user=Depends(get_current_user)): | 
					
						
							|  |  |  |     if request.app.state.config.SHOW_ADMIN_DETAILS: | 
					
						
							|  |  |  |         admin_email = request.app.state.config.ADMIN_EMAIL | 
					
						
							|  |  |  |         admin_name = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 22:36:25 +08:00
										 |  |  |         log.info(f"Admin details - Email: {admin_email}, Name: {admin_name}") | 
					
						
							| 
									
										
										
										
											2024-01-02 04:32:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |         if admin_email: | 
					
						
							|  |  |  |             admin = Users.get_user_by_email(admin_email) | 
					
						
							|  |  |  |             if admin: | 
					
						
							|  |  |  |                 admin_name = admin.name | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             admin = Users.get_first_user() | 
					
						
							|  |  |  |             if admin: | 
					
						
							|  |  |  |                 admin_email = admin.email | 
					
						
							|  |  |  |                 admin_name = admin.name | 
					
						
							| 
									
										
										
										
											2024-01-02 04:32:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |         return { | 
					
						
							|  |  |  |             "name": admin_name, | 
					
						
							|  |  |  |             "email": admin_email, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         raise HTTPException(400, detail=ERROR_MESSAGES.ACTION_PROHIBITED) | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ############################ | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  | # ToggleSignUp | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  | @router.get("/admin/config") | 
					
						
							|  |  |  | async def get_admin_config(request: Request, user=Depends(get_admin_user)): | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |         "SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS, | 
					
						
							| 
									
										
										
										
											2024-12-26 00:50:57 +08:00
										 |  |  |         "WEBUI_URL": request.app.state.config.WEBUI_URL, | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |         "ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP, | 
					
						
							| 
									
										
										
										
											2024-11-20 04:17:23 +08:00
										 |  |  |         "ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY, | 
					
						
							| 
									
										
										
										
											2024-12-27 12:57:51 +08:00
										 |  |  |         "ENABLE_API_KEY_ENDPOINT_RESTRICTIONS": request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS, | 
					
						
							|  |  |  |         "API_KEY_ALLOWED_ENDPOINTS": request.app.state.config.API_KEY_ALLOWED_ENDPOINTS, | 
					
						
							| 
									
										
										
										
											2024-12-23 12:02:14 +08:00
										 |  |  |         "ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS, | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |         "DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE, | 
					
						
							|  |  |  |         "JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN, | 
					
						
							|  |  |  |         "ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING, | 
					
						
							| 
									
										
										
										
											2024-08-19 21:16:49 +08:00
										 |  |  |         "ENABLE_MESSAGE_RATING": request.app.state.config.ENABLE_MESSAGE_RATING, | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  | class AdminConfig(BaseModel): | 
					
						
							|  |  |  |     SHOW_ADMIN_DETAILS: bool | 
					
						
							| 
									
										
										
										
											2024-12-26 00:50:57 +08:00
										 |  |  |     WEBUI_URL: str | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     ENABLE_SIGNUP: bool | 
					
						
							| 
									
										
										
										
											2024-11-20 04:17:23 +08:00
										 |  |  |     ENABLE_API_KEY: bool | 
					
						
							| 
									
										
										
										
											2024-12-27 12:57:51 +08:00
										 |  |  |     ENABLE_API_KEY_ENDPOINT_RESTRICTIONS: bool | 
					
						
							|  |  |  |     API_KEY_ALLOWED_ENDPOINTS: str | 
					
						
							| 
									
										
										
										
											2024-12-23 12:02:14 +08:00
										 |  |  |     ENABLE_CHANNELS: bool | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     DEFAULT_USER_ROLE: str | 
					
						
							|  |  |  |     JWT_EXPIRES_IN: str | 
					
						
							|  |  |  |     ENABLE_COMMUNITY_SHARING: bool | 
					
						
							| 
									
										
										
										
											2024-08-19 21:16:49 +08:00
										 |  |  |     ENABLE_MESSAGE_RATING: bool | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  | @router.post("/admin/config") | 
					
						
							|  |  |  | async def update_admin_config( | 
					
						
							|  |  |  |     request: Request, form_data: AdminConfig, user=Depends(get_admin_user) | 
					
						
							| 
									
										
										
										
											2024-02-14 17:17:43 +08:00
										 |  |  | ): | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     request.app.state.config.SHOW_ADMIN_DETAILS = form_data.SHOW_ADMIN_DETAILS | 
					
						
							| 
									
										
										
										
											2024-12-26 00:50:57 +08:00
										 |  |  |     request.app.state.config.WEBUI_URL = form_data.WEBUI_URL | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     request.app.state.config.ENABLE_SIGNUP = form_data.ENABLE_SIGNUP | 
					
						
							| 
									
										
										
										
											2024-12-27 12:57:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-20 04:17:23 +08:00
										 |  |  |     request.app.state.config.ENABLE_API_KEY = form_data.ENABLE_API_KEY | 
					
						
							| 
									
										
										
										
											2024-12-27 12:57:51 +08:00
										 |  |  |     request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS = ( | 
					
						
							|  |  |  |         form_data.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     request.app.state.config.API_KEY_ALLOWED_ENDPOINTS = ( | 
					
						
							|  |  |  |         form_data.API_KEY_ALLOWED_ENDPOINTS | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 12:02:14 +08:00
										 |  |  |     request.app.state.config.ENABLE_CHANNELS = form_data.ENABLE_CHANNELS | 
					
						
							| 
									
										
										
										
											2024-02-20 12:44:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     if form_data.DEFAULT_USER_ROLE in ["pending", "user", "admin"]: | 
					
						
							|  |  |  |         request.app.state.config.DEFAULT_USER_ROLE = form_data.DEFAULT_USER_ROLE | 
					
						
							| 
									
										
										
										
											2024-02-20 12:44:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     pattern = r"^(-1|0|(-?\d+(\.\d+)?)(ms|s|m|h|d|w))$" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Check if the input string matches the pattern | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     if re.match(pattern, form_data.JWT_EXPIRES_IN): | 
					
						
							|  |  |  |         request.app.state.config.JWT_EXPIRES_IN = form_data.JWT_EXPIRES_IN | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     request.app.state.config.ENABLE_COMMUNITY_SHARING = ( | 
					
						
							|  |  |  |         form_data.ENABLE_COMMUNITY_SHARING | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-19 21:16:49 +08:00
										 |  |  |     request.app.state.config.ENABLE_MESSAGE_RATING = form_data.ENABLE_MESSAGE_RATING | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |         "SHOW_ADMIN_DETAILS": request.app.state.config.SHOW_ADMIN_DETAILS, | 
					
						
							| 
									
										
										
										
											2024-12-26 00:50:57 +08:00
										 |  |  |         "WEBUI_URL": request.app.state.config.WEBUI_URL, | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |         "ENABLE_SIGNUP": request.app.state.config.ENABLE_SIGNUP, | 
					
						
							| 
									
										
										
										
											2024-11-20 04:17:23 +08:00
										 |  |  |         "ENABLE_API_KEY": request.app.state.config.ENABLE_API_KEY, | 
					
						
							| 
									
										
										
										
											2024-12-27 12:57:51 +08:00
										 |  |  |         "ENABLE_API_KEY_ENDPOINT_RESTRICTIONS": request.app.state.config.ENABLE_API_KEY_ENDPOINT_RESTRICTIONS, | 
					
						
							|  |  |  |         "API_KEY_ALLOWED_ENDPOINTS": request.app.state.config.API_KEY_ALLOWED_ENDPOINTS, | 
					
						
							| 
									
										
										
										
											2024-12-26 00:50:57 +08:00
										 |  |  |         "ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS, | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |         "DEFAULT_USER_ROLE": request.app.state.config.DEFAULT_USER_ROLE, | 
					
						
							|  |  |  |         "JWT_EXPIRES_IN": request.app.state.config.JWT_EXPIRES_IN, | 
					
						
							|  |  |  |         "ENABLE_COMMUNITY_SHARING": request.app.state.config.ENABLE_COMMUNITY_SHARING, | 
					
						
							| 
									
										
										
										
											2024-08-19 21:16:49 +08:00
										 |  |  |         "ENABLE_MESSAGE_RATING": request.app.state.config.ENABLE_MESSAGE_RATING, | 
					
						
							| 
									
										
										
										
											2024-06-04 12:17:43 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-03-26 18:22:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | class LdapServerConfig(BaseModel): | 
					
						
							|  |  |  |     label: str | 
					
						
							|  |  |  |     host: str | 
					
						
							|  |  |  |     port: Optional[int] = None | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |     attribute_for_mail: str = "mail" | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     attribute_for_username: str = "uid" | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     app_dn: str | 
					
						
							|  |  |  |     app_dn_password: str | 
					
						
							|  |  |  |     search_base: str | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     search_filters: str = "" | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     use_tls: bool = True | 
					
						
							|  |  |  |     certificate_path: Optional[str] = None | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     ciphers: Optional[str] = "ALL" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | @router.get("/admin/config/ldap/server", response_model=LdapServerConfig) | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  | async def get_ldap_server(request: Request, user=Depends(get_admin_user)): | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     return { | 
					
						
							|  |  |  |         "label": request.app.state.config.LDAP_SERVER_LABEL, | 
					
						
							|  |  |  |         "host": request.app.state.config.LDAP_SERVER_HOST, | 
					
						
							|  |  |  |         "port": request.app.state.config.LDAP_SERVER_PORT, | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |         "attribute_for_mail": request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL, | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |         "attribute_for_username": request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME, | 
					
						
							|  |  |  |         "app_dn": request.app.state.config.LDAP_APP_DN, | 
					
						
							|  |  |  |         "app_dn_password": request.app.state.config.LDAP_APP_PASSWORD, | 
					
						
							|  |  |  |         "search_base": request.app.state.config.LDAP_SEARCH_BASE, | 
					
						
							|  |  |  |         "search_filters": request.app.state.config.LDAP_SEARCH_FILTERS, | 
					
						
							|  |  |  |         "use_tls": request.app.state.config.LDAP_USE_TLS, | 
					
						
							|  |  |  |         "certificate_path": request.app.state.config.LDAP_CA_CERT_FILE, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         "ciphers": request.app.state.config.LDAP_CIPHERS, | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | @router.post("/admin/config/ldap/server") | 
					
						
							|  |  |  | async def update_ldap_server( | 
					
						
							|  |  |  |     request: Request, form_data: LdapServerConfig, user=Depends(get_admin_user) | 
					
						
							|  |  |  | ): | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     required_fields = [ | 
					
						
							|  |  |  |         "label", | 
					
						
							|  |  |  |         "host", | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |         "attribute_for_mail", | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         "attribute_for_username", | 
					
						
							|  |  |  |         "app_dn", | 
					
						
							|  |  |  |         "app_dn_password", | 
					
						
							|  |  |  |         "search_base", | 
					
						
							|  |  |  |     ] | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     for key in required_fields: | 
					
						
							|  |  |  |         value = getattr(form_data, key) | 
					
						
							|  |  |  |         if not value: | 
					
						
							|  |  |  |             raise HTTPException(400, detail=f"Required field {key} is empty") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if form_data.use_tls and not form_data.certificate_path: | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         raise HTTPException( | 
					
						
							|  |  |  |             400, detail="TLS is enabled but certificate file path is missing" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     request.app.state.config.LDAP_SERVER_LABEL = form_data.label | 
					
						
							|  |  |  |     request.app.state.config.LDAP_SERVER_HOST = form_data.host | 
					
						
							|  |  |  |     request.app.state.config.LDAP_SERVER_PORT = form_data.port | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |     request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL = form_data.attribute_for_mail | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |     request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME = ( | 
					
						
							|  |  |  |         form_data.attribute_for_username | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     request.app.state.config.LDAP_APP_DN = form_data.app_dn | 
					
						
							|  |  |  |     request.app.state.config.LDAP_APP_PASSWORD = form_data.app_dn_password | 
					
						
							|  |  |  |     request.app.state.config.LDAP_SEARCH_BASE = form_data.search_base | 
					
						
							|  |  |  |     request.app.state.config.LDAP_SEARCH_FILTERS = form_data.search_filters | 
					
						
							|  |  |  |     request.app.state.config.LDAP_USE_TLS = form_data.use_tls | 
					
						
							|  |  |  |     request.app.state.config.LDAP_CA_CERT_FILE = form_data.certificate_path | 
					
						
							|  |  |  |     request.app.state.config.LDAP_CIPHERS = form_data.ciphers | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |         "label": request.app.state.config.LDAP_SERVER_LABEL, | 
					
						
							|  |  |  |         "host": request.app.state.config.LDAP_SERVER_HOST, | 
					
						
							|  |  |  |         "port": request.app.state.config.LDAP_SERVER_PORT, | 
					
						
							| 
									
										
										
										
											2025-01-10 08:53:03 +08:00
										 |  |  |         "attribute_for_mail": request.app.state.config.LDAP_ATTRIBUTE_FOR_MAIL, | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |         "attribute_for_username": request.app.state.config.LDAP_ATTRIBUTE_FOR_USERNAME, | 
					
						
							|  |  |  |         "app_dn": request.app.state.config.LDAP_APP_DN, | 
					
						
							|  |  |  |         "app_dn_password": request.app.state.config.LDAP_APP_PASSWORD, | 
					
						
							|  |  |  |         "search_base": request.app.state.config.LDAP_SEARCH_BASE, | 
					
						
							|  |  |  |         "search_filters": request.app.state.config.LDAP_SEARCH_FILTERS, | 
					
						
							|  |  |  |         "use_tls": request.app.state.config.LDAP_USE_TLS, | 
					
						
							|  |  |  |         "certificate_path": request.app.state.config.LDAP_CA_CERT_FILE, | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  |         "ciphers": request.app.state.config.LDAP_CIPHERS, | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | @router.get("/admin/config/ldap") | 
					
						
							|  |  |  | async def get_ldap_config(request: Request, user=Depends(get_admin_user)): | 
					
						
							|  |  |  |     return {"ENABLE_LDAP": request.app.state.config.ENABLE_LDAP} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | class LdapConfigForm(BaseModel): | 
					
						
							|  |  |  |     enable_ldap: Optional[bool] = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  | @router.post("/admin/config/ldap") | 
					
						
							| 
									
										
										
										
											2024-11-17 13:07:56 +08:00
										 |  |  | async def update_ldap_config( | 
					
						
							|  |  |  |     request: Request, form_data: LdapConfigForm, user=Depends(get_admin_user) | 
					
						
							|  |  |  | ): | 
					
						
							| 
									
										
										
										
											2024-11-06 06:20:54 +08:00
										 |  |  |     request.app.state.config.ENABLE_LDAP = form_data.enable_ldap | 
					
						
							|  |  |  |     return {"ENABLE_LDAP": request.app.state.config.ENABLE_LDAP} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 18:22:17 +08:00
										 |  |  | ############################ | 
					
						
							|  |  |  | # API Key | 
					
						
							|  |  |  | ############################ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # create api key | 
					
						
							|  |  |  | @router.post("/api_key", response_model=ApiKey) | 
					
						
							| 
									
										
										
										
											2024-11-20 10:21:55 +08:00
										 |  |  | async def generate_api_key(request: Request, user=Depends(get_current_user)): | 
					
						
							| 
									
										
										
										
											2024-11-20 10:17:38 +08:00
										 |  |  |     if not request.app.state.config.ENABLE_API_KEY: | 
					
						
							| 
									
										
										
										
											2024-11-19 22:14:52 +08:00
										 |  |  |         raise HTTPException( | 
					
						
							| 
									
										
										
										
											2024-11-20 04:17:23 +08:00
										 |  |  |             status.HTTP_403_FORBIDDEN, | 
					
						
							|  |  |  |             detail=ERROR_MESSAGES.API_KEY_CREATION_NOT_ALLOWED, | 
					
						
							| 
									
										
										
										
											2024-11-19 22:14:52 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 18:22:17 +08:00
										 |  |  |     api_key = create_api_key() | 
					
						
							| 
									
										
										
										
											2024-04-03 00:27:35 +08:00
										 |  |  |     success = Users.update_user_api_key_by_id(user.id, api_key) | 
					
						
							| 
									
										
										
										
											2024-11-20 04:17:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-26 18:22:17 +08:00
										 |  |  |     if success: | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             "api_key": api_key, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_API_KEY_ERROR) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # delete api key | 
					
						
							|  |  |  | @router.delete("/api_key", response_model=bool) | 
					
						
							|  |  |  | async def delete_api_key(user=Depends(get_current_user)): | 
					
						
							| 
									
										
										
										
											2024-04-03 00:27:35 +08:00
										 |  |  |     success = Users.update_user_api_key_by_id(user.id, None) | 
					
						
							| 
									
										
										
										
											2024-03-26 18:22:17 +08:00
										 |  |  |     return success | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # get api key | 
					
						
							|  |  |  | @router.get("/api_key", response_model=ApiKey) | 
					
						
							|  |  |  | async def get_api_key(user=Depends(get_current_user)): | 
					
						
							| 
									
										
										
										
											2024-04-03 00:27:35 +08:00
										 |  |  |     api_key = Users.get_user_api_key_by_id(user.id) | 
					
						
							| 
									
										
										
										
											2024-03-26 18:22:17 +08:00
										 |  |  |     if api_key: | 
					
						
							|  |  |  |         return { | 
					
						
							|  |  |  |             "api_key": api_key, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         raise HTTPException(404, detail=ERROR_MESSAGES.API_KEY_NOT_FOUND) |