mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 17:26:55 +08:00
Add config to hide default passwords or force password change at first login #1355
This commit is contained in:
committed by
fit2cloud-chenyw
parent
c1d333e62d
commit
4ee923c968
@@ -2,21 +2,29 @@ from typing import Annotated
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
from apps.system.schemas.logout_schema import LogoutSchema
|
||||
from apps.system.schemas.system_schema import BaseUserDTO
|
||||
from apps.system.schemas.system_schema import BaseUserDTO, LoginPwdEditor
|
||||
from common.core.deps import SessionDep, Trans
|
||||
from common.utils.crypto import sqlbot_decrypt
|
||||
from ..crud.user import authenticate
|
||||
from common.core.security import create_access_token
|
||||
from ..crud.user import authenticate, check_pwd_format, clean_user_cache, get_db_user
|
||||
from common.core.security import create_access_token, default_pwd, md5pwd, verify_md5pwd
|
||||
from datetime import timedelta
|
||||
from common.core.config import settings
|
||||
from common.core.schemas import Token
|
||||
from sqlbot_xpack.authentication.manage import logout as xpack_logout
|
||||
from sqlbot_xpack.config.arg_manage import get_group_args
|
||||
|
||||
from common.audit.models.log_model import OperationType, OperationModules
|
||||
from common.audit.schemas.logger_decorator import system_log, LogConfig
|
||||
|
||||
router = APIRouter(tags=["login"], prefix="/login")
|
||||
|
||||
|
||||
async def initial_pwd_disabled(session) -> bool:
|
||||
login_args = await get_group_args(session=session, flag='login')
|
||||
disabled_arg = next((a for a in login_args if a.pkey == 'login.initial_pwd_disabled'), None)
|
||||
return bool(disabled_arg and str(disabled_arg.pval).strip().lower() == 'true')
|
||||
|
||||
|
||||
@router.post("/access-token")
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.LOGIN,
|
||||
@@ -39,13 +47,46 @@ async def local_login(
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.user_disable', msg = trans('i18n_concat_admin')))
|
||||
if user.origin is not None and user.origin != 0:
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.origin_error'))
|
||||
if (
|
||||
user.id != 1
|
||||
and await initial_pwd_disabled(session)
|
||||
and verify_md5pwd(default_pwd(), user.password)
|
||||
):
|
||||
return Token(access_token='', need_change_pwd=True)
|
||||
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
user_dict = user.to_dict()
|
||||
return Token(access_token=create_access_token(
|
||||
user_dict, expires_delta=access_token_expires
|
||||
))
|
||||
return Token(
|
||||
access_token=create_access_token(user_dict, expires_delta=access_token_expires),
|
||||
need_change_pwd=False,
|
||||
)
|
||||
|
||||
@router.post("/logout")
|
||||
|
||||
@router.post("/change-pwd")
|
||||
@system_log(LogConfig(
|
||||
operation_type=OperationType.UPDATE_PWD,
|
||||
module=OperationModules.USER,
|
||||
result_id_expr="id"
|
||||
))
|
||||
async def login_change_pwd(session: SessionDep, trans: Trans, editor: LoginPwdEditor):
|
||||
origin_account = await sqlbot_decrypt(editor.account)
|
||||
origin_pwd = await sqlbot_decrypt(editor.pwd)
|
||||
new_pwd = await sqlbot_decrypt(editor.new_pwd)
|
||||
user: BaseUserDTO = authenticate(session=session, account=origin_account, password=origin_pwd)
|
||||
if not user:
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.account_pwd_error'))
|
||||
if user.origin is not None and user.origin != 0:
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.origin_error'))
|
||||
if not check_pwd_format(new_pwd):
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_format_invalid', key = trans('i18n_user.password')))
|
||||
if await initial_pwd_disabled(session) and new_pwd == default_pwd():
|
||||
raise HTTPException(status_code=400, detail=trans('i18n_login.new_pwd_is_initial'))
|
||||
db_user = get_db_user(session=session, user_id=user.id)
|
||||
db_user.password = md5pwd(new_pwd)
|
||||
session.add(db_user)
|
||||
await clean_user_cache(user.id)
|
||||
return db_user
|
||||
|
||||
@router.post("/logout")
|
||||
async def logout(session: SessionDep, request: Request, dto: LogoutSchema):
|
||||
if dto.origin != 0:
|
||||
return await xpack_logout(session, request, dto)
|
||||
|
||||
@@ -18,6 +18,7 @@ from common.core.security import default_md5_pwd, md5pwd, verify_md5pwd
|
||||
from common.core.sqlbot_cache import clear_cache
|
||||
from common.core.config import settings
|
||||
from apps.swagger.i18n import PLACEHOLDER_PREFIX
|
||||
from sqlbot_xpack.config.arg_manage import get_group_args
|
||||
|
||||
router = APIRouter(tags=["system_user"], prefix="/user")
|
||||
|
||||
@@ -45,7 +46,11 @@ async def user_info(current_user: CurrentUser) -> UserInfoDTO:
|
||||
|
||||
@router.get("/defaultPwd", include_in_schema=False)
|
||||
@require_permissions(permission=SqlbotPermission(role=['admin']))
|
||||
async def default_pwd() -> str:
|
||||
async def default_pwd(session: SessionDep) -> str:
|
||||
login_args = await get_group_args(session=session, flag='login')
|
||||
hidden_arg = next((a for a in login_args if a.pkey == 'login.initial_pwd_hidden'), None)
|
||||
if hidden_arg and str(hidden_arg.pval).strip().lower() == 'true':
|
||||
return ''
|
||||
return settings.DEFAULT_PWD
|
||||
|
||||
@router.get("/pager/{pageNum}/{pageSize}", response_model=PaginatedResponse[UserGrid], summary=f"{PLACEHOLDER_PREFIX}system_user_grid", description=f"{PLACEHOLDER_PREFIX}system_user_grid")
|
||||
|
||||
@@ -83,6 +83,12 @@ class PwdEditor(BaseModel):
|
||||
new_pwd: str = Field(description=f"{PLACEHOLDER_PREFIX}new_pwd")
|
||||
|
||||
|
||||
class LoginPwdEditor(BaseModel):
|
||||
account: str = Field(description=f"{PLACEHOLDER_PREFIX}user_account")
|
||||
pwd: str = Field(description=f"{PLACEHOLDER_PREFIX}origin_pwd")
|
||||
new_pwd: str = Field(description=f"{PLACEHOLDER_PREFIX}new_pwd")
|
||||
|
||||
|
||||
class UserWsBase(BaseModel):
|
||||
uid_list: list[int] = Field(description=f"{PLACEHOLDER_PREFIX}uid")
|
||||
oid: Optional[int] = Field(default=None, description=f"{PLACEHOLDER_PREFIX}oid")
|
||||
|
||||
@@ -16,6 +16,7 @@ class Token(SQLModel):
|
||||
access_token: str
|
||||
token_type: str = "bearer"
|
||||
platform_info: Optional[dict] = None
|
||||
need_change_pwd: Optional[bool] = None
|
||||
|
||||
class XOAuth2PasswordBearer(OAuth2PasswordBearer):
|
||||
async def __call__(self, request: Request) -> Optional[str]:
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "Account is disabled, {msg}",
|
||||
"origin_error": "Invalid login method",
|
||||
"prohibit_auto_create": "Automatically creating users is prohibited. Please synchronize users first",
|
||||
"no_platform_user": "Account does not exist. Please sync the user first."
|
||||
"no_platform_user": "Account does not exist. Please sync the user first.",
|
||||
"new_pwd_is_initial": "The new password cannot be the initial password"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "Account",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "계정이 비활성화되었습니다, {msg}",
|
||||
"origin_error": "잘못된 로그인 방식입니다",
|
||||
"prohibit_auto_create": "사용자 자동 생성이 금지되어 있습니다. 먼저 사용자를 동기화해 주세요",
|
||||
"no_platform_user": "계정이 존재하지 않습니다. 먼저 사용자를 동기화하세요."
|
||||
"no_platform_user": "계정이 존재하지 않습니다. 먼저 사용자를 동기화하세요.",
|
||||
"new_pwd_is_initial": "새 비밀번호는 초기 비밀번호로 설정할 수 없습니다"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "계정",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "账号已禁用,{msg}",
|
||||
"origin_error": "登录方式错误",
|
||||
"prohibit_auto_create": "禁止自动创建用户,请先同步用户",
|
||||
"no_platform_user": "账号不存在,请先同步用户"
|
||||
"no_platform_user": "账号不存在,请先同步用户",
|
||||
"new_pwd_is_initial": "新密码不能为初始密码"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "账号",
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"user_disable": "帳號已禁用,{msg}",
|
||||
"origin_error": "登入方式錯誤",
|
||||
"prohibit_auto_create": "禁止自動建立用戶,請先同步用戶",
|
||||
"no_platform_user": "帳號不存在,請先同步用戶"
|
||||
"no_platform_user": "帳號不存在,請先同步用戶",
|
||||
"new_pwd_is_initial": "新密碼不能為初始密碼"
|
||||
},
|
||||
"i18n_user": {
|
||||
"account": "帳號",
|
||||
|
||||
Reference in New Issue
Block a user