fix: 修复 mysql 8.0 改密失败的问题

pull/74/head
ssongliu 2022-12-08 19:07:32 +08:00 committed by ssongliu
parent 12b668ecd1
commit 77ff593403
14 changed files with 104 additions and 55 deletions

View File

@ -25,7 +25,7 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
helper.SuccessWithData(c, nil) helper.SuccessWithData(c, nil)
} }
func (b *BaseApi) UpdateMysql(c *gin.Context) { func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
var req dto.ChangeDBInfo var req dto.ChangeDBInfo
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) 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) helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return 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) helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return return
} }

View File

@ -94,7 +94,6 @@ type MysqlConfUpdateByFile struct {
type ChangeDBInfo struct { type ChangeDBInfo struct {
ID uint `json:"id"` ID uint `json:"id"`
Operation string `json:"operation" validate:"required,oneof=password privilege"`
Value string `json:"value" validate:"required"` Value string `json:"value" validate:"required"`
} }

View File

@ -32,7 +32,8 @@ type IMysqlService interface {
SearchWithPage(search dto.PageInfo) (int64, interface{}, error) SearchWithPage(search dto.PageInfo) (int64, interface{}, error)
ListDBName() ([]string, error) ListDBName() ([]string, error)
Create(mysqlDto dto.MysqlDBCreate) 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 UpdateVariables(updatas []dto.MysqlVariablesUpdate) error
UpdateConfByFile(info dto.MysqlConfUpdateByFile) error UpdateConfByFile(info dto.MysqlConfUpdateByFile) error
@ -269,7 +270,7 @@ func (u *MysqlService) Delete(id uint) error {
return nil return nil
} }
func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error { func (u *MysqlService) ChangePassword(info dto.ChangeDBInfo) error {
var ( var (
mysql model.DatabaseMysql mysql model.DatabaseMysql
err error err error
@ -284,21 +285,30 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error {
if err != nil { if err != nil {
return err return err
} }
if info.Operation == "password" {
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 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 { if err := excuteSql(app.ContainerName, app.Password, passwordChangeCMD); err != nil {
return err return err
} }
_ = mysqlRepo.Update(mysql.ID, map[string]interface{}{"password": info.Value}) _ = mysqlRepo.Update(mysql.ID, map[string]interface{}{"password": info.Value})
return nil return nil
} }
hosts, err := excuteSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';") hosts, err := excuteSqlForRows(app.ContainerName, app.Password, "select host from mysql.user where user='root';")
if err != nil { if err != nil {
return err return err
} }
for _, host := range hosts { for _, host := range hosts {
if host == "%" || host == "localhost" { 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 { 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 return err
} }
} }
@ -308,6 +318,21 @@ func (u *MysqlService) ChangeInfo(info dto.ChangeDBInfo) error {
return nil 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 { if info.ID == 0 {
mysql.Name = "*" mysql.Name = "*"
mysql.Username = "root" mysql.Username = "root"

View File

@ -22,7 +22,8 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
baseApi := v1.ApiGroupApp.BaseApi baseApi := v1.ApiGroupApp.BaseApi
{ {
withRecordRouter.POST("", baseApi.CreateMysql) 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("/backup", baseApi.BackupMysql)
withRecordRouter.POST("/recover/byupload", baseApi.RecoverMysqlByUpload) withRecordRouter.POST("/recover/byupload", baseApi.RecoverMysqlByUpload)
withRecordRouter.POST("/recover", baseApi.RecoverMysql) withRecordRouter.POST("/recover", baseApi.RecoverMysql)

View File

@ -113,7 +113,6 @@ export namespace Database {
} }
export interface ChangeInfo { export interface ChangeInfo {
id: number; id: number;
operation: string;
value: string; value: string;
} }

View File

@ -19,8 +19,11 @@ export const recoverByUpload = (params: Database.RecoverByUpload) => {
export const addMysqlDB = (params: Database.MysqlDBCreate) => { export const addMysqlDB = (params: Database.MysqlDBCreate) => {
return http.post(`/databases`, params); return http.post(`/databases`, params);
}; };
export const updateMysqlDBInfo = (params: Database.ChangeInfo) => { export const updateMysqlAccess = (params: Database.ChangeInfo) => {
return http.put(`/databases/${params.id}`, params); 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<Database.VariablesUpdate>) => { export const updateMysqlVariables = (params: Array<Database.VariablesUpdate>) => {
return http.post(`/databases/variables/update`, params); return http.post(`/databases/variables/update`, params);

View File

@ -13,7 +13,7 @@ const props = defineProps({
default: 'runnning', default: 'runnning',
}, },
}); });
let status = ref(''); let status = ref('running');
const getColor = (status: string) => { const getColor = (status: string) => {
switch (status) { switch (status) {

View File

@ -231,7 +231,7 @@ export default {
backupList: '', backupList: '',
backList: '', backList: '',
loadBackup: '', loadBackup: '',
setting: 'Mysql ', setting: '',
remoteAccess: '访', remoteAccess: '访',
remoteConnHelper: 'root mysql ', remoteConnHelper: 'root mysql ',
changePassword: '', changePassword: '',

View File

@ -174,7 +174,8 @@ import {
deleteMysqlDB, deleteMysqlDB,
loadMysqlBaseInfo, loadMysqlBaseInfo,
searchMysqlDBs, searchMysqlDBs,
updateMysqlDBInfo, updateMysqlAccess,
updateMysqlPassword,
} from '@/api/modules/database'; } from '@/api/modules/database';
import i18n from '@/lang'; import i18n from '@/lang';
import { useDeleteData } from '@/hooks/use-delete-data'; import { useDeleteData } from '@/hooks/use-delete-data';
@ -262,12 +263,24 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
if (!formEl) return; if (!formEl) return;
formEl.validate(async (valid) => { formEl.validate(async (valid) => {
if (!valid) return; if (!valid) return;
changeForm.value = changeForm.operation === 'password' ? changeForm.password : changeForm.privilege; let param = {
changeForm.mysqlName = mysqlName.value; id: changeForm.id,
await updateMysqlDBInfo(changeForm); value: '',
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); };
if (changeForm.operation === 'password') {
param.value = changeForm.password;
await updateMysqlPassword(param);
search(); search();
changeVisiable.value = false; changeVisiable.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
return;
}
param.value = changeForm.privilege;
changeForm.mysqlName = mysqlName.value;
await updateMysqlAccess(param);
search();
changeVisiable.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
}); });
}; };

View File

@ -29,7 +29,7 @@ import { reactive, ref } from 'vue';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm, ElMessage } from 'element-plus'; 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'; import ConfirmDialog from '@/components/confirm-dialog/index.vue';
const loading = ref(false); const loading = ref(false);
@ -52,11 +52,10 @@ const acceptParams = (): void => {
const onSubmit = async () => { const onSubmit = async () => {
let param = { let param = {
id: 0, id: 0,
operation: 'password',
value: form.password, value: form.password,
}; };
loading.value = true; loading.value = true;
await updateMysqlDBInfo(param) await updateMysqlPassword(param)
.then(() => { .then(() => {
loading.value = false; loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));

View File

@ -30,7 +30,7 @@ import { reactive, ref } from 'vue';
import { Rules } from '@/global/form-rules'; import { Rules } from '@/global/form-rules';
import i18n from '@/lang'; import i18n from '@/lang';
import { ElForm, ElMessage } from 'element-plus'; 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'; import ConfirmDialog from '@/components/confirm-dialog/index.vue';
const loading = ref(false); const loading = ref(false);
@ -57,11 +57,10 @@ const acceptParams = (prop: DialogProps): void => {
const onSubmit = async () => { const onSubmit = async () => {
let param = { let param = {
id: 0, id: 0,
operation: 'privilege',
value: form.privilege ? '%' : 'localhost', value: form.privilege ? '%' : 'localhost',
}; };
loading.value = true; loading.value = true;
await updateMysqlDBInfo(param) await updateMysqlAccess(param)
.then(() => { .then(() => {
loading.value = false; loading.value = false;
ElMessage.success(i18n.global.t('commons.msg.operationSuccess')); ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="demo-collapse" v-show="onSetting"> <div class="demo-collapse" v-show="onSetting">
<el-card style="margin-top: 5px" v-loading="loading"> <el-card style="margin-top: 5px" v-loading="loading">
<LayoutContent :header="$t('database.setting')" :back-name="'Mysql'" :reload="true"> <LayoutContent :header="'Mysql ' + $t('database.setting')" :back-name="'Mysql'" :reload="true">
<el-collapse v-model="activeName" accordion> <el-collapse v-model="activeName" accordion>
<el-collapse-item :title="$t('database.confChange')" name="1"> <el-collapse-item :title="$t('database.confChange')" name="1">
<codemirror <codemirror
@ -110,7 +110,6 @@ interface DialogProps {
const dialogContainerLogRef = ref(); const dialogContainerLogRef = ref();
const acceptParams = (params: DialogProps): void => { const acceptParams = (params: DialogProps): void => {
onSetting.value = true; onSetting.value = true;
loading.value = true;
loadBaseInfo(); loadBaseInfo();
loadVariables(); loadVariables();
loadSlowLogs(); loadSlowLogs();
@ -217,14 +216,9 @@ const loadSlowLogs = async () => {
}; };
const loadMysqlConf = async (path: string) => { const loadMysqlConf = async (path: string) => {
await LoadFile({ path: path }) const res = await LoadFile({ path: path });
.then((res) => {
loading.value = false; loading.value = false;
mysqlConf.value = res.data; mysqlConf.value = res.data;
})
.catch(() => {
loading.value = false;
});
}; };
defineExpose({ defineExpose({

View File

@ -4,7 +4,7 @@
<AppStatus :app-key="'redis'" style="margin-top: 20px" @setting="onSetting" @is-exist="checkExist"></AppStatus> <AppStatus :app-key="'redis'" style="margin-top: 20px" @setting="onSetting" @is-exist="checkExist"></AppStatus>
<div v-show="redisIsExist"> <div v-show="redisIsExist">
<el-button style="margin-top: 20px" type="p" @click="goDashboard" icon="Position"> <el-button style="margin-top: 20px" type="primary" plain @click="goDashboard" icon="Position">
Redis-Commander Redis-Commander
</el-button> </el-button>

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="demo-collapse" v-show="settingShow"> <div class="demo-collapse" v-show="settingShow">
<el-card style="margin-top: 5px"> <el-card style="margin-top: 5px" v-loading="loading">
<LayoutContent :header="$t('database.setting')" back-name="Redis" :reload="true" v-loading="loading"> <LayoutContent :header="'Redis ' + $t('database.setting')" back-name="Redis" :reload="true">
<el-collapse v-model="activeName" accordion> <el-collapse v-model="activeName" accordion>
<el-collapse-item :title="$t('database.baseSetting')" name="1"> <el-collapse-item :title="$t('database.baseSetting')" name="1">
<el-radio-group v-model="confShowType" @change="onChangeMode"> <el-radio-group v-model="confShowType" @change="onChangeMode">