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

Commit 916ff68

Browse files
committed
Merge branch 'release-0.3.0'
2 parents 8cf0504 + 88ded9c commit 916ff68

Some content is hidden

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

55 files changed

+934
-206
lines changed

Makefile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ PICK_DIR = $(HOME)/.pick
77
BIN_DIR = /usr/local/bin
88
INSTALL = install
99

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

1212
all: build
1313

@@ -29,10 +29,10 @@ goget:
2929
GOPATH=$(GOPATH) $(CURDIR)/vendor/bin/godeps -u dependencies.tsv
3030
mkdir -p $(shell dirname "$(CURDIR)/vendor/src/$(GOPKG)")
3131
rm -f $(CURDIR)/vendor/src/$(GOPKG)
32-
ln -sf $(PWD)/src $(CURDIR)/vendor/src/$(GOPKG)
32+
ln -sf $(PWD) $(CURDIR)/vendor/src/$(GOPKG)
3333

3434
build: install_hooks goget
35-
GOPATH=$(GOPATH) go build -o bin/pick $(GOPKG)
35+
GOPATH=$(GOPATH) go build -o bin/pick .
3636

3737
test: goget
3838
GOPATH=$(GOPATH) go test -v $(FOLDERS)
@@ -49,6 +49,9 @@ fmt: gofmt
4949
gofmt:
5050
GOPATH=$(GOPATH) go fmt $(FOLDERS)
5151

52+
govet:
53+
GOPATH=$(GOPATH) go tool vet $(FOLDERS)
54+
5255
config:
5356
@if [ ! -f "$(PICK_DIR)/config.toml" ]; then \
5457
OLD_UMASK=$(shell echo `umask`) ; \

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ pick
33
A minimal password manager for OS X and Linux.
44

55
```sh
6-
$ go get -u github.com/bndw/pick
6+
$ brew tap bndw/pick
7+
$ brew install bndw/pick/pick-pass
78
```
89

910
or

src/backends/client.go renamed to backends/client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ func New(config *Config) (Client, error) {
1010
switch config.Type {
1111
default:
1212
fallthrough
13-
case "file":
13+
case ConfigTypeFile:
1414
return NewDiskBackend(*config)
15-
case "mock":
15+
case ConfigTypeMock:
1616
return NewMockBackend(), nil
1717
}
1818
}

backends/config.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package backends
2+
3+
type Config struct {
4+
Type string `toml:"type"`
5+
Backup backupConfig `toml:"backup"`
6+
Settings map[string]interface{} `toml:"settings"`
7+
}
8+
9+
type backupConfig struct {
10+
DirPath string
11+
AutoEnabled bool `toml:"auto"`
12+
MaxFiles int `toml:"max"`
13+
}
14+
15+
const (
16+
ConfigTypeFile = "file"
17+
ConfigTypeMock = "mock"
18+
)
19+
20+
func NewDefaultConfig() Config {
21+
return Config{
22+
Type: ConfigTypeFile,
23+
Backup: backupConfig{
24+
AutoEnabled: true,
25+
MaxFiles: 100,
26+
},
27+
}
28+
}

src/backends/disk.go renamed to backends/disk.go

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"io/ioutil"
66
"os"
7+
"sort"
78
"strings"
89
"time"
910

@@ -27,9 +28,12 @@ var (
2728
)
2829

2930
type DiskBackend struct {
30-
path string
31+
path string
32+
backupConfig backupConfig
3133
}
3234

35+
type fileInfoSlice []os.FileInfo
36+
3337
func NewDiskBackend(config Config) (*DiskBackend, error) {
3438
var err error
3539
if homeDir, err = homedir.Dir(); err != nil {
@@ -46,7 +50,12 @@ func NewDiskBackend(config Config) (*DiskBackend, error) {
4650
}
4751
}
4852

49-
return &DiskBackend{safePath}, nil
53+
config.Backup.DirPath = fmt.Sprintf(defaultBackupDir, homeDir, defaultSafeDirName)
54+
55+
return &DiskBackend{
56+
path: safePath,
57+
backupConfig: config.Backup,
58+
}, nil
5059
}
5160

5261
func (db *DiskBackend) Load() ([]byte, error) {
@@ -74,8 +83,63 @@ func (db *DiskBackend) Save(data []byte) error {
7483
return nil
7584
}
7685

86+
func (f fileInfoSlice) Len() int {
87+
return len(f)
88+
}
89+
90+
func (f fileInfoSlice) Less(i, j int) bool {
91+
return f[i].ModTime().Before(f[j].ModTime())
92+
}
93+
94+
func (f fileInfoSlice) Swap(i, j int) {
95+
f[i], f[j] = f[j], f[i]
96+
}
97+
98+
func (db *DiskBackend) cleanOldBackups(max int) error {
99+
files, err := ioutil.ReadDir(db.backupConfig.DirPath)
100+
if err != nil {
101+
return err
102+
}
103+
104+
filesSorted := make(fileInfoSlice, 0, len(files))
105+
for _, f := range files {
106+
filesSorted = append(filesSorted, f)
107+
}
108+
sort.Sort(filesSorted)
109+
max = min(max, len(filesSorted))
110+
111+
for _, f := range filesSorted[:len(filesSorted)-max] {
112+
p := fmt.Sprintf("%s/%s", db.backupConfig.DirPath, f.Name())
113+
if err := os.Remove(p); err != nil {
114+
fmt.Println("Error removing old backup", err.Error())
115+
}
116+
}
117+
118+
return nil
119+
}
120+
121+
func min(a, b int) int {
122+
if a <= b {
123+
return a
124+
}
125+
return b
126+
}
127+
77128
func (db *DiskBackend) Backup() error {
78-
backupDir := fmt.Sprintf(defaultBackupDir, homeDir, defaultSafeDirName)
129+
if db.backupConfig.MaxFiles == 0 {
130+
// Keep no backups
131+
db.cleanOldBackups(0)
132+
return &errors.BackupDisabled{}
133+
} else if db.backupConfig.MaxFiles > 0 {
134+
// Subtract one as we are about to create another backup
135+
if err := db.cleanOldBackups(db.backupConfig.MaxFiles - 1); err != nil {
136+
if !os.IsNotExist(err) {
137+
fmt.Println("Failed to remove old backup(s)", err.Error())
138+
}
139+
}
140+
}
141+
142+
backupDir := db.backupConfig.DirPath
79143
timeFormat := time.Now().Format(defaultBackupTimeFormat)
80144
backupFileName := fmt.Sprintf(defaultBackupFileName, timeFormat)
81145
backupPath := backupDir + "/" + backupFileName

src/backends/mock.go renamed to backends/mock.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ type mockBackend struct {
77

88
func NewMockBackend() *mockBackend {
99
safeData := []byte(`-----BEGIN PGP MESSAGE-----
10+
1011
wx4EBwMI/EyvqWA12cNgJBnoGRxYO1D0/F/w5Ro5uafS4AHkLjgl3wFVjIRB1vbo
1112
GSX6FeE9q+Ap4JzhoTTgcOLB6iyW4HDmGZFzcVq+JgYYg0+7Q+4jlC/bBxyhtb1h
1213
UHBuCvFGG4ENExdLliCsixI1bP8KB2TlLH459U859KWkg1aEJJ+1FeDR5E1GwV5y
File renamed without changes.
File renamed without changes.

src/commands/backup.go renamed to commands/backup.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"os"
66

7+
"github.com/bndw/pick/safe"
78
"github.com/spf13/cobra"
89
)
910

@@ -25,7 +26,7 @@ func Backup(args ...string) int {
2526
return handleError(err)
2627
}
2728

28-
if err := backendClient.Backup(); err != nil {
29+
if err := safe.Backup(backendClient); err != nil {
2930
return handleError(err)
3031
}
3132

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

config.toml.in

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
type = "file"
2121
[storage.settings]
2222
path = "$HOME/.pick/pick.safe"
23+
#[storage.backup]
24+
# Whether to auto-create backups before the safe is modified.
25+
#auto = true
26+
# The number of backups to keep.
27+
# Specify -1 to allow unlimited backups, 0 to not create backups at all.
28+
#max = 100
2329

2430

2531
## Encryption
@@ -28,6 +34,8 @@ type = "file"
2834
# Only uncomment / adjust the settings in the [encryption] section if you know what you are doing.
2935
# If you change something and we update our default (recommended) settings, your safe will
3036
# _not_ automatically upgrade to our new recommendations.
37+
# All settings in the [encryption] section can be modified on-the-fly, i.e. your safe
38+
# will automatically upgrade from the old to the new encryption settings.
3139
# The encryption section controls the configuration of the safe encryption.
3240
#
3341
# [encryption]
@@ -51,10 +59,22 @@ type = "file"
5159
# # Specifies the key length (in bytes) to use for AES.
5260
# # Currently supported values: 32, 24, 16 for 256bit, 192bit, 128bit respectively.
5361
# keylen = 32
54-
# # The hash function to use for PBKDF2.
55-
# # Currently supported values: "sha512", "sha256".
56-
# pbkdf2hash = "sha512"
57-
# # The number of iterations used to derive the key from your password.
58-
# pbkdf2iterations = 100000
59-
# # Specifies the salt length (in bytes) for the PBKDF2.
60-
# pbkdf2saltlen = 16
62+
# # Specifies the key derivation function to use.
63+
# # Currently supported values: "pbkdf2", "scrypt".
64+
# keyderivation = "pbkdf2"
65+
# # Settings for the "pbkdf2" Key-Derivation type
66+
# [encryption.aes_gcm.pbkdf2]
67+
# # The hash function to use for PBKDF2.
68+
# # Currently supported values: "sha512", "sha256".
69+
# hash = "sha512"
70+
# # The number of iterations used to derive the key from your password.
71+
# iterations = 100000
72+
# # Specifies the salt length (in bytes) for the PBKDF2.
73+
# saltlen = 16
74+
# # Settings for the "scrypt" key-derivation type
75+
# [encryption.aes_gcm.scrypt]
76+
# n = 131072
77+
# r = 8
78+
# p = 1
79+
# # Specifies the salt length (in bytes) for Scrypt.
80+
# saltlen = 16

src/config/config.go renamed to config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ func Load(version string) (*Config, error) {
3434

3535
configFile := fmt.Sprintf(defaultConfigFileTmpl, home)
3636
config := Config{
37+
Storage: backends.NewDefaultConfig(),
3738
Encryption: crypto.NewDefaultConfig(),
3839
General: generalConfig{
3940
PasswordLen: defaultPasswordLen,

0 commit comments

Comments
 (0)