#!/usr/bin/env python

import sys
import os
import optparse
import shutil
import pwd

# these are the only paths within a user's home directory that can be written
_DESTINATION_PATHS = ['nimbus_creds', 'nimbus_creds.tar.gz', 'nimbus_creds.zip']

_USAGE = """%prog [--force] user source_creds [dest_name]

Places a credential directory or file into a user's home directory. Intended to be
safely run under sudo. Acceptable destination names (within the user's home) are:
\t""" + '\n\t'.join(_DESTINATION_PATHS) 

def setup_options():
    parser = optparse.OptionParser(usage=_USAGE)
    parser.add_option('--force', '-f', action="store_true", default=False,
            dest='force', help="Force overwriting of existing files")
    return parser

def chown_recursive(path, uid, gid):
    os.chown(path, uid, gid)
    for root, dirs, files in os.walk(path):
        for d in dirs:
            os.chown(os.path.join(root, d), uid, gid)
        for f in files:
            os.chown(os.path.join(root, f), uid, gid)

def main(args=sys.argv[1:]):
    parser = setup_options()
    opts, args = parser.parse_args()

    if len(args) != 2 and len(args) != 3:
        parser.print_help()
        return 1

    user, source_path = args[0], args[1]

    try:
        user_entry = pwd.getpwnam(user)
    except KeyError:
        print "User %s does not exist!" % user
        return 1
    uid, gid, home_dir = user_entry[2], user_entry[3], user_entry[5]

    if not os.path.exists(home_dir):
        print "home directory %s doesn't exist!" % home_dir
        return 1

    if not os.path.exists(source_path):
        print "source path %s does not exist!" % source_path
        return 1

    if len(args) == 3:
        dest_name = args[2]
    else:
        dest_name = os.path.basename(source_path)

    if dest_name not in _DESTINATION_PATHS:
        print "Destination '%s' forbidden. Only the following may be used:" % dest_name
        print "\n".join(_DESTINATION_PATHS)
        return 1

    dest_path = os.path.join(home_dir, dest_name)
    if os.path.exists(dest_path):
        if not opts.force:
            print "Destination path %s exists, not overwriting." % dest_path
            print "Specify --force to proceed."
            return 1
        if os.path.isdir(dest_path):
            shutil.rmtree(dest_path)

    #alright not the most secure, basically trusting that source files will have 
    # sensible permissions
    if os.path.isdir(source_path):
        shutil.copytree(source_path, dest_path, symlinks=True)
        os.chmod(dest_path, 0700)
        chown_recursive(dest_path, uid, gid)
    else:
        shutil.copy2(source_path, dest_path)
        os.chmod(dest_path, 0600)
        os.chown(dest_path, uid, gid)
    return 0

if __name__ == "__main__":
    sys.exit(main())
