mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 00:09:16 +08:00
feat: PostgreSQL 增加权限设置 (#3537)
This commit is contained in:
parent
51077b0597
commit
9a905750af
@ -85,6 +85,28 @@ func (b *BaseApi) UpdatePostgresqlDescription(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database Postgresql
|
||||
// @Summary Change postgresql privileges
|
||||
// @Description 修改 postgresql 用户权限
|
||||
// @Accept json
|
||||
// @Param request body dto.ChangeDBInfo true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/pg/privileges [post]
|
||||
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新数据库 [database] 用户 [username] 权限","formatEN":"Update [user] privileges of database [database]"}
|
||||
func (b *BaseApi) ChangePostgresqlPrivileges(c *gin.Context) {
|
||||
var req dto.PostgresqlPrivileges
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := postgresqlService.ChangePrivileges(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database Postgresql
|
||||
// @Summary Change postgresql password
|
||||
// @Description 修改 postgresql 密码
|
||||
|
@ -19,7 +19,7 @@ type PostgresqlDBInfo struct {
|
||||
Format string `json:"format"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Permission string `json:"permission"`
|
||||
SuperUser bool `json:"superUser"`
|
||||
BackupCount int `json:"backupCount"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
@ -39,15 +39,23 @@ type PostgresqlDBCreate struct {
|
||||
Format string `json:"format"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Permission string `json:"permission" validate:"required"`
|
||||
SuperUser bool `json:"superUser"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type PostgresqlBindUser struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
SuperUser bool `json:"superUser"`
|
||||
}
|
||||
|
||||
type PostgresqlPrivileges struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
SuperUser bool `json:"superUser"`
|
||||
}
|
||||
|
||||
type PostgresqlLoadDB struct {
|
||||
|
@ -8,5 +8,6 @@ type DatabasePostgresql struct {
|
||||
Format string `json:"format" gorm:"type:varchar(64);not null"`
|
||||
Username string `json:"username" gorm:"type:varchar(256);not null"`
|
||||
Password string `json:"password" gorm:"type:varchar(256);not null"`
|
||||
SuperUser bool `json:"superUser" gorm:"type:varchar(64)" `
|
||||
Description string `json:"description" gorm:"type:varchar(256);"`
|
||||
}
|
||||
|
@ -4,13 +4,14 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
@ -307,13 +308,13 @@ func reCreatePostgresqlDB(dbID uint, database model.Database, oldEnv string) (*m
|
||||
oldUser, _ := envMap["PANEL_DB_USER"].(string)
|
||||
oldPassword, _ := envMap["PANEL_DB_USER_PASSWORD"].(string)
|
||||
createDB, err := postgresqlService.Create(context.Background(), dto.PostgresqlDBCreate{
|
||||
Name: oldName,
|
||||
From: database.From,
|
||||
Database: database.Name,
|
||||
Format: "UTF8",
|
||||
Username: oldUser,
|
||||
Password: oldPassword,
|
||||
Permission: "%",
|
||||
Name: oldName,
|
||||
From: database.From,
|
||||
Database: database.Name,
|
||||
Format: "UTF8",
|
||||
Username: oldUser,
|
||||
Password: oldPassword,
|
||||
SuperUser: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, envMap, err
|
||||
|
@ -29,6 +29,7 @@ type IPostgresqlService interface {
|
||||
BindUser(req dto.PostgresqlBindUser) error
|
||||
Create(ctx context.Context, req dto.PostgresqlDBCreate) (*model.DatabasePostgresql, error)
|
||||
LoadFromRemote(database string) error
|
||||
ChangePrivileges(req dto.PostgresqlPrivileges) error
|
||||
ChangePassword(info dto.ChangeDBInfo) error
|
||||
UpdateDescription(req dto.UpdateDescription) error
|
||||
DeleteCheck(req dto.PostgresqlDBDeleteCheck) ([]string, error)
|
||||
@ -84,6 +85,9 @@ func (u *PostgresqlService) ListDBOption() ([]dto.PostgresqlOption, error) {
|
||||
}
|
||||
|
||||
func (u *PostgresqlService) BindUser(req dto.PostgresqlBindUser) error {
|
||||
if cmd.CheckIllegal(req.Name, req.Username, req.Password) {
|
||||
return buserr.New(constant.ErrCmdIllegal)
|
||||
}
|
||||
dbItem, err := postgresqlRepo.Get(postgresqlRepo.WithByPostgresqlName(req.Database), commonRepo.WithByName(req.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -94,10 +98,11 @@ func (u *PostgresqlService) BindUser(req dto.PostgresqlBindUser) error {
|
||||
return err
|
||||
}
|
||||
if err := pgClient.CreateUser(client.CreateInfo{
|
||||
Name: req.Name,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
Timeout: 300,
|
||||
Name: req.Name,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
SuperUser: req.SuperUser,
|
||||
Timeout: 300,
|
||||
}, false); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -106,8 +111,9 @@ func (u *PostgresqlService) BindUser(req dto.PostgresqlBindUser) error {
|
||||
return fmt.Errorf("decrypt database db password failed, err: %v", err)
|
||||
}
|
||||
if err := postgresqlRepo.Update(dbItem.ID, map[string]interface{}{
|
||||
"username": req.Username,
|
||||
"password": pass,
|
||||
"username": req.Username,
|
||||
"password": pass,
|
||||
"super_user": req.SuperUser,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -142,10 +148,11 @@ func (u *PostgresqlService) Create(ctx context.Context, req dto.PostgresqlDBCrea
|
||||
createItem.PostgresqlName = req.Database
|
||||
defer cli.Close()
|
||||
if err := cli.Create(client.CreateInfo{
|
||||
Name: req.Name,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
Timeout: 300,
|
||||
Name: req.Name,
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
SuperUser: req.SuperUser,
|
||||
Timeout: 300,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -306,6 +313,31 @@ func (u *PostgresqlService) Delete(ctx context.Context, req dto.PostgresqlDBDele
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *PostgresqlService) ChangePrivileges(req dto.PostgresqlPrivileges) error {
|
||||
if cmd.CheckIllegal(req.Database, req.Username) {
|
||||
return buserr.New(constant.ErrCmdIllegal)
|
||||
}
|
||||
dbItem, err := postgresqlRepo.Get(postgresqlRepo.WithByPostgresqlName(req.Database), commonRepo.WithByName(req.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli, err := LoadPostgresqlClientByFrom(req.Database)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cli.Close()
|
||||
|
||||
if err := cli.ChangePrivileges(client.Privileges{Username: req.Username, SuperUser: req.SuperUser, Timeout: 300}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := postgresqlRepo.Update(dbItem.ID, map[string]interface{}{
|
||||
"super_user": req.SuperUser,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *PostgresqlService) ChangePassword(req dto.ChangeDBInfo) error {
|
||||
if cmd.CheckIllegal(req.Value) {
|
||||
return buserr.New(constant.ErrCmdIllegal)
|
||||
|
@ -64,6 +64,7 @@ func Init() {
|
||||
|
||||
migrations.AddTablePHPExtensions,
|
||||
migrations.AddTableDatabasePostgresql,
|
||||
migrations.AddPostgresqlSuperUser,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
@ -148,3 +148,13 @@ var AddTableDatabasePostgresql = &gormigrate.Migration{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var AddPostgresqlSuperUser = &gormigrate.Migration{
|
||||
ID: "20231225-add-postgresql-super_user",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.DatabasePostgresql{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ func (s *DatabaseRouter) InitRouter(Router *gin.RouterGroup) {
|
||||
cmdRouter.POST("/pg/bind", baseApi.BindPostgresqlUser)
|
||||
cmdRouter.POST("/pg/del/check", baseApi.DeleteCheckPostgresql)
|
||||
cmdRouter.POST("/pg/del", baseApi.DeletePostgresql)
|
||||
cmdRouter.POST("/pg/privileges", baseApi.ChangePostgresqlPrivileges)
|
||||
cmdRouter.POST("/pg/password", baseApi.ChangePostgresqlPassword)
|
||||
cmdRouter.POST("/pg/description", baseApi.UpdatePostgresqlDescription)
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ type PostgresqlClient interface {
|
||||
Create(info client.CreateInfo) error
|
||||
CreateUser(info client.CreateInfo, withDeleteDB bool) error
|
||||
Delete(info client.DeleteInfo) error
|
||||
ChangePrivileges(info client.Privileges) error
|
||||
ChangePassword(info client.PasswordChangeInfo) error
|
||||
|
||||
Backup(info client.BackupInfo) error
|
||||
|
@ -16,9 +16,17 @@ type DBInfo struct {
|
||||
}
|
||||
|
||||
type CreateInfo struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"userName"`
|
||||
Password string `json:"password"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"userName"`
|
||||
Password string `json:"password"`
|
||||
SuperUser bool `json:"superUser"`
|
||||
|
||||
Timeout uint `json:"timeout"` // second
|
||||
}
|
||||
|
||||
type Privileges struct {
|
||||
Username string `json:"userName"`
|
||||
SuperUser bool `json:"superUser"`
|
||||
|
||||
Timeout uint `json:"timeout"` // second
|
||||
}
|
||||
|
@ -46,6 +46,15 @@ func (r *Local) Create(info CreateInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Local) ChangePrivileges(info Privileges) error {
|
||||
super := "SUPERUSER"
|
||||
if !info.SuperUser {
|
||||
super = "NOSUPERUSER"
|
||||
}
|
||||
changeSql := fmt.Sprintf("ALTER USER \"%s\" WITH %s", info.Username, super)
|
||||
return r.ExecSQL(changeSql, info.Timeout)
|
||||
}
|
||||
|
||||
func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error {
|
||||
createSql := fmt.Sprintf("CREATE USER \"%s\" WITH PASSWORD '%s'", info.Username, info.Password)
|
||||
if err := r.ExecSQL(createSql, info.Timeout); err != nil {
|
||||
@ -61,6 +70,18 @@ func (r *Local) CreateUser(info CreateInfo, withDeleteDB bool) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
if info.SuperUser {
|
||||
if err := r.ChangePrivileges(Privileges{SuperUser: true, Username: info.Username, Timeout: info.Timeout}); err != nil {
|
||||
if withDeleteDB {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Username: info.Username,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
grantStr := fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE \"%s\" TO \"%s\"", info.Name, info.Username)
|
||||
if err := r.ExecSQL(grantStr, info.Timeout); err != nil {
|
||||
if withDeleteDB {
|
||||
|
@ -65,6 +65,18 @@ func (r *Remote) CreateUser(info CreateInfo, withDeleteDB bool) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
if info.SuperUser {
|
||||
if err := r.ChangePrivileges(Privileges{SuperUser: true, Username: info.Username, Timeout: info.Timeout}); err != nil {
|
||||
if withDeleteDB {
|
||||
_ = r.Delete(DeleteInfo{
|
||||
Name: info.Name,
|
||||
Username: info.Username,
|
||||
ForceDelete: true,
|
||||
Timeout: 300})
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
grantSql := fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE \"%s\" TO \"%s\"", info.Name, info.Username)
|
||||
if err := r.ExecSQL(grantSql, info.Timeout); err != nil {
|
||||
if withDeleteDB {
|
||||
@ -97,6 +109,14 @@ func (r *Remote) Delete(info DeleteInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Remote) ChangePrivileges(info Privileges) error {
|
||||
super := "SUPERUSER"
|
||||
if !info.SuperUser {
|
||||
super = "NOSUPERUSER"
|
||||
}
|
||||
return r.ExecSQL(fmt.Sprintf("ALTER USER \"%s\" WITH %s", info.Username, super), info.Timeout)
|
||||
}
|
||||
|
||||
func (r *Remote) ChangePassword(info PasswordChangeInfo) error {
|
||||
return r.ExecSQL(fmt.Sprintf("ALTER USER \"%s\" WITH ENCRYPTED PASSWORD '%s'", info.Username, info.Password), info.Timeout)
|
||||
}
|
||||
|
@ -5016,6 +5016,49 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/pg/privileges": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "修改 postgresql 用户权限",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Database Postgresql"
|
||||
],
|
||||
"summary": "Change postgresql privileges",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.ChangeDBInfo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFunctions": [],
|
||||
"bodyKeys": [
|
||||
"database",
|
||||
"username"
|
||||
],
|
||||
"formatEN": "Update [user] privileges of database [database]",
|
||||
"formatZH": "更新数据库 [database] 用户 [username] 权限",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/pg/search": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -16942,6 +16985,9 @@ const docTemplate = `{
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"superUser": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
@ -16954,7 +17000,6 @@ const docTemplate = `{
|
||||
"from",
|
||||
"name",
|
||||
"password",
|
||||
"permission",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
@ -16980,8 +17025,8 @@ const docTemplate = `{
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"permission": {
|
||||
"type": "string"
|
||||
"superUser": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
|
@ -5009,6 +5009,49 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/pg/privileges": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "修改 postgresql 用户权限",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Database Postgresql"
|
||||
],
|
||||
"summary": "Change postgresql privileges",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.ChangeDBInfo"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFunctions": [],
|
||||
"bodyKeys": [
|
||||
"database",
|
||||
"username"
|
||||
],
|
||||
"formatEN": "Update [user] privileges of database [database]",
|
||||
"formatZH": "更新数据库 [database] 用户 [username] 权限",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/databases/pg/search": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -16935,6 +16978,9 @@
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"superUser": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
@ -16947,7 +16993,6 @@
|
||||
"from",
|
||||
"name",
|
||||
"password",
|
||||
"permission",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
@ -16973,8 +17018,8 @@
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"permission": {
|
||||
"type": "string"
|
||||
"superUser": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
|
@ -2008,6 +2008,8 @@ definitions:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
superUser:
|
||||
type: boolean
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
@ -2033,8 +2035,8 @@ definitions:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
permission:
|
||||
type: string
|
||||
superUser:
|
||||
type: boolean
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
@ -2042,7 +2044,6 @@ definitions:
|
||||
- from
|
||||
- name
|
||||
- password
|
||||
- permission
|
||||
- username
|
||||
type: object
|
||||
dto.PostgresqlDBDelete:
|
||||
@ -8160,6 +8161,34 @@ paths:
|
||||
formatEN: Update database [name] password
|
||||
formatZH: 更新数据库 [name] 密码
|
||||
paramKeys: []
|
||||
/databases/pg/privileges:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 修改 postgresql 用户权限
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.ChangeDBInfo'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Change postgresql privileges
|
||||
tags:
|
||||
- Database Postgresql
|
||||
x-panel-log:
|
||||
BeforeFunctions: []
|
||||
bodyKeys:
|
||||
- database
|
||||
- username
|
||||
formatEN: Update [user] privileges of database [database]
|
||||
formatZH: 更新数据库 [database] 用户 [username] 权限
|
||||
paramKeys: []
|
||||
/databases/pg/search:
|
||||
post:
|
||||
consumes:
|
||||
|
@ -151,6 +151,13 @@ export namespace Database {
|
||||
database: string;
|
||||
username: string;
|
||||
password: string;
|
||||
superUser: boolean;
|
||||
}
|
||||
export interface PgChangePrivileges {
|
||||
name: string;
|
||||
database: string;
|
||||
username: string;
|
||||
superUser: boolean;
|
||||
}
|
||||
export interface PostgresqlDBDelete {
|
||||
id: number;
|
||||
@ -159,18 +166,6 @@ export namespace Database {
|
||||
forceDelete: boolean;
|
||||
deleteBackup: boolean;
|
||||
}
|
||||
export interface PostgresqlStatus {
|
||||
uptime: string;
|
||||
version: string;
|
||||
max_connections: string;
|
||||
autovacuum: string;
|
||||
current_connections: string;
|
||||
hit_ratio: string;
|
||||
shared_buffers: string;
|
||||
buffers_clean: string;
|
||||
maxwritten_clean: string;
|
||||
buffers_backend_fsync: string;
|
||||
}
|
||||
export interface PostgresqlDBDeleteCheck {
|
||||
id: number;
|
||||
type: string;
|
||||
@ -199,7 +194,7 @@ export namespace Database {
|
||||
format: string;
|
||||
username: string;
|
||||
password: string;
|
||||
permission: string;
|
||||
superUser: boolean;
|
||||
description: string;
|
||||
}
|
||||
export interface PostgresqlDBInfo {
|
||||
@ -211,7 +206,7 @@ export namespace Database {
|
||||
format: string;
|
||||
username: string;
|
||||
password: string;
|
||||
permission: string;
|
||||
superUser: boolean;
|
||||
description: string;
|
||||
}
|
||||
export interface ChangeInfo {
|
||||
|
@ -27,6 +27,9 @@ export const addPostgresqlDB = (params: Database.PostgresqlDBCreate) => {
|
||||
export const bindPostgresqlUser = (params: Database.PgBind) => {
|
||||
return http.post(`/databases/pg/bind`, params, TimeoutEnum.T_40S);
|
||||
};
|
||||
export const changePrivileges = (params: Database.PgChangePrivileges) => {
|
||||
return http.post(`/databases/pg/privileges`, params, TimeoutEnum.T_40S);
|
||||
};
|
||||
export const searchPostgresqlDBs = (params: Database.SearchDBWithPage) => {
|
||||
return http.post<ResPage<Database.PostgresqlDBInfo>>(`/databases/pg/search`, params);
|
||||
};
|
||||
|
@ -383,7 +383,9 @@ const message = {
|
||||
|
||||
loadFromRemote: 'Load from server',
|
||||
userBind: 'Bind User',
|
||||
pgBind: 'Bind User (Binding existing users is not currently supported)',
|
||||
pgBindHelper:
|
||||
'This operation is used to create a new user and bind it to the target database. Currently, selecting users already existing in the database is not supported.',
|
||||
pgSuperUser: 'Super User',
|
||||
loadFromRemoteHelper:
|
||||
'This action will synchronize the database info on the server to 1Panel, do you want to continue?',
|
||||
passwordHelper: 'Unable to retrieve, please modify',
|
||||
|
@ -376,7 +376,8 @@ const message = {
|
||||
|
||||
loadFromRemote: '從服務器獲取',
|
||||
userBind: '綁定使用者',
|
||||
pgBind: '綁定用戶 (暫不支持綁定已有用戶)',
|
||||
pgBindHelper: '此操作用於創建新使用者並將其綁定到目標資料庫,暫不支援選擇已存在於資料庫中的使用者。',
|
||||
pgSuperUser: '超級使用者',
|
||||
loadFromRemoteHelper: '此操作將同步服務器上數據庫信息到 1Panel,是否繼續?',
|
||||
passwordHelper: '無法獲取密碼,請修改',
|
||||
local: '本地',
|
||||
|
@ -376,7 +376,8 @@ const message = {
|
||||
|
||||
loadFromRemote: '从服务器获取',
|
||||
userBind: '绑定用户',
|
||||
pgBind: '绑定用户 (暂不支持绑定已有用户)',
|
||||
pgBindHelper: '该操作用于创建新用户并将其绑定到目标数据库,暂不支持选择已存在于数据库中的用户。',
|
||||
pgSuperUser: '超级用户',
|
||||
loadFromRemoteHelper: '此操作将同步服务器上数据库信息到 1Panel,是否继续?',
|
||||
passwordHelper: '无法获取密码,请修改',
|
||||
local: '本地',
|
||||
|
@ -7,12 +7,16 @@
|
||||
<el-form v-loading="loading" ref="changeFormRef" :model="form" :rules="rules" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('database.pgBind')" prop="username">
|
||||
<el-alert type="warning" :title="$t('database.pgBindHelper')" :closable="false" />
|
||||
<el-form-item class="mt-5" :label="$t('database.userBind')" prop="username">
|
||||
<el-input v-model="form.username" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.login.password')" prop="password">
|
||||
<el-input type="password" clearable show-password v-model="form.password" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.permission')" prop="superUser">
|
||||
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
@ -49,6 +53,7 @@ const form = reactive({
|
||||
name: '',
|
||||
username: '',
|
||||
password: '',
|
||||
superUser: true,
|
||||
});
|
||||
const confirmDialogRef = ref();
|
||||
|
||||
@ -81,6 +86,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
database: form.database,
|
||||
username: form.username,
|
||||
password: form.password,
|
||||
superUser: form.superUser,
|
||||
};
|
||||
loading.value = true;
|
||||
await bindPostgresqlUser(param)
|
||||
|
@ -20,6 +20,9 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.permission')" prop="superUser">
|
||||
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('commons.table.type')" prop="database">
|
||||
<el-tag>{{ form.database + ' [' + form.type + ']' }}</el-tag>
|
||||
@ -66,8 +69,7 @@ const form = reactive({
|
||||
format: '',
|
||||
username: '',
|
||||
password: '',
|
||||
permission: '',
|
||||
permissionIPs: '',
|
||||
superUser: true,
|
||||
description: '',
|
||||
});
|
||||
const rules = reactive({
|
||||
@ -91,8 +93,7 @@ const acceptParams = (params: DialogProps): void => {
|
||||
form.database = params.database;
|
||||
form.format = 'UTF8';
|
||||
form.username = '';
|
||||
form.permission = '%';
|
||||
form.permissionIPs = '';
|
||||
form.superUser = true;
|
||||
form.description = '';
|
||||
random();
|
||||
createVisible.value = true;
|
||||
|
@ -207,6 +207,7 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<PrivilegesDialog ref="privilegesRef" @search="search" />
|
||||
<BindDialog ref="bindRef" @search="search" />
|
||||
<PasswordDialog ref="passwordRef" @search="search" />
|
||||
<RootPasswordDialog ref="connRef" />
|
||||
@ -226,6 +227,7 @@ import BindDialog from '@/views/database/postgresql/bind/index.vue';
|
||||
import OperateDialog from '@/views/database/postgresql/create/index.vue';
|
||||
import DeleteDialog from '@/views/database/postgresql/delete/index.vue';
|
||||
import PasswordDialog from '@/views/database/postgresql/password/index.vue';
|
||||
import PrivilegesDialog from '@/views/database/postgresql/privileges/index.vue';
|
||||
import RootPasswordDialog from '@/views/database/postgresql/conn/index.vue';
|
||||
import AppResources from '@/views/database/postgresql/check/index.vue';
|
||||
import AppStatus from '@/components/app-status/index.vue';
|
||||
@ -264,6 +266,7 @@ const currentDBName = ref();
|
||||
const checkRef = ref();
|
||||
const deleteRef = ref();
|
||||
const bindRef = ref();
|
||||
const privilegesRef = ref();
|
||||
|
||||
const pgadminPort = ref();
|
||||
const dashboardName = ref();
|
||||
@ -508,6 +511,21 @@ const buttons = [
|
||||
onChangePassword(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('database.permission'),
|
||||
disabled: (row: Database.PostgresqlDBInfo) => {
|
||||
return !row.username;
|
||||
},
|
||||
click: (row: Database.PostgresqlDBInfo) => {
|
||||
let param = {
|
||||
database: currentDBName.value,
|
||||
name: row.name,
|
||||
username: row.username,
|
||||
superUser: row.superUser,
|
||||
};
|
||||
privilegesRef.value.acceptParams(param);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('database.backupList'),
|
||||
click: (row: Database.PostgresqlDBInfo) => {
|
||||
|
93
frontend/src/views/database/postgresql/privileges/index.vue
Normal file
93
frontend/src/views/database/postgresql/privileges/index.vue
Normal file
@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-drawer v-model="changeVisible" :destroy-on-close="true" :close-on-click-modal="false" width="30%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('database.permission')" :resource="form.name" :back="handleClose" />
|
||||
</template>
|
||||
<el-form v-loading="loading" :model="form" label-position="top">
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item :label="$t('database.userBind')">
|
||||
<el-tag>
|
||||
{{ form.username }}
|
||||
</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.permission')" prop="superUser">
|
||||
<el-checkbox v-model="form.superUser">{{ $t('database.pgSuperUser') }}</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button :disabled="loading" @click="changeVisible = false">
|
||||
{{ $t('commons.button.cancel') }}
|
||||
</el-button>
|
||||
<el-button :disabled="loading" type="primary" @click="onSubmit()">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { ElForm } from 'element-plus';
|
||||
import { changePrivileges } from '@/api/modules/database';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const loading = ref();
|
||||
const changeVisible = ref(false);
|
||||
const form = reactive({
|
||||
database: '',
|
||||
name: '',
|
||||
username: '',
|
||||
superUser: true,
|
||||
});
|
||||
|
||||
interface DialogProps {
|
||||
database: string;
|
||||
name: string;
|
||||
username: string;
|
||||
superUser: boolean;
|
||||
}
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
form.database = params.database;
|
||||
form.name = params.name;
|
||||
form.username = params.username;
|
||||
form.superUser = params.superUser;
|
||||
changeVisible.value = true;
|
||||
};
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
const handleClose = () => {
|
||||
changeVisible.value = false;
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
let param = {
|
||||
name: form.name,
|
||||
database: form.database,
|
||||
username: form.username,
|
||||
superUser: form.superUser,
|
||||
};
|
||||
loading.value = true;
|
||||
await changePrivileges(param)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
emit('search');
|
||||
changeVisible.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
Loading…
x
Reference in New Issue
Block a user