Something went wrong. Try again.
Personal configuration files
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105#!/usr/bin/env python3from __future__ import annotationsimport argparseimport jsonimport osimport shleximport subprocessimport sysfrom enum import Enumfrom typing import TYPE_CHECKING, castfrom urllib import parseclass Operation(Enum): ERASE = "erase" GET = "get" STORE = "store"if TYPE_CHECKING: class Args(argparse.Namespace): bitwarden: str session: str | None operation: Operationparser = argparse.ArgumentParser(description="Bitwarden credential helper for Git.")parser.add_argument( "-b", "--bitwarden", type=str, help="command to execute the Bitwarden CLI, defaults to bw", default="bw",)parser.add_argument( "-s", "--session", type=str, default=os.getenv("BW_SESSION"), help="Bitwarden session key, doesn't need to be set if $BW_SESSION is set",)parser.add_argument( "operation", type=Operation, help="argument provided by Git (get|store|erase)")args = cast("Args", parser.parse_args())if args.operation != Operation.GET: # We don't care about store or erase at the moment. print(f"Ignoring {args.operation} directive. Use Bitwarden directly.") sys.exit(0)if args.session is None: print("No Bitwarden session key provided", file=sys.stderr) sys.exit(1)params: dict[str, str] = {}for line in sys.stdin.readlines(): parts = line.split("=", maxsplit=1) # If we are handed a line like "password=", skip it. if not parts[0]: continue params[parts[0]] = parts[1].rstrip()# No use for any other protocols at the momentif params["protocol"] != "smtp": exit(0)username = parse.quote(params["username"])proc = subprocess.run( [*shlex.split(args.bitwarden), "--session", args.session, "list", "items"], check=True, encoding="utf-8", stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,)proc.check_returncode()items = json.loads(proc.stdout)for item in items: login = item.get("login") if not login: continue username = login.get("username") if not username: continue password = login.get("password") if not password: continue if params["protocol"] == "smtp": if item.get("name") != "git-send-email": continue print(f"password={password}") sys.exit(0)sys.exit(1)