#!/usr/bin/env python
"""
Automatically provide credentials (username/passwords) read from a file.

This is useful to avoid having to type in your password in some repositories. If
you are regularly pushing from/pulling into a checkout that is in a shared or
public space, and you don't feel comfortable placing your username/password in
the hgrc URL, where others who have access can read them, you can use this to
automatically supply the credentials.

The format of the password file is::

  realm, uri, username, password
  realm, uri, username, password
  ...

The location of the file is '~/.hgpasswd' by default and can be overridden with
the environment variable 'HGPASSWD'.

Future work: we could support encrypted files decrypted using gpg (and gpg-agent
to avoid having to type your password).
"""
# This should work with Mercurial 1.1.

__author__ = 'Martin Blais <blais@furius.ca>'
# Other contributors:
# Owen Jacobson <owen.jacobson@grimoire.ca>: Patch for making it work with
# 'clone' command.

# stdlib imports
import sys, os, re
from os.path import join, exists

# mercurial imports
from mercurial import httprepo
if hasattr(httprepo, 'passwordmgr'): # 1.0
    pcont = httprepo
else: # 1.1
    from mercurial import url
    pcont = url


def uisetup(ui):

    # Patch up the password manager class.
    pcont.passwordmgr.__oldinit__ = pcont.passwordmgr.__init__
    pcont.passwordmgr.__init__ = passwordmgr__init__

    # Read in the database of default passwords.
    if "HOME" in os.environ:
        passfn = os.environ.get('HGPASSWD', join(os.environ['HOME'], '.hgpasswd'))
        if exists(passfn):
            read_passwords(passfn)


def passwordmgr__init__(self, ui):
    """ Monkey-patched version of the passwordmgr constructor that injects the
    default passwords during construction. """
    pcont.passwordmgr.__oldinit__(self, ui)
    for realm, uri, user, passwd in passwords:
        self.add_password(realm, uri, user, passwd)

passwords = []

def read_passwords(fn):
    """ Read the password file and return a list of (realm, uri, user, passwd)
    tuples. The file must be a list of such comma-separated values on each line."""
    try:
        passwords[:] = []
        for line in open(fn).readlines():
            line = line.strip()
            if not line or re.match('\s*#.*', line):
                continue # ignore comments and empty lines
            entry = line.split(',', 3)
            if len(entry) != 4:
                print >> sys.stderr, ("Error in passwd file %s: %s" % (fn, line))
                raise SystemExit
            passwords.append( map(str.strip, entry) )
    except Exception, e:
        print >> sys.stderr, ("Error opening passwd file: %s" % e)




