########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Server/Client/Commands/Passwd.py,v 1.9 2005/03/07 03:38:02 uogbuji Exp $
"""
Implementation of '4ss passwd' command
(functions defined here are used by the Ft.Lib.CommandLine framework)

Copyright 2004 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

__doc__ = """This command sets a 4Suite repository User's password. \
It will first prompt for the new password to set. Then it will attempt \
to connect to the repository and change the password, prompting first \
for credentials and access info if necessary. The user accessing the \
repository must have write access on the User resource for which the \
password is being modified."""

import sys

from Ft.Server.Client import FtServerClientException
from Ft.Server.Client.Commands import CommandUtil
from Ft.Server.Common import ResourceTypes, ClAuthenticate


def Run(options, args):
    #The user may have to log in with current info first
    print "You may be asked to authenticate using current credentials"
    sys.stdout.flush()
    
    commit = False
    repo = CommandUtil.GetRepository(options, '4ss.passwd')

    #Then query for updated passwords
    while True:
        passwd = ClAuthenticate.GetPass('Enter new password for %s: '%args['userName'])
        passwd2 = ClAuthenticate.GetPass('Re-enter password to confirm: ')
        if passwd == passwd2:
            break
        else:
            print >> sys.stderr, 'Passwords did not match. Please try again.'
            sys.stderr.flush()

    passwdHash = ClAuthenticate.HashPasswd(passwd)

    if repo is not None:
        name = args['userName']
        try:
            user = repo.fetchUserOrGroupByName(name)
            if user is not None:
                if user.isResourceType(ResourceTypes.ResourceType.USER):
                    user.setPassword(passwdHash)
                    commit = True
                else:
                    #FIXME: use FtServerClientException?
                    sys.stderr.write("%s is a Group, not a User.\n" % name)
                    sys.stderr.flush()

            else:
                #FIXME: use FtServerClientException?
                sys.stderr.write("User %s does not exist.\n" % name)
                sys.stderr.flush()

        finally:
            try:
                if commit:
                    repo.txCommit()
                    sys.stderr.write("Password for user %r changed.\n" % name)
                    sys.stderr.flush()
                else:
                    repo.txRollback()
                    sys.stderr.write("Password for user %r was not changed.\n" % name)
                    sys.stderr.flush()
            except:
                pass

    return


def Register():
    from Ft.Lib.CommandLine import Options, Command, Arguments
    cmd = Command.Command('passwd',
                          'Set the password for a User in a repository',
                          'molson',
                          __doc__,
                          function = Run,
                          arguments = [Arguments.RequiredArgument('userName',
                                                                  'User for which to change the password',
                                                                  str),
                                       ],
                          fileName = __file__,
                          )
    return cmd
