enpassreadercli 0.5.1__tar.gz → 0.5.2__tar.gz

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.
Files changed (50) hide show
  1. enpassreadercli-0.5.2/.VERSION +1 -0
  2. {enpassreadercli-0.5.1/enpassreadercli → enpassreadercli-0.5.2}/HISTORY.rst +9 -0
  3. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/PKG-INFO +11 -2
  4. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/Pipfile +1 -1
  5. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/Pipfile.lock +3 -3
  6. enpassreadercli-0.5.2/enpassreadercli/.VERSION +1 -0
  7. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2/enpassreadercli}/HISTORY.rst +9 -0
  8. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/Pipfile +1 -1
  9. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/Pipfile.lock +3 -3
  10. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/enpassreadercli.py +83 -17
  11. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/requirements.txt +1 -1
  12. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli.egg-info/PKG-INFO +11 -2
  13. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli.egg-info/requires.txt +1 -1
  14. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/requirements.txt +1 -1
  15. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/tests/test_enpassreadercli.py +72 -5
  16. enpassreadercli-0.5.1/.VERSION +0 -1
  17. enpassreadercli-0.5.1/enpassreadercli/.VERSION +0 -1
  18. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/AUTHORS.rst +0 -0
  19. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/CONTRIBUTING.rst +0 -0
  20. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/LICENSE +0 -0
  21. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/MANIFEST.in +0 -0
  22. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/README.rst +0 -0
  23. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/USAGE.rst +0 -0
  24. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/dev-requirements.txt +0 -0
  25. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/Makefile +0 -0
  26. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/authors.rst +0 -0
  27. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/conf.py +0 -0
  28. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/contributing.rst +0 -0
  29. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/history.rst +0 -0
  30. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/index.rst +0 -0
  31. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/installation.rst +0 -0
  32. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/readme.rst +0 -0
  33. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/docs/usage.rst +0 -0
  34. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/AUTHORS.rst +0 -0
  35. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/CONTRIBUTING.rst +0 -0
  36. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/LICENSE +0 -0
  37. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/README.rst +0 -0
  38. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/USAGE.rst +0 -0
  39. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/__init__.py +0 -0
  40. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/_version.py +0 -0
  41. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/conf/logging.json-example +0 -0
  42. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/dev-requirements.txt +0 -0
  43. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli/enpassreadercliexceptions.py +0 -0
  44. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli.egg-info/SOURCES.txt +0 -0
  45. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli.egg-info/dependency_links.txt +0 -0
  46. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli.egg-info/entry_points.txt +0 -0
  47. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli.egg-info/not-zip-safe +0 -0
  48. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/enpassreadercli.egg-info/top_level.txt +0 -0
  49. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/setup.cfg +0 -0
  50. {enpassreadercli-0.5.1 → enpassreadercli-0.5.2}/setup.py +0 -0
@@ -0,0 +1 @@
1
+ 0.5.2
@@ -74,3 +74,12 @@ History
74
74
  ------------------
75
75
 
76
76
  * Bump dependencies.
77
+
78
+
79
+ 0.5.2 (16-10-2026)
80
+ ------------------
81
+
82
+ * Require enpassreaderlib 0.4.1 which verifies the authentication tag of encrypted values and opens the database read only.
83
+ * Report values that fail authentication instead of crashing, skipping them when enumerating and exiting with an error.
84
+ * Report invalid key files and missing database paths with their own error messages.
85
+ * Close the database connection when done.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enpassreadercli
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: A cli to access enpass 6 encrypted databases and read, list and search values.
5
5
  Home-page: https://github.com/costastf/enpassreadercli
6
6
  Author: Costas Tyfoxylos
@@ -19,7 +19,7 @@ Requires-Python: >=3.11
19
19
  License-File: LICENSE
20
20
  License-File: AUTHORS.rst
21
21
  Requires-Dist: coloredlogs>=15.0.1; python_version >= "2.7" and python_version != "3.0" and python_version != "3.1" and python_version != "3.2" and python_version != "3.3" and python_version != "3.4"
22
- Requires-Dist: enpassreaderlib>=0.4.0
22
+ Requires-Dist: enpassreaderlib>=0.4.1
23
23
  Requires-Dist: prompt-toolkit>=3.0.53; python_version >= "3.10"
24
24
  Requires-Dist: pyotp>=2.10.0; python_version >= "3.8"
25
25
  Dynamic: author
@@ -180,3 +180,12 @@ History
180
180
  ------------------
181
181
 
182
182
  * Bump dependencies.
183
+
184
+
185
+ 0.5.2 (16-10-2026)
186
+ ------------------
187
+
188
+ * Require enpassreaderlib 0.4.1 which verifies the authentication tag of encrypted values and opens the database read only.
189
+ * Report values that fail authentication instead of crashing, skipping them when enumerating and exiting with an error.
190
+ * Report invalid key files and missing database paths with their own error messages.
191
+ * Close the database connection when done.
@@ -28,6 +28,6 @@ toml = ">=0.10,<1.0"
28
28
  [packages]
29
29
 
30
30
  coloredlogs = ">=15.0,<16.0"
31
- enpassreaderlib = ">=0.4.0,<1.0"
31
+ enpassreaderlib = ">=0.4.1,<1.0"
32
32
  prompt-toolkit = ">=3.0,<4.0"
33
33
  pyotp = ">=2.8.0,<3.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_meta": {
3
3
  "hash": {
4
- "sha256": "73e7adf733b348b796d9c99223e69cdc1c25e3f42f183f67aa6ff97b991a2fba"
4
+ "sha256": "09f21fca803fc6fcac17eef3dd72263ab34b5667252b513dfb9395092805693f"
5
5
  },
6
6
  "pipfile-spec": 6,
7
7
  "requires": {
@@ -27,10 +27,10 @@
27
27
  },
28
28
  "enpassreaderlib": {
29
29
  "hashes": [
30
- "sha256:d7bc90e057dcf19865cd4864b15312a28489832edd54a42701502c545eda293e"
30
+ "sha256:8db081f8ffb4588b7a3748505d63336aec3b8423401a42575c3ada4567da25b5"
31
31
  ],
32
32
  "index": "pypi",
33
- "version": "==0.4.0"
33
+ "version": "==0.4.1"
34
34
  },
35
35
  "humanfriendly": {
36
36
  "hashes": [
@@ -0,0 +1 @@
1
+ 0.5.2
@@ -74,3 +74,12 @@ History
74
74
  ------------------
75
75
 
76
76
  * Bump dependencies.
77
+
78
+
79
+ 0.5.2 (16-10-2026)
80
+ ------------------
81
+
82
+ * Require enpassreaderlib 0.4.1 which verifies the authentication tag of encrypted values and opens the database read only.
83
+ * Report values that fail authentication instead of crashing, skipping them when enumerating and exiting with an error.
84
+ * Report invalid key files and missing database paths with their own error messages.
85
+ * Close the database connection when done.
@@ -28,6 +28,6 @@ toml = ">=0.10,<1.0"
28
28
  [packages]
29
29
 
30
30
  coloredlogs = ">=15.0,<16.0"
31
- enpassreaderlib = ">=0.4.0,<1.0"
31
+ enpassreaderlib = ">=0.4.1,<1.0"
32
32
  prompt-toolkit = ">=3.0,<4.0"
33
33
  pyotp = ">=2.8.0,<3.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "_meta": {
3
3
  "hash": {
4
- "sha256": "73e7adf733b348b796d9c99223e69cdc1c25e3f42f183f67aa6ff97b991a2fba"
4
+ "sha256": "09f21fca803fc6fcac17eef3dd72263ab34b5667252b513dfb9395092805693f"
5
5
  },
6
6
  "pipfile-spec": 6,
7
7
  "requires": {
@@ -27,10 +27,10 @@
27
27
  },
28
28
  "enpassreaderlib": {
29
29
  "hashes": [
30
- "sha256:d7bc90e057dcf19865cd4864b15312a28489832edd54a42701502c545eda293e"
30
+ "sha256:8db081f8ffb4588b7a3748505d63336aec3b8423401a42575c3ada4567da25b5"
31
31
  ],
32
32
  "index": "pypi",
33
- "version": "==0.4.0"
33
+ "version": "==0.4.1"
34
34
  },
35
35
  "humanfriendly": {
36
36
  "hashes": [
@@ -39,7 +39,9 @@ import argparse
39
39
  import coloredlogs
40
40
  import pyotp
41
41
  from enpassreaderlib import EnpassDB
42
- from enpassreaderlib.enpassreaderlibexceptions import EnpassDatabaseError
42
+ from enpassreaderlib.enpassreaderlibexceptions import (EnpassDatabaseError,
43
+ EnpassDecryptionError,
44
+ EnpassKeyfileError)
43
45
  from prompt_toolkit import prompt
44
46
  from prompt_toolkit.completion import Completer, Completion, FuzzyCompleter
45
47
 
@@ -350,45 +352,109 @@ def get_missing_value_message(entry, field=None, totp=False):
350
352
  return f'Entry with title of "{entry.title}" does not have a password set.'
351
353
 
352
354
 
353
- def main():
355
+ def open_database(args):
354
356
  """
355
- Main method.
357
+ Opens the enpass database.
358
+
359
+ Args:
360
+ args: The parsed cli arguments.
361
+
362
+ Returns:
363
+ enpass (EnpassDB): The opened database, exits with an error if it cannot be opened.
356
364
 
357
- This method holds what you want to execute when
358
- the script is run on command line.
359
365
  """
360
- args = get_arguments()
361
- setup_logging(args.log_level, args.logger_config)
366
+ if not os.path.isfile(args.path):
367
+ LOGGER.error(f'The database file "{args.path}" does not exist.')
368
+ raise SystemExit(1)
362
369
  try:
363
- enpass = EnpassDB(args.path, args.password, args.key_file, args.pbkdf2_rounds)
370
+ return EnpassDB(args.path, args.password, args.key_file, args.pbkdf2_rounds)
371
+ except EnpassKeyfileError:
372
+ LOGGER.error(f'The key file "{args.key_file}" does not hold a valid enpass key.')
373
+ raise SystemExit(1) from None
364
374
  except EnpassDatabaseError:
365
375
  LOGGER.error(('Could not read or decrypt the database. '
366
376
  'Please validate that the path provided is a valid enpass database, '
367
377
  'that the provided password and optional key file are correct and that the pbkdf2 rounds'
368
378
  f' provided ("{args.pbkdf2_rounds}") match the configuration of your database.'))
369
379
  raise SystemExit(1) from None
380
+
381
+
382
+ def list_values(enpass, field=None, totp=False):
383
+ """
384
+ Prints the requested value of all the entries that have it.
385
+
386
+ Entries whose value fails authentication are reported and skipped.
387
+
388
+ Args:
389
+ enpass: The opened database.
390
+ field: The label or type of the field to list, the password is listed if not provided.
391
+ totp: If set the current totp code is listed.
392
+
393
+ Returns:
394
+ exit_code (int): 0 if all values could be decrypted else 1.
395
+
396
+ """
397
+ exit_code = 0
398
+ for entry in enpass.entries:
399
+ try:
400
+ value = get_value(entry, field, totp)
401
+ except EnpassDecryptionError:
402
+ LOGGER.error(f'The value of entry with title of "{entry.title}" failed authentication, skipping.')
403
+ exit_code = 1
404
+ continue
405
+ if value is not None:
406
+ print(f'{entry.title}: {value}')
407
+ return exit_code
408
+
409
+
410
+ def run(args, enpass):
411
+ """
412
+ Executes the requested action against the opened database.
413
+
414
+ Args:
415
+ args: The parsed cli arguments.
416
+ enpass: The opened database.
417
+
418
+ Returns:
419
+ exit_code (int): The exit code of the cli.
420
+
421
+ """
370
422
  if args.list:
371
- for entry in enpass.entries:
372
- value = get_value(entry, args.field, args.totp)
373
- if value is not None:
374
- print(f'{entry.title}: {value}')
375
- raise SystemExit(0)
423
+ return list_values(enpass, args.field, args.totp)
376
424
  interactive = args.search or args.fuzzy
377
425
  entry_title = interactive_prompt('Title :', EnpassCompleter(enpass), args.fuzzy) if interactive else args.entry
378
426
  entry = enpass.get_entry(entry_title)
379
427
  if not entry:
380
428
  LOGGER.error(f'No entry found with title of "{entry_title}".')
381
- raise SystemExit(1) from None
429
+ return 1
382
430
  field = args.field
383
431
  if interactive and not field and not args.totp:
384
432
  field = interactive_prompt('Field :', FieldCompleter(entry.field_labels), args.fuzzy)
385
433
  field = field if field.strip() else None
386
- value = get_value(entry, field, args.totp)
434
+ try:
435
+ value = get_value(entry, field, args.totp)
436
+ except EnpassDecryptionError:
437
+ LOGGER.error(f'The value of entry with title of "{entry.title}" failed authentication and cannot be trusted.')
438
+ return 1
387
439
  if value is None:
388
440
  LOGGER.error(get_missing_value_message(entry, field, args.totp))
389
- raise SystemExit(1) from None
441
+ return 1
390
442
  print(value)
391
- raise SystemExit(0) from None
443
+ return 0
444
+
445
+
446
+ def main():
447
+ """
448
+ Main method.
449
+
450
+ This method holds what you want to execute when
451
+ the script is run on command line.
452
+ """
453
+ args = get_arguments()
454
+ setup_logging(args.log_level, args.logger_config)
455
+ with open_database(args) as enpass:
456
+ exit_code = run(args, enpass)
457
+ raise SystemExit(exit_code)
392
458
 
393
459
 
394
460
  if __name__ == '__main__':
@@ -8,6 +8,6 @@
8
8
  # Please use Pipfile to update the requirements.
9
9
  #
10
10
  coloredlogs>=15.0.1 ; python_version >= '2.7' and python_version != '3.0' and python_version != '3.1' and python_version != '3.2' and python_version != '3.3' and python_version != '3.4'
11
- enpassreaderlib>=0.4.0
11
+ enpassreaderlib>=0.4.1
12
12
  prompt-toolkit>=3.0.53 ; python_version >= '3.10'
13
13
  pyotp>=2.10.0 ; python_version >= '3.8'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enpassreadercli
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: A cli to access enpass 6 encrypted databases and read, list and search values.
5
5
  Home-page: https://github.com/costastf/enpassreadercli
6
6
  Author: Costas Tyfoxylos
@@ -19,7 +19,7 @@ Requires-Python: >=3.11
19
19
  License-File: LICENSE
20
20
  License-File: AUTHORS.rst
21
21
  Requires-Dist: coloredlogs>=15.0.1; python_version >= "2.7" and python_version != "3.0" and python_version != "3.1" and python_version != "3.2" and python_version != "3.3" and python_version != "3.4"
22
- Requires-Dist: enpassreaderlib>=0.4.0
22
+ Requires-Dist: enpassreaderlib>=0.4.1
23
23
  Requires-Dist: prompt-toolkit>=3.0.53; python_version >= "3.10"
24
24
  Requires-Dist: pyotp>=2.10.0; python_version >= "3.8"
25
25
  Dynamic: author
@@ -180,3 +180,12 @@ History
180
180
  ------------------
181
181
 
182
182
  * Bump dependencies.
183
+
184
+
185
+ 0.5.2 (16-10-2026)
186
+ ------------------
187
+
188
+ * Require enpassreaderlib 0.4.1 which verifies the authentication tag of encrypted values and opens the database read only.
189
+ * Report values that fail authentication instead of crashing, skipping them when enumerating and exiting with an error.
190
+ * Report invalid key files and missing database paths with their own error messages.
191
+ * Close the database connection when done.
@@ -1,4 +1,4 @@
1
- enpassreaderlib>=0.4.0
1
+ enpassreaderlib>=0.4.1
2
2
 
3
3
  [:python_version >= "2.7" and python_version != "3.0" and python_version != "3.1" and python_version != "3.2" and python_version != "3.3" and python_version != "3.4"]
4
4
  coloredlogs>=15.0.1
@@ -8,6 +8,6 @@
8
8
  # Please use Pipfile to update the requirements.
9
9
  #
10
10
  coloredlogs>=15.0.1 ; python_version >= '2.7' and python_version != '3.0' and python_version != '3.1' and python_version != '3.2' and python_version != '3.3' and python_version != '3.4'
11
- enpassreaderlib>=0.4.0
11
+ enpassreaderlib>=0.4.1
12
12
  prompt-toolkit>=3.0.53 ; python_version >= '3.10'
13
13
  pyotp>=2.10.0 ; python_version >= '3.8'
@@ -33,6 +33,11 @@ Tests for `enpassreadercli` module.
33
33
 
34
34
  """
35
35
 
36
+ import argparse
37
+ import contextlib
38
+ import io
39
+ import os
40
+ import tempfile
36
41
  import unittest as std_unittest
37
42
 
38
43
  from betamax.fixtures import unittest
@@ -40,7 +45,7 @@ from enpassreaderlib.enpassreaderlib import Entry
40
45
  from prompt_toolkit.document import Document
41
46
 
42
47
  from enpassreadercli.enpassreadercli import (FieldCompleter, get_arguments, get_missing_value_message, get_totp,
43
- get_value)
48
+ get_value, list_values, open_database, run)
44
49
 
45
50
  __author__ = '''Costas Tyfoxylos <costas.tyf@gmail.com>'''
46
51
  __docformat__ = '''google'''
@@ -72,17 +77,17 @@ class TestEnpassreadercli(unittest.BetamaxTestCase):
72
77
  pass
73
78
 
74
79
 
75
- def build_entry(fields, totp_seed=None):
76
- """Builds an entry with non sensitive fields and no password."""
80
+ def build_entry(fields, totp_seed=None, title='Service', sensitive=False):
81
+ """Builds an entry with no password, sensitive fields hold their raw stored value."""
77
82
  row = {'key': bytes(44),
78
- 'title': 'Service',
83
+ 'title': title,
79
84
  'uuid': '00000000-0000-0000-0000-000000000000',
80
85
  'password_value': None,
81
86
  'password_value_hash': None,
82
87
  'totp_value': totp_seed,
83
88
  'totp_value_hash': None,
84
89
  'totp_value_sensitive': 0}
85
- field_rows = [{'label': label, 'type': type_, 'value': value, 'sensitive': 0}
90
+ field_rows = [{'label': label, 'type': type_, 'value': value, 'sensitive': int(sensitive)}
86
91
  for label, type_, value in fields]
87
92
  return Entry(row, field_rows)
88
93
 
@@ -155,3 +160,65 @@ class TestArguments(std_unittest.TestCase):
155
160
  def test_empty_field_is_rejected(self):
156
161
  with self.assertRaises(SystemExit):
157
162
  get_arguments(['-d', 'db', '-p', 'pass', '-g', 'Service', '-F', ''])
163
+
164
+
165
+ class FakeDatabase:
166
+ """Stands in for an opened EnpassDB holding the provided entries."""
167
+
168
+ def __init__(self, entries):
169
+ self.entries = entries
170
+
171
+ def get_entry(self, name):
172
+ return next((entry for entry in self.entries if entry.title.lower() == name.lower()), None)
173
+
174
+
175
+ # A value that is not a valid gcm ciphertext and tag for the entry key so it fails authentication
176
+ TAMPERED_VALUE = '00' * 24
177
+
178
+
179
+ class TestTamperedValues(std_unittest.TestCase):
180
+
181
+ def setUp(self):
182
+ self.database = FakeDatabase([build_entry([('API key', 'text', TAMPERED_VALUE)], title='Bad', sensitive=True),
183
+ build_entry([('API key', 'text', 'key-value')], title='Good')])
184
+
185
+ def test_listing_skips_tampered_entries_and_fails(self):
186
+ output = io.StringIO()
187
+ with contextlib.redirect_stdout(output), self.assertLogs('enpassreadercli', level='ERROR'):
188
+ exit_code = list_values(self.database, 'api key')
189
+ self.assertEqual(exit_code, 1)
190
+ self.assertEqual(output.getvalue(), 'Good: key-value\n')
191
+
192
+ def test_single_tampered_entry_fails(self):
193
+ args = get_arguments(['-d', 'db', '-p', 'pass', '-g', 'Bad', '-F', 'api key'])
194
+ output = io.StringIO()
195
+ with contextlib.redirect_stdout(output), self.assertLogs('enpassreadercli', level='ERROR'):
196
+ exit_code = run(args, self.database)
197
+ self.assertEqual(exit_code, 1)
198
+ self.assertEqual(output.getvalue(), '')
199
+
200
+
201
+ class TestOpenDatabase(std_unittest.TestCase):
202
+
203
+ @staticmethod
204
+ def arguments(path, key_file=''):
205
+ return argparse.Namespace(path=path, password='pass', key_file=key_file, pbkdf2_rounds=1)
206
+
207
+ def test_missing_database_fails_without_creating_it(self):
208
+ with tempfile.TemporaryDirectory() as directory:
209
+ path = os.path.join(directory, 'missing.enpassdb')
210
+ with self.assertLogs('enpassreadercli', level='ERROR'), self.assertRaises(SystemExit):
211
+ open_database(self.arguments(path))
212
+ self.assertFalse(os.path.exists(path))
213
+
214
+ def test_invalid_key_file_fails(self):
215
+ with tempfile.TemporaryDirectory() as directory:
216
+ path = os.path.join(directory, 'vault.enpassdb')
217
+ key_file = os.path.join(directory, 'vault.enpassdbx')
218
+ with open(path, 'wb') as database:
219
+ database.write(b'not an enpass database' * 64)
220
+ with open(key_file, 'w', encoding='utf-8') as key:
221
+ key.write('<key>not hex</key>')
222
+ with self.assertLogs('enpassreadercli', level='ERROR') as logs, self.assertRaises(SystemExit):
223
+ open_database(self.arguments(path, key_file))
224
+ self.assertIn('key file', logs.output[0])
@@ -1 +0,0 @@
1
- 0.5.1
@@ -1 +0,0 @@
1
- 0.5.1
File without changes