Add QR-to-CSV utility and switch canonical format to CSV
Add qr_to_sheet.py: decode saved OTP QR screenshots and append new credentials to the canonical CSV, deduplicated on the otpauth:// data. Add otpauth.py (parse_otpauth / canonical_key / build_otpauth), shared by both tools. The canonical format becomes a minimal CSV (issuer, account, otpauth_uri, source_file); load_credentials reads CSV or xlsx and derives crypto from the immutable otpauth_uri while taking issuer/account from their editable label columns.
This commit is contained in:
18
test_oath.py
18
test_oath.py
@@ -228,6 +228,24 @@ class TestLoadCredentials(unittest.TestCase):
|
||||
self.assertEqual(g.source, "g.png")
|
||||
self.assertEqual((creds[1].algorithm, creds[1].digits, creds[1].period), (HMAC_SHA256, 8, 15))
|
||||
|
||||
def test_csv_takes_labels_from_columns_and_crypto_from_otpauth(self):
|
||||
import csv
|
||||
d = tempfile.mkdtemp()
|
||||
path = os.path.join(d, "otp-keys.csv")
|
||||
with open(path, "w", newline="", encoding="utf-8") as f:
|
||||
w = csv.writer(f)
|
||||
w.writerow(["issuer", "account", "otpauth_uri", "source_file"])
|
||||
# otpauth label is "Amal Graafstra"; the editable account differs
|
||||
w.writerow(["Heroku", "amal@vivokey.com",
|
||||
"otpauth://totp/Heroku:Amal%20Graafstra?secret=JBSWY3DP"
|
||||
"&issuer=Heroku&algorithm=SHA256&digits=8&period=60", "h.png"])
|
||||
creds = load_credentials(path)
|
||||
c = creds[0]
|
||||
self.assertEqual((c.issuer, c.account), ("Heroku", "amal@vivokey.com")) # from columns
|
||||
self.assertEqual(c.secret, "JBSWY3DP") # from otpauth
|
||||
self.assertEqual((c.oath_type, c.algorithm, c.digits, c.period),
|
||||
(TOTP_TYPE, HMAC_SHA256, 8, 60)) # from otpauth
|
||||
|
||||
|
||||
class TestCardChannel(unittest.TestCase):
|
||||
def test_reassembles_61xx_via_send_remaining(self):
|
||||
|
||||
Reference in New Issue
Block a user