"""
w2lapp.passwd.py: change password associated with entry

web2ldap - a web-based LDAP Client,
see http://www.web2ldap.de for details

(c) by Michael Stroeder <michael@stroeder.com>

This module is distributed under the terms of the
GPL (GNU GENERAL PUBLIC LICENSE) Version 2
(see http://www.gnu.org/copyleft/gpl.html)

$Id: passwd.py,v 1.16 2002/01/15 19:02:31 michael Exp $
"""

import ldap,ldaputil.base,ldaputil.passwd, \
       w2lapp.cnf,w2lapp.core,w2lapp.gui,w2lapp.login

available_hashtypes = ldaputil.passwd.AVAIL_USERPASSWORD_SCHEMES.items()

def w2l_Passwd(sid,outf,command,form,ls,dn):

  if 'passwd_who' in form.inputFieldNames:
    passwd_who = form.field['passwd_who'].value[0]
  else:
    if ls.who:
      passwd_who = ls.who
    else:      
      passwd_who = dn

  if passwd_who and \
     ('passwd_newpasswd' in form.inputFieldNames):

    if len(form.field['passwd_newpasswd'].value)!=2:
      raise w2lapp.core.ErrorExitClass(ls,dn,'Repeat password!')

    if form.field['passwd_newpasswd'].value[0]!=form.field['passwd_newpasswd'].value[1]:
      raise w2lapp.core.ErrorExitClass(ls,dn,'New passwords do not match!')

    passwd_input = form.field['passwd_newpasswd'].value[0]

    if not passwd_input:
      raise w2lapp.core.ErrorExitClass(ls,dn,'Empty passwords not allowed!')

    if 'passwd_scheme' in form.inputFieldNames:
      passwd_scheme = form.field['passwd_scheme'].value[0]
    else:
      raise w2lapp.core.ErrorExitClass(ls,dn,'Password encryption method required!')

    userPassword = ldaputil.passwd.UserPassword(
      l=ls.l,dn=passwd_who.encode(ls.charset),charset=ls.charset,multiple=0
    )
    # Work around the problem that LDAP applications use different
    # charset encodings for the userPassword attribute
    new_passwd_value = []
    for c in ['utf-8']:#,'iso-8859-1']:
      try:
        new_passwd_str = passwd_input.encode(c)
      except UnicodeError:
        pass
      else:
        new_passwd_value.append(
          userPassword.encodePassword(
            new_passwd_str,passwd_scheme
          )
        )

    modlist = [(ldap.MOD_REPLACE,'userPassword',new_passwd_value)]
    # Modify password
    ls.modifyEntry(passwd_who,modlist)

    # Check if relogin is necessary
    if ldaputil.base.normalize_dn(passwd_who.lower())==ldaputil.base.normalize_dn(ls.who.lower()):
      ls.bind('','')
      w2lapp.login.w2l_Login(
        sid,outf,'searchform',form,ls,dn,
        login_msg='Password changed of entry %s. A new login is required!' % (w2lapp.gui.DisplayDN(sid,form,ls,passwd_who)),
        who=passwd_who,relogin=0,nomenu=1
      )
    else:
      w2lapp.gui.SimpleMessage(
        sid,outf,form,ls,dn,
        message='Changed password of entry %s.' % (
          w2lapp.gui.DisplayDN(sid,form,ls,passwd_who)
        ),
        main_menu_list=w2lapp.gui.MainMenu(sid,form,ls,dn),
        context_menu_list=[]
      )

  else:
    config_hashtypes = w2lapp.cnf.GetParam(ls,'passwd_hashtypes',[])
    if config_hashtypes:
      # The set of hash types are restricted by local configuration
      default_hashtypes = [
        hash_type
        for hash_type in available_hashtypes
        if hash_type[0] in config_hashtypes
      ]
      form.field['passwd_scheme'].options = default_hashtypes

    # Leeres Passworteingabeformular ausgeben
    w2lapp.gui.TopSection(
      sid,outf,form,ls,dn,'Change password',
      w2lapp.gui.MainMenu(sid,form,ls,dn),
      context_menu_list=[]
    )
    outf.write("""<div id=InputDiv>
<h1>Change password</h1>
<form
  action="%s/passwd/%s"
  method="POST"
  enctype="application/x-www-form-urlencoded"
  accept-charset="%s"
>
  <input type="hidden" type="dn" name="dn" value="%s">
  <input type="hidden" name="passwd_who" value="%s">
  <table summary="Password input form">
  <tr>
    <td>Change password for</td>
    <td>%s on %s</td>
  </tr>
  <tr>
    <td>New password</td>
    <td><input type="password" name="passwd_newpasswd" maxlength="30" size="30" value=""></td>
  </tr>
  <tr>
    <td>repeat new password</td>
    <td><input type="password" name="passwd_newpasswd" maxlength="30" size="30" value=""></td>
  </tr>
  <tr>
    <td>Password encryption method</td>
    <td>%s</td>
  </tr>
</table>
<input type="submit" value="Change Password">
<input type="reset" value="Reset">
</form>
</div>
""" % (
    form.script_name,
    sid,
    form.accept_charset,
    w2lapp.core.utf2display(form.accept_charset,dn),
    w2lapp.core.utf2display(form.accept_charset,passwd_who),
    w2lapp.gui.DisplayDN(sid,form,ls,passwd_who),
    ls.host.encode('ascii'),
    form.field['passwd_scheme'].inputHTML()
  )
)
    w2lapp.gui.PrintFooter(outf,form)


