Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 解决数据库用户指定多个 ip 无效的问题 #1019

Merged
merged 1 commit into from
May 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 65 additions & 29 deletions backend/app/service/database_mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/app/model"
"github.com/1Panel-dev/1Panel/backend/app/repo"
"github.com/1Panel-dev/1Panel/backend/buserr"
"github.com/1Panel-dev/1Panel/backend/constant"
"github.com/1Panel-dev/1Panel/backend/global"
Expand Down Expand Up @@ -99,22 +100,7 @@ func (u *MysqlService) Create(ctx context.Context, req dto.MysqlDBCreate) (*mode
}
return nil, err
}
tmpPermission := req.Permission
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("create user '%s'@'%s' identified by '%s';", req.Username, tmpPermission, req.Password)); err != nil {
_ = excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop database `%s`", req.Name))
if strings.Contains(err.Error(), "ERROR 1396") {
return nil, buserr.New(constant.ErrUserIsExist)
}
return nil, err
}
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to '%s'@'%s'", req.Name, req.Username, tmpPermission)
if req.Name == "*" {
grantStr = fmt.Sprintf("grant all privileges on *.* to '%s'@'%s'", mysql.Username, tmpPermission)
}
if app.Version == "5.7.39" {
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, req.Password)
}
if err := excSQL(app.ContainerName, app.Password, grantStr); err != nil {
if err := u.createUser(app, req); err != nil {
return nil, err
}

Expand Down Expand Up @@ -284,24 +270,30 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
}

if info.Value != mysql.Permission {
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists '%s'@'%s'", mysql.Username, mysql.Permission)); err != nil {
return err
var userlist []string
if strings.Contains(mysql.Permission, ",") {
userlist = strings.Split(mysql.Permission, ",")
} else {
userlist = append(userlist, mysql.Permission)
}
for _, user := range userlist {
if len(user) != 0 {
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists '%s'@'%s'", mysql.Username, user)); err != nil {
return err
}
}
}
if info.ID == 0 {
return nil
}
}
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("create user if not exists '%s'@'%s' identified by '%s';", mysql.Username, info.Value, mysql.Password)); err != nil {
return err
}
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to '%s'@'%s'", mysql.Name, mysql.Username, info.Value)
if mysql.Name == "*" {
grantStr = fmt.Sprintf("grant all privileges on *.* to '%s'@'%s'", mysql.Username, info.Value)
}
if app.Version == "5.7.39" {
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, mysql.Password)
}
if err := excuteSql(app.ContainerName, app.Password, grantStr); err != nil {

if err := u.createUser(app, dto.MysqlDBCreate{
Username: mysql.Username,
Name: mysql.Name,
Permission: info.Value,
Password: mysql.Password,
}); err != nil {
return err
}
if err := excuteSql(app.ContainerName, app.Password, "flush privileges"); err != nil {
Expand Down Expand Up @@ -475,6 +467,50 @@ func (u *MysqlService) LoadStatus() (*dto.MysqlStatus, error) {
return &info, nil
}

func (u *MysqlService) createUser(app *repo.RootInfo, req dto.MysqlDBCreate) error {
var userlist []string
if strings.Contains(req.Permission, ",") {
ips := strings.Split(req.Permission, ",")
for _, ip := range ips {
if len(ip) != 0 {
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", req.Username, ip))
}
}
} else {
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", req.Username, req.Permission))
}

for _, user := range userlist {
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("create user %s identified by '%s';", user, req.Password)); err != nil {
handleCreateError(req.Name, userlist, app)
if strings.Contains(err.Error(), "ERROR 1396") {
return buserr.New(constant.ErrUserIsExist)
}
return err
}
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to %s", req.Name, user)
if req.Name == "*" {
grantStr = fmt.Sprintf("grant all privileges on *.* to %s", user)
}
if app.Version == "5.7.39" {
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, req.Password)
}
if err := excSQL(app.ContainerName, app.Password, grantStr); err != nil {
handleCreateError(req.Name, userlist, app)
return err
}
}
return nil
}
func handleCreateError(dbName string, userlist []string, app *repo.RootInfo) {
_ = excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop database `%s`", dbName))
for _, user := range userlist {
if err := excSQL(app.ContainerName, app.Password, fmt.Sprintf("drop user if exists %s", user)); err != nil {
global.LOG.Errorf("drop user failed, err: %v", err)
}
}
}

func excuteSqlForMaps(containerName, password, command string) (map[string]string, error) {
cmd := exec.Command("docker", "exec", containerName, "mysql", "-uroot", "-p"+password, "-e", command)
stdout, err := cmd.CombinedOutput()
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ const message = {
loadBackup: 'Import',
setting: 'Settings',
remoteAccess: 'Remote access',
remoteHelper: 'One in a row, for example:\n172.16.10.111\n172.16.10.112',
remoteHelper: 'Multiple IP comma-delimited, example: 172.16.10.111, 172.16.10.112',
remoteConnHelper:
'Remote connection to mysql as user root may have security risks. Therefore, perform this operation with caution.',
changePassword: 'Password',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lang/modules/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ const message = {
loadBackup: '导入备份',
setting: '设置',
remoteAccess: '远程访问',
remoteHelper: '一行一个,例:\n172.16.10.111\n172.16.10.112',
remoteHelper: '多个 ip 以逗号分隔,例:172.16.10.111,172.16.10.112',
remoteConnHelper: 'root 帐号远程连接 mysql 有安全风险,开启需谨慎!',
changePassword: '改密',
changePasswordHelper: '当前数据库已经关联应用,修改密码将同步修改应用中数据库密码,修改后重启生效。',
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/views/database/mysql/create/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@
</el-select>
</el-form-item>
<el-form-item v-if="form.permission === 'ip'" prop="permissionIPs">
<el-input clearable v-model="form.permissionIPs" />
<el-input
clearable
:autosize="{ minRows: 2, maxRows: 5 }"
type="textarea"
v-model="form.permissionIPs"
/>
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
</el-form-item>
<el-form-item :label="$t('commons.table.description')" prop="description">
<el-input type="textarea" clearable v-model="form.description" />
Expand Down Expand Up @@ -131,6 +137,10 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
createVisiable.value = false;
})
.catch(() => {
if (form.permission != '%') {
form.permissionIPs = form.permission;
form.permission = 'ip';
}
loading.value = false;
});
});
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/views/database/mysql/password/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@
:rules="Rules.requiredInput"
>
<el-input
:placeholder="$t('database.remoteHelper')"
clearable
:autosize="{ minRows: 2, maxRows: 5 }"
type="textarea"
v-model="changeForm.privilegeIPs"
/>
<span class="input-help">{{ $t('database.remoteHelper') }}</span>
</el-form-item>
</div>
</el-col>
Expand Down Expand Up @@ -158,7 +158,7 @@ const submitChangeInfo = async (formEl: FormInstance | undefined) => {
if (changeForm.privilege !== 'ip') {
param.value = changeForm.privilege;
} else {
param.value = changeForm.privilegeIPs.replaceAll('/n', ',');
param.value = changeForm.privilegeIPs;
}
loading.value = true;
await updateMysqlAccess(param)
Expand Down