From 1b4c2becf48972ba88d50ac79ae977093168b22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Soko=C5=82owski?= Date: Tue, 7 May 2024 14:48:35 +0200 Subject: [PATCH] lookup_plugins/bitwarden: ignore stderr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we get weird JSON parsing errors: ``` An unhandled exception occurred while running the lookup plugin 'bitwarden'. Error was a , original message: Extra data: line 1 column 843 (char 842). Extra data: line 1 column 843 (char 842) ``` Signed-off-by: Jakub SokoĊ‚owski --- ansible/lookup_plugins/bitwarden.py | 40 +++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/ansible/lookup_plugins/bitwarden.py b/ansible/lookup_plugins/bitwarden.py index 91e87a5..d757ef0 100755 --- a/ansible/lookup_plugins/bitwarden.py +++ b/ansible/lookup_plugins/bitwarden.py @@ -7,9 +7,11 @@ # This plugin can be run directly by specifying the field followed by a list of # entries, e.g. bitwarden.py password google.com wufoo.com # -# This version includes fixes that can be found in this fork: -# https://github.com/status-im/ansible-modules-bitwarden -# +# CHANGES: +# - Dropped custom_field argument +# - Started checking sources in order +# - Refactored Bitwarden class, added get_item() +# - Split LookupModule.run into two functions from __future__ import (absolute_import, division, print_function) __metaclass__ = type @@ -17,7 +19,6 @@ import json import os import sys -from shutil import which from subprocess import Popen, PIPE, STDOUT, check_output from ansible.errors import AnsibleError @@ -69,7 +70,9 @@ class Bitwarden(object): def __init__(self, path): self._cli_path = path self._bw_session = "" - if which("bw") is None: + try: + check_output([self._cli_path, "--version"]) + except OSError: raise AnsibleError("Command not found: {0}".format(self._cli_path)) @property @@ -84,12 +87,20 @@ class Bitwarden(object): def cli_path(self): return self._cli_path + @property + def logged_in(self): + # Parse Bitwarden status to check if logged in + if self.status() == 'unlocked': + return True + else: + return False + def _run(self, args): my_env = os.environ.copy() if self.session != "": my_env["BW_SESSION"] = self.session p = Popen([self.cli_path] + args, stdin=PIPE, - stdout=PIPE, stderr=STDOUT, env=my_env) + stdout=PIPE, stderr=PIPE, env=my_env) out, _ = p.communicate() out = out.decode() rc = p.wait() @@ -118,6 +129,13 @@ class Bitwarden(object): def sync(self): self._run(['sync']) + def status(self): + try: + data = json.loads(self._run(['status'])) + except json.decoder.JSONDecodeError as e: + raise AnsibleError("Error decoding Bitwarden status: %s" % e) + return data['status'] + def get_entry(self, key, field): return self._run(["get", field, key]) @@ -149,12 +167,18 @@ class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): self.bw = Bitwarden(path=kwargs.get('path', 'bw')) + if not self.bw.logged_in: + raise AnsibleError("Not logged into Bitwarden: please run " + "'bw login', or 'bw unlock' and set the " + "BW_SESSION environment variable first") + + values = [] + if kwargs.get('sync'): self.bw.sync() if kwargs.get('session'): self.bw.session = kwargs.get('session') - values = [] for term in terms: rval = self.lookup(term, kwargs) if rval is None: @@ -191,7 +215,7 @@ def main(): print("Usage: %s [name name ...]" % os.path.basename(__file__)) return -1 - print(LookupModule().run(sys.argv[2:], variables=None, field=sys.argv[1])) + print(LookupModule().run(sys.argv[2:], variables=None, field=sys.argv[1], file='origin.crt')) return 0