62 lines
1.7 KiB
Python
62 lines
1.7 KiB
Python
from os import environ
|
|
from os.path import expanduser
|
|
from subprocess import check_output, CalledProcessError
|
|
|
|
from bundlewrap.exceptions import FaultUnavailable
|
|
from bundlewrap.utils import Fault
|
|
from bundlewrap.utils.text import bold, yellow
|
|
from bundlewrap.utils.ui import io
|
|
|
|
PASSWORD_STORE_DIR = expanduser(environ.get('BW_PASS_DIR', '~/.password-store'))
|
|
DUMMY_MODE = environ.get('PW_PASS_DUMMY_MODE', '0') == '1'
|
|
|
|
cache = {}
|
|
|
|
def _get_contents_from_pass(identifier: str):
|
|
try:
|
|
return cache[identifier]
|
|
except KeyError:
|
|
# Not yet fetched from pass
|
|
pass
|
|
|
|
with io.job('{p} fetching {identifier}'.format(
|
|
p=bold('pass'),
|
|
identifier=identifier,
|
|
)):
|
|
try:
|
|
pass_output = check_output(
|
|
['pass', 'show', identifier],
|
|
env={
|
|
'PASSWORD_STORE_DIR': PASSWORD_STORE_DIR,
|
|
}
|
|
).decode('UTF-8').splitlines()
|
|
except FileNotFoundError:
|
|
raise FaultUnavailable('pass not found')
|
|
except CalledProcessError as e:
|
|
raise FaultUnavailable('pass exited {} when trying to get secret "{}"'.format(
|
|
e.returncode,
|
|
identifier,
|
|
))
|
|
|
|
cache[identifier] = {}
|
|
cache[identifier]['password'] = pass_output[0]
|
|
|
|
# TODO import all other options set in pass
|
|
|
|
return cache[identifier]
|
|
|
|
|
|
def _password(identifier):
|
|
if DUMMY_MODE:
|
|
return 'PASS DUMMY PASSWORD'
|
|
else:
|
|
secret = _get_contents_from_pass(identifier)
|
|
return secret['password']
|
|
|
|
|
|
def password(identifier):
|
|
return Fault(
|
|
'bwpass password',
|
|
_password,
|
|
identifier=identifier,
|
|
)
|