-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathentry.go
171 lines (144 loc) · 4.82 KB
/
entry.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package gokeepasslib
import (
"encoding/xml"
w "github.com/tobischo/gokeepasslib/v3/wrappers"
)
type EntryOption func(*Entry)
func WithEntryFormattedTime(formatted bool) EntryOption {
return func(e *Entry) {
WithTimeDataFormattedTime(formatted)(&e.Times)
}
}
// Entry is the structure which holds information about a parsed entry in a keepass database
type Entry struct {
UUID UUID `xml:"UUID"`
IconID int64 `xml:"IconID"`
CustomIconUUID UUID `xml:"CustomIconUUID"`
ForegroundColor string `xml:"ForegroundColor"`
BackgroundColor string `xml:"BackgroundColor"`
OverrideURL string `xml:"OverrideURL"`
Tags string `xml:"Tags"`
Times TimeData `xml:"Times"`
Values []ValueData `xml:"String,omitempty"`
AutoType AutoTypeData `xml:"AutoType"`
Histories []History `xml:"History"`
Binaries []BinaryReference `xml:"Binary,omitempty"`
CustomData []CustomData `xml:"CustomData>Item"`
}
// NewEntry return a new entry with time data and uuid set
func NewEntry(options ...EntryOption) Entry {
entry := Entry{}
entry.Times = NewTimeData()
entry.UUID = NewUUID()
for _, option := range options {
option(&entry)
}
return entry
}
func (e *Entry) setKdbxFormatVersion(version formatVersion) {
(&e.Times).setKdbxFormatVersion(version)
for i := range e.Histories {
(&e.Histories[i]).setKdbxFormatVersion(version)
}
}
// Clone creates a copy of an Entry struct including its child entities
func (e Entry) Clone() Entry {
clone := e
clone.UUID = NewUUID()
clone.Values = make([]ValueData, len(clone.Values))
copy(clone.Values, e.Values)
clone.Histories = make([]History, len(clone.Histories))
for i, history := range e.Histories {
clone.Histories[i] = history.Clone()
}
clone.Binaries = make([]BinaryReference, len(clone.Binaries))
copy(clone.Binaries, e.Binaries)
clone.CustomData = make([]CustomData, len(clone.CustomData))
copy(clone.CustomData, e.CustomData)
return clone
}
// Get returns the value in e corresponding with key k, or an empty string otherwise
func (e *Entry) Get(key string) *ValueData {
for i := range e.Values {
if e.Values[i].Key == key {
return &e.Values[i]
}
}
return nil
}
// GetContent returns the content of the value belonging to the given key in string form
func (e *Entry) GetContent(key string) string {
val := e.Get(key)
if val == nil {
return ""
}
return val.Value.Content
}
// GetIndex returns the index of the Value belonging to the given key, or -1 if none is found
func (e *Entry) GetIndex(key string) int {
for i := range e.Values {
if e.Values[i].Key == key {
return i
}
}
return -1
}
// GetPassword returns the password of an entry
func (e *Entry) GetPassword() string {
return e.GetContent("Password")
}
// GetPasswordIndex returns the index in the values slice belonging to the password
func (e *Entry) GetPasswordIndex() int {
return e.GetIndex("Password")
}
// GetTitle returns the title of an entry
func (e *Entry) GetTitle() string {
return e.GetContent("Title")
}
// History stores information about changes made to an entry,
// in the form of a list of previous versions of that entry
type History struct {
Entries []Entry `xml:"Entry"`
}
func (h *History) setKdbxFormatVersion(version formatVersion) {
for i := range h.Entries {
(&h.Entries[i]).setKdbxFormatVersion(version)
}
}
// Clone creates a copy of a History struct including its child entities
func (h History) Clone() History {
clone := h
clone.Entries = make([]Entry, len(h.Entries))
for i, entry := range h.Entries {
clone.Entries[i] = entry.Clone()
}
return clone
}
// ValueData is a structure containing key value pairs of information stored in an entry
type ValueData struct {
Key string `xml:"Key"`
Value V `xml:"Value"`
}
// V is a wrapper for the content of a value, so that it can store whether it is protected
type V struct {
Content string `xml:",chardata"`
Protected w.BoolWrapper `xml:"Protected,attr,omitempty"`
}
// AutoTypeData is a structure containing auto type settings of an entry
type AutoTypeData struct {
Enabled w.BoolWrapper `xml:"Enabled"`
DataTransferObfuscation int64 `xml:"DataTransferObfuscation"`
DefaultSequence string `xml:"DefaultSequence"`
Associations []AutoTypeAssociation `xml:"Association,omitempty"`
}
// AutoTypeAssociation is a structure that store the keystroke sequence of a window for AutoTypeData
type AutoTypeAssociation struct {
Window string `xml:"Window"`
KeystrokeSequence string `xml:"KeystrokeSequence"`
}
// CustomData is the structure for plugins custom data
type CustomData struct {
XMLName xml.Name `xml:"Item"`
Key string `xml:"Key"`
Value string `xml:"Value"`
}