Files
clr-installer/tui/useradd.go
Mark D Horn 59302346d6 linter: enable whitespace
Signed-off-by: Mark D Horn <mark.d.horn@intel.com>
2020-04-24 14:53:17 -07:00

397 lines
10 KiB
Go

// Copyright © 2020 Intel Corporation
//
// SPDX-License-Identifier: GPL-3.0-only
package tui
import (
"strings"
"github.com/clearlinux/clr-installer/log"
"github.com/clearlinux/clr-installer/user"
"github.com/VladimirMarkelov/clui"
term "github.com/nsf/termbox-go"
)
// UseraddPage is the Page implementation for the user add configuration page
type UseraddPage struct {
BasePage
user *user.User
definedUsers []string
addMode bool
titleLabel *clui.Label
loginEdit *clui.EditField
usernameEdit *clui.EditField
passwordEdit *clui.EditField
pwConfirmEdit *clui.EditField
adminCheck *clui.CheckBox
deleteBtn *SimpleButton
changedPwd bool
changedLogin bool
loginWarning *clui.Label
usernameWarning *clui.Label
passwordWarning *clui.Label
confirmBtn *SimpleButton
}
// GetConfiguredValue Returns the string representation of currently value set
func (page *UseraddPage) GetConfiguredValue() string {
users := page.getModel().Users
res := []string{}
if len(users) == 0 {
return "No users added"
}
for _, curr := range users {
tks := []string{curr.Login}
if curr.Admin {
tks = append(tks, "admin")
}
res = append(res, strings.Join(tks, ":"))
}
return strings.Join(res, ", ")
}
// Activate updates the UI elements
func (page *UseraddPage) Activate() {
title := "Modify User"
page.clearForm()
prevPage := page.tui.getPage(TuiPageUserManager)
sel, ok := prevPage.GetData().(*SelectedUser)
if ok {
page.user = sel.user
page.definedUsers = sel.definedUsers
page.addMode = sel.addMode
if sel.addMode {
title = "Add New User"
} else {
page.resetForm()
}
}
page.titleLabel.SetTitle(title)
page.setConfirmButton()
}
// SetDone copies the edited user data into the cache and sets the page as done
func (page *UseraddPage) SetDone(done bool) bool {
// SetDone can only be called if the Confirm Button is enable;
// hence we know the data is valid
page.user.UserName = page.usernameEdit.Title()
page.user.Login = page.loginEdit.Title()
if page.addMode || page.changedPwd {
if err := page.user.SetPassword(page.passwordEdit.Title()); err != nil {
log.Warning("Failed to encrypt password: %v", err)
page.clearForm()
page.GotoPage(TuiPageUserManager)
}
}
if page.adminCheck.State() != 0 {
page.user.Admin = true
} else {
page.user.Admin = false
}
page.GotoPage(TuiPageUserManager)
return false
}
func (page *UseraddPage) setConfirmButton() {
if page.usernameWarning.Title() == "" &&
page.loginWarning.Title() == "" &&
page.passwordWarning.Title() == "" &&
page.loginEdit.Title() != "" &&
page.passwordEdit.Title() != "" {
page.confirmBtn.SetEnabled(true)
} else {
page.confirmBtn.SetEnabled(false)
}
}
func (page *UseraddPage) validateUsername() {
username := page.usernameEdit.Title()
if ok, msg := user.IsValidUsername(username); !ok {
page.usernameWarning.SetTitle(msg)
} else {
page.usernameWarning.SetTitle("")
}
page.setConfirmButton()
}
func (page *UseraddPage) validateLogin() {
page.loginWarning.SetTitle("")
login := page.loginEdit.Title()
if ok, msg := user.IsValidLogin(login); !ok {
page.loginWarning.SetTitle(msg)
}
if notok, err := user.IsSysDefaultUser(login); notok || err != nil {
if err != nil {
page.Panic(err)
}
page.loginWarning.SetTitle("Specified login is a system default user")
}
for _, curr := range page.definedUsers {
if curr == page.loginEdit.Title() {
page.loginWarning.SetTitle("User must be unique")
break
}
}
page.setConfirmButton()
}
func (page *UseraddPage) validatePassword() {
if !page.changedPwd {
return
}
if ok, msg := user.IsValidPassword(page.passwordEdit.Title()); !ok {
page.passwordWarning.SetTitle(msg)
} else if page.passwordEdit.Title() != page.pwConfirmEdit.Title() {
page.passwordWarning.SetTitle("Passwords do not match")
} else {
page.passwordWarning.SetTitle("")
}
page.setConfirmButton()
}
func newUseraddPage(tui *Tui) (Page, error) {
page := &UseraddPage{}
page.setup(tui, TuiPageUseradd, NoButtons, TuiPageUserManager)
page.titleLabel = clui.CreateLabel(page.content, AutoSize, 2, "", clui.Fixed)
frm := clui.CreateFrame(page.content, AutoSize, AutoSize, BorderNone, Fixed)
frm.SetPack(clui.Horizontal)
lblFrm := clui.CreateFrame(frm, 10, AutoSize, BorderNone, Fixed)
lblFrm.SetPack(clui.Vertical)
lblFrm.SetPaddings(1, 0)
newFieldLabel(lblFrm, "User Name:")
newFieldLabel(lblFrm, "Login:")
newFieldLabel(lblFrm, "Password:")
newFieldLabel(lblFrm, "Confirm:")
fldFrm := clui.CreateFrame(frm, 50, AutoSize, BorderNone, Fixed)
fldFrm.SetPack(clui.Vertical)
page.usernameEdit, page.usernameWarning = newEditField(fldFrm, true, nil, 0)
page.usernameEdit.OnChange(func(ev clui.Event) {
if len(page.loginEdit.Title()) == 0 {
page.changedLogin = false
}
page.validateUsername()
if !page.changedLogin {
name := strings.Split(page.usernameEdit.Title(), ",")[0]
// Remove the invalid characters
name = strings.Replace(name, " ", "", -1)
name = strings.Replace(name, "'", "", -1)
name = strings.Replace(name, ".", "", -1)
name = strings.ToLower(name)
if len(name) > user.MaxLoginLength {
name = name[0:(user.MaxLoginLength - 1)]
}
page.loginEdit.SetTitle(name)
}
})
page.usernameWarning.SetVisible(true)
page.loginEdit, page.loginWarning = newEditField(fldFrm, true, nil, 0)
page.loginEdit.OnChange(func(ev clui.Event) {
if len(page.loginEdit.Title()) == 0 {
page.changedLogin = false
}
page.validateLogin()
})
// If the user types in the Login field, no longer auto-generate
// the login value based on the UserName
page.loginEdit.OnKeyPress(func(k term.Key, ch rune) bool {
page.changedLogin = true
return false
})
page.loginEdit.OnActive(func(active bool) {
if page.loginEdit.Active() {
page.validateLogin()
}
})
page.loginWarning.SetVisible(true)
page.passwordEdit, _ = newEditField(fldFrm, false, nil, 0)
page.passwordEdit.SetPasswordMode(true)
page.passwordEdit.OnChange(func(ev clui.Event) {
page.validatePassword()
})
page.passwordEdit.OnActive(func(active bool) {
if page.passwordEdit.Active() {
page.validatePassword()
}
})
page.passwordEdit.OnKeyPress(func(k term.Key, ch rune) bool {
if k == term.KeyCtrlU {
page.revealPassword()
return true
}
if k == term.KeyArrowUp || k == term.KeyArrowDown {
return false
}
if !page.changedPwd {
page.changedPwd = true
page.passwordEdit.SetTitle("")
page.pwConfirmEdit.SetTitle("")
}
return false
})
page.pwConfirmEdit, page.passwordWarning = newEditField(fldFrm, true, nil, 2)
page.pwConfirmEdit.SetPasswordMode(true)
page.passwordWarning.SetVisible(true)
page.passwordWarning.SetMultiline(true)
page.pwConfirmEdit.OnChange(func(ev clui.Event) {
page.validatePassword()
})
page.pwConfirmEdit.OnActive(func(active bool) {
if page.pwConfirmEdit.Active() {
page.validatePassword()
}
})
page.pwConfirmEdit.OnKeyPress(func(k term.Key, ch rune) bool {
if k == term.KeyCtrlU {
page.revealPassword()
return true
}
if k == term.KeyArrowUp || k == term.KeyArrowDown {
return false
}
if !page.changedPwd {
page.changedPwd = true
page.passwordEdit.SetTitle("")
page.pwConfirmEdit.SetTitle("")
}
return false
})
adminFrm := clui.CreateFrame(fldFrm, 5, 2, BorderNone, Fixed)
adminFrm.SetPack(clui.Vertical)
page.adminCheck = clui.CreateCheckBox(adminFrm, 1, "Administrator", Fixed)
cancelBtn := CreateSimpleButton(page.cFrame, AutoSize, AutoSize, "Cancel", Fixed)
cancelBtn.OnClick(func(ev clui.Event) {
page.clearForm()
page.GotoPage(TuiPageUserManager)
})
page.confirmBtn = CreateSimpleButton(page.cFrame, AutoSize, AutoSize, "Confirm", Fixed)
page.confirmBtn.OnClick(func(ev clui.Event) {
page.SetDone(true)
})
page.deleteBtn = CreateSimpleButton(page.cFrame, AutoSize, AutoSize, "Delete", Fixed)
page.deleteBtn.SetEnabled(false)
page.deleteBtn.OnClick(func(ev clui.Event) {
// Clear the form and user data; with Login being empty,
// this will result in the user not being re-added, aka deleted.
page.user.UserName = ""
page.user.Login = ""
page.user.Password = ""
page.user.Admin = false
page.clearForm()
page.GotoPage(TuiPageUserManager)
})
resetBtn := CreateSimpleButton(page.cFrame, AutoSize, AutoSize, "Reset", Fixed)
resetBtn.OnClick(func(ev clui.Event) {
if page.addMode {
page.clearForm()
} else {
page.resetForm()
}
page.setConfirmButton()
})
page.activated = page.usernameEdit
return page, nil
}
func (page *UseraddPage) revealPassword() {
if !page.addMode {
return
}
if page.passwordEdit.PasswordMode() {
page.passwordEdit.SetPasswordMode(false)
page.pwConfirmEdit.SetPasswordMode(false)
} else {
page.passwordEdit.SetPasswordMode(true)
page.pwConfirmEdit.SetPasswordMode(true)
}
}
func (page *UseraddPage) resetForm() {
page.usernameEdit.SetTitle(page.user.UserName)
page.loginEdit.SetTitle(page.user.Login)
page.changedLogin = true // Assume the user wants to keep this
page.changedPwd = false
if !page.addMode {
page.passwordEdit.SetTitle("************")
page.pwConfirmEdit.SetTitle("************")
page.passwordWarning.SetTitle("")
}
if page.user.Admin {
page.adminCheck.SetState(1)
}
page.deleteBtn.SetEnabled(true)
clui.ActivateControl(page.tui.currPage.GetWindow(), page.usernameEdit)
}
func (page *UseraddPage) clearForm() {
page.usernameEdit.SetTitle("")
// Need to ensure there is a change in the title so
// that the validation code executes
page.loginEdit.SetTitle(" ")
page.loginEdit.SetTitle("")
page.changedLogin = false
// Need to ensure there is a change in the title and
// change flag is set so that the validation code executes
page.changedPwd = true
page.passwordEdit.SetTitle(" ")
page.passwordEdit.SetTitle("")
page.changedPwd = false
page.pwConfirmEdit.SetTitle("")
page.passwordEdit.SetPasswordMode(true)
page.pwConfirmEdit.SetPasswordMode(true)
page.adminCheck.SetState(1)
page.deleteBtn.SetEnabled(false)
page.confirmBtn.SetEnabled(false)
clui.ActivateControl(page.tui.currPage.GetWindow(), page.usernameEdit)
}