Skip to content

Commit

Permalink
Merge pull request #126 from yast/reusable_root_widget
Browse files Browse the repository at this point in the history
Reusable root widget
  • Loading branch information
jreidinger committed Dec 1, 2016
2 parents 8f9bfdf + 019a7b5 commit 29fe7d5
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 158 deletions.
7 changes: 7 additions & 0 deletions package/yast2-users.changes
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Thu Dec 1 09:41:59 UTC 2016 - jreidinger@suse.com

- prepare reusable widget for setting root password
(needed for FATE#321754)
- 3.2.5

-------------------------------------------------------------------
Tue Oct 11 12:10:21 UTC 2016 - hguo@suse.com

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-users.spec
Expand Up @@ -17,7 +17,7 @@


Name: yast2-users
Version: 3.1.57.1
Version: 3.1.57.2
Release: 0

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.am
Expand Up @@ -64,7 +64,8 @@ ylib_DATA = \
lib/users/encryption_method.rb \
lib/users/proposal.rb \
lib/users/encryption_proposal.rb \
lib/users/users_database.rb
lib/users/users_database.rb \
lib/users/widgets.rb

scrconf_DATA = \
scrconf/uid.scr \
Expand Down
168 changes: 13 additions & 155 deletions src/lib/users/dialogs/inst_root_first.rb
Expand Up @@ -18,9 +18,12 @@
# To contact Novell about this file by physical or electronic mail, you may find
# current contact information at www.novell.com.
# ------------------------------------------------------------------------------

require "users/widgets"
require "users/ca_password_validator"
require "users/local_password"


module Yast
# This library provides a simple dialog for setting new password for the
# system adminitrator (root) including checking quality of the password
Expand All @@ -33,12 +36,9 @@ class InstRootFirstDialog

def run
Yast.import "UI"
Yast.import "GetInstArgs"
Yast.import "Mode"
Yast.import "Popup"
Yast.import "Report"
Yast.import "UsersSimple"
Yast.import "Wizard"
Yast.import "CWM"

textdomain "users"

Expand All @@ -48,8 +48,13 @@ def run
# helpful when testing all manually on a running system
Wizard.CreateDialog if separate_wizard_needed?

create_ui
ret = handle_ui
Wizard.SetTitleIcon("yast-users")

ret = CWM.show(
content,
# Title for root-password dialogue
caption: _("Password for the System Administrator \"root\""),
)

Wizard.CloseDialog if separate_wizard_needed?

Expand All @@ -59,163 +64,16 @@ def run
private

# Returns a UI widget-set for the dialog
def root_password_ui
current_password = UsersSimple.GetRootPassword || ""

def content
VBox(
VStretch(),
HSquash(
VBox(
# advise users to remember their new password
Left(Label(_("Do not forget what you enter here."))),
VSpacing(0.8),
Password(
Id(:pw1),
Opt(:hstretch),
# Label: get password for user root
_("&Password for root User"),
current_password
),
VSpacing(0.8),
Password(
Id(:pw2),
Opt(:hstretch),
# Label: get same password again for verification
_("Con&firm Password"),
current_password
),
VSpacing(2.4),
# text entry label
InputField(Opt(:hstretch), _("&Test Keyboard Layout"))
)
::Users::PasswordWidget.new
),
VStretch()
)
end

# Returns help for the dialog
def root_password_help
# help text ( explain what the user "root" is and does ) 1
helptext = _(
"<p>\n" \
"Unlike normal users of the system, who write texts, create\n" \
"graphics, or browse the Internet, the user \"root\" exists on\n" \
"every system and is called into action whenever\n" \
"administrative tasks need to be performed. Only log in as root\n" \
"when you need to be the system administrator.\n" \
"</p>\n"
).dup <<

# help text, continued 2
_(
"<p>\n" \
"Because the root user is equipped with extensive permissions, the password\n" \
"for \"root\" should be chosen carefully. A combination of letters and numbers\n" \
"is recommended. To ensure that the password was entered correctly,\n" \
"reenter it in a second field.\n" \
"</p>\n"
) <<

# help text, continued 3
_(
"<p>\n" \
"All the rules for user passwords apply to the \"root\" password:\n" \
"Distinguish between uppercase and lowercase. A password should have at\n" \
"least 5 characters and, as a rule, not contain any accented letters or umlauts.\n" \
"</p>\n"
)

helptext = helptext + UsersSimple.ValidPasswordHelptext

# help text, continued 4
helptext << _(
"<p>\n" \
"Do not forget this \"root\" password.\n" \
"</p>"
)

helptext << ::Users::CAPasswordValidator.new.help_text

helptext
end

# Sets the wizard dialog contents
def create_ui
Wizard.SetTitleIcon("yast-users")

Wizard.SetContents(
# Title for root-password dialogue
_("Password for the System Administrator \"root\""),
root_password_ui,
root_password_help,
GetInstArgs.enable_back || Mode.normal,
GetInstArgs.enable_next || Mode.normal
)
end

# Handles user's input and returns symbol what to do next
# @return [Symbol] :next, :back or :abort
def handle_ui
begin
UI.SetFocus(Id(:pw1))
ret = Wizard.UserInput

if ret == :abort || ret == :cancel
if Popup.ConfirmAbort(:incomplete)
ret = :abort
else
ret = :try_again
next
end
end

ret = :next if ret == :accept # from proposal

if ret == :next
password_1 = Convert.to_string(UI.QueryWidget(Id(:pw1), :Value))
password_2 = Convert.to_string(UI.QueryWidget(Id(:pw2), :Value))

if validate_password(password_1, password_2)
UsersSimple.SetRootPassword(password_1)
else
ret = :try_again
end
end
end until ret == :next || ret == :back || ret == :abort

ret
end

# Validates whether password1 and password2 match and are valid
def validate_password(password_1, password_2)
if password_1 != password_2
# report misspellings of the password
Popup.Message(_("The passwords do not match.\nTry again."))
return false
end

if password_1.empty?
Popup.Error(_("No password entered.\nTry again."))
return false
end

error = UsersSimple.CheckPassword(password_1, "local")

if error != ""
Report.Error(error)
return false
end

passwd = ::Users::LocalPassword.new(username: "root", plain: password_1)
# User can confirm using "invalid" password confirming all the errors
if !passwd.valid?
errors = passwd.errors + [_("Really use this password?")]
return false unless Popup.YesNo(errors.join("\n\n"))
end

return true
end

# Returns whether we need/ed to create new UI Wizard
def separate_wizard_needed?
Mode.normal
Expand Down
153 changes: 153 additions & 0 deletions src/lib/users/widgets.rb
@@ -0,0 +1,153 @@
# encoding: utf-8

# ------------------------------------------------------------------------------
# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
#
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of version 2 of the GNU General Public License as published by the
# Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, contact Novell, Inc.
#
# To contact Novell about this file by physical or electronic mail, you may find
# current contact information at www.novell.com.
# ------------------------------------------------------------------------------

require "yast"
require "cwm/widget"

require "users/ca_password_validator"
require "users/local_password"

Yast.import "Popup"
Yast.import "Report"
Yast.import "UsersSimple"

module Users
class PasswordWidget < CWM::CustomWidget
def initialize
textdomain "users"
end

def contents
VBox(
# advise users to remember their new password
Left(Label(_("Do not forget what you enter here."))),
VSpacing(0.8),
Password(
Id(:pw1),
Opt(:hstretch),
# Label: get password for user root
_("&Password for root User")
),
VSpacing(0.8),
Password(
Id(:pw2),
Opt(:hstretch),
# Label: get same password again for verification
_("Con&firm Password")
),
VSpacing(2.4),
# text entry label
InputField(Opt(:hstretch), _("&Test Keyboard Layout"))
)
end

def init
current_password = Yast::UsersSimple.GetRootPassword
return if !current_password || current_password.empty?

Yast::UI.ChangeWidget(Id(:pw1), :Value, current_password)
Yast::UI.ChangeWidget(Id(:pw2), :Value, current_password)
end

def validate
password1 = Yast::UI.QueryWidget(Id(:pw1), :Value)
password2 = Yast::UI.QueryWidget(Id(:pw2), :Value)
if password1 != password2
# report misspellings of the password
Yast::Popup.Message(_("The passwords do not match.\nTry again."))
Yast::UI.SetFocus(Id(:pw2))
return false
end

if password1.empty?
Yast::Popup.Error(_("No password entered.\nTry again."))
Yast::UI.SetFocus(Id(:pw1))
return false
end

error = Yast::UsersSimple.CheckPassword(password1, "local")

if error != ""
Yast::Report.Error(error)
Yast::UI.SetFocus(Id(:pw1))
return false
end

passwd = ::Users::LocalPassword.new(username: "root", plain: password1)
# User can confirm using "invalid" password confirming all the errors
if !passwd.valid?
errors = passwd.errors + [_("Really use this password?")]
Yast::UI.SetFocus(Id(:pw1))
return false unless Yast::Popup.YesNo(errors.join("\n\n"))
end

return true
end

def store
password1 = Yast::UI.QueryWidget(Id(:pw1), :Value)
Yast::UsersSimple.SetRootPassword(password1)
end

def help
# help text ( explain what the user "root" is and does ) 1
helptext = _(
"<p>\n" \
"Unlike normal users of the system, who write texts, create\n" \
"graphics, or browse the Internet, the user \"root\" exists on\n" \
"every system and is called into action whenever\n" \
"administrative tasks need to be performed. Only log in as root\n" \
"when you need to be the system administrator.\n" \
"</p>\n"
).dup <<

# help text, continued 2
_(
"<p>\n" \
"Because the root user is equipped with extensive permissions, the password\n" \
"for \"root\" should be chosen carefully. A combination of letters and numbers\n" \
"is recommended. To ensure that the password was entered correctly,\n" \
"reenter it in a second field.\n" \
"</p>\n"
) <<

# help text, continued 3
_(
"<p>\n" \
"All the rules for user passwords apply to the \"root\" password:\n" \
"Distinguish between uppercase and lowercase. A password should have at\n" \
"least 5 characters and, as a rule, not contain any accented letters or umlauts.\n" \
"</p>\n"
)

helptext << Yast::UsersSimple.ValidPasswordHelptext

# help text, continued 4
helptext << _(
"<p>\n" \
"Do not forget this \"root\" password.\n" \
"</p>"
)

helptext << ::Users::CAPasswordValidator.new.help_text
end
end
end

0 comments on commit 29fe7d5

Please sign in to comment.