Skip to content
This repository was archived by the owner on Nov 9, 2019. It is now read-only.

Commit 4ca6cb4

Browse files
committed
Merge branch 'release-0.4.0'
2 parents 3671241 + 421a82f commit 4ca6cb4

51 files changed

Lines changed: 1765 additions & 242 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: go
2+
go:
3+
- 1.6
4+
- tip
5+
install:
6+
- make
7+
script:
8+
- make build
9+
- make test

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ INSTALL = install
99

1010
FOLDERS = $(shell find . -mindepth 1 -type d -not -path "*.git*" -not -path "./githooks*" -not -path "./vendor*" -not -path "*bin*")
1111

12+
VERSION = $(shell cat VERSION)
13+
LDFLAGS = -ldflags "-X main.version=$(VERSION)"
14+
1215
all: build
1316

1417
install_hooks:
@@ -32,7 +35,7 @@ goget:
3235
ln -sf $(PWD) $(CURDIR)/vendor/src/$(GOPKG)
3336

3437
build: install_hooks goget
35-
GOPATH=$(GOPATH) go build -o bin/pick .
38+
GOPATH=$(GOPATH) go build $(LDFLAGS) -o bin/pick .
3639

3740
test: goget
3841
GOPATH=$(GOPATH) go test -v $(FOLDERS)
@@ -65,4 +68,4 @@ clean:
6568
rm -rf vendor/
6669
rm -rf bin/
6770

68-
.PHONY: all install_hooks goget build test install uninstall fmt gofmt config clean
71+
.PHONY: all install_hooks goget build test install uninstall fmt gofmt govet config clean

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pick
22
====
3+
[![Build Status](https://travis-ci.org/bndw/pick.svg?branch=master)](https://travis-ci.org/bndw/pick)
4+
35
A minimal password manager for OS X and Linux.
46

57
![demo](https://github.com/bndw/pick/raw/master/demo.gif)
@@ -8,7 +10,7 @@ A minimal password manager for OS X and Linux.
810

911
#### go get
1012
```sh
11-
$ go get github.com/bndw/pick
13+
$ go get -u github.com/bndw/pick
1214
```
1315

1416
#### Homebrew
@@ -34,6 +36,7 @@ Available Commands:
3436
backup Backup the safe
3537
cat Cat a credential
3638
cp Copy a credential to the clipboard
39+
edit Edit a credential
3740
export Export decrypted credentials in JSON format
3841
ls List all credentials
3942
rm Remove a credential

VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.4.0

backends/client.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ type Client interface {
44
Load() ([]byte, error)
55
Save([]byte) error
66
Backup() error
7+
SafeLocation() string
78
}
89

910
func New(config *Config) (Client, error) {

backends/disk.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ func (db *DiskBackend) Save(data []byte) error {
8383
return nil
8484
}
8585

86+
func (db *DiskBackend) SafeLocation() string {
87+
return db.path
88+
}
89+
8690
func (f fileInfoSlice) Len() int {
8791
return len(f)
8892
}

backends/mock.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ func (b *mockBackend) Save(ciphertext []byte) error {
3030
b.Data = ciphertext
3131
return nil
3232
}
33+
34+
func (b *mockBackend) SafeLocation() string {
35+
return "mock-safe-location"
36+
}

commands/add.go

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,66 @@ package commands
22

33
import (
44
"fmt"
5-
"os"
65

76
"github.com/bndw/pick/errors"
7+
"github.com/bndw/pick/strings"
88
"github.com/bndw/pick/utils"
9+
"github.com/bndw/pick/utils/pswdgen"
910
"github.com/spf13/cobra"
11+
"github.com/spf13/pflag"
1012
)
1113

1214
func init() {
1315
rootCmd.AddCommand(&cobra.Command{
1416
Use: "add [name] [username] [password]",
1517
Short: "Add a credential",
16-
Long: `The add command is used to add a new credential.
17-
`,
18+
Long: "The add command is used to add a new credential.",
1819
Run: func(cmd *cobra.Command, args []string) {
19-
os.Exit(Add(args...))
20+
runCommand(Add, cmd, args)
2021
},
2122
})
2223
}
2324

24-
func Add(args ...string) int {
25-
safe, err := loadSafe()
25+
func Add(args []string, flags *pflag.FlagSet) error {
26+
safe, err := newSafeLoader().Load()
2627
if err != nil {
27-
return handleError(err)
28+
return err
2829
}
2930

30-
name, username, password, errCode := parseAddArgs(args)
31-
if errCode > 0 {
32-
return errCode
31+
name, username, password, err := parseAddArgs(args)
32+
if err != nil {
33+
return err
3334
}
3435

3536
account, err := safe.Add(name, username, password)
3637
if _, conflict := err.(*errors.AccountExists); conflict && overwrite(name) {
37-
var replaceErr error
38-
if account, replaceErr = safe.Replace(name, username, password); replaceErr != nil {
39-
return handleError(replaceErr)
38+
var editErr error
39+
if account, editErr = safe.Edit(name, username, password); editErr != nil {
40+
return editErr
4041
}
4142
} else if err != nil {
42-
return handleError(err)
43+
return err
4344
}
4445

4546
fmt.Println("Credential added")
4647
if utils.Confirm("Copy password to clipboard", true) {
4748
if err := utils.CopyToClipboard(account.Password); err != nil {
48-
return handleError(err)
49+
return err
4950
}
51+
fmt.Println(strings.PasswordCopiedToClipboard)
5052
}
51-
return 0
53+
return nil
5254
}
5355

5456
func overwrite(name string) bool {
5557
prompt := fmt.Sprintf("%s already exists, overwrite", name)
5658
return utils.Confirm(prompt, false)
5759
}
5860

59-
func parseAddArgs(args []string) (name, username, password string, errCode int) {
61+
func parseAddArgs(args []string) (name, username, password string, err error) {
6062
if len(args) > 3 {
61-
fmt.Println("Usage: add [name] [username] [password]")
62-
return "", "", "", 1
63+
err = &errors.InvalidCommandUsage{}
64+
return
6365
}
6466

6567
switch len(args) {
@@ -73,41 +75,32 @@ func parseAddArgs(args []string) (name, username, password string, errCode int)
7375
name = args[0]
7476
}
7577

76-
errCode = 1
77-
var err error
78-
7978
if name == "" {
8079
if name, err = utils.GetInput("Enter a credential name"); err != nil {
81-
fmt.Println(err)
8280
return
8381
}
8482
}
8583

8684
if username == "" {
8785
if username, err = utils.GetInput(fmt.Sprintf("Enter a username for %s", name)); err != nil {
88-
fmt.Println(err)
8986
return
9087
}
9188
}
9289

9390
if password == "" {
9491
if utils.Confirm("Generate password", true) {
95-
password, err = utils.GeneratePassword(config.General.PasswordLen)
96-
if err != nil {
97-
fmt.Println(err)
92+
if password, err = pswdgen.Generate(config.General.Password); err != nil {
9893
return
9994
}
10095
} else {
10196
var _password []byte
10297
if _password, err = utils.GetPasswordInput(fmt.Sprintf("Enter a password for %s", name)); err != nil {
103-
fmt.Println(err)
10498
return
10599
}
106100

107101
password = string(_password)
108102
}
109103
}
110104

111-
errCode = 0
112105
return
113106
}

commands/backup.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,33 @@ package commands
22

33
import (
44
"fmt"
5-
"os"
65

76
"github.com/bndw/pick/safe"
87
"github.com/spf13/cobra"
8+
"github.com/spf13/pflag"
99
)
1010

1111
func init() {
1212
rootCmd.AddCommand(&cobra.Command{
1313
Use: "backup",
1414
Short: "Backup the safe",
15-
Long: `The backup command is used to backup your current safe.
16-
`,
15+
Long: "The backup command is used to backup your current safe.",
1716
Run: func(cmd *cobra.Command, args []string) {
18-
os.Exit(Backup(args...))
17+
runCommand(Backup, cmd, args)
1918
},
2019
})
2120
}
2221

23-
func Backup(args ...string) int {
22+
func Backup(args []string, flags *pflag.FlagSet) error {
2423
backendClient, err := newBackendClient()
2524
if err != nil {
26-
return handleError(err)
25+
return err
2726
}
2827

2928
if err := safe.Backup(backendClient); err != nil {
30-
return handleError(err)
29+
return err
3130
}
3231

3332
fmt.Println("Backup created")
34-
return 0
33+
return nil
3534
}

commands/cat.go

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,83 @@ package commands
22

33
import (
44
"fmt"
5-
"os"
65

6+
"github.com/bndw/pick/errors"
7+
"github.com/bndw/pick/safe"
78
"github.com/bndw/pick/utils"
89
"github.com/spf13/cobra"
10+
"github.com/spf13/pflag"
911
)
1012

1113
func init() {
12-
rootCmd.AddCommand(&cobra.Command{
14+
cmd := &cobra.Command{
1315
Use: "cat [name]",
1416
Short: "Cat a credential",
15-
Long: `The cat command is used to print a credential to stdout.
16-
`,
17+
Long: "The cat command is used to print a credential to stdout.",
1718
Run: func(cmd *cobra.Command, args []string) {
18-
if len(args) != 1 {
19-
fmt.Println("USAGE: cat [name]")
20-
os.Exit(1)
21-
}
22-
23-
os.Exit(Cat(args...))
19+
runCommand(Cat, cmd, args)
2420
},
25-
})
21+
}
22+
cmd.Flags().Bool("history", false, "show credential history")
23+
rootCmd.AddCommand(cmd)
24+
}
25+
26+
func printAccount(name string, account *safe.Account, showHistory bool) {
27+
// Print header
28+
if showHistory && account.History != nil {
29+
history := account.History
30+
account.History = nil
31+
history = append(history, *account)
32+
for i, l := 0, len(history); i < l; i++ {
33+
printCredential(&history[i], " ", i == 0)
34+
}
35+
} else {
36+
// Print a credential
37+
printCredential(account, "", true)
38+
}
39+
}
40+
41+
func printCredential(account *safe.Account, printPrefix string, isInitialAccount bool) {
42+
// Print a credential
43+
var createdOrModified string
44+
if isInitialAccount {
45+
createdOrModified = "created"
46+
} else {
47+
createdOrModified = "modified"
48+
}
49+
fmt.Printf("%s: %s\n%susername: %s\n%spassword: %s\n",
50+
createdOrModified,
51+
utils.FormatUnixTime(account.ModifiedOn),
52+
printPrefix, account.Username,
53+
printPrefix, account.Password)
2654
}
2755

28-
func Cat(args ...string) int {
29-
safe, err := loadSafe()
56+
func Cat(args []string, flags *pflag.FlagSet) error {
57+
if len(args) != 1 {
58+
return &errors.InvalidCommandUsage{}
59+
}
60+
name := args[0]
61+
62+
showHistory, err := parseCatFlags(flags)
3063
if err != nil {
31-
return handleError(err)
64+
return err
3265
}
3366

34-
account, err := safe.Get(args[0])
67+
safe, err := newSafeLoader().Load()
3568
if err != nil {
36-
return handleError(err)
69+
return err
3770
}
3871

39-
fmt.Printf(`account: %s
40-
username: %s
41-
password: %s
42-
created: %s
43-
`, account.Name, account.Username, account.Password,
44-
utils.FormatUnixTime(account.CreatedOn))
45-
return 0
72+
account, err := safe.Get(name)
73+
if err != nil {
74+
return err
75+
}
76+
77+
printAccount(name, account, showHistory)
78+
return nil
79+
}
80+
81+
func parseCatFlags(flags *pflag.FlagSet) (showHistory bool, err error) {
82+
showHistory, err = flags.GetBool("history")
83+
return
4684
}

0 commit comments

Comments
 (0)