#!/usr/bin/python
import os, sys, datetime

KEYTYPES = 'ssh-rsa', 'ssh-ed25519'
AUTHFILE = '/srv/hg/.ssh/authorized_keys'
KEYDIR = '/srv/hg/keys'
WEBDIR = '/srv/hg/web'
ADMIN = set()
# Explanation:
# - `cd /data/hg/repos` allows for short ssh URLs, e.g. ssh://hg@hg.python.org/test
#   instead of ssh://hg@hg.python.org/repos/test
# - `HGPUSHER=%s` allows hooks/mail.py to know who pushed the changes, and display
#   it in the notification e-mail.
COMMAND = 'command="cd /srv/hg/repos && HGPUSHER=%s /usr/bin/hg-ssh /srv/hg/repos/*"'
CMDOPTS = [
        'no-port-forwarding', 'no-X11-forwarding',
        'no-agent-forwarding', 'no-pty',
]

if sys.argv[1:2] == ['--update']:
    os.chdir(KEYDIR)
    if os.path.isdir('.hg'):
        os.system('hg --config trusted.users=hg pull -u')
    else:
        os.system('svn up')

keys = os.listdir(KEYDIR)
data = {}
users = []
for u in keys:
        added = False
        fn = os.path.join(KEYDIR, u)
        if os.path.isdir(fn):
                continue

        f = open(fn)
        lines = [i.strip() for i in f if i.strip()]
        f.close()

        for ln in lines:
                bits = ln.split(' ', 2)
                if bits[0] not in KEYTYPES:
                        print 'unknown key type %s for user %s' % (bits[0], u)
                        continue
                ukeys = data.setdefault(u, [])
                ukeys.append((bits[0], bits[1]))
                added = True
        if added:
                users.append(u)

dt = datetime.datetime.utcnow()
# chmod'ing early avoids race conditions.  the strict perms are needed
# otherwise sshd will ignore the file.
fd = os.open(AUTHFILE + '.tmp', os.O_CREAT | os.O_WRONLY, 0o640)
f = os.fdopen(fd, "w")

notice = """
# ATTENTION: this file was generated by genauth on %s
# don't modify it manually but edit bin/genauth instead, and run it again
""" % dt

print >> f, notice
for u in ADMIN:
        keys = data.pop(u)
        for type, k in keys:
                print >> f, '%s %s %s (admin)' % (type, k, u)

for u, keys in sorted(data.iteritems()):
        for type, k in keys:
                cmd = COMMAND % u
                opts = ','.join(CMDOPTS)
                print >> f, '%s,%s %s %s %s' % (cmd, opts, type, k, u)
print >> f, notice

f.close()
os.rename(AUTHFILE + '.tmp', AUTHFILE)

f = open(os.path.join(WEBDIR, 'committers'), 'w')
f.write('\n'.join(sorted(users)))
f.close()
