commit
97b612c1b3
9
main.go
9
main.go
@ -64,6 +64,15 @@ func initOptions() {
|
|||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options.ReadOnly {
|
||||||
|
msg := `------------------------------------------------------
|
||||||
|
SECURITY WARNING: You are running pgweb in read-only mode.
|
||||||
|
This mode is designed for environments where users could potentially delete / change data.
|
||||||
|
For proper read-only access please follow postgresql role management documentation.
|
||||||
|
------------------------------------------------------`
|
||||||
|
fmt.Println(msg)
|
||||||
|
}
|
||||||
|
|
||||||
printVersion()
|
printVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +225,29 @@ func (client *Client) Query(query string) (*Result, error) {
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *Client) SetReadOnlyMode() error {
|
||||||
|
var value string
|
||||||
|
if err := client.db.Get(&value, "SHOW default_transaction_read_only;"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if value == "off" {
|
||||||
|
_, err := client.db.Exec("SET default_transaction_read_only=on;")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (client *Client) query(query string, args ...interface{}) (*Result, error) {
|
func (client *Client) query(query string, args ...interface{}) (*Result, error) {
|
||||||
|
// We're going to force-set transaction mode on every query.
|
||||||
|
// This is needed so that default mode could not be changed by user.
|
||||||
|
if command.Opts.ReadOnly {
|
||||||
|
if err := client.SetReadOnlyMode(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action := strings.ToLower(strings.Split(query, " ")[0])
|
action := strings.ToLower(strings.Split(query, " ")[0])
|
||||||
if action == "update" || action == "delete" {
|
if action == "update" || action == "delete" {
|
||||||
res, err := client.db.Exec(query, args...)
|
res, err := client.db.Exec(query, args...)
|
||||||
|
@ -333,6 +333,18 @@ func test_HistoryUniqueness(t *testing.T) {
|
|||||||
assert.Equal(t, "SELECT * FROM books WHERE id = 1", client.History[0].Query)
|
assert.Equal(t, "SELECT * FROM books WHERE id = 1", client.History[0].Query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_ReadOnlyMode(t *testing.T) {
|
||||||
|
url := fmt.Sprintf("postgres://%s@%s:%s/%s?sslmode=disable", serverUser, serverHost, serverPort, serverDatabase)
|
||||||
|
client, _ := NewFromUrl(url, nil)
|
||||||
|
|
||||||
|
err := client.SetReadOnlyMode()
|
||||||
|
assert.Equal(t, nil, err)
|
||||||
|
|
||||||
|
_, err = client.Query("CREATE TABLE foobar(id integer);")
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "in a read-only transaction")
|
||||||
|
}
|
||||||
|
|
||||||
func TestAll(t *testing.T) {
|
func TestAll(t *testing.T) {
|
||||||
if onWindows() {
|
if onWindows() {
|
||||||
t.Log("Unit testing on Windows platform is not supported.")
|
t.Log("Unit testing on Windows platform is not supported.")
|
||||||
@ -361,7 +373,9 @@ func TestAll(t *testing.T) {
|
|||||||
test_TableRowsOrderEscape(t)
|
test_TableRowsOrderEscape(t)
|
||||||
test_ResultCsv(t)
|
test_ResultCsv(t)
|
||||||
test_History(t)
|
test_History(t)
|
||||||
|
test_HistoryUniqueness(t)
|
||||||
test_HistoryError(t)
|
test_HistoryError(t)
|
||||||
|
test_ReadOnlyMode(t)
|
||||||
|
|
||||||
teardownClient()
|
teardownClient()
|
||||||
teardown()
|
teardown()
|
||||||
|
@ -24,6 +24,7 @@ type Options struct {
|
|||||||
SkipOpen bool `short:"s" long:"skip-open" description:"Skip browser open on start"`
|
SkipOpen bool `short:"s" long:"skip-open" description:"Skip browser open on start"`
|
||||||
Sessions bool `long:"sessions" description:"Enable multiple database sessions" default:"false"`
|
Sessions bool `long:"sessions" description:"Enable multiple database sessions" default:"false"`
|
||||||
Prefix string `long:"prefix" description:"Add a url prefix"`
|
Prefix string `long:"prefix" description:"Add a url prefix"`
|
||||||
|
ReadOnly bool `long:"readonly" description:"Run database connection in readonly mode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var Opts Options
|
var Opts Options
|
||||||
|
Loading…
x
Reference in New Issue
Block a user