Skip to content

Commit 0f0f08e

Browse files
authored
refactor: move vault loading into registry (#79)
* refactor: move vault loading into registry * fix: vault type usage list
1 parent 6cc86dd commit 0f0f08e

18 files changed

Lines changed: 216 additions & 168 deletions

File tree

‎cmd/andcli/main.go‎

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"context"
45
"fmt"
56
"log"
67
"os"
@@ -13,12 +14,13 @@ import (
1314
"github.com/tjblackheart/andcli/v2/internal/input"
1415
"github.com/tjblackheart/andcli/v2/internal/model"
1516
"github.com/tjblackheart/andcli/v2/internal/vaults"
16-
"github.com/tjblackheart/andcli/v2/internal/vaults/aegis"
17-
"github.com/tjblackheart/andcli/v2/internal/vaults/andotp"
18-
"github.com/tjblackheart/andcli/v2/internal/vaults/keepass"
19-
"github.com/tjblackheart/andcli/v2/internal/vaults/protonpass"
20-
"github.com/tjblackheart/andcli/v2/internal/vaults/stratum"
21-
"github.com/tjblackheart/andcli/v2/internal/vaults/twofas"
17+
18+
_ "github.com/tjblackheart/andcli/v2/internal/vaults/aegis"
19+
_ "github.com/tjblackheart/andcli/v2/internal/vaults/andotp"
20+
_ "github.com/tjblackheart/andcli/v2/internal/vaults/keepass"
21+
_ "github.com/tjblackheart/andcli/v2/internal/vaults/protonpass"
22+
_ "github.com/tjblackheart/andcli/v2/internal/vaults/stratum"
23+
_ "github.com/tjblackheart/andcli/v2/internal/vaults/twofas"
2224
)
2325

2426
func main() {
@@ -70,42 +72,10 @@ func open(cfg *config.Config) (vaults.Vault, error) {
7072
return nil, err
7173
}
7274

73-
defer func() {
74-
for i := range pw {
75-
pw[i] = 0
76-
}
77-
}()
78-
79-
done := make(chan struct{})
80-
81-
var vault vaults.Vault
82-
go func() {
83-
switch cfg.Type {
84-
case vaults.ANDOTP:
85-
vault, err = andotp.Open(cfg.File, pw)
86-
case vaults.AEGIS:
87-
vault, err = aegis.Open(cfg.File, pw)
88-
case vaults.TWOFAS:
89-
vault, err = twofas.Open(cfg.File, pw)
90-
case vaults.STRATUM:
91-
vault, err = stratum.Open(cfg.File, pw)
92-
case vaults.KEEPASS:
93-
vault, err = keepass.Open(cfg.File, pw)
94-
case vaults.PROTON:
95-
vault, err = protonpass.Open(cfg.File, pw)
96-
default:
97-
vault, err = nil, fmt.Errorf("vault type %q: not implemented", cfg.Type)
98-
}
99-
done <- struct{}{}
100-
}()
101-
102-
select {
103-
case <-done:
104-
case <-time.After(cfg.DecryptionTimeoutD()):
105-
return nil, fmt.Errorf("decrypt: operation timed out. wrong type?")
106-
}
75+
ctx, cancel := context.WithTimeout(context.Background(), cfg.DecryptionTimeoutD())
76+
defer cancel()
10777

108-
return vault, err
78+
return vaults.Open(ctx, cfg.File, pw, cfg.Type)
10979
}
11080

11181
func password(piped bool) ([]byte, error) {

‎internal/config/config.go‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ import (
1616

1717
type (
1818
Config struct {
19-
File string `yaml:"file"`
20-
Type vaults.Type `yaml:"type"`
21-
ClipboardCmd string `yaml:"clipboard_cmd"`
22-
Options *Opts `yaml:"options"`
23-
Theme *Theme `yaml:"theme"`
24-
SessionTimeout int `yaml:"session_timeout"`
19+
File string `yaml:"file"`
20+
Type vaults.VaultType `yaml:"type"`
21+
ClipboardCmd string `yaml:"clipboard_cmd"`
22+
Options *Opts `yaml:"options"`
23+
Theme *Theme `yaml:"theme"`
24+
SessionTimeout int `yaml:"session_timeout"`
2525
//
2626
path string
2727
passwordFromStdin bool

‎internal/config/config_test.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ theme:
235235

236236
cfg := &Config{
237237
File: "/new/vault.json",
238-
Type: vaults.Type("2fas"),
238+
Type: vaults.VaultType("2fas"),
239239
ClipboardCmd: "pbcopy",
240240
SessionTimeout: 300,
241241
Options: &Opts{
@@ -302,7 +302,7 @@ func Test_create(t *testing.T) {
302302
// default config
303303
want := &Config{
304304
File: abs,
305-
Type: vaults.Type(*vtype),
305+
Type: vaults.VaultType(*vtype),
306306
SessionTimeout: 300,
307307
ClipboardCmd: "",
308308
Options: &Opts{

‎internal/config/flags.go‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
var (
1515
set = flag.NewFlagSet("default", flag.ExitOnError)
1616
vfile = set.StringP("file", "f", "", "Path to the encrypted vault (deprecated: Pass the filename directly)")
17-
vtype = set.StringP("type", "t", "", fmt.Sprintf("Vault type (%s)", vaults.StrTypes()))
17+
vtype = set.StringP("type", "t", "", "Vault types")
1818
cmd = set.StringP("clipboard-cmd", "c", "", "A custom clipboard command, including args (xclip, wl-copy, pbcopy etc.)")
1919
pwstdin = set.Bool("passwd-stdin", false, "Read the vault password from stdin. If set, skips the password input.")
2020
query = set.StringP("query", "q", "", "Query the vault directly and skip TUI functionality")
@@ -27,6 +27,7 @@ var (
2727
// Parses given flags into the existing config.
2828
func (cfg *Config) parseFlags() error {
2929
set.Usage = func() { usage(true) }
30+
set.Lookup("type").Usage = fmt.Sprintf("Vault type (%s)", vaults.StrTypes())
3031

3132
if err := set.Parse(os.Args[1:]); err != nil {
3233
log.Printf("%s: %s", buildinfo.AppName, err)
@@ -54,7 +55,7 @@ func (cfg *Config) parseFlags() error {
5455
}
5556

5657
if *vtype != "" {
57-
cfg.Type = vaults.Type(*vtype)
58+
cfg.Type = vaults.VaultType(*vtype)
5859
cfg.dirty = true
5960
}
6061

‎internal/vaults/aegis/aegis.go‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ type (
5858
}
5959
)
6060

61+
func init() { vaults.Register(vaultType, Open) }
62+
6163
func Open(filename string, pass []byte) (vaults.Vault, error) {
6264
var v aegis
6365

@@ -88,7 +90,7 @@ func Open(filename string, pass []byte) (vaults.Vault, error) {
8890
return nil, fmt.Errorf("%s: %w", vaultType, err)
8991
}
9092

91-
return v, nil
93+
return &v, nil
9294
}
9395

9496
func (v aegis) Entries() []vaults.Entry {

‎internal/vaults/aegis/aegis_test.go‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ func TestOpen(t *testing.T) {
2525
for _, tt := range tests {
2626
t.Run(tt.name, func(t *testing.T) {
2727
v, err := Open(tt.filename, []byte(tt.password))
28-
if tt.fails {
29-
if err == nil {
30-
t.Fatal("Open() expected error, got none")
28+
if tt.fails {
29+
if err == nil {
30+
t.Fatal("Open() expected error, got none")
31+
}
32+
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) {
33+
t.Fatalf("Open() error = %v, want %v", err, tt.wantErr)
34+
}
35+
return
3136
}
32-
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) {
33-
t.Fatalf("Open() error = %v, want %v", err, tt.wantErr)
34-
}
35-
return
36-
}
3737

3838
entries := v.Entries()
3939
if len(entries) != 1 {

‎internal/vaults/andotp/andotp.go‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@ type (
3232
}
3333
)
3434

35+
func init() { vaults.Register(vaultType, Open) }
36+
3537
func Open(filename string, pass []byte) (vaults.Vault, error) {
3638
b, err := os.ReadFile(filename)
3739
if err != nil {
3840
return nil, fmt.Errorf("%s: %w", vaultType, err)
3941
}
4042

41-
v := &andotp{entries: make([]entry, 0)}
43+
v := andotp{entries: make([]entry, 0)}
4244

4345
if v.IsPlain(b) {
4446
return nil, vaults.ErrIsPlain
@@ -53,7 +55,7 @@ func Open(filename string, pass []byte) (vaults.Vault, error) {
5355
return nil, fmt.Errorf("%s: %w", vaultType, err)
5456
}
5557

56-
return v, nil
58+
return &v, nil
5759
}
5860

5961
func (v andotp) Entries() []vaults.Entry {

‎internal/vaults/andotp/andotp_test.go‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ func TestOpen(t *testing.T) {
2424
for _, tt := range tests {
2525
t.Run(tt.name, func(t *testing.T) {
2626
v, err := Open(tt.filename, []byte(tt.password))
27-
if tt.fails {
28-
if err == nil {
29-
t.Fatal("Open() expected error, got none")
27+
if tt.fails {
28+
if err == nil {
29+
t.Fatal("Open() expected error, got none")
30+
}
31+
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) {
32+
t.Fatalf("Open() error = %v, want %v", err, tt.wantErr)
33+
}
34+
return
3035
}
31-
if tt.wantErr != nil && !errors.Is(err, tt.wantErr) {
32-
t.Fatalf("Open() error = %v, want %v", err, tt.wantErr)
33-
}
34-
return
35-
}
3636

3737
entries := v.Entries()
3838
if len(entries) != 1 {

‎internal/vaults/keepass/keepass.go‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ var _ vaults.Vault = &keepass{}
1818

1919
type keepass struct{ entries []gokeepasslib.Entry }
2020

21+
func init() { vaults.Register(vaultType, Open) }
22+
2123
func Open(filename string, pass []byte) (vaults.Vault, error) {
2224
v := keepass{entries: make([]gokeepasslib.Entry, 0)}
2325
db := gokeepasslib.NewDatabase()
@@ -43,7 +45,7 @@ func Open(filename string, pass []byte) (vaults.Vault, error) {
4345

4446
v.entries = append(v.entries, parseGroups(db.Content.Root.Groups)...)
4547

46-
return v, nil
48+
return &v, nil
4749
}
4850

4951
func (v keepass) Entries() []vaults.Entry {

‎internal/vaults/protonpass/protonpass.go‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ var (
2525
)
2626

2727
type (
28-
envelope struct{ Vaults map[string]proton }
28+
envelope struct{ Vaults map[string]protonvault }
2929

3030
// protonvault only implements the essentials for reading OTP data.
31-
proton struct {
31+
protonvault struct {
3232
Name, Description string
3333
Items []struct {
3434
Data struct {
@@ -43,14 +43,16 @@ type (
4343
}
4444
)
4545

46+
func init() { vaults.Register(vaultType, Open) }
47+
4648
func Open(filename string, pass []byte) (vaults.Vault, error) {
4749
b, err := read(filename)
4850
if err != nil {
4951
return nil, fmt.Errorf("%s: %s", vaultType, err)
5052
}
5153

52-
var e envelope
53-
if e.IsPlain(b) {
54+
var v envelope
55+
if v.IsPlain(b) {
5456
return nil, vaults.ErrIsPlain
5557
}
5658

@@ -64,11 +66,11 @@ func Open(filename string, pass []byte) (vaults.Vault, error) {
6466
return nil, fmt.Errorf("%s: %s", vaultType, err)
6567
}
6668

67-
if err := json.Unmarshal(result.Bytes(), &e); err != nil {
69+
if err := json.Unmarshal(result.Bytes(), &v); err != nil {
6870
return nil, fmt.Errorf("%s: %s", vaultType, err)
6971
}
7072

71-
return e, nil
73+
return &v, nil
7274
}
7375

7476
func (e envelope) Entries() []vaults.Entry {

0 commit comments

Comments
 (0)