-
Notifications
You must be signed in to change notification settings - Fork 1
/
item.go
157 lines (141 loc) · 2.81 KB
/
item.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package main
import (
"io/ioutil"
"os"
yaml "gopkg.in/yaml.v2"
)
// Item is password item.
type Item struct {
Name string `yaml:"name"`
// Description is free description of password.
Description string `yaml:"description"`
// Password text.
Password string `yaml:"password"`
// Master password flag.
Master bool `yaml:"master"`
}
// NewItem returns new item that initialized give values.
func NewItem(name string, desc string, pwd string) Item {
return Item{
Name: name,
Description: desc,
Password: pwd,
}
}
// NewMasterItem returns new item for master password.
func NewMasterItem(name string, pwd string) Item {
return Item{
Name: name,
Password: pwd,
Master: true,
}
}
// Items is item list.
type Items []Item
// Find item that has given keyword.
func (is Items) Find(name string) *Item {
for _, it := range is {
if name == it.Name {
return &it
}
}
return nil
}
// LoadItems load items from file on given path.
func LoadItems(key []byte, path string) (Items, error) {
_, err := os.Stat(path)
if err != nil {
return Items{}, nil
}
p, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
dec, err := Decrypt(key, string(p))
if err != nil {
return nil, err
}
var is Items
err = yaml.Unmarshal(dec, &is)
if err != nil {
return nil, err
}
return is, nil
}
// LoadItemsWithConfig load items using given config.
func LoadItemsWithConfig(cfg Config) (Items, error) {
key, err := GetKey(cfg.KeyFile)
if err != nil {
return nil, err
}
return LoadItems(key, cfg.DataFile)
}
// Save items to file on given path.
func (is Items) Save(key []byte, path string) error {
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
p, err := yaml.Marshal(is)
if err != nil {
return err
}
enc, err := Encrypt(key, p)
if err != nil {
return err
}
f.WriteString(enc)
return nil
}
// Update same name item with given item.
func (is Items) Update(nit Item) Items {
nis := Items(make([]Item, len(is)))
for i, it := range is {
if it.Name == nit.Name {
nis[i] = nit
} else {
nis[i] = it
}
}
return nis
}
// Remove item that has given name.
func (is Items) Remove(name string) Items {
nis := Items([]Item{})
for _, it := range is {
if it.Name != name {
nis = append(nis, it)
}
}
return nis
}
// ToDataTable returns data for tablewriter.
func (is Items) ToDataTable() [][]string {
var data [][]string
for _, it := range is {
if it.Master {
continue
}
data = append(data, []string{it.Name, it.Description})
}
return data
}
// HasMaster returns that contains master item.
func (is Items) HasMaster() bool {
for _, it := range is {
if it.Master {
return true
}
}
return false
}
// Master returns master item.
func (is Items) Master() *Item {
for _, it := range is {
if it.Master {
return &it
}
}
return nil
}