Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e925a34

Browse files
committed
Merge branch '124-db-for-restricted-user' into 'master'
feat: allow defining a database name for a restricted user (joe#124) Closes #124 See merge request postgres-ai/database-lab!259
2 parents 5016f88 + a3c7bb8 commit e925a34

File tree

9 files changed

+62
-42
lines changed

9 files changed

+62
-42
lines changed

api/swagger-spec/dblab_server_swagger.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ definitions:
389389
restricted:
390390
type: "boolean"
391391
default: false
392+
db_name:
393+
type: "string"
392394

393395
UpdateClone:
394396
type: "object"

cmd/cli/commands/clone/actions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ func create(cliCtx *cli.Context) error {
5858
Username: cliCtx.String("username"),
5959
Password: cliCtx.String("password"),
6060
Restricted: cliCtx.Bool("restricted"),
61+
DBName: cliCtx.String("db-name"),
6162
},
6263
}
6364

cmd/cli/commands/clone/command_list.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ func CommandList() []*cli.Command {
4747
Name: "restricted",
4848
Usage: "create a user with restricted permissions",
4949
},
50+
&cli.StringFlag{
51+
Name: "db-name",
52+
Usage: "available database for a user with restricted permissions",
53+
},
5054
&cli.StringFlag{
5155
Name: "id",
5256
Usage: "clone ID (optional)",

pkg/client/dblabapi/types/clone.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type DatabaseRequest struct {
2424
Username string `json:"username"`
2525
Password string `json:"password"`
2626
Restricted bool `json:"restricted"`
27+
DBName string `json:"db_name"`
2728
}
2829

2930
// SnapshotCloneFieldRequest represents snapshot params of a create request.

pkg/services/cloning/mode_base.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,15 @@ func (c *baseCloning) CreateClone(cloneRequest *types.CloneCreateRequest) (*mode
139139

140140
c.setWrapper(clone.ID, w)
141141

142+
ephemeralUser := resources.EphemeralUser{
143+
Name: w.username,
144+
Password: w.password,
145+
Restricted: cloneRequest.DB.Restricted,
146+
AvailableDB: cloneRequest.DB.DBName,
147+
}
148+
142149
go func() {
143-
session, err := c.provision.StartSession(w.username, w.password, w.snapshot.ID, cloneRequest.DB.Restricted, cloneRequest.ExtraConf)
150+
session, err := c.provision.StartSession(w.snapshot.ID, ephemeralUser, cloneRequest.ExtraConf)
144151
if err != nil {
145152
// TODO(anatoly): Empty room case.
146153
log.Errf("Failed to start session: %v.", err)

pkg/services/provision/databases/postgres/postgres.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func Start(r runners.Runner, c *resources.AppConfig) error {
7373
return errors.Wrap(fmt.Errorf("postgres fatal error"), "cannot start Postgres")
7474
}
7575

76-
out, err := runSimpleSQL("select pg_is_in_recovery()", c)
76+
out, err := runSimpleSQL("select pg_is_in_recovery()", getPgConnStr(c.Host, c.DB.DBName, c.DB.Username, c.Port))
7777

7878
if err == nil {
7979
// Server does not need promotion if it is not in recovery.
@@ -148,23 +148,22 @@ func pgctlPromote(r runners.Runner, c *resources.AppConfig) (string, error) {
148148
}
149149

150150
// Generate postgres connection string.
151-
func getPgConnStr(c *resources.AppConfig) string {
151+
func getPgConnStr(host, dbname, username string, port uint) string {
152152
var sb strings.Builder
153153

154-
if c.Host != "" {
155-
sb.WriteString("host=" + c.Host + " ")
154+
if host != "" {
155+
sb.WriteString("host=" + host + " ")
156156
}
157157

158-
sb.WriteString("port=" + strconv.Itoa(int(c.Port)) + " ")
159-
sb.WriteString("dbname=" + c.DB.DBName + " ")
160-
sb.WriteString("user=" + c.DB.Username + " ")
158+
sb.WriteString("port=" + strconv.Itoa(int(port)) + " ")
159+
sb.WriteString("dbname=" + dbname + " ")
160+
sb.WriteString("user=" + username + " ")
161161

162162
return sb.String()
163163
}
164164

165-
// Executes simple SQL commands which returns one string value.
166-
func runSimpleSQL(command string, c *resources.AppConfig) (string, error) {
167-
connStr := getPgConnStr(c)
165+
// runSimpleSQL executes simple SQL commands which returns one string value.
166+
func runSimpleSQL(command, connStr string) (string, error) {
168167
db, err := sql.Open("postgres", connStr)
169168

170169
if err != nil {

pkg/services/provision/databases/postgres/postgres_mgmt.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func ResetAllPasswords(c *resources.AppConfig, whitelistUsers []string) error {
5959
query := strings.Replace(ResetPasswordsQuery,
6060
"{{OPTIONAL_WHERE}}", optionalWhere, 1)
6161

62-
out, err := runSimpleSQL(query, c)
62+
out, err := runSimpleSQL(query, getPgConnStr(c.Host, c.DB.DBName, c.DB.Username, c.Port))
6363
if err != nil {
6464
return errors.Wrap(err, "failed to run psql")
6565
}
@@ -70,16 +70,21 @@ func ResetAllPasswords(c *resources.AppConfig, whitelistUsers []string) error {
7070
}
7171

7272
// CreateUser defines a method for creation of Postgres user.
73-
func CreateUser(c *resources.AppConfig, username, password string, restricted bool) error {
73+
func CreateUser(c *resources.AppConfig, user resources.EphemeralUser) error {
7474
var query string
7575

76-
if restricted {
77-
query = restrictedUserQuery(username, password, c.DB.DBName)
76+
dbName := c.DB.DBName
77+
if user.AvailableDB != "" {
78+
dbName = user.AvailableDB
79+
}
80+
81+
if user.Restricted {
82+
query = restrictedUserQuery(user.Name, user.Password, dbName)
7883
} else {
79-
query = superuserQuery(username, password)
84+
query = superuserQuery(user.Name, user.Password)
8085
}
8186

82-
out, err := runSimpleSQL(query, c)
87+
out, err := runSimpleSQL(query, getPgConnStr(c.Host, dbName, c.DB.Username, c.Port))
8388
if err != nil {
8489
return errors.Wrap(err, "failed to run psql")
8590
}

pkg/services/provision/mode_local.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func (p *Provisioner) Reload(cfg Config, dbCfg resources.DB) {
143143
}
144144

145145
// StartSession starts a new session.
146-
func (p *Provisioner) StartSession(username, password, snapshotID string, restricted bool,
146+
func (p *Provisioner) StartSession(snapshotID string, user resources.EphemeralUser,
147147
extraConfig map[string]string) (*resources.Session, error) {
148148
snapshotID, err := p.getSnapshotID(snapshotID)
149149
if err != nil {
@@ -181,22 +181,20 @@ func (p *Provisioner) StartSession(username, password, snapshotID string, restri
181181
return nil, errors.Wrap(err, "failed to start a container")
182182
}
183183

184-
if err := p.prepareDB(appConfig, username, password, restricted); err != nil {
184+
if err := p.prepareDB(appConfig, user); err != nil {
185185
return nil, errors.Wrap(err, "failed to prepare a database")
186186
}
187187

188188
atomic.AddUint32(&p.sessionCounter, 1)
189189

190190
session := &resources.Session{
191-
ID: strconv.FormatUint(uint64(p.sessionCounter), 10),
192-
Pool: fsm.Pool().Name,
193-
Port: port,
194-
User: appConfig.DB.Username,
195-
SocketHost: appConfig.Host,
196-
EphemeralUser: username,
197-
EphemeralPassword: password,
198-
Restricted: restricted,
199-
ExtraConfig: extraConfig,
191+
ID: strconv.FormatUint(uint64(p.sessionCounter), 10),
192+
Pool: fsm.Pool().Name,
193+
Port: port,
194+
User: appConfig.DB.Username,
195+
SocketHost: appConfig.Host,
196+
EphemeralUser: user,
197+
ExtraConfig: extraConfig,
200198
}
201199

202200
return session, nil
@@ -265,7 +263,7 @@ func (p *Provisioner) ResetSession(session *resources.Session, snapshotID string
265263
return errors.Wrap(err, "failed to start a container")
266264
}
267265

268-
if err := p.prepareDB(appConfig, session.EphemeralUser, session.EphemeralPassword, session.Restricted); err != nil {
266+
if err := p.prepareDB(appConfig, session.EphemeralUser); err != nil {
269267
return errors.Wrap(err, "failed to prepare a database")
270268
}
271269

@@ -566,7 +564,7 @@ func (p *Provisioner) scanCSVLogFile(ctx context.Context, filename string, avail
566564
}
567565
}
568566

569-
func (p *Provisioner) prepareDB(pgConf *resources.AppConfig, username, password string, restricted bool) error {
567+
func (p *Provisioner) prepareDB(pgConf *resources.AppConfig, user resources.EphemeralUser) error {
570568
if !p.config.KeepUserPasswords {
571569
whitelist := []string{p.dbCfg.Username}
572570

@@ -575,7 +573,7 @@ func (p *Provisioner) prepareDB(pgConf *resources.AppConfig, username, password
575573
}
576574
}
577575

578-
if err := postgres.CreateUser(pgConf, username, password, restricted); err != nil {
576+
if err := postgres.CreateUser(pgConf, user); err != nil {
579577
return errors.Wrap(err, "failed to create user")
580578
}
581579

pkg/services/provision/resources/resources.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,11 @@ type Session struct {
1515
Pool string
1616

1717
// Database.
18-
Port uint
19-
User string
20-
SocketHost string
21-
22-
// TODO(anatoly): Were private fields. How to keep them private?
23-
// For user-defined username and password.
24-
EphemeralUser string
25-
EphemeralPassword string
26-
Restricted bool
27-
28-
ExtraConfig map[string]string
18+
Port uint
19+
User string
20+
SocketHost string
21+
EphemeralUser EphemeralUser
22+
ExtraConfig map[string]string
2923
}
3024

3125
// Disk defines disk status.
@@ -37,6 +31,15 @@ type Disk struct {
3731
DataSize uint64
3832
}
3933

34+
// EphemeralUser describes an ephemeral database user defined by Database Lab users.
35+
type EphemeralUser struct {
36+
// TODO(anatoly): Were private fields. How to keep them private?
37+
Name string
38+
Password string
39+
Restricted bool
40+
AvailableDB string
41+
}
42+
4043
// Snapshot defines snapshot of the data with related meta-information.
4144
type Snapshot struct {
4245
ID string

0 commit comments

Comments
 (0)