diff --git a/internal/apps/mysql/service.go b/internal/apps/mysql/service.go index 27448b81f1..18eb40c051 100644 --- a/internal/apps/mysql/service.go +++ b/internal/apps/mysql/service.go @@ -199,7 +199,7 @@ func (s *Service) SetRootPassword(w http.ResponseWriter, r *http.Request) { return } } else { - if err = mysql.UserPassword("root", req.Password); err != nil { + if err = mysql.UserPassword("root", req.Password, "localhost"); err != nil { service.Error(w, http.StatusInternalServerError, "%v", err) return } diff --git a/internal/biz/database.go b/internal/biz/database.go index 7a5f35233c..8bd89eae0a 100644 --- a/internal/biz/database.go +++ b/internal/biz/database.go @@ -4,13 +4,22 @@ import ( "github.com/TheTNB/panel/internal/http/request" ) -type DatabaseStatus string +type DatabaseType string + +const ( + DatabaseTypeMysql DatabaseType = "mysql" + DatabaseTypePostgresql DatabaseType = "postgresql" + DatabaseTypeMongoDB DatabaseType = "mongodb" + DatabaseSQLite DatabaseType = "sqlite" + DatabaseTypeRedis DatabaseType = "redis" +) type Database struct { - Name string `json:"name"` - Server string `json:"server"` - ServerID uint `json:"server_id"` - Encoding string `json:"encoding"` + Type DatabaseType `json:"type"` + Name string `json:"name"` + Server string `json:"server"` + ServerID uint `json:"server_id"` + Encoding string `json:"encoding"` } type DatabaseRepo interface { diff --git a/internal/biz/database_server.go b/internal/biz/database_server.go index 6a59eb1ec5..1e928e8b52 100644 --- a/internal/biz/database_server.go +++ b/internal/biz/database_server.go @@ -9,16 +9,6 @@ import ( "github.com/TheTNB/panel/internal/http/request" ) -type DatabaseType string - -const ( - DatabaseTypeMysql DatabaseType = "mysql" - DatabaseTypePostgresql DatabaseType = "postgresql" - DatabaseTypeMongoDB DatabaseType = "mongodb" - DatabaseSQLite DatabaseType = "sqlite" - DatabaseTypeRedis DatabaseType = "redis" -) - type DatabaseServerStatus string const ( diff --git a/internal/biz/database_user.go b/internal/biz/database_user.go index ef6451a8e0..4a37af8e36 100644 --- a/internal/biz/database_user.go +++ b/internal/biz/database_user.go @@ -27,6 +27,8 @@ type DatabaseUser struct { Remark string `gorm:"not null" json:"remark"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` + + Server *DatabaseServer `gorm:"foreignKey:ServerID;references:ID" json:"server"` } func (r *DatabaseUser) BeforeSave(tx *gorm.DB) error { diff --git a/internal/data/database.go b/internal/data/database.go index 41f075fed6..dad0c55bc0 100644 --- a/internal/data/database.go +++ b/internal/data/database.go @@ -33,6 +33,7 @@ func (r databaseRepo) List(page, limit uint) ([]*biz.Database, int64, error) { if databases, err := mysql.Databases(); err == nil { for item := range slices.Values(databases) { database = append(database, &biz.Database{ + Type: biz.DatabaseTypeMysql, Name: item.Name, Server: server.Name, ServerID: server.ID, @@ -47,6 +48,7 @@ func (r databaseRepo) List(page, limit uint) ([]*biz.Database, int64, error) { if databases, err := postgres.Databases(); err == nil { for item := range slices.Values(databases) { database = append(database, &biz.Database{ + Type: biz.DatabaseTypePostgresql, Name: item.Name, Server: server.Name, ServerID: server.ID, @@ -73,28 +75,36 @@ func (r databaseRepo) Create(req *request.DatabaseCreate) error { if err != nil { return err } - if err = mysql.UserCreate(req.Username, req.Password); err != nil { - return err + if req.CreateUser { + if err = mysql.UserCreate(req.Username, req.Password, req.Host); err != nil { + return err + } } if err = mysql.DatabaseCreate(req.Name); err != nil { return err } - if err = mysql.PrivilegesGrant(req.Username, req.Name); err != nil { - return err + if req.Username != "" { + if err = mysql.PrivilegesGrant(req.Username, req.Name, req.Host); err != nil { + return err + } } case biz.DatabaseTypePostgresql: postgres, err := db.NewPostgres(server.Username, server.Password, server.Host, server.Port) if err != nil { return err } - if err = postgres.UserCreate(req.Username, req.Password); err != nil { - return err + if req.CreateUser { + if err = postgres.UserCreate(req.Username, req.Password); err != nil { + return err + } } if err = postgres.DatabaseCreate(req.Name); err != nil { return err } - if err = postgres.PrivilegesGrant(req.Username, req.Name); err != nil { - return err + if req.Username != "" { + if err = postgres.PrivilegesGrant(req.Username, req.Name); err != nil { + return err + } } } diff --git a/internal/data/database_user.go b/internal/data/database_user.go index 824fc57429..9a75dc62fe 100644 --- a/internal/data/database_user.go +++ b/internal/data/database_user.go @@ -30,7 +30,7 @@ func (r databaseUserRepo) Count() (int64, error) { func (r databaseUserRepo) List(page, limit uint) ([]*biz.DatabaseUser, int64, error) { var user []*biz.DatabaseUser var total int64 - err := app.Orm.Model(&biz.DatabaseUser{}).Order("id desc").Count(&total).Offset(int((page - 1) * limit)).Limit(int(limit)).Find(&user).Error + err := app.Orm.Model(&biz.DatabaseUser{}).Preload("Server").Order("id desc").Count(&total).Offset(int((page - 1) * limit)).Limit(int(limit)).Find(&user).Error for u := range slices.Values(user) { r.fillUser(u) @@ -41,7 +41,7 @@ func (r databaseUserRepo) List(page, limit uint) ([]*biz.DatabaseUser, int64, er func (r databaseUserRepo) Get(id uint) (*biz.DatabaseUser, error) { user := new(biz.DatabaseUser) - if err := app.Orm.Where("id = ?", id).First(user).Error; err != nil { + if err := app.Orm.Preload("Server").Where("id = ?", id).First(user).Error; err != nil { return nil, err } @@ -62,11 +62,11 @@ func (r databaseUserRepo) Create(req *request.DatabaseUserCreate) error { if err != nil { return err } - if err = mysql.UserCreate(req.Username, req.Password); err != nil { + if err = mysql.UserCreate(req.Username, req.Password, req.Host); err != nil { return err } for name := range slices.Values(req.Privileges) { - if err = mysql.PrivilegesGrant(req.Username, name); err != nil { + if err = mysql.PrivilegesGrant(req.Username, name, req.Host); err != nil { return err } } @@ -89,6 +89,7 @@ func (r databaseUserRepo) Create(req *request.DatabaseUserCreate) error { ServerID: req.ServerID, Username: req.Username, Password: req.Password, + Host: req.Host, Remark: req.Remark, } @@ -113,12 +114,12 @@ func (r databaseUserRepo) Update(req *request.DatabaseUserUpdate) error { return err } if req.Password != "" { - if err = mysql.UserPassword(user.Username, req.Password); err != nil { + if err = mysql.UserPassword(user.Username, req.Password, user.Host); err != nil { return err } } for name := range slices.Values(req.Privileges) { - if err = mysql.PrivilegesGrant(user.Username, name); err != nil { + if err = mysql.PrivilegesGrant(user.Username, name, user.Host); err != nil { return err } } diff --git a/internal/data/website.go b/internal/data/website.go index 9318fcb0c3..27cd4d3ad4 100644 --- a/internal/data/website.go +++ b/internal/data/website.go @@ -308,13 +308,13 @@ func (r *websiteRepo) Create(req *request.WebsiteCreate) (*biz.Website, error) { if err != nil { return nil, err } - if err = mysql.UserCreate(req.DBUser, req.DBPassword); err != nil { + if err = mysql.UserCreate(req.DBUser, req.DBPassword, "localhost"); err != nil { return nil, err } if err = mysql.DatabaseCreate(req.DBName); err != nil { return nil, err } - if err = mysql.PrivilegesGrant(req.DBUser, req.DBName); err != nil { + if err = mysql.PrivilegesGrant(req.DBUser, req.DBName, "localhost"); err != nil { return nil, err } } diff --git a/internal/http/request/database.go b/internal/http/request/database.go index d64a27fd4a..739b1f7251 100644 --- a/internal/http/request/database.go +++ b/internal/http/request/database.go @@ -4,8 +4,9 @@ type DatabaseCreate struct { ServerID uint `form:"server_id" json:"server_id" validate:"required,exists=database_servers id"` Name string `form:"name" json:"name" validate:"required"` CreateUser bool `form:"create_user" json:"create_user"` - Username string `form:"username" json:"username"` - Password string `form:"password" json:"password"` + Username string `form:"username" json:"username" validate:"required_if=CreateUser true"` + Password string `form:"password" json:"password" validate:"required_if=CreateUser true"` + Host string `form:"host" json:"host"` Remark string `form:"remark" json:"remark"` } diff --git a/internal/http/request/database_user.go b/internal/http/request/database_user.go index 753aba680d..a168052cc6 100644 --- a/internal/http/request/database_user.go +++ b/internal/http/request/database_user.go @@ -2,8 +2,9 @@ package request type DatabaseUserCreate struct { ServerID uint `form:"server_id" json:"server_id" validate:"required,exists=database_servers id"` - Username string `form:"username" json:"username"` - Password string `form:"password" json:"password"` + Username string `form:"username" json:"username" validate:"required"` + Password string `form:"password" json:"password" validate:"required"` + Host string `form:"host" json:"host"` Privileges []string `form:"privileges" json:"privileges"` Remark string `form:"remark" json:"remark"` } diff --git a/pkg/db/mysql.go b/pkg/db/mysql.go index f8be3c44e0..e167da8a5c 100644 --- a/pkg/db/mysql.go +++ b/pkg/db/mysql.go @@ -98,8 +98,8 @@ func (m *MySQL) DatabaseSize(name string) (int64, error) { return size, err } -func (m *MySQL) UserCreate(user, password string) error { - _, err := m.Exec(fmt.Sprintf("CREATE USER IF NOT EXISTS '%s'@'localhost' IDENTIFIED BY '%s'", user, password)) +func (m *MySQL) UserCreate(user, password, host string) error { + _, err := m.Exec(fmt.Sprintf("CREATE USER IF NOT EXISTS '%s'@'%s' IDENTIFIED BY '%s'", user, host, password)) m.flushPrivileges() return err } @@ -110,14 +110,14 @@ func (m *MySQL) UserDrop(user string) error { return err } -func (m *MySQL) UserPassword(user, password string) error { - _, err := m.Exec(fmt.Sprintf("ALTER USER '%s'@'localhost' IDENTIFIED BY '%s'", user, password)) +func (m *MySQL) UserPassword(user, password, host string) error { + _, err := m.Exec(fmt.Sprintf("ALTER USER '%s'@'%s' IDENTIFIED BY '%s'", user, host, password)) m.flushPrivileges() return err } -func (m *MySQL) PrivilegesGrant(user, database string) error { - _, err := m.Exec(fmt.Sprintf("GRANT ALL PRIVILEGES ON %s.* TO '%s'@'localhost'", database, user)) +func (m *MySQL) PrivilegesGrant(user, database, host string) error { + _, err := m.Exec(fmt.Sprintf("GRANT ALL PRIVILEGES ON %s.* TO '%s'@'%s'", database, user, host)) m.flushPrivileges() return err } @@ -164,8 +164,8 @@ func (m *MySQL) UserPrivileges(user, host string) (map[string][]string, error) { return privileges, nil } -func (m *MySQL) PrivilegesRevoke(user, database string) error { - _, err := m.Exec(fmt.Sprintf("REVOKE ALL PRIVILEGES ON %s.* FROM '%s'@'localhost'", database, user)) +func (m *MySQL) PrivilegesRevoke(user, database, host string) error { + _, err := m.Exec(fmt.Sprintf("REVOKE ALL PRIVILEGES ON %s.* FROM '%s'@'%s'", database, user, host)) m.flushPrivileges() return err } diff --git a/web/src/views/database/CreateDatabaseModal.vue b/web/src/views/database/CreateDatabaseModal.vue index 13f42cc08f..d59dca7830 100644 --- a/web/src/views/database/CreateDatabaseModal.vue +++ b/web/src/views/database/CreateDatabaseModal.vue @@ -4,12 +4,16 @@ import { NButton, NInput } from 'naive-ui' const show = defineModel('show', { type: Boolean, required: true }) const createModel = ref({ - database: '', + server_id: null, + name: '', + create_user: false, username: '', password: '', host: 'localhost' }) +const servers = ref<{ label: string; value: string }[]>([]) + const hostType = [ { label: '本地(localhost)', value: 'localhost' }, { label: '所有(%)', value: '%' }, @@ -23,6 +27,17 @@ const handleCreate = () => { window.$bus.emit('database:refresh') }) } + +onMounted(() => { + database.serverList(1, 10000).then((data: any) => { + for (const server of data.items) { + servers.value.push({ + label: server.name, + value: server.id + }) + } + }) +})