diff --git a/backend/app/api/v1/database_mysql.go b/backend/app/api/v1/database_mysql.go index 03201541e..1a8336ca3 100644 --- a/backend/app/api/v1/database_mysql.go +++ b/backend/app/api/v1/database_mysql.go @@ -25,7 +25,7 @@ func (b *BaseApi) CreateMysql(c *gin.Context) { helper.SuccessWithData(c, nil) } -func (b *BaseApi) UpdateMysql(c *gin.Context) { +func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) { var req dto.ChangeDBInfo if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) @@ -35,7 +35,24 @@ func (b *BaseApi) UpdateMysql(c *gin.Context) { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - if err := mysqlService.ChangeInfo(req); err != nil { + if err := mysqlService.ChangePassword(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, nil) +} + +func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) { + var req dto.ChangeDBInfo + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := global.VALID.Struct(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := mysqlService.ChangeAccess(req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } diff --git a/backend/app/dto/database.go b/backend/app/dto/database.go index f745ef415..4d7ea5bc3 100644 --- a/backend/app/dto/database.go +++ b/backend/app/dto/database.go @@ -93,9 +93,8 @@ type MysqlConfUpdateByFile struct { } type ChangeDBInfo struct { - ID uint `json:"id"` - Operation string `json:"operation" validate:"required,oneof=password privilege"` - Value string `json:"value" validate:"required"` + ID uint `json:"id"` + Value string `json:"value" validate:"required"` } type DBBaseInfo struct { diff --git a/backend/app/service/database_mysql.go b/backend/app/service/database_mysql.go index 75dc7ca76..ab7daf584 100644 --- a/backend/app/service/database_mysql.go +++ b/backend/app/service/database_mysql.go @@ -32,7 +32,8 @@ type IMysqlService interface { SearchWithPage(search dto.PageInfo) (int64, interface{}, error) ListDBName() ([]string, error) Create(mysqlDto dto.MysqlDBCreate) error - ChangeInfo(info dto.ChangeDBInfo) error + ChangeAccess(info dto.ChangeDBInfo) error + ChangePassword(info dto.ChangeDBInfo) error UpdateVariables(updatas []dto.MysqlVariablesUpdate) error UpdateConfByFile(info dto.MysqlConfUpdateByFile) error @@ -269,7 +270,7 @@ func (u *MysqlService) Delete(id uint) error { return nil } -func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error { +func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error { var ( mysql model.DatabaseMysql err error @@ -284,30 +285,54 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error { if err != nil { return err } - if info.Operation == "password" { - if info.ID != 0 { - if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("set password for %s@%s = password('%s')", mysql.Username, mysql.Permission, info.Value)); err != nil { - return err - } - _ = mysqlRepo.Update(mysql.ID, map[string]interface{}{"password": info.Value}) - return nil - } - hosts, err := excuteSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';") - if err != nil { + + passwordChangeCMD := fmt.Sprintf("set password for '%s'@'%s' = password('%s')", mysql.Username, mysql.Permission, info.Value) + if app.Version != "5.7.39" { + passwordChangeCMD = fmt.Sprintf("ALTER USER '%s'@'%s' IDENTIFIED WITH mysql_native_password BY '%s';", mysql.Username, mysql.Permission, info.Value) + } + if info.ID != 0 { + if err := excuteSql(app.ContainerName, app.Password, passwordChangeCMD); err != nil { return err } - for _, host := range hosts { - if host == "%" || host == "localhost" { - if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("set password for root@'%s' = password('%s')", host, info.Value)); err != nil { - return err - } - } - } - updateInstallInfoInDB("mysql", "password", info.Value) - updateInstallInfoInDB("phpmyadmin", "password", info.Value) + _ = mysqlRepo.Update(mysql.ID, map[string]interface{}{"password": info.Value}) return nil } + hosts, err := excuteSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';") + if err != nil { + return err + } + for _, host := range hosts { + if host == "%" || host == "localhost" { + passwordRootChangeCMD := fmt.Sprintf("set password for 'root'@'%s' = password('%s')", host, info.Value) + if app.Version != "5.7.39" { + passwordRootChangeCMD = fmt.Sprintf("ALTER USER 'root'@'%s' IDENTIFIED WITH mysql_native_password BY '%s';", host, info.Value) + } + if err := excuteSql(app.ContainerName, app.Password, passwordRootChangeCMD); err != nil { + return err + } + } + } + updateInstallInfoInDB("mysql", "password", info.Value) + updateInstallInfoInDB("phpmyadmin", "password", info.Value) + return nil +} + +func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error { + var ( + mysql model.DatabaseMysql + err error + ) + if info.ID != 0 { + mysql, err = mysqlRepo.Get(commonRepo.WithByID(info.ID)) + if err != nil { + return err + } + } + app, err := appInstallRepo.LoadBaseInfoByKey("mysql") + if err != nil { + return err + } if info.ID == 0 { mysql.Name = "*" mysql.Username = "root" diff --git a/backend/router/ro_database.go b/backend/router/ro_database.go index 3134c65b9..3e7462ae7 100644 --- a/backend/router/ro_database.go +++ b/backend/router/ro_database.go @@ -22,7 +22,8 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) { baseApi := v1.ApiGroupApp.BaseApi { withRecordRouter.POST("", baseApi.CreateMysql) - withRecordRouter.PUT("/:id", baseApi.UpdateMysql) + withRecordRouter.POST("/change/access", baseApi.ChangeMysqlAccess) + withRecordRouter.POST("/change/password", baseApi.ChangeMysqlPassword) withRecordRouter.POST("/backup", baseApi.BackupMysql) withRecordRouter.POST("/recover/byupload", baseApi.RecoverMysqlByUpload) withRecordRouter.POST("/recover", baseApi.RecoverMysql) diff --git a/frontend/src/api/interface/database.ts b/frontend/src/api/interface/database.ts index 0ccf0db38..ed9b5f743 100644 --- a/frontend/src/api/interface/database.ts +++ b/frontend/src/api/interface/database.ts @@ -113,7 +113,6 @@ export namespace Database { } export interface ChangeInfo { id: number; - operation: string; value: string; } diff --git a/frontend/src/api/modules/database.ts b/frontend/src/api/modules/database.ts index 85480e7a1..531c56069 100644 --- a/frontend/src/api/modules/database.ts +++ b/frontend/src/api/modules/database.ts @@ -19,8 +19,11 @@ export const recoverByUpload = (params: Database.RecoverByUpload) => { export const addMysqlDB = (params: Database.MysqlDBCreate) => { return http.post(`/databases`, params); }; -export const updateMysqlDBInfo = (params: Database.ChangeInfo) => { - return http.put(`/databases/${params.id}`, params); +export const updateMysqlAccess = (params: Database.ChangeInfo) => { + return http.post(`/databases/change/access`, params); +}; +export const updateMysqlPassword = (params: Database.ChangeInfo) => { + return http.post(`/databases/change/[password]`, params); }; export const updateMysqlVariables = (params: Array) => { return http.post(`/databases/variables/update`, params); diff --git a/frontend/src/components/status/index.vue b/frontend/src/components/status/index.vue index 7f3882517..b2976781a 100644 --- a/frontend/src/components/status/index.vue +++ b/frontend/src/components/status/index.vue @@ -13,7 +13,7 @@ const props = defineProps({ default: 'runnning', }, }); -let status = ref(''); +let status = ref('running'); const getColor = (status: string) => { switch (status) { diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 4daa6d0bf..d6ee314b7 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -231,7 +231,7 @@ export default { backupList: '备份列表', backList: '返回列表', loadBackup: '导入备份', - setting: 'Mysql 设置', + setting: '设置', remoteAccess: '远程访问', remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险,开启需谨慎!', changePassword: '改密', diff --git a/frontend/src/views/database/mysql/index.vue b/frontend/src/views/database/mysql/index.vue index 5de4ad8fd..c8dd5735a 100644 --- a/frontend/src/views/database/mysql/index.vue +++ b/frontend/src/views/database/mysql/index.vue @@ -174,7 +174,8 @@ import { deleteMysqlDB, loadMysqlBaseInfo, searchMysqlDBs, - updateMysqlDBInfo, + updateMysqlAccess, + updateMysqlPassword, } from '@/api/modules/database'; import i18n from '@/lang'; import { useDeleteData } from '@/hooks/use-delete-data'; @@ -262,12 +263,24 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => { if (!formEl) return; formEl.validate(async (valid) => { if (!valid) return; - changeForm.value = changeForm.operation === 'password' ? changeForm.password : changeForm.privilege; + let param = { + id: changeForm.id, + value: '', + }; + if (changeForm.operation === 'password') { + param.value = changeForm.password; + await updateMysqlPassword(param); + search(); + changeVisiable.value = false; + ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); + return; + } + param.value = changeForm.privilege; changeForm.mysqlName = mysqlName.value; - await updateMysqlDBInfo(changeForm); - ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); + await updateMysqlAccess(param); search(); changeVisiable.value = false; + ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); }); }; diff --git a/frontend/src/views/database/mysql/password/index.vue b/frontend/src/views/database/mysql/password/index.vue index 43eb747b0..7d7068892 100644 --- a/frontend/src/views/database/mysql/password/index.vue +++ b/frontend/src/views/database/mysql/password/index.vue @@ -29,7 +29,7 @@ import { reactive, ref } from 'vue'; import { Rules } from '@/global/form-rules'; import i18n from '@/lang'; import { ElForm, ElMessage } from 'element-plus'; -import { updateMysqlDBInfo } from '@/api/modules/database'; +import { updateMysqlPassword } from '@/api/modules/database'; import ConfirmDialog from '@/components/confirm-dialog/index.vue'; const loading = ref(false); @@ -52,11 +52,10 @@ const acceptParams = (): void => { const onSubmit = async () => { let param = { id: 0, - operation: 'password', value: form.password, }; loading.value = true; - await updateMysqlDBInfo(param) + await updateMysqlPassword(param) .then(() => { loading.value = false; ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); diff --git a/frontend/src/views/database/mysql/remote/index.vue b/frontend/src/views/database/mysql/remote/index.vue index 3aff9e78e..71a40b650 100644 --- a/frontend/src/views/database/mysql/remote/index.vue +++ b/frontend/src/views/database/mysql/remote/index.vue @@ -30,7 +30,7 @@ import { reactive, ref } from 'vue'; import { Rules } from '@/global/form-rules'; import i18n from '@/lang'; import { ElForm, ElMessage } from 'element-plus'; -import { updateMysqlDBInfo } from '@/api/modules/database'; +import { updateMysqlAccess } from '@/api/modules/database'; import ConfirmDialog from '@/components/confirm-dialog/index.vue'; const loading = ref(false); @@ -57,11 +57,10 @@ const acceptParams = (prop: DialogProps): void => { const onSubmit = async () => { let param = { id: 0, - operation: 'privilege', value: form.privilege ? '%' : 'localhost', }; loading.value = true; - await updateMysqlDBInfo(param) + await updateMysqlAccess(param) .then(() => { loading.value = false; ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); diff --git a/frontend/src/views/database/mysql/setting/index.vue b/frontend/src/views/database/mysql/setting/index.vue index d07b47094..c52bf05c4 100644 --- a/frontend/src/views/database/mysql/setting/index.vue +++ b/frontend/src/views/database/mysql/setting/index.vue @@ -1,7 +1,7 @@