Skip to content

Instantly share code, notes, and snippets.

@daskol
Last active January 22, 2022 22:07
Show Gist options
  • Save daskol/98e76ad9b7b6e50f1eba9f8368d1170c to your computer and use it in GitHub Desktop.
Save daskol/98e76ad9b7b6e50f1eba9f8368d1170c to your computer and use it in GitHub Desktop.
Simple git credential helper in Python
#!/usr/bin/env python3
"""Simple script is a git credential helper which extracts password from
password store (pass).
"""
from argparse import ArgumentParser, Namespace
from dataclasses import dataclass
from subprocess import check_output
from sys import stdin, stdout
from typing import Optional, TextIO
parser = ArgumentParser(description=__doc__)
parser.add_argument('-t',
'--template',
type=str,
default='{username}@{host}',
help='password name template')
parser.add_argument('action', type=str, help='operation to execute')
@dataclass
class Credential:
username: Optional[str] = None
password: Optional[str] = None
protocol: Optional[str] = None
host: Optional[str] = None
path: Optional[str] = None
@staticmethod
def read(fin: Optional[TextIO] = None) -> 'Credential':
res = Credential()
if not fin:
fin = stdin
for line in (line.strip() for line in stdin):
if line == '':
break
if '=' not in line:
raise RuntimeError('Unable to read credential from stdin.')
param, value = line.split('=', 1)
if param == 'username':
res.username = value
elif param == 'password':
res.password = value
elif param == 'protocol':
res.protocol = value
elif param == 'host':
res.host = value
elif param == 'path':
res.path = value
return res
def write(self, fout: Optional[TextIO] = None):
if not fout:
fout = stdout
def write_param(param: str):
if (value := getattr(self, param, None)):
fout.write(f'{param}={value}\n')
write_param('username')
write_param('password')
write_param('protocol')
write_param('host')
write_param('port')
def get_credential(template: str):
credential = Credential.read()
pass_target = template.format(host=credential.host,
username=credential.username)
pass_output = check_output(['pass', pass_target])
credential.password = pass_output.decode('utf-8').strip()
credential.write()
def main(args: Namespace):
if args.action == 'get':
get_credential(args.template)
if __name__ == '__main__':
main(parser.parse_args())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment