#!/usr/bin/env python3

# A little tool to encrypt/decrypt git secrets. Kinda like password-store, but more purpose specific and portable.

import logging
import os
import sys
import subprocess

keys = [
    "63DFE737F078657CC8A51C00C29ADD73B3563D82", # q3k
    "482FF104C29294AD1CAF827BA43890A3DE74ECC7", # inf
    "F07205946C07EEB2041A72FBC60C64879534F768", # cz2
    #"0879F9FCA1C836677BB808C870FD60197E195C26", # implr (expired 2019-02-09)
]


logger = logging.getLogger(__name__)


def encrypt(src, dst):
    cmd = ['gpg' , '--encrypt', '--armor', '--batch', '--yes', '--output', dst]
    for k in keys:
        cmd.append('--recipient')
        cmd.append(k)
    cmd.append(src)
    subprocess.check_call(cmd)

def decrypt(src, dst):
    cmd = ['gpg', '--decrypt', '--batch', '--yes', '--output', dst, src]
    subprocess.check_call(cmd)


class SecretStoreMissing(Exception):
    pass


class SecretStore(object):
    def __init__(self, plain_root, cipher_root):
        self.proot = plain_root
        self.croot = cipher_root

    def exists(self, suffix):
        p = os.path.join(self.proot, suffix)
        c = os.path.join(self.croot, suffix)
        return os.path.exists(c) or os.path.exists(p)

    def plaintext(self, suffix):
        p = os.path.join(self.proot, suffix)
        c = os.path.join(self.croot, suffix)

        if not os.path.exists(p) or os.path.getctime(p) < os.path.getctime(c):
            logger.info("Decrypting {} ({})...".format(suffix, c))
            decrypt(c, p)

        return p

    def open(self, suffix, mode, *a, **kw):
        p = os.path.join(self.proot, suffix)
        c = os.path.join(self.croot, suffix)
        if 'w' in mode:
            return open(p, mode, *a, **kw)

        if not self.exists(suffix):
            raise SecretStoreMissing("Secret {} does not exist".format(suffix))

        if not os.path.exists(p) or os.path.getctime(p) < os.path.getctime(c):
            logger.info("Decrypting {} ({})...".format(suffix, c))
            decrypt(c, p)

        return open(p, mode, *a, **kw)


def main():
    if len(sys.argv) < 3 or sys.argv[1] not in ('encrypt', 'decrypt'):
        sys.stderr.write("Usage: {} encrypt/decrypt file\n".format(sys.argv[0]))
        sys.stderr.flush()
        return 1

    action = sys.argv[1]
    src = sys.argv[2]

    if action == 'encrypt':
        encrypt(src, '-')
    else:
        decrypt(src, '-')

if __name__ == '__main__':
    sys.exit(main() or 0)
