138 lines
3.2 KiB
Python
138 lines
3.2 KiB
Python
from os import environ
|
|
from os.path import expanduser
|
|
|
|
from bundlewrap.exceptions import FaultUnavailable
|
|
from bundlewrap.utils import Fault
|
|
from bundlewrap.utils.text import bold, yellow
|
|
from bundlewrap.utils.ui import io
|
|
from pykeepass import PyKeePass
|
|
from pykeepass.exceptions import CredentialsError
|
|
|
|
DUMMY_MODE = environ.get('BW_KEEPASS_DUMMY_MODE', '0') == '1'
|
|
KEEPASS_FILE = environ.get('BW_KEEPASS_FILE', None)
|
|
KEEPASS_PASS = environ.get('BW_KEEPASS_PASSWORD', None)
|
|
|
|
cache = {}
|
|
|
|
|
|
try:
|
|
with open(expanduser('~/.bw_keepass.cfg'), 'r') as f:
|
|
cfg = f.read().splitlines()
|
|
|
|
if not KEEPASS_FILE:
|
|
KEEPASS_FILE = cfg[0].strip()
|
|
|
|
if not KEEPASS_PASS and len(cfg) > 1:
|
|
KEEPASS_PASS = cfg[1]
|
|
except (FileNotFoundError, IndexError):
|
|
pass
|
|
|
|
|
|
def _get_contents_from_keepass(path):
|
|
if not KEEPASS_FILE or not KEEPASS_PASS:
|
|
raise FaultUnavailable('BW_KEEPASS_FILE and/or BW_KEEPASS_PASSWORD missing')
|
|
|
|
if isinstance(path, list):
|
|
list_path = path
|
|
string_path = '|'.join(path)
|
|
else:
|
|
list_path = path.split('|')
|
|
string_path = path
|
|
|
|
try:
|
|
return cache[string_path]
|
|
except KeyError:
|
|
# Not yet fetched from keepass
|
|
pass
|
|
|
|
with io.job('{p} looking up "{path}" in "{file}"'.format(
|
|
p=bold('KeePass'),
|
|
path=list_path,
|
|
file=KEEPASS_FILE,
|
|
)):
|
|
try:
|
|
keepass = PyKeePass(expanduser(KEEPASS_FILE), KEEPASS_PASS)
|
|
|
|
result = keepass.find_entries_by_path(list_path, first=True)
|
|
except CredentialsError:
|
|
raise FaultUnavailable('Your specified BW_KEEPASS_PASSWORD is invalid for use with {}'.format(KEEPASS_FILE))
|
|
except Exception as e:
|
|
raise FaultUnavailable('Exception while trying to get path "{}" from file "{}": {}'.format(
|
|
list_path,
|
|
KEEPASS_FILE,
|
|
repr(e)
|
|
))
|
|
|
|
if not result:
|
|
raise FaultUnavailable('Could not find any entries for path "{}" in file "{}"'.format(
|
|
list_path,
|
|
KEEPASS_FILE,
|
|
))
|
|
|
|
cache[string_path] = result
|
|
|
|
return cache[string_path]
|
|
|
|
|
|
def _password(path):
|
|
if DUMMY_MODE:
|
|
return 'KEEPASS DUMMY PASSWORD'
|
|
else:
|
|
secret = _get_contents_from_keepass(path)
|
|
return secret.password
|
|
|
|
|
|
def password(path):
|
|
return Fault(
|
|
'bwkeepass password',
|
|
_password,
|
|
path=path,
|
|
)
|
|
|
|
|
|
def _username(path):
|
|
if DUMMY_MODE:
|
|
return 'KEEPASS DUMMY USERNAME'
|
|
else:
|
|
secret = _get_contents_from_keepass(path)
|
|
return secret.username
|
|
|
|
|
|
def username(path):
|
|
return Fault(
|
|
'bwkeepass username',
|
|
_username,
|
|
path=path,
|
|
)
|
|
|
|
|
|
def _url(path):
|
|
if DUMMY_MODE:
|
|
return 'http://KEEPASS.DUMMY.URL'
|
|
else:
|
|
secret = _get_contents_from_keepass(path)
|
|
return secret.url
|
|
|
|
|
|
def url(path):
|
|
return Fault(
|
|
'bwkeepass url',
|
|
_url,
|
|
path=path,
|
|
)
|
|
|
|
|
|
def _notes(path):
|
|
if DUMMY_MODE:
|
|
return 'KEEPASS DUMMY NOTES'
|
|
else:
|
|
secret = _get_contents_from_keepass(path)
|
|
return secret.notes
|
|
|
|
|
|
def notes(path):
|
|
return Fault(
|
|
'bwkeepass notes',
|
|
_notes,
|
|
path=path,
|
|
)
|