vasm / src / vasm / ui / tui / modules /

#!/usr/bin/env python

#    This file is part of VASM.
#    VASM is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License v3 as published by
#    the Free Software Foundation.
#    VASM is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with VASM.  If not, see <>.

text mode module to provide a way for the user to change their password
__author__ = "Moises Henriquez"
__author_email__ = "moc.liamg@xnl.E0M"[::-1]

import urwid
import os
from import dialogs, widgets
from vasm.backend.utils import _
from vasm.backend import passwords
import logging

logger = logging.getLogger('vasm')

VASM_CATEGORY = "Personal"
VASM_LABEL = "Change My Password"

class PassDialog(widgets.TuiModule):
    """ Text module to modify a user's password """
    def __init__(self, parent):
        self.parent = parent
        self._title_text = _("Change user password")
        body = []
        self.currpass = urwid.Edit(caption=_("Current Password: "), mask="*")
        self.newpass1 = urwid.Edit(caption=_("Enter New Password: "), mask="*")
        self.newpass2 = urwid.Edit(caption=_("Verify Password: "), mask="*")
        for entry in (
            self.currpass, self.newpass1, self.newpass2):
            wrap = urwid.AttrWrap(entry, 'button', 'entry done')

        buttons = [("OK", self.on_ok), ("Cancel", self.close_module)]
        self._module_description = _(
            "Update your password in the fields provided below.  "\
            "Passwords should be at least 6 characters long and be made up of "\
            "a mixture of letters and numbers."
            desc = [self._module_description],
            header = self._title_text,
            body = body,
            buttons = buttons,
            parent = self.parent)
        self.body = urwid.LineBox(self.get_body())
        # Because module's body is interactive, we want to default the focus to the body
        # section.
    def on_ok(self, widget):
        """ Perform some tests first and then trigger the change """
        oldpass = self.currpass.get_edit_text()
        pass1 = self.newpass1.get_edit_text()
        pass2 = self.newpass2.get_edit_text()
        # first check that both passwords are the same
        if not passwords.test_passwords_match(pass1, pass2):
            return self.report_password_error(
                _("Passwords do not match.  Please enter the same password twice."))
        # Now check the password length
        if not passwords.test_password_length(pass1):
            return self.report_password_error(
                _("New password is too short.  Select a password at least 6 characters long.")
        # after all tests are passed, make the call
        return self.do_change_password(oldpass, pass2)
    def report_password_error(self, error):
        """ Report a password error """
        dia = dialogs.Error(
            parent = self.parent,
            message = error,
            buttons = [("OK", self.return_to_module)]
    def do_change_password(self, oldpass, newpass, user=None):
        """ Make the call after the tests have been performed to change the password """
        error = ""
        if user is None:
            user = os.getenv("USERNAME")
        # request the password change
            passwords.change_password(user, oldpass, newpass)
  'Changed password for %s'% user)
        except passwords.BadPasswordException:
            dia = dialogs.Error(
                parent = self.parent,
                message = _("The current password you entered is incorrect.  Your password remains unchanged."),
                buttons = [("OK", self.return_to_module)]
            logger.error("Unable to change password for %s.  Current password is incorrect."% user)
            return self.parent.pop_module_dialog(dia)
        except passwords.BadNewPasswordException:
            dia = dialogs.Error(
                parent = self.parent,
                message = ' '.join((
                    _("The new password you entered does not meet the minimum requirements."), " ",
                    _("Passwords should be at least 6 characters long.")
                buttons = [("OK", self.return_to_module)]
            logger.error("Unable to change password for %s.  New password is bad."% user)
            return self.parent.pop_module_dialog(dia)
        dia = dialogs.Info(
            parent = self.parent,
            message = _("Your password has been successfully changed."),
            buttons = [("OK", self.close_module)]
        logger.debug("Passowrd for %s has been changed"%user)
        return self.parent.pop_module_dialog(dia)        

def __vasm_test__():
    """ Set of tests to anounce this module to vasm """
    return True

def __run__(parent_toplevel):
    #mod = AboutVL(parent_toplevel)
    mod = PassDialog(parent_toplevel)