22from fastapi import APIRouter , Depends , HTTPException , Request
33from fastapi .security import OAuth2PasswordRequestForm
44from apps .system .schemas .logout_schema import LogoutSchema
5- from apps .system .schemas .system_schema import BaseUserDTO
5+ from apps .system .schemas .system_schema import BaseUserDTO , LoginPwdEditor
66from common .core .deps import SessionDep , Trans
77from common .utils .crypto import sqlbot_decrypt
8- from ..crud .user import authenticate
9- from common .core .security import create_access_token
8+ from ..crud .user import authenticate , check_pwd_format , clean_user_cache , get_db_user
9+ from common .core .security import create_access_token , default_pwd , md5pwd , verify_md5pwd
1010from datetime import timedelta
1111from common .core .config import settings
1212from common .core .schemas import Token
1313from sqlbot_xpack .authentication .manage import logout as xpack_logout
14+ from sqlbot_xpack .config .arg_manage import get_group_args
1415
1516from common .audit .models .log_model import OperationType , OperationModules
1617from common .audit .schemas .logger_decorator import system_log , LogConfig
1718
1819router = APIRouter (tags = ["login" ], prefix = "/login" )
1920
21+
22+ async def initial_pwd_disabled (session ) -> bool :
23+ login_args = await get_group_args (session = session , flag = 'login' )
24+ disabled_arg = next ((a for a in login_args if a .pkey == 'login.initial_pwd_disabled' ), None )
25+ return bool (disabled_arg and str (disabled_arg .pval ).strip ().lower () == 'true' )
26+
27+
2028@router .post ("/access-token" )
2129@system_log (LogConfig (
2230 operation_type = OperationType .LOGIN ,
@@ -39,13 +47,46 @@ async def local_login(
3947 raise HTTPException (status_code = 400 , detail = trans ('i18n_login.user_disable' , msg = trans ('i18n_concat_admin' )))
4048 if user .origin is not None and user .origin != 0 :
4149 raise HTTPException (status_code = 400 , detail = trans ('i18n_login.origin_error' ))
50+ if (
51+ user .id != 1
52+ and await initial_pwd_disabled (session )
53+ and verify_md5pwd (default_pwd (), user .password )
54+ ):
55+ return Token (access_token = '' , need_change_pwd = True )
4256 access_token_expires = timedelta (minutes = settings .ACCESS_TOKEN_EXPIRE_MINUTES )
4357 user_dict = user .to_dict ()
44- return Token (access_token = create_access_token (
45- user_dict , expires_delta = access_token_expires
46- ))
58+ return Token (
59+ access_token = create_access_token (user_dict , expires_delta = access_token_expires ),
60+ need_change_pwd = False ,
61+ )
62+
63+
64+ @router .post ("/change-pwd" )
65+ @system_log (LogConfig (
66+ operation_type = OperationType .UPDATE_PWD ,
67+ module = OperationModules .USER ,
68+ result_id_expr = "id"
69+ ))
70+ async def login_change_pwd (session : SessionDep , trans : Trans , editor : LoginPwdEditor ):
71+ origin_account = await sqlbot_decrypt (editor .account )
72+ origin_pwd = await sqlbot_decrypt (editor .pwd )
73+ new_pwd = await sqlbot_decrypt (editor .new_pwd )
74+ user : BaseUserDTO = authenticate (session = session , account = origin_account , password = origin_pwd )
75+ if not user :
76+ raise HTTPException (status_code = 400 , detail = trans ('i18n_login.account_pwd_error' ))
77+ if user .origin is not None and user .origin != 0 :
78+ raise HTTPException (status_code = 400 , detail = trans ('i18n_login.origin_error' ))
79+ if not check_pwd_format (new_pwd ):
80+ raise HTTPException (status_code = 400 , detail = trans ('i18n_format_invalid' , key = trans ('i18n_user.password' )))
81+ if await initial_pwd_disabled (session ) and new_pwd == default_pwd ():
82+ raise HTTPException (status_code = 400 , detail = trans ('i18n_login.new_pwd_is_initial' ))
83+ db_user = get_db_user (session = session , user_id = user .id )
84+ db_user .password = md5pwd (new_pwd )
85+ session .add (db_user )
86+ await clean_user_cache (user .id )
87+ return db_user
4788
48- @router .post ("/logout" )
89+ @router .post ("/logout" )
4990async def logout (session : SessionDep , request : Request , dto : LogoutSchema ):
5091 if dto .origin != 0 :
5192 return await xpack_logout (session , request , dto )
0 commit comments