-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
117 lines (106 loc) · 2.69 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package main
import (
"io/ioutil"
"os"
"path/filepath"
yaml "gopkg.in/yaml.v2"
"github.com/pinzolo/xdgdir"
)
var app = xdgdir.NewApp("spwd")
// Config is configurations holder of spwd app.
type Config struct {
// KeyFile is file path of secret file.
KeyFile string `yaml:"key_file"`
// DataFile is file path of storing encrypted passwords.
DataFile string `yaml:"data_file"`
// FilteringCommand is command for filtering in search subcommand.
FilteringCommand string `yaml:"filtering_command"`
// UnprotectiveCommands are commands that are not protected with master password.
UnprotectiveCommands []string `yaml:"unprotective_commands"`
}
// GetConfig return merged configuration.
func GetConfig() (Config, error) {
dcfg, err := DefaultConfig()
if err != nil {
return dcfg, err
}
fcfg, ok := FileConfig()
if ok {
return dcfg.Merge(fcfg), nil
}
return dcfg, nil
}
// Merge config values and returns new Config.
func (cfg Config) Merge(other Config) Config {
newCfg := Config{
KeyFile: cfg.KeyFile,
DataFile: cfg.DataFile,
FilteringCommand: cfg.FilteringCommand,
UnprotectiveCommands: cfg.UnprotectiveCommands,
}
if other.KeyFile != "" {
newCfg.KeyFile = other.KeyFile
}
if other.DataFile != "" {
newCfg.DataFile = other.DataFile
}
if other.FilteringCommand != "" {
newCfg.FilteringCommand = other.FilteringCommand
}
if len(other.UnprotectiveCommands) != 0 {
newCfg.UnprotectiveCommands = other.UnprotectiveCommands
}
return newCfg
}
// IsProtective returns whether given command is a command to protect.
// copy and search are always protected.
func (cfg Config) IsProtective(cmd string) bool {
if cmd == "copy" || cmd == "search" {
return true
}
for _, c := range cfg.UnprotectiveCommands {
if c == cmd {
return false
}
}
return true
}
// DefaultConfig return sefault configuration.
func DefaultConfig() (Config, error) {
df, err := app.DataFile("data.dat")
if err != nil {
return Config{}, err
}
return Config{
KeyFile: filepath.Join(homeDir(), ".ssh", "id_rsa"),
DataFile: df,
FilteringCommand: "peco",
}, nil
}
// FileConfig return configuration of config file.
// Second bool return value is existence of config file.
func FileConfig() (Config, bool) {
cf, err := app.ConfigFile("config.yml")
if err != nil {
return Config{}, false
}
if _, err = os.Stat(cf); err != nil {
return Config{}, false
}
p, err := ioutil.ReadFile(cf)
if err != nil {
return Config{}, false
}
var cfg Config
if err = yaml.Unmarshal(p, &cfg); err != nil {
return Config{}, false
}
return cfg, true
}
func homeDir() string {
home := os.Getenv("HOME")
if home != "" {
return home
}
return os.Getenv("USERPROFILE")
}