keepassx 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.codeclimate.yml +30 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +64 -0
- data/.travis.yml +12 -3
- data/Gemfile +4 -2
- data/Guardfile +16 -0
- data/LICENSE +19 -0
- data/README.md +33 -0
- data/Rakefile +3 -2
- data/keepassx.gemspec +20 -10
- data/lib/keepassx.rb +42 -3
- data/lib/keepassx/aes_crypt.rb +16 -6
- data/lib/keepassx/database.rb +218 -27
- data/lib/keepassx/database/dumper.rb +87 -0
- data/lib/keepassx/database/finder.rb +102 -0
- data/lib/keepassx/database/loader.rb +217 -0
- data/lib/keepassx/entry.rb +70 -38
- data/lib/keepassx/field/base.rb +191 -0
- data/lib/keepassx/field/entry.rb +32 -0
- data/lib/keepassx/field/group.rb +27 -0
- data/lib/keepassx/fieldable.rb +161 -0
- data/lib/keepassx/group.rb +93 -20
- data/lib/keepassx/hashable_payload.rb +6 -0
- data/lib/keepassx/header.rb +102 -27
- data/lib/keepassx/version.rb +5 -0
- data/spec/factories.rb +23 -0
- data/spec/fixtures/database_empty.kdb +0 -0
- data/spec/fixtures/database_test.kdb +0 -0
- data/spec/fixtures/database_test_dumped.yml +76 -0
- data/spec/fixtures/database_with_key.kdb +0 -0
- data/spec/fixtures/database_with_key.key +1 -0
- data/spec/fixtures/database_with_key2.key +1 -0
- data/spec/fixtures/test_data_array.yml +113 -0
- data/spec/fixtures/test_data_array_dumped.yml +124 -0
- data/spec/keepassx/database_spec.rb +491 -29
- data/spec/keepassx/entry_spec.rb +95 -0
- data/spec/keepassx/group_spec.rb +92 -0
- data/spec/keepassx_spec.rb +17 -0
- data/spec/spec_helper.rb +59 -3
- metadata +143 -69
- data/.rvmrc +0 -1
- data/Gemfile.lock +0 -28
- data/lib/keepassx/entry_field.rb +0 -49
- data/lib/keepassx/group_field.rb +0 -44
- data/spec/test_database.kdb +0 -0
@@ -1,56 +1,518 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Keepassx::Database do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
|
5
|
+
GROUPS_COUNT = 5
|
6
|
+
ENTRIES_COUNT = 5
|
7
|
+
|
8
|
+
let(:data_array) { YAML.load(File.read(File.join(FIXTURE_PATH, 'test_data_array.yml'))) }
|
9
|
+
let(:data_array_dumped) { File.read(File.join(FIXTURE_PATH, 'test_data_array_dumped.yml')) }
|
10
|
+
|
11
|
+
let(:test_db) { Keepassx::Database.new(TEST_DATABASE_PATH) }
|
12
|
+
let(:test_db_dumped) { File.read(File.join(FIXTURE_PATH, 'database_test_dumped.yml')) }
|
13
|
+
|
14
|
+
let(:empty_db) { Keepassx::Database.new(EMPTY_DATABASE_PATH) }
|
15
|
+
let(:test_group) { build(:group) }
|
16
|
+
let(:test_entry) { build(:entry) }
|
17
|
+
|
18
|
+
let(:keyfile_db) { Keepassx::Database.new(KEYFILE_DATABASE_PATH) }
|
19
|
+
let(:keyfile) { File.join(FIXTURE_PATH, 'database_with_key.key') }
|
20
|
+
let(:keyfile2) { File.join(FIXTURE_PATH, 'database_with_key2.key') }
|
21
|
+
|
22
|
+
describe 'empty database' do
|
23
|
+
before :each do
|
24
|
+
empty_db.unlock('test')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should have 2 groups' do
|
28
|
+
expect(empty_db.groups.size).to eq 2
|
29
|
+
expect(empty_db.groups.map(&:name).sort).to eq ['Internet', 'eMail']
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should have 2 special entries' do
|
33
|
+
expect(empty_db.entries.size).to eq 2
|
34
|
+
expect(empty_db.entries.map(&:name).sort).to eq ['Meta-Info', 'Meta-Info']
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should have 1 KPX_CUSTOM_ICONS_4 entry' do
|
38
|
+
entry = empty_db.find_entry(notes: 'KPX_CUSTOM_ICONS_4')
|
39
|
+
expect(entry).to be_a(Keepassx::Entry)
|
40
|
+
expect(entry.notes).to eq 'KPX_CUSTOM_ICONS_4'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should have 1 KPX_GROUP_TREE_STATE entry' do
|
44
|
+
entry = empty_db.find_entry(notes: 'KPX_GROUP_TREE_STATE')
|
45
|
+
expect(entry).to be_a(Keepassx::Entry)
|
46
|
+
expect(entry.notes).to eq 'KPX_GROUP_TREE_STATE'
|
8
47
|
end
|
9
48
|
end
|
10
49
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
50
|
+
|
51
|
+
describe '.new' do
|
52
|
+
context 'when database is instanciated from file' do
|
53
|
+
let(:test_db) { described_class.new(File.open(TEST_DATABASE_PATH)) }
|
54
|
+
|
55
|
+
before :each do
|
56
|
+
test_db.unlock('testmasterpassword')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'properly initialized from file' do
|
60
|
+
expect { test_db }.to_not raise_error
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should have valid headers' do
|
64
|
+
expect(test_db.valid?).to be true
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should have valid length' do
|
68
|
+
expect(test_db.length).to eq 1457
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should have valid encryption_type headers' do
|
72
|
+
expect(test_db.header.encryption_type).to eq 'SHA2'
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'has groups_count counter properly set' do
|
76
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'has entries_count counter properly set' do
|
80
|
+
expect(test_db.header.entries_count).to eq ENTRIES_COUNT
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'contains proper number of test groups' do
|
84
|
+
expect(test_db.groups.length).to eq GROUPS_COUNT
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'contains proper number of test entries' do
|
88
|
+
expect(test_db.entries.length).to eq ENTRIES_COUNT
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'preserves original data' do
|
92
|
+
expect(test_db.to_yaml(skip_date: true)).to eq test_db_dumped
|
93
|
+
end
|
15
94
|
end
|
16
95
|
|
17
|
-
|
18
|
-
|
96
|
+
context 'when database is instanciated from string' do
|
97
|
+
let(:test_db) { described_class.new(TEST_DATABASE_PATH) }
|
98
|
+
|
99
|
+
before :each do
|
100
|
+
test_db.unlock('testmasterpassword')
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'properly initialized from string' do
|
104
|
+
expect { test_db }.to_not raise_error
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should have valid headers' do
|
108
|
+
expect(test_db.valid?).to be true
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should have valid length' do
|
112
|
+
expect(test_db.length).to eq 1457
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should have valid encryption_type headers' do
|
116
|
+
expect(test_db.header.encryption_type).to eq 'SHA2'
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'has groups_count counter properly set' do
|
120
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'has entries_count counter properly set' do
|
124
|
+
expect(test_db.header.entries_count).to eq ENTRIES_COUNT
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'contains proper number of test groups' do
|
128
|
+
expect(test_db.groups.length).to eq GROUPS_COUNT
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'contains proper number of test entries' do
|
132
|
+
expect(test_db.entries.length).to eq ENTRIES_COUNT
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'preserves original data' do
|
136
|
+
expect(test_db.to_yaml(skip_date: true)).to eq test_db_dumped
|
137
|
+
end
|
19
138
|
end
|
20
139
|
|
21
|
-
|
22
|
-
|
140
|
+
context 'when database is instanciated from array' do
|
141
|
+
let(:test_db) { described_class.new(data_array) }
|
142
|
+
|
143
|
+
it 'properly initialized from Array' do
|
144
|
+
expect { test_db }.to_not raise_error
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should have valid headers' do
|
148
|
+
expect(test_db.valid?).to be true
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should have valid length' do
|
152
|
+
expect(test_db.length).to eq 2189
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should have valid encryption_type headers' do
|
156
|
+
expect(test_db.header.encryption_type).to eq 'SHA2'
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'has groups_count counter properly set' do
|
160
|
+
expect(test_db.header.groups_count).to eq 13
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'has entries_count counter properly set' do
|
164
|
+
expect(test_db.header.entries_count).to eq 4
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'contains proper number of test groups' do
|
168
|
+
expect(test_db.groups.length).to eq 13
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'contains proper number of test entries' do
|
172
|
+
expect(test_db.entries.length).to eq 4
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'preserves original data' do
|
176
|
+
expect(test_db.to_yaml(skip_date: true)).to eq data_array_dumped
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
describe '#unlock' do
|
183
|
+
context 'when no key file is needed' do
|
184
|
+
it 'returns true when the master password is correct' do
|
185
|
+
expect(test_db.unlock('testmasterpassword')).to be true
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'returns false when the master password is incorrect' do
|
189
|
+
expect(test_db.unlock('bad password')).to be false
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when a key file is needed' do
|
194
|
+
it 'returns true when the master password is correct and a valid keyfile is given' do
|
195
|
+
expect(keyfile_db.unlock('test', keyfile)).to be true
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'returns false when the master password is incorrect' do
|
199
|
+
expect(keyfile_db.unlock('bad password', keyfile)).to be false
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'returns false when the keyfile is missing' do
|
203
|
+
expect(keyfile_db.unlock('test')).to be false
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'returns false when the keyfile dont match' do
|
207
|
+
expect(keyfile_db.unlock('test', keyfile2)).to be false
|
208
|
+
end
|
23
209
|
end
|
24
210
|
end
|
25
211
|
|
26
|
-
|
212
|
+
|
213
|
+
describe '#locked?' do
|
214
|
+
it 'returns true when database is locked' do
|
215
|
+
expect(test_db.locked?).to be true
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'returns false when database is unlocked' do
|
219
|
+
test_db.unlock('testmasterpassword')
|
220
|
+
expect(test_db.locked?).to be false
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
describe '#to_a' do
|
226
|
+
it 'returns Array database representation' do
|
227
|
+
expect(described_class.new(data_array).to_a.class).to be Array
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
describe '#checksum' do
|
233
|
+
let(:db1) { described_class.new data_array }
|
234
|
+
let(:db2) { described_class.new data_array }
|
235
|
+
|
236
|
+
it 'has the same checksum for the same data' do
|
237
|
+
expect(db1.checksum).to eq db2.checksum
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
context 'unlocked database' do
|
27
243
|
before :each do
|
28
|
-
|
29
|
-
|
244
|
+
test_db.unlock('testmasterpassword')
|
245
|
+
end
|
246
|
+
|
247
|
+
describe '#entries' do
|
248
|
+
it 'has entries' do
|
249
|
+
expect(test_db.entries.map(&:name).sort).to eq ['Meta-Info', 'Meta-Info', 'entry2', 'test entry', 'test entry 2']
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe '#groups' do
|
254
|
+
it 'has groups' do
|
255
|
+
expect(test_db.groups.map(&:name).sort).to eq ['Backup', 'Internet', 'Web', 'Wikipedia', 'eMail']
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
describe '#find_entry' do
|
260
|
+
it 'can find entries by their name' do
|
261
|
+
expect(test_db.find_entry('test entry').password).to eq 'testpassword'
|
262
|
+
expect(test_db.find_entry(name: 'test entry').creation_time).to eq Time.local(2011, 9, 3, 15, 34, 47)
|
263
|
+
expect(test_db.find_entry('foo')).to be nil
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#find_group' do
|
268
|
+
it 'can find groups by their name' do
|
269
|
+
expect(test_db.find_group('Backup').name).to eq 'Backup'
|
270
|
+
expect(test_db.find_group('foo')).to be nil
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'has "Internet" group level properly set' do
|
274
|
+
expect(test_db.find_group('Internet').level).to eq 0
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'has "Internet" group parent properly set' do
|
278
|
+
expect(test_db.find_group('Internet').parent).to be nil
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'has "Web" group level properly set' do
|
282
|
+
expect(test_db.find_group('Web').level).to eq 1
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'has "Web" group parent properly set' do
|
286
|
+
expect(test_db.find_group('Web').parent).to eq test_db.find_group('Internet')
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'has "Wikipedia" group level properly set' do
|
290
|
+
expect(test_db.find_group('Wikipedia').level).to eq 2
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'has "Wikipedia" group parent properly set' do
|
294
|
+
expect(test_db.find_group('Wikipedia').parent).to eq test_db.find_group('Web')
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'has "eMail" group level properly set' do
|
298
|
+
expect(test_db.find_group('eMail').level).to eq 0
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'has "eMail" group parent properly set' do
|
302
|
+
expect(test_db.find_group('eMail').parent).to be nil
|
303
|
+
end
|
30
304
|
end
|
31
305
|
|
32
|
-
|
33
|
-
|
306
|
+
describe '#find_entries' do
|
307
|
+
it 'should returns a list of entries' do
|
308
|
+
expect(test_db.find_entries).to eq test_db.entries
|
309
|
+
expect { |b| test_db.find_entries(&b) }.to yield_successive_args(*test_db.entries)
|
310
|
+
end
|
34
311
|
end
|
35
312
|
|
36
|
-
|
37
|
-
|
313
|
+
describe '#find_groups' do
|
314
|
+
it 'should returns a list of groups' do
|
315
|
+
expect(test_db.find_groups).to eq test_db.groups
|
316
|
+
expect { |b| test_db.find_groups(&b) }.to yield_successive_args(*test_db.groups)
|
317
|
+
end
|
38
318
|
end
|
39
319
|
|
40
|
-
|
41
|
-
|
42
|
-
|
320
|
+
describe '#search' do
|
321
|
+
it 'can search for entries' do
|
322
|
+
entries = test_db.search('test')
|
323
|
+
expect(entries.first.name).to eq 'test entry'
|
324
|
+
end
|
325
|
+
|
326
|
+
it 'can search for entries case-insensitively' do
|
327
|
+
entries = test_db.search('TEST')
|
328
|
+
expect(entries.first.name).to eq 'test entry'
|
329
|
+
end
|
330
|
+
|
331
|
+
# it 'will find the current values of entries with history' do
|
332
|
+
# entries = test_db.search 'entry2'
|
333
|
+
# expect(entries.size).to eq 1
|
334
|
+
# expect(entries.first.name).to eq 'entry2'
|
335
|
+
# expect(entries.first.backup?).to be true
|
336
|
+
# end
|
43
337
|
end
|
44
338
|
|
45
|
-
|
46
|
-
|
47
|
-
|
339
|
+
describe '#add_group' do
|
340
|
+
context 'when arg is a Keepassx::Group' do
|
341
|
+
it 'should increment groups_count' do
|
342
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT
|
343
|
+
test_db.add_group(test_group)
|
344
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT + 1
|
345
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT + 1
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
context 'when arg is a Hash of options' do
|
350
|
+
it 'should increment groups_count' do
|
351
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT
|
352
|
+
test_db.add_group(attributes_for(:group))
|
353
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT + 1
|
354
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT + 1
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
context 'when arg is neither a Keepassx::Group or a Hash of options' do
|
359
|
+
it 'should raise an error' do
|
360
|
+
expect { test_db.add_group(nil) }.to raise_error(ArgumentError)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
context 'with nested groups' do
|
365
|
+
it 'should increment groups_count' do
|
366
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT
|
367
|
+
parent_group = test_db.add_group(attributes_for(:group, id: 0, name: 'parent_group'))
|
368
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT + 1
|
369
|
+
expect(test_db.groups).to include(parent_group)
|
370
|
+
child_group = test_db.add_group(attributes_for(:group, id: 1, name: 'child_group', parent: parent_group))
|
371
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT + 2
|
372
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT + 2
|
373
|
+
expect(child_group.parent).to eq parent_group
|
374
|
+
end
|
375
|
+
|
376
|
+
it 'should increment groups_count' do
|
377
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT
|
378
|
+
parent_group = test_db.add_group(attributes_for(:group, id: 0, name: 'parent_group'))
|
379
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT + 1
|
380
|
+
expect(test_db.groups).to include(parent_group)
|
381
|
+
child_group = test_db.add_group(attributes_for(:group, id: 1, name: 'child_group', parent: :parent_group))
|
382
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT + 2
|
383
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT + 2
|
384
|
+
expect(child_group.parent).to eq parent_group
|
385
|
+
end
|
386
|
+
end
|
48
387
|
end
|
49
388
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
389
|
+
describe '#add_entry' do
|
390
|
+
context 'when arg is a Keepassx::Entry' do
|
391
|
+
it 'should increment entries_count' do
|
392
|
+
expect(test_db.entries.size).to eq ENTRIES_COUNT
|
393
|
+
test_db.add_entry(test_entry)
|
394
|
+
expect(test_db.entries.size).to eq ENTRIES_COUNT + 1
|
395
|
+
expect(test_db.header.entries_count).to eq ENTRIES_COUNT + 1
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
context 'when arg is a Hash of options' do
|
400
|
+
it 'should increment entries_count' do
|
401
|
+
expect(test_db.entries.size).to eq ENTRIES_COUNT
|
402
|
+
test_db.add_entry(attributes_for(:entry))
|
403
|
+
expect(test_db.entries.size).to eq ENTRIES_COUNT + 1
|
404
|
+
expect(test_db.header.entries_count).to eq ENTRIES_COUNT + 1
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
context 'when arg is neither a Keepassx::Group or a Hash of options' do
|
409
|
+
it 'should raise an error' do
|
410
|
+
expect { test_db.add_group(nil) }.to raise_error(ArgumentError)
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe '#delete_group' do
|
416
|
+
it 'should decrement entries_count' do
|
417
|
+
group = test_db.find_group('eMail')
|
418
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT
|
419
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT
|
420
|
+
test_db.delete_group(group)
|
421
|
+
expect(test_db.groups.size).to eq GROUPS_COUNT - 1
|
422
|
+
expect(test_db.header.groups_count).to eq GROUPS_COUNT - 1
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
describe '#delete_entry' do
|
427
|
+
it 'should decrement entries_count' do
|
428
|
+
entry = test_db.find_entry('test entry')
|
429
|
+
expect(test_db.entries.size).to eq ENTRIES_COUNT
|
430
|
+
expect(test_db.header.entries_count).to eq ENTRIES_COUNT
|
431
|
+
test_db.delete_entry(entry)
|
432
|
+
expect(test_db.entries.size).to eq ENTRIES_COUNT - 1
|
433
|
+
expect(test_db.header.entries_count).to eq ENTRIES_COUNT - 1
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
describe '#save' do
|
438
|
+
context 'when database is saved from an existing file' do
|
439
|
+
it 'should save the database in KeePassX format' do
|
440
|
+
# Save database in /tmp to not override existing one
|
441
|
+
expect { test_db.save(path: '/tmp/keepass1.kdb') }.to_not raise_error
|
442
|
+
expect(File.exist?('/tmp/keepass1.kdb')).to be true
|
443
|
+
|
444
|
+
# Reopen it and compare with original db
|
445
|
+
db = described_class.new('/tmp/keepass1.kdb')
|
446
|
+
expect(db.locked?).to be true
|
447
|
+
db.unlock('testmasterpassword')
|
448
|
+
expect(db.to_yaml).to eq test_db.to_yaml
|
449
|
+
|
450
|
+
# Be sure to delete existing tmp files
|
451
|
+
expect(File.unlink('/tmp/keepass1.kdb')).to eq 1
|
452
|
+
expect(File.exist?('/tmp/keepass1.kdb')).to be false
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
context 'when database is saved from a data file' do
|
457
|
+
it 'should raise an error if path is not set' do
|
458
|
+
test_db = described_class.new(data_array)
|
459
|
+
expect { test_db.save }.to raise_error(ArgumentError)
|
460
|
+
end
|
461
|
+
|
462
|
+
it 'should raise an error if path is not set' do
|
463
|
+
test_db = described_class.new(data_array)
|
464
|
+
expect { test_db.save(password: 'foo') }.to raise_error(ArgumentError)
|
465
|
+
end
|
466
|
+
|
467
|
+
it 'should raise an error if password is not set' do
|
468
|
+
test_db = described_class.new(data_array)
|
469
|
+
expect { test_db.save(path: '/tmp/keepass2.kdb') }.to raise_error(ArgumentError)
|
470
|
+
end
|
471
|
+
|
472
|
+
it 'should save the database if the path and the password are set' do
|
473
|
+
# Create new db from array of data
|
474
|
+
test_db = described_class.new(data_array)
|
475
|
+
|
476
|
+
# Save database in /tmp
|
477
|
+
expect { test_db.save(path: '/tmp/keepass2.kdb', password: 'testmasterpassword') }.to_not raise_error
|
478
|
+
expect(File.exist?('/tmp/keepass2.kdb')).to be true
|
479
|
+
|
480
|
+
# Reopen it and compare with original db
|
481
|
+
db = described_class.new('/tmp/keepass2.kdb')
|
482
|
+
expect(db.locked?).to be true
|
483
|
+
db.unlock('testmasterpassword')
|
484
|
+
expect(db.to_yaml).to eq test_db.to_yaml
|
485
|
+
|
486
|
+
# Be sure to delete existing tmp files
|
487
|
+
expect(File.unlink('/tmp/keepass2.kdb')).to eq 1
|
488
|
+
expect(File.exist?('/tmp/keepass2.kdb')).to be false
|
489
|
+
end
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
|
495
|
+
describe 'create database from scratch' do
|
496
|
+
it 'should allow creation of database from scratch' do
|
497
|
+
# Create a new Database object
|
498
|
+
db = described_class.new('/tmp/test_db.kdb')
|
499
|
+
# Add a group
|
500
|
+
group = db.add_group(name: 'Foo')
|
501
|
+
# Add an entry in this group
|
502
|
+
entry = db.add_entry(name: 'Bar', group: group)
|
503
|
+
# Save database
|
504
|
+
expect { db.save(password: 'testpassword') }.to_not raise_error
|
505
|
+
# Do some checks
|
506
|
+
expect(File.exist?('/tmp/test_db.kdb')).to be true
|
507
|
+
|
508
|
+
# Reopen it and compare with original db
|
509
|
+
new_db = described_class.new('/tmp/test_db.kdb')
|
510
|
+
expect(new_db.locked?).to be true
|
511
|
+
new_db.unlock('testpassword')
|
512
|
+
expect(new_db.to_yaml(skip_date: true)).to eq db.to_yaml(skip_date: true)
|
513
|
+
|
514
|
+
# Be sure to delete existing tmp files
|
515
|
+
expect(File.unlink('/tmp/test_db.kdb')).to eq 1
|
54
516
|
end
|
55
517
|
end
|
56
518
|
end
|