[PATCH] Fix the password confirmation match check

David Shea dshea at redhat.com
Wed Sep 18 19:04:12 UTC 2013


The check for whether the password field and the password confirmation
field match is run when either field is changed, since changes to either
field will cause the state of the match to change. This was working
correctly when a change to either field broke the match, but was not
always working when a change fixed the match. The check object for the
field not changed remained in a failure state, making it impossible to
exit the spoke even though the password matched. This fixes that by
manually running the check on the field not changed.
---
 pyanaconda/ui/gui/__init__.py    | 11 +++++++++--
 pyanaconda/ui/gui/spokes/user.py | 33 ++++++++++++++++++++++++++-------
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
index 7f18c4b..f971794 100644
--- a/pyanaconda/ui/gui/__init__.py
+++ b/pyanaconda/ui/gui/__init__.py
@@ -98,9 +98,16 @@ class GUICheck(object):
             self._handler_id = None
             self._check_status = None
 
-    def update_check_status(self, editable=None, data=None):
+    def update_check_status(self, editable=None, check_data=None):
         """Run an input validation check."""
-        new_check_status = self._run_check(self._editable, self._check_data)
+
+        # Allow check parameters to be overriden in parameters
+        if editable is None:
+            editable = self._editable
+        if check_data is None:
+            check_data = self._check_data
+
+        new_check_status = self._run_check(editable, check_data)
         check_status_changed = (self._check_status != new_check_status)
         self._check_status = new_check_status
 
diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py
index 1ee9399..dd2d217 100644
--- a/pyanaconda/ui/gui/spokes/user.py
+++ b/pyanaconda/ui/gui/spokes/user.py
@@ -279,9 +279,13 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke):
         self.add_check(self.pw, self._checkPasswordEmpty, None)
         
         # The password confirmation needs to be checked whenever either of the password
-        # fields change
-        self.add_check(self.confirm, self._checkPasswordConfirm, None)
-        self.add_check(self.pw, self._checkPasswordConfirm, None)
+        # fields change. Separate checks are created on each field so that edits on
+        # either will trigger a check and so that the last edited field will get the focus
+        # when Done is clicked. Whichever check is run needs to run the other check in
+        # order to reset the status. The check_data field is used as a flag to prevent
+        # infinite recursion.
+        self._confirm_check = self.add_check(self.confirm, self._checkPasswordConfirm, None)
+        self._password_check = self.add_check(self.pw, self._checkPasswordConfirm, None)
 
         # Keep a reference to this check, since it has to be manually run for the
         # click Done twice check.
@@ -483,16 +487,31 @@ class UserSpoke(FirstbootSpokeMixIn, NormalSpoke):
         else:
             return None
 
-    def _checkPasswordConfirm(self, editable=None, data=None):
+    def _checkPasswordConfirm(self, editable=None, reset_status=None):
         """If the user has entered confirmation data, check whether it matches the password."""
+
+        # This check is triggered by changes to either the password field or the
+        # confirmation field. If this method is being run from a successful check
+        # to reset the status, just return success
+        if reset_status:
+            return None
         
         # Skip the check if no password is required
         if (not self.usepassword.get_active()) or self._user.password_kickstarted:
-            return None
+            result = None
         elif self.confirm.get_text() and (self.pw.get_text() != self.confirm.get_text()):
-            return _("The passwords do not match.")
+            result = _("The passwords do not match.")
         else:
-            return None
+            result = None
+
+        # If the check succeeded, reset the status of the other check object
+        if result is None:
+            if editable == self.confirm:
+                self._password_check.update_check_status(check_data=True)
+            else:
+                self._confirm_check.update_check_status(check_data=True)
+
+        return result
 
     def _checkPasswordStrength(self, editable=None, data=None):
         """Update the error message based on password strength.
-- 
1.8.3.1



More information about the anaconda-patches mailing list