From: David Shea dshea@redhat.com
There's no need to validate the password twice, and it would make more sense anyway for the strength reported by the strength bar to match the strength we're using to enforce policy.
Also, one of the checks was bypassing the input delay that I went through all the trouble of adding. Checking the password on every keystroke can case UI freezes and we should avoid doing it.
Initialize the strength bar to "0" in glade so that entering the spoke does not display a medium strength before the initial check runs. --- pyanaconda/ui/gui/spokes/password.glade | 6 +--- pyanaconda/ui/gui/spokes/password.py | 52 ++++++++++++++--------------- pyanaconda/ui/gui/spokes/user.glade | 1 - pyanaconda/ui/gui/spokes/user.py | 59 +++++++++++++++------------------ 4 files changed, 53 insertions(+), 65 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/password.glade b/pyanaconda/ui/gui/spokes/password.glade index c0b38f6..d632049 100644 --- a/pyanaconda/ui/gui/spokes/password.glade +++ b/pyanaconda/ui/gui/spokes/password.glade @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> +<!-- Generated with glade 3.19.0 --> <interface> <requires lib="gtk+" version="3.6"/> <requires lib="AnacondaWidgets" version="1.0"/> @@ -120,7 +120,6 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="valign">center</property> - <property name="value">2</property> <property name="max_value">4</property> <property name="mode">discrete</property> </object> @@ -169,9 +168,6 @@ <child> <placeholder/> </child> - <child> - <placeholder/> - </child> </object> <packing> <property name="expand">False</property> diff --git a/pyanaconda/ui/gui/spokes/password.py b/pyanaconda/ui/gui/spokes/password.py index 895a0d3..fab502e 100644 --- a/pyanaconda/ui/gui/spokes/password.py +++ b/pyanaconda/ui/gui/spokes/password.py @@ -195,22 +195,12 @@ def _checkPasswordConfirm(self, inputcheck):
return result
- def _updatePwQuality(self): + def _updatePwQuality(self, empty, strength): """Update the password quality information. - - This function is called by the ::changed signal handler on the - password field. """
- pwtext = self.pw.get_text() - - # Reset the counters used for the "press Done twice" logic - self._waiveStrengthClicks = 0 - self._waiveASCIIClicks = 0 - - self._pwq_valid, strength, self._pwq_error = validatePassword(pwtext, "root", minlen=self.policy.minlen) - - if not pwtext: + # If the password is empty, clear the strength bar + if empty: val = 0 elif strength < 50: val = 1 @@ -226,38 +216,48 @@ def _updatePwQuality(self): self.pw_label.set_text(text)
def on_password_changed(self, editable, data=None): + # Reset the counters used for the "press Done twice" logic + self._waiveStrengthClicks = 0 + self._waiveASCIIClicks = 0 + # Update the password/confirm match check on changes to the main password field self._confirm_check.update_check_status()
- self._updatePwQuality() - def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength.
- Convert the strength set by _updatePwQuality into an error message. + Update the password strength bar and set an error message. """
pw = self.pw.get_text() confirm = self.confirm.get_text()
# Skip the check if no password is required - if (not pw and not confirm) and self._kickstarted: + if self._kickstarted: + return InputCheck.CHECK_OK + + # If the password is empty, clear the strength bar and skip this check + if not pw and not confirm: + self._updatePwQuality(True, 0) return InputCheck.CHECK_OK
- # Check for validity errors - if (not self._pwq_valid) and (self._pwq_error): - return self._pwq_error + # determine the password strength + valid, pwstrength, error = validatePassword(pw, "root", minlen=self.policy.minlen) + + # set the strength bar + self._updatePwQuality(False, pwstrength)
- # use strength from policy, not bars - _valid, pwstrength, _error = validatePassword(pw, "root", minlen=self.policy.minlen) + # If the password failed the validity check, fail this check + if not valid and error: + return error
if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: - if self._pwq_error: - return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % self._pwq_error + if error: + return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % error else: return _(PASSWORD_WEAK_CONFIRM) else: @@ -267,8 +267,8 @@ def _checkPasswordStrength(self, inputcheck): else: done_msg = _(PASSWORD_DONE_TWICE)
- if self._pwq_error: - return _(PASSWORD_WEAK_WITH_ERROR) % self._pwq_error + " " + done_msg + if error: + return _(PASSWORD_WEAK_WITH_ERROR) % error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: diff --git a/pyanaconda/ui/gui/spokes/user.glade b/pyanaconda/ui/gui/spokes/user.glade index 8025849..80cfdc2 100644 --- a/pyanaconda/ui/gui/spokes/user.glade +++ b/pyanaconda/ui/gui/spokes/user.glade @@ -233,7 +233,6 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="valign">center</property> - <property name="value">2</property> <property name="max_value">4</property> <property name="mode">discrete</property> </object> diff --git a/pyanaconda/ui/gui/spokes/user.py b/pyanaconda/ui/gui/spokes/user.py index b8bc4e0..cc47c0a 100644 --- a/pyanaconda/ui/gui/spokes/user.py +++ b/pyanaconda/ui/gui/spokes/user.py @@ -247,11 +247,6 @@ def initialize(self):
self.guesser = True
- # Updated during the password changed event and used by the password - # field validity checker - self._pwq_error = None - self._pwq_valid = True - self.pw_bar = self.builder.get_object("password_bar") self.pw_label = self.builder.get_object("password_label")
@@ -381,20 +376,12 @@ def sensitive(self): def completed(self): return len(self.data.user.userList) > 0
- def _updatePwQuality(self): + def _updatePwQuality(self, empty, strength): """This method updates the password indicators according to the password entered by the user. """ - pwtext = self.pw.get_text() - username = self.username.get_text() - - # Reset the counters used for the "press Done twice" logic - self._waiveStrengthClicks = 0 - self._waiveASCIIClicks = 0 - - self._pwq_valid, strength, self._pwq_error = validatePassword(pwtext, username) - - if not pwtext: + # If the password is empty, clear the strength bar + if empty: val = 0 elif strength < 50: val = 1 @@ -404,6 +391,7 @@ def _updatePwQuality(self): val = 3 else: val = 4 + text = _(PASSWORD_STRENGTH_DESC[val])
self.pw_bar.set_value(val) @@ -422,7 +410,9 @@ def usepassword_toggled(self, togglebutton=None, data=None):
def password_changed(self, editable=None, data=None): """Update the password strength level bar""" - self._updatePwQuality() + # Reset the counters used for the "press Done twice" logic + self._waiveStrengthClicks = 0 + self._waiveASCIIClicks = 0
# Update the password/confirm match check on changes to the main password field self._confirm_check.update_check_status() @@ -508,36 +498,39 @@ def _checkPasswordConfirm(self, inputcheck): def _checkPasswordStrength(self, inputcheck): """Update the error message based on password strength.
- The password strength has already been checked in _updatePwQuality, called - previously in the signal chain. This method converts the data set from there - into an error message. - The password strength check can be waived by pressing "Done" twice. This is controlled through the self._waiveStrengthClicks counter. The counter is set in on_back_clicked, which also re-runs this check manually. """
# Skip the check if no password is required - if (not self.usepassword.get_active()) or \ - ((not self.pw.get_text()) and (self._user.password_kickstarted)): + if not self.usepassword.get_active or self._user.password_kickstarted: return InputCheck.CHECK_OK
- # If the password failed the validity check, fail this check - if (not self._pwq_valid) and (self._pwq_error): - return self._pwq_error - - # use strength from policy, not bars + # If the password is empty, clear the strength bar and skip this check pw = self.pw.get_text() + if not pw: + self._updatePwQuality(True, 0) + return InputCheck.CHECK_OK + + # determine the password strength username = self.username.get_text() - _valid, pwstrength, _error = validatePassword(pw, username, minlen=self.policy.minlen) + valid, pwstrength, error = validatePassword(pw, username, minlen=self.policy.minlen) + + # set the strength bar + self._updatePwQuality(False, pwstrength) + + # If the password failed the validity check, fail this check + if not valid and error: + return error
if pwstrength < self.policy.minquality: # If Done has been clicked twice, waive the check if self._waiveStrengthClicks > 1: return InputCheck.CHECK_OK elif self._waiveStrengthClicks == 1: - if self._pwq_error: - return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % self._pwq_error + if error: + return _(PASSWORD_WEAK_CONFIRM_WITH_ERROR) % error else: return _(PASSWORD_WEAK_CONFIRM) else: @@ -547,8 +540,8 @@ def _checkPasswordStrength(self, inputcheck): else: done_msg = _(PASSWORD_DONE_TWICE)
- if self._pwq_error: - return _(PASSWORD_WEAK_WITH_ERROR) % self._pwq_error + " " + done_msg + if error: + return _(PASSWORD_WEAK_WITH_ERROR) % error + " " + done_msg else: return _(PASSWORD_WEAK) % done_msg else: