2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-05 03:22:32 +08:00
Files
panel/pkg/db/postgres.go
耗子 194287554e refactor: migrate to chi framework (#165)
* refactor: 重构部分完成

* fix: 添加.gitkeep

* fix: build

* fix: lint

* fix: lint

* chore(deps): Update module github.com/go-playground/validator/v10 to v10.22.1 (#162)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): Update module gorm.io/gorm to v1.25.12 (#161)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): Update module golang.org/x/net to v0.29.0 (#159)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* workflow: 更新工作流

* workflow: test new download

* feat: merge frontend project

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: fix frontend build

* workflow: update to ubuntu-24.04

* workflow: rename build-*

* workflow: 修改fetch-depth

* chore(deps): Update dependency eslint to v9 (#164)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(frontend): update dependences

* chore(frontend): fix lint

* chore(frontend): fix lint

* workflow: add govulncheck

* workflow: disable nilaway

* feat: 使用新的压缩解压库

* fix: 测试

* fix: 测试

* fix: 测试

* feat: 添加ntp包

* chore(deps): Lock file maintenance (#168)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): Update module github.com/go-resty/resty/v2 to v2.15.0 (#167)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): Update dependency @iconify/json to v2.2.249 (#169)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat: 添加限流器

* feat: 调整登录限流

* feat: 证书

* fix: lint

* feat: 证书dns

* feat: 证书acme账号

* fix: 修改UserID导致的一系列问题

* feat: 低配版任务队列

* feat: 队列完成

* fix: lint

* fix: lint

* fix: swagger和前端路由

* fix: 去掉ntp测试

* feat: 完成插件接口

* feat: 完成cron

* feat: 完成safe

* chore(deps): Update dependency vue to v3.5.6 (#170)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): Update dependency @vueuse/core to v11.1.0 (#171)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): Update dependency vite to v5.4.6 (#173)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): Update unocss monorepo to v0.62.4 (#172)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore: update renovate config

* feat: 新的firewall客户端

* fix: lint

* feat: firewall完成

* feat: ssh完成

* feat: 容器完成1/2

* feat: 容器完成

* feat: 文件完成

* feat: systemctl及设置

* fix: windows编译

* fix: session not work

* fix: migrate not work

* feat: 前端路由

* feat: 初步支持cli

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-18 01:43:14 +08:00

207 lines
5.2 KiB
Go

package db
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
"github.com/TheTNB/panel/pkg/io"
"github.com/TheTNB/panel/pkg/shell"
"github.com/TheTNB/panel/pkg/systemctl"
"github.com/TheTNB/panel/pkg/types"
)
type Postgres struct {
db *sql.DB
username string
password string
address string
port uint
}
func NewPostgres(username, password, address string, port uint) (*Postgres, error) {
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=postgres sslmode=disable", address, port, username, password)
if password == "" {
dsn = fmt.Sprintf("host=%s port=%d user=%s dbname=postgres sslmode=disable", address, port, username)
}
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, fmt.Errorf("初始化Postgres连接失败: %w", err)
}
if db.Ping() != nil {
return nil, fmt.Errorf("连接Postgres失败: %w", err)
}
return &Postgres{
db: db,
username: username,
password: password,
address: address,
port: port,
}, nil
}
func (m *Postgres) Close() error {
return m.db.Close()
}
func (m *Postgres) Ping() error {
return m.db.Ping()
}
func (m *Postgres) Query(query string, args ...any) (*sql.Rows, error) {
return m.db.Query(query, args...)
}
func (m *Postgres) QueryRow(query string, args ...any) *sql.Row {
return m.db.QueryRow(query, args...)
}
func (m *Postgres) Exec(query string, args ...any) (sql.Result, error) {
return m.db.Exec(query, args...)
}
func (m *Postgres) Prepare(query string) (*sql.Stmt, error) {
return m.db.Prepare(query)
}
func (m *Postgres) DatabaseCreate(name string) error {
_, err := m.Exec(fmt.Sprintf("CREATE DATABASE %s", name))
return err
}
func (m *Postgres) DatabaseDrop(name string) error {
_, err := m.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", name))
return err
}
func (m *Postgres) UserCreate(user, password string) error {
_, err := m.Exec(fmt.Sprintf("CREATE USER %s WITH PASSWORD '%s'", user, password))
if err != nil {
return err
}
return nil
}
func (m *Postgres) UserDrop(user string) error {
_, err := m.Exec(fmt.Sprintf("DROP USER IF EXISTS %s", user))
if err != nil {
return err
}
_, _ = shell.Execf(`sed -i '/%s/d' /www/server/postgresql/data/pg_hba.conf`, user)
return systemctl.Reload("postgresql")
}
func (m *Postgres) UserPassword(user, password string) error {
_, err := m.Exec(fmt.Sprintf("ALTER USER %s WITH PASSWORD '%s'", user, password))
return err
}
func (m *Postgres) PrivilegesGrant(user, database string) error {
if _, err := m.Exec(fmt.Sprintf("ALTER DATABASE %s OWNER TO %s", database, user)); err != nil {
return err
}
if _, err := m.Exec(fmt.Sprintf("GRANT ALL PRIVILEGES ON DATABASE %s TO %s", database, user)); err != nil {
return err
}
return nil
}
func (m *Postgres) PrivilegesRevoke(user, database string) error {
_, err := m.Exec(fmt.Sprintf("REVOKE ALL PRIVILEGES ON DATABASE %s FROM %s", database, user))
return err
}
func (m *Postgres) HostAdd(database, user, host string) error {
config := fmt.Sprintf("host %s %s %s scram-sha-256", database, user, host)
if err := io.WriteAppend("/www/server/postgresql/data/pg_hba.conf", config); err != nil {
return err
}
return systemctl.Reload("postgresql")
}
func (m *Postgres) HostRemove(database, user, host string) error {
regex := fmt.Sprintf(`host\s+%s\s+%s\s+%s`, database, user, host)
if _, err := shell.Execf(`sed -i '/%s/d' /www/server/postgresql/data/pg_hba.conf`, regex); err != nil {
return err
}
return systemctl.Reload("postgresql")
}
func (m *Postgres) Users() ([]types.PostgresUser, error) {
query := `
SELECT rolname,
rolsuper,
rolcreaterole,
rolcreatedb,
rolreplication,
rolbypassrls
FROM pg_roles
WHERE rolcanlogin = true;
`
rows, err := m.Query(query)
if err != nil {
return nil, err
}
defer rows.Close()
var users []types.PostgresUser
for rows.Next() {
var user types.PostgresUser
var super, canCreateRole, canCreateDb, replication, bypassRls bool
if err = rows.Scan(&user.Role, &super, &canCreateRole, &canCreateDb, &replication, &bypassRls); err != nil {
return nil, err
}
permissions := map[string]bool{
"超级用户": super,
"创建角色": canCreateRole,
"创建数据库": canCreateDb,
"可以复制": replication,
"绕过行级安全": bypassRls,
}
for perm, enabled := range permissions {
if enabled {
user.Attributes = append(user.Attributes, perm)
}
}
if len(user.Attributes) == 0 {
user.Attributes = append(user.Attributes, "无")
}
users = append(users, user)
}
return users, nil
}
func (m *Postgres) Databases() ([]types.PostgresDatabase, error) {
query := `
SELECT d.datname, pg_catalog.pg_get_userbyid(d.datdba), pg_catalog.pg_encoding_to_char(d.encoding)
FROM pg_catalog.pg_database d
WHERE datistemplate = false;
`
rows, err := m.Query(query)
if err != nil {
return nil, err
}
defer rows.Close()
var databases []types.PostgresDatabase
for rows.Next() {
var db types.PostgresDatabase
if err := rows.Scan(&db.Name, &db.Owner, &db.Encoding); err != nil {
return nil, err
}
databases = append(databases, db)
}
return databases, nil
}