mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
fix mongodb root password sync (#12547)
#### What this PR does / why we need it? #### Summary of your change #### Please indicate you've done the following: - [ ] Made sure tests are passing and test coverage is added if needed. - [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/). - [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.
This commit is contained in:
@@ -171,6 +171,37 @@ func (b *BaseApi) ChangeMongodbPassword(c *gin.Context) {
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Database Mongodb
|
||||
// @Summary Change mongodb root password
|
||||
// @Accept json
|
||||
// @Param request body dto.ChangeDBInfo true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /databases/mongodb/root/password [post]
|
||||
// @x-panel-log {"bodyKeys":["database"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mongodb 数据库 [database] root 密码","formatEN":"update mongodb database [database] root password"}
|
||||
func (b *BaseApi) ChangeMongodbRootPassword(c *gin.Context) {
|
||||
var req dto.ChangeDBInfo
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(req.Value) != 0 {
|
||||
value, err := base64.StdEncoding.DecodeString(req.Value)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
req.Value = string(value)
|
||||
}
|
||||
|
||||
if err := mongodbService.ChangeRootPassword(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Database Mongodb
|
||||
// @Summary Load mongodb privileges
|
||||
// @Accept json
|
||||
|
||||
@@ -11,7 +11,7 @@ type DBConfUpdateByFile struct {
|
||||
type ChangeDBInfo struct {
|
||||
ID uint `json:"id"`
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mysql-cluster postgresql-cluster redis-cluster"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mongodb mysql-cluster postgresql-cluster redis-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Value string `json:"value" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -874,7 +874,7 @@ func updateInstallInfoInDB(appKey, appName, param string, value interface{}) err
|
||||
envKey := ""
|
||||
switch param {
|
||||
case "password":
|
||||
if appKey == "mysql" || appKey == "mariadb" || appKey == "postgresql" {
|
||||
if appKey == "mysql" || appKey == "mariadb" || appKey == "postgresql" || appKey == "mongodb" {
|
||||
envKey = "PANEL_DB_ROOT_PASSWORD="
|
||||
} else {
|
||||
envKey = "PANEL_REDIS_ROOT_PASSWORD="
|
||||
@@ -915,7 +915,7 @@ func updateInstallInfoInDB(appKey, appName, param string, value interface{}) err
|
||||
"param": strings.ReplaceAll(appInstall.Param, oldVal, newVal),
|
||||
"env": strings.ReplaceAll(appInstall.Env, oldVal, newVal),
|
||||
}, repo.WithByID(appInstall.ID))
|
||||
if appKey == "mysql" || appKey == "postgresql" {
|
||||
if appKey == "mysql" || appKey == "postgresql" || appKey == "mongodb" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ type IMongodbService interface {
|
||||
UpdateDescription(req dto.UpdateDescription) error
|
||||
BindUser(req dto.MongodbBind) error
|
||||
ChangePassword(req dto.MongodbPassword) error
|
||||
ChangeRootPassword(req dto.ChangeDBInfo) error
|
||||
LoadPrivileges(req dto.MongodbPrivilegesLoad) (string, error)
|
||||
ChangePrivileges(req dto.MongodbPrivileges) error
|
||||
DeleteCheck(req dto.MongodbDBDeleteCheck) ([]dto.DBResource, error)
|
||||
@@ -188,6 +189,40 @@ func (u *MongodbService) ChangePassword(req dto.MongodbPassword) error {
|
||||
return mongodbRepo.Update(dbItem.ID, map[string]interface{}{"password": pass})
|
||||
}
|
||||
|
||||
func (u *MongodbService) ChangeRootPassword(req dto.ChangeDBInfo) error {
|
||||
if cmd.CheckIllegal(req.Value) {
|
||||
return buserr.New("ErrCmdIllegal")
|
||||
}
|
||||
if req.From != constant.AppResourceLocal {
|
||||
return buserr.New("ErrRecordNotFound")
|
||||
}
|
||||
|
||||
appInfo, err := appInstallRepo.LoadBaseInfo(req.Type, req.Database)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if appInfo.UserName == "" {
|
||||
return buserr.New("ErrRecordNotFound")
|
||||
}
|
||||
if err := updateMongodbPassword(req.From, req.Database, "admin", appInfo.UserName, req.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updateInstallInfoInDB(req.Type, req.Database, "password", req.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
remote, err := databaseRepo.Get(repo.WithByName(req.Database))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pass, err := encrypt.StringEncrypt(req.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("encrypt mongodb root password failed, err: %v", err)
|
||||
}
|
||||
_ = databaseRepo.Update(remote.ID, map[string]interface{}{"password": pass})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *MongodbService) DeleteCheck(req dto.MongodbDBDeleteCheck) ([]dto.DBResource, error) {
|
||||
var res []dto.DBResource
|
||||
db, err := mongodbRepo.Get(repo.WithByID(req.ID))
|
||||
|
||||
@@ -65,6 +65,7 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) {
|
||||
cmdRouter.POST("/mongodb/load", baseApi.LoadMongodbFromRemote)
|
||||
cmdRouter.POST("/mongodb/bind", baseApi.BindMongodbUser)
|
||||
cmdRouter.POST("/mongodb/password", baseApi.ChangeMongodbPassword)
|
||||
cmdRouter.POST("/mongodb/root/password", baseApi.ChangeMongodbRootPassword)
|
||||
cmdRouter.POST("/mongodb/privileges", baseApi.LoadMongodbPrivileges)
|
||||
cmdRouter.POST("/mongodb/privileges/change", baseApi.ChangeMongodbPrivileges)
|
||||
cmdRouter.POST("/mongodb/del/check", baseApi.DeleteCheckMongodb)
|
||||
|
||||
@@ -112,6 +112,11 @@ export const updateMongodbPassword = (params: Database.MongodbPassword) => {
|
||||
encodeBase64Fields(request, ['password']);
|
||||
return http.post(`/databases/mongodb/password`, request, TimeoutEnum.T_40S);
|
||||
};
|
||||
export const updateMongodbRootPassword = (params: Database.ChangeInfo) => {
|
||||
let request = deepCopy(params) as Database.ChangeInfo;
|
||||
encodeBase64Fields(request, ['value']);
|
||||
return http.post(`/databases/mongodb/root/password`, request, TimeoutEnum.T_40S);
|
||||
};
|
||||
export const updateMongodbDescription = (params: DescriptionUpdate) => {
|
||||
return http.post(`/databases/mongodb/description`, params, TimeoutEnum.T_40S);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<DrawerPro v-model="dialogVisible" :header="$t('database.databaseConnInfo')" @close="handleClose" size="small">
|
||||
<el-form @submit.prevent v-loading="loading" :model="form" label-position="top">
|
||||
<el-form @submit.prevent v-loading="loading" ref="formRef" :rules="rules" :model="form" label-position="top">
|
||||
<el-form-item v-if="form.from === 'local'">
|
||||
<template #label>
|
||||
<div class="conn-label">
|
||||
@@ -73,15 +73,43 @@
|
||||
|
||||
<el-divider border-style="dashed" />
|
||||
|
||||
<el-form-item :label="$t('commons.login.username')">
|
||||
<el-tag>{{ form.username || '-' }}</el-tag>
|
||||
<CopyButton v-if="form.username" :content="form.username" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="form.from === 'local' ? $t('database.rootPassword') : $t('commons.login.password')">
|
||||
<el-tag>{{ form.password || '-' }}</el-tag>
|
||||
<CopyButton v-if="form.password" :content="form.password" />
|
||||
</el-form-item>
|
||||
<div v-if="form.from === 'local'">
|
||||
<el-form-item :label="$t('commons.login.username')">
|
||||
<el-input type="text" style="width: calc(100% - 60px)" readonly disabled v-model="form.username">
|
||||
<template #append>
|
||||
<el-button-group>
|
||||
<CopyButton :content="form.username" :isIcon="false" />
|
||||
</el-button-group>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.rootPassword')" prop="password">
|
||||
<el-input
|
||||
style="width: calc(100% - 205px)"
|
||||
type="password"
|
||||
show-password
|
||||
clearable
|
||||
v-model="form.password"
|
||||
/>
|
||||
<el-button-group>
|
||||
<CopyButton :isIcon="false" class="copy_button" :content="form.password" />
|
||||
<el-button @click="random">
|
||||
{{ $t('commons.button.random') }}
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
<span class="input-help">{{ $t('commons.rule.illegalChar') }}</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-form-item :label="$t('commons.login.username')">
|
||||
<el-tag>{{ form.username || '-' }}</el-tag>
|
||||
<CopyButton v-if="form.username" :content="form.username" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.login.password')">
|
||||
<el-tag>{{ form.password || '-' }}</el-tag>
|
||||
<CopyButton v-if="form.password" :content="form.password" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@@ -89,6 +117,9 @@
|
||||
<el-button :disabled="loading" @click="dialogVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading || form.status !== 'Running'" type="primary" @click="onSave(formRef)">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</DrawerPro>
|
||||
@@ -96,8 +127,12 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { getDatabase } from '@/api/modules/database';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { getDatabase, updateMongodbRootPassword } from '@/api/modules/database';
|
||||
import { getAppConnInfo } from '@/api/modules/app';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { getRandomStr } from '@/utils/id';
|
||||
import { getAgentSettingInfo } from '@/api/modules/setting';
|
||||
import { copyText } from '@/utils/clipboard';
|
||||
import i18n from '@/lang';
|
||||
@@ -121,6 +156,13 @@ const form = reactive({
|
||||
username: '',
|
||||
});
|
||||
|
||||
const rules = reactive({
|
||||
password: [Rules.requiredInput, Rules.noSpace, Rules.illegal],
|
||||
});
|
||||
|
||||
type FormInstance = InstanceType<typeof ElForm>;
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
interface DialogProps {
|
||||
from: string;
|
||||
type: string;
|
||||
@@ -128,6 +170,7 @@ interface DialogProps {
|
||||
}
|
||||
|
||||
const acceptParams = async (params: DialogProps): Promise<void> => {
|
||||
form.password = '';
|
||||
form.from = params.from;
|
||||
form.type = params.type;
|
||||
form.database = params.database;
|
||||
@@ -139,6 +182,10 @@ const handleClose = () => {
|
||||
dialogVisible.value = false;
|
||||
};
|
||||
|
||||
const random = () => {
|
||||
form.password = getRandomStr(16);
|
||||
};
|
||||
|
||||
const loadSystemIP = async () => {
|
||||
const res = await getAgentSettingInfo();
|
||||
form.systemIP = res.data.systemIP || globalStore.currentNodeAddr || i18n.global.t('database.localIP');
|
||||
@@ -187,6 +234,38 @@ const copyConnURL = (isContainer: boolean) => {
|
||||
copyText(`mongodb://${user}:${encodedPassword}@${host}:${port}/admin?authSource=admin`);
|
||||
};
|
||||
|
||||
const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('database.changeConnHelper', [i18n.global.t('database.rootPassword')]),
|
||||
i18n.global.t('commons.msg.infoTitle'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
cancelButtonText: i18n.global.t('commons.button.cancel'),
|
||||
},
|
||||
).then(async () => {
|
||||
loading.value = true;
|
||||
await updateMongodbRootPassword({
|
||||
id: 0,
|
||||
from: form.from,
|
||||
type: form.type,
|
||||
database: form.database,
|
||||
value: form.password,
|
||||
})
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
dialogVisible.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
@@ -201,6 +280,16 @@ defineExpose({
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.copy_button {
|
||||
border-radius: 0px;
|
||||
border-left-width: 0px;
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
border-top-right-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user