feat: Mysql 数据库增删、改密、改权限方法封装
This commit is contained in:
230
backend/utils/mysql/client/remote.go
Normal file
230
backend/utils/mysql/client/remote.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
)
|
||||
|
||||
type Remote struct {
|
||||
Client *sql.DB
|
||||
}
|
||||
|
||||
func NewRemote(client *sql.DB) *Remote {
|
||||
return &Remote{Client: client}
|
||||
}
|
||||
|
||||
func (r *Remote) Create(info CreateInfo) error {
|
||||
createSql := fmt.Sprintf("create database `%s` default character set %s collate %s", info.Name, info.Format, formatMap[info.Format])
|
||||
if err := r.ExecSQL(createSql, info.Timeout); err != nil {
|
||||
if strings.Contains(err.Error(), "ERROR 1007") {
|
||||
return buserr.New(constant.ErrDatabaseIsExist)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err := r.CreateUser(CreateInfo{Name: info.Name, Version: info.Version, UserName: info.UserName, Permission: info.Permission, Timeout: info.Timeout}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) CreateUser(info CreateInfo) error {
|
||||
var userlist []string
|
||||
if strings.Contains(info.Permission, ",") {
|
||||
ips := strings.Split(info.Permission, ",")
|
||||
for _, ip := range ips {
|
||||
if len(ip) != 0 {
|
||||
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", info.UserName, ip))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", info.UserName, info.Permission))
|
||||
}
|
||||
|
||||
for _, user := range userlist {
|
||||
if err := r.ExecSQL(fmt.Sprintf("create user %s identified by '%s';", user, info.Password), info.Timeout); err != nil {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Version: info.Version,
|
||||
UserName: info.UserName,
|
||||
Permission: info.Permission,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
if strings.Contains(err.Error(), "ERROR 1396") {
|
||||
return buserr.New(constant.ErrUserIsExist)
|
||||
}
|
||||
return err
|
||||
}
|
||||
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to %s", info.Name, user)
|
||||
if info.Name == "*" {
|
||||
grantStr = fmt.Sprintf("grant all privileges on *.* to %s", user)
|
||||
}
|
||||
if strings.HasPrefix(info.Version, "5.7") || strings.HasPrefix(info.Version, "5.6") {
|
||||
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, info.Password)
|
||||
}
|
||||
if err := r.ExecSQL(grantStr, info.Timeout); err != nil {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Version: info.Version,
|
||||
UserName: info.UserName,
|
||||
Permission: info.Permission,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) Delete(info DeleteInfo) error {
|
||||
var userlist []string
|
||||
if strings.Contains(info.Permission, ",") {
|
||||
ips := strings.Split(info.Permission, ",")
|
||||
for _, ip := range ips {
|
||||
if len(ip) != 0 {
|
||||
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", info.UserName, ip))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", info.UserName, info.Permission))
|
||||
}
|
||||
|
||||
for _, user := range userlist {
|
||||
if strings.HasPrefix(info.Version, "5.6") {
|
||||
if err := r.ExecSQL(fmt.Sprintf("drop user %s", user), info.Timeout); err != nil && !info.ForceDelete {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := r.ExecSQL(fmt.Sprintf("drop user if exists %s", user), info.Timeout); err != nil && !info.ForceDelete {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(info.Name) != 0 {
|
||||
if err := r.ExecSQL(fmt.Sprintf("drop database if exists `%s`", info.Name), info.Timeout); err != nil && !info.ForceDelete {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !info.ForceDelete {
|
||||
global.LOG.Info("execute delete database sql successful, now start to drop uploads and records")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) ChangePassword(info PasswordChangeInfo) error {
|
||||
if info.UserName != "root" {
|
||||
var userlist []string
|
||||
if strings.Contains(info.Permission, ",") {
|
||||
ips := strings.Split(info.Permission, ",")
|
||||
for _, ip := range ips {
|
||||
if len(ip) != 0 {
|
||||
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", info.UserName, ip))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
userlist = append(userlist, fmt.Sprintf("'%s'@'%s'", info.UserName, info.Permission))
|
||||
}
|
||||
|
||||
for _, user := range userlist {
|
||||
passwordChangeSql := fmt.Sprintf("set password for %s = password('%s')", user, info.Password)
|
||||
if !strings.HasPrefix(info.Version, "5.7") && !strings.HasPrefix(info.Version, "5.6") {
|
||||
passwordChangeSql = fmt.Sprintf("ALTER USER %s IDENTIFIED WITH mysql_native_password BY '%s';", user, info.Password)
|
||||
}
|
||||
if err := r.ExecSQL(passwordChangeSql, info.Timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
hosts, err := r.ExecSQLForHosts(info.Timeout)
|
||||
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.Password)
|
||||
if !strings.HasPrefix(info.Version, "5.7") && !strings.HasPrefix(info.Version, "5.6") {
|
||||
passwordRootChangeCMD = fmt.Sprintf("alter user 'root'@'%s' identified with mysql_native_password BY '%s';", host, info.Password)
|
||||
}
|
||||
if err := r.ExecSQL(passwordRootChangeCMD, info.Timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) ChangeAccess(info AccessChangeInfo) error {
|
||||
if info.UserName == "root" {
|
||||
info.OldPermission = "%"
|
||||
info.Name = "*"
|
||||
}
|
||||
if info.Permission != info.OldPermission {
|
||||
if err := r.Delete(DeleteInfo{
|
||||
Version: info.Version,
|
||||
UserName: info.UserName,
|
||||
Permission: info.OldPermission,
|
||||
ForceDelete: true,
|
||||
Timeout: 300}); err != nil {
|
||||
return err
|
||||
}
|
||||
if info.UserName == "root" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err := r.CreateUser(CreateInfo{Name: info.Name, Version: info.Version, UserName: info.UserName, Permission: info.Permission, Timeout: info.Timeout}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) Close() {
|
||||
_ = r.Client.Close()
|
||||
}
|
||||
|
||||
func (r *Remote) ExecSQL(command string, timeout uint) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if _, err := r.Client.ExecContext(ctx, command); err != nil {
|
||||
return err
|
||||
}
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return buserr.New(constant.ErrExecTimeOut)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) ExecSQLForHosts(timeout uint) ([]string, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
results, err := r.Client.QueryContext(ctx, "select host from mysql.user where user='root';")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return nil, buserr.New(constant.ErrExecTimeOut)
|
||||
}
|
||||
var rows []string
|
||||
for results.Next() {
|
||||
var host string
|
||||
if err := results.Scan(&host); err != nil {
|
||||
continue
|
||||
}
|
||||
rows = append(rows, host)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
Reference in New Issue
Block a user