Coverage for pass_import/formats/otp.py: 100%
25 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-02-26 12:11 +0000
« prev ^ index » next coverage.py v7.4.3, created at 2024-02-26 12:11 +0000
1# -*- encoding: utf-8 -*-
2# pass import - Passwords importer swiss army knife
3# Copyright (C) 2017-2024 Alexandre PUJOL <alexandre@pujol.io>.
4#
6import json
8from pass_import.formats.json import JSON
11class OTP(JSON):
12 """Base class for OTP based importers."""
13 content = ''
15 # Import methods
17 @staticmethod
18 def _otp(item):
19 otp = f"otpauth://{item.get('type', 'totp').lower()}/totp-secret?"
20 otp += f"secret={item['secret']}&issuer={item['label']}"
21 for setting in ['algorithm', 'digits', 'counter', 'period']:
22 if setting in item:
23 otp += f"&{setting}={item[setting]}"
24 return otp
26 def parse(self):
27 """Parse OTP based file."""
28 jsons = json.loads(self.content)
29 for item in jsons:
30 entry = {}
31 entry['title'] = item['label']
32 entry['otpauth'] = self._otp(item)
34 for key in ['type', 'thumbnail', 'last_used']:
35 entry[key] = str(item.get(key, '')).lower()
36 entry['tags'] = ', '.join(item['tags'])
37 self.data.append(entry)
39 # Context manager method
41 def open(self):
42 """Parse OTP based file."""
43 super().open()
44 self.content = self.file.read()