mirror of https://github.com/jackc/pgx.git
commit
4618730e71
41
pgpass.go
41
pgpass.go
|
@ -9,7 +9,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parsepgpass(cfg *ConnConfig, line string) *string {
|
func parsepgpass(line, cfgHost, cfgPort, cfgDatabase, cfgUsername string) *string {
|
||||||
const (
|
const (
|
||||||
backslash = "\r"
|
backslash = "\r"
|
||||||
colon = "\n"
|
colon = "\n"
|
||||||
|
@ -21,6 +21,9 @@ func parsepgpass(cfg *ConnConfig, line string) *string {
|
||||||
username
|
username
|
||||||
pw
|
pw
|
||||||
)
|
)
|
||||||
|
if strings.HasPrefix(line, "#") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
line = strings.Replace(line, `\:`, colon, -1)
|
line = strings.Replace(line, `\:`, colon, -1)
|
||||||
line = strings.Replace(line, `\\`, backslash, -1)
|
line = strings.Replace(line, `\\`, backslash, -1)
|
||||||
parts := strings.Split(line, `:`)
|
parts := strings.Split(line, `:`)
|
||||||
|
@ -34,23 +37,19 @@ func parsepgpass(cfg *ConnConfig, line string) *string {
|
||||||
parts[i] = strings.Replace(strings.Replace(parts[i], backslash, `\`, -1), colon, `:`, -1)
|
parts[i] = strings.Replace(strings.Replace(parts[i], backslash, `\`, -1), colon, `:`, -1)
|
||||||
switch i {
|
switch i {
|
||||||
case host:
|
case host:
|
||||||
if parts[i] != cfg.Host {
|
if parts[i] != cfgHost {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case port:
|
case port:
|
||||||
portstr := fmt.Sprintf(`%v`, cfg.Port)
|
if parts[i] != cfgPort {
|
||||||
if portstr == "0" {
|
|
||||||
portstr = "5432"
|
|
||||||
}
|
|
||||||
if parts[i] != portstr {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case database:
|
case database:
|
||||||
if parts[i] != cfg.Database {
|
if parts[i] != cfgDatabase {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case username:
|
case username:
|
||||||
if parts[i] != cfg.User {
|
if parts[i] != cfgUsername {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,10 +71,32 @@ func pgpass(cfg *ConnConfig) (found bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
|
host := cfg.Host
|
||||||
|
if _, err := os.Stat(host); err == nil {
|
||||||
|
host = "localhost"
|
||||||
|
}
|
||||||
|
port := fmt.Sprintf(`%v`, cfg.Port)
|
||||||
|
if port == "0" {
|
||||||
|
port = "5432"
|
||||||
|
}
|
||||||
|
username := cfg.User
|
||||||
|
if username == "" {
|
||||||
|
user, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
username = user.Username
|
||||||
|
}
|
||||||
|
database := cfg.Database
|
||||||
|
if database == "" {
|
||||||
|
database = username
|
||||||
|
}
|
||||||
|
|
||||||
scanner := bufio.NewScanner(f)
|
scanner := bufio.NewScanner(f)
|
||||||
var pw *string
|
var pw *string
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
pw = parsepgpass(cfg, scanner.Text())
|
pw = parsepgpass(scanner.Text(), host, port, database, username)
|
||||||
if pw != nil {
|
if pw != nil {
|
||||||
cfg.Password = *pw
|
cfg.Password = *pw
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/user"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -20,6 +21,8 @@ var passfile = [][]string{
|
||||||
{"test1", "5432", "curlydb", "curly", "nyuknyuknyuk"},
|
{"test1", "5432", "curlydb", "curly", "nyuknyuknyuk"},
|
||||||
{"test2", "5432", "*", "shemp", "heymoe"},
|
{"test2", "5432", "*", "shemp", "heymoe"},
|
||||||
{"test2", "5432", "*", "*", `test\\ing\:`},
|
{"test2", "5432", "*", "*", `test\\ing\:`},
|
||||||
|
{"localhost", "*", "*", "*", "sesam"},
|
||||||
|
{"test3", "*", "", "", "swordfish"}, // user will be filled later
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPGPass(t *testing.T) {
|
func TestPGPass(t *testing.T) {
|
||||||
|
@ -27,9 +30,20 @@ func TestPGPass(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
user, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
passfile[len(passfile)-1][2] = user.Username
|
||||||
|
passfile[len(passfile)-1][3] = user.Username
|
||||||
|
|
||||||
defer tf.Close()
|
defer tf.Close()
|
||||||
defer os.Remove(tf.Name())
|
defer os.Remove(tf.Name())
|
||||||
os.Setenv("PGPASSFILE", tf.Name())
|
os.Setenv("PGPASSFILE", tf.Name())
|
||||||
|
_, err = fmt.Fprintln(tf, "#some comment\n\n#more comment")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
for _, l := range passfile {
|
for _, l := range passfile {
|
||||||
_, err := fmt.Fprintln(tf, strings.Join(l, `:`))
|
_, err := fmt.Fprintln(tf, strings.Join(l, `:`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -48,9 +62,28 @@ func TestPGPass(t *testing.T) {
|
||||||
if cfg.Password != unescape(l[4]) {
|
if cfg.Password != unescape(l[4]) {
|
||||||
t.Fatalf(`Password mismatch entry %v want %s got %s`, i, unescape(l[4]), cfg.Password)
|
t.Fatalf(`Password mismatch entry %v want %s got %s`, i, unescape(l[4]), cfg.Password)
|
||||||
}
|
}
|
||||||
|
if l[0] == "localhost" {
|
||||||
|
// using some existing path as socket
|
||||||
|
cfg := ConnConfig{Host: tf.Name(), Database: l[2], User: l[3]}
|
||||||
|
found := pgpass(&cfg)
|
||||||
|
if !found {
|
||||||
|
t.Fatalf("Entry %v not found", i)
|
||||||
|
}
|
||||||
|
if cfg.Password != unescape(l[4]) {
|
||||||
|
t.Fatalf(`Password mismatch entry %v want %s got %s`, i, unescape(l[4]), cfg.Password)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cfg := ConnConfig{Host: "derp", Database: "herp", User: "joe"}
|
cfg := ConnConfig{Host: "test3"}
|
||||||
found := pgpass(&cfg)
|
found := pgpass(&cfg)
|
||||||
|
if !found {
|
||||||
|
t.Fatalf("Entry for default user name")
|
||||||
|
}
|
||||||
|
if cfg.Password != "swordfish" {
|
||||||
|
t.Fatalf(`Password mismatch for default user entry, want %s got %s`, "swordfish", cfg.Password)
|
||||||
|
}
|
||||||
|
cfg = ConnConfig{Host: "derp", Database: "herp", User: "joe"}
|
||||||
|
found = pgpass(&cfg)
|
||||||
if found {
|
if found {
|
||||||
t.Fatal("bad found")
|
t.Fatal("bad found")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue