Start pass2keepass script

This commit is contained in:
Tunui Franken 2024-07-25 09:09:25 +02:00
commit 46e3a00a39
2 changed files with 140 additions and 0 deletions

138
pass2keepass.py Executable file
View file

@ -0,0 +1,138 @@
#!/usr/bin/env python3
import os
import sys
from getpass import getpass
import gnupg
from pykeepass import PyKeePass
VERBOSE = bool("-v" in sys.argv or "--verbose" in sys.argv)
def main() -> None:
"""Open the a KeePass database, drop the entries and import them from Pass"""
if len(sys.argv) != 2:
usage()
sys.exit(1)
db_path = sys.argv[1]
database = PyKeePass(db_path, getpass(f"Password for {db_path}: "))
pass_store = PassStore()
pass_store.print_tree()
drop_kp_database(database)
def drop_kp_database(database: PyKeePass) -> None:
"""Remove all groups and entries from a KeePass database"""
print("Dropping entries...")
for entry in database.entries:
vprint(f" {entry.title}")
entry.delete()
print("Dropping groups...")
for group in database.groups:
vprint(f" {group.name}")
group.delete()
class PassStore:
"""Class to represent a Pass Store"""
def __init__(self):
gpg = gnupg.GPG()
self.path = os.path.expanduser(
os.environ.get("PASSWORD_STORE_DIR", "~/.password-store")
)
print(f"Loading Password store at {self.path}...")
self.groups = [PassGroup("root_group")]
for item in sorted(os.listdir(self.path)):
if item.startswith("."): # .git, .gitignore, .gpg-id, etc.
continue
if os.path.isfile(os.path.join(self.path, item)):
self.groups[0].entries.append(PassEntry(os.path.join(self.path, item)))
continue
if os.path.isdir(os.path.join(self.path, item)):
group = PassGroup(os.path.join(self.path, item))
group.trickle_down()
self.groups.append(group)
continue
print(f"Unrecognized item {item}")
def print_tree(self):
"""Print a tree of the store"""
for group in self.groups:
group.print_tree()
class PassGroup:
"""Class to represent a Pass Store directory"""
def __init__(self, path: str):
vprint(f"Got group at {path}")
self.path = path
self.name = os.path.basename(path)
self.groups: list[PassGroup] = []
self.entries: list[PassEntry] = []
def trickle_down(self):
"""Move down the group to find subgroups and entries"""
for item in sorted(os.listdir(self.path)):
if item.startswith("."): # .git, .gitignore, .gpg-id, etc.
continue
if os.path.isfile(os.path.join(self.path, item)):
self.entries.append(PassEntry(os.path.join(self.path, item)))
continue
if os.path.isdir(os.path.join(self.path, item)):
group = PassGroup(os.path.join(self.path, item))
group.trickle_down()
self.groups.append(group)
continue
print(f"Unrecognized item {item}")
def print_tree(self):
"""Print a tree of this group"""
print(f"{self.name}:")
for entry in self.entries:
print(f" - {entry.name}")
for group in self.groups:
group.print_tree()
class PassEntry:
"""Class to represent a Pass Store file"""
def __init__(self, path: str):
vprint(f"Got entry at {path}")
self.path = path
self.name = os.path.basename(path).removesuffix(".gpg")
self.group = os.path.basename(os.path.dirname(path))
self.password = ""
self.username = ""
self.url = ""
self.notes = ""
def usage():
"""Print usage"""
print(f"Usage: {sys.argv[0]} [-v|--verbose] path_to_database.kdbx", file=sys.stderr)
def vprint(*args, **kwargs):
"""Print if VERBOSE is True"""
if VERBOSE:
print(*args, **kwargs)
if __name__ == "__main__":
main()

2
requirements.txt Normal file
View file

@ -0,0 +1,2 @@
gnupg
pykeepass