#!/usr/bin/env python3 import argparse import gnupg import os import sys from google.oauth2.credentials import Credentials as Oauth2Creds from google.auth.transport.requests import Request as AuthRequest def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) class SMTPCredential(object): CONFIG_DICT = { 'dtor@chromium.org' : ('Chromium', False), 'dtor@google.com' : ('Google', False), 'dmitry.torokhov@gmail.com' : ('Gmail', True), 'dtor@kernel.org' : ('Kernel.org', False), } def __init__(self): self.gpg = gnupg.GPG(gpgbinary="gpg2", use_agent=True) self.data_path = os.path.expanduser('~/.mutt/passwords/') def get_unencrypted_data(self, config_name): file_name = os.path.join(self.data_path, config_name) with open(file_name, 'r') as fp: lines = fp.read().splitlines() return next(iter(lines), None) def get_encrypted_data(self, config_name): file_name = os.path.join(self.data_path, config_name) with open(file_name, 'rb') as fp: crypt = self.gpg.decrypt_file(fp) if crypt.ok: lines = crypt.data.splitlines() return next(iter(lines), None) def get_password(self, config_name): return self.get_encrypted_data(config_name) def get_oauth2_creds(self, config_name): client_id = self.get_unencrypted_data(config_name + ".oauth.client") client_secret = self.get_encrypted_data(config_name + ".oauth.secret") refresh_token = self.get_encrypted_data(config_name + ".oauth.refresh") if client_id and client_secret and refresh_token: return Oauth2Creds(None, refresh_token=refresh_token, token_uri='https://oauth2.googleapis.com/token', client_id=client_id, client_secret=client_secret) def get_oauth2_token(self, config_name): creds = self.get_oauth2_creds(config_name) if creds: creds.refresh(AuthRequest()) return creds.token def get(self, username, **kwargs): (name, oauth2) = self.CONFIG_DICT[username] secret = self.get_oauth2_token(name) if oauth2 \ else self.get_password(name) if secret: print("password={0}".format(secret)) def main(): parser = argparse.ArgumentParser() parser.add_argument('operation', action="store", type=str, help="Git action to be performed (get|store|erase)") # parse all arguments arguments = parser.parse_args() myvars = {} for line in sys.stdin: name, val = line.partition("=")[::2] myvars[name.strip()] = val.strip() if arguments.operation == "get": try: protocol = myvars.pop('protocol') username = myvars.pop('username') cred_class = globals()[protocol.upper() + "Credential"] cred = cred_class() cred.get(username, **myvars) except: eprint("Failed to get credential") raise elif arguments.operation == "store": pass elif arguments.operation == "erase": pass else: eprint("Invalid git operation") if __name__ == "__main__": main()