mirror of https://github.com/1Panel-dev/1Panel
fix: 修复 mysql 8.0 改密失败的问题
parent
12b668ecd1
commit
77ff593403
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -113,7 +113,6 @@ export namespace Database {
|
||||||
}
|
}
|
||||||
export interface ChangeInfo {
|
export interface ChangeInfo {
|
||||||
id: number;
|
id: number;
|
||||||
operation: string;
|
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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: '改密',
|
||||||
|
|
|
@ -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'));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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'));
|
||||||
|
|
|
@ -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'));
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in New Issue