login-app: Use a pure-Go tty interface instead of curses
This commit is contained in:
parent
af53a37d33
commit
8ab758ac9a
5
Makefile
5
Makefile
@ -1,10 +1,11 @@
|
||||
tuto1: token-validator/token-validator server.iso
|
||||
|
||||
login-app: pkg/login-app/build.yml pkg/login-app/Dockerfile pkg/login-app/cmd/login.go pkg/login-app/cmd/main.go pkg/login-app/cmd/windows.go
|
||||
pkg/login-app: pkg/login-app/cmd/login.go pkg/login-app/cmd/dialog-checklogin.go pkg/login-app/cmd/cmd pkg/login-app/cmd/dialog-login.go pkg/login-app/cmd/login-app pkg/login-app/cmd/dialog-errmsg.go pkg/login-app/cmd/main.go pkg/login-app/cmd/dialog-reboot.go pkg/login-app/cmd/debug.log pkg/login-app/build.yml pkg/login-app/Dockerfile
|
||||
linuxkit pkg build -org nemunaire pkg/login-app/
|
||||
#linuxkit pkg push -org nemunaire --sign=false pkg/login-app/
|
||||
touch pkg/login-app
|
||||
|
||||
login-initrd.img: login.yml login-app
|
||||
login-initrd.img: login.yml pkg/login-app
|
||||
linuxkit build -docker $<
|
||||
|
||||
token-validator/token-validator: token-validator/*.go
|
||||
|
@ -3,14 +3,14 @@ FROM golang:alpine as gobuild
|
||||
ENV GOOS linux
|
||||
ENV GOARCH amd64
|
||||
|
||||
RUN apk add --no-cache git pkgconfig ncurses-dev ncurses-static gcc libc-dev
|
||||
RUN apk add --no-cache git gcc
|
||||
|
||||
WORKDIR /go/src/login-app
|
||||
|
||||
ADD cmd ./
|
||||
|
||||
RUN go get -d -v
|
||||
RUN go build -v -tags netgo -ldflags '-w -extldflags "-static -lpanelw -lncursesw"'
|
||||
RUN go build -v -tags netgo
|
||||
|
||||
|
||||
FROM alpine
|
||||
@ -19,7 +19,6 @@ MAINTAINER Pierre-Olivier Mercier <nemunaire@nemunai.re>
|
||||
EXPOSE 8081
|
||||
|
||||
COPY --from=gobuild /go/src/login-app/login-app /bin/login-app
|
||||
COPY --from=gobuild /etc/terminfo/l/linux /etc/terminfo/l/linux
|
||||
COPY --from=gobuild /usr/share/udhcpc/default.script /usr/share/udhcpc/default.script
|
||||
|
||||
ENTRYPOINT ["/bin/login-app"]
|
||||
|
79
pkg/login-app/cmd/dialog-checklogin.go
Normal file
79
pkg/login-app/cmd/dialog-checklogin.go
Normal file
@ -0,0 +1,79 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
ui "github.com/VladimirMarkelov/clui"
|
||||
)
|
||||
|
||||
type CheckDialog struct {
|
||||
View *ui.Window
|
||||
|
||||
result int
|
||||
beforeClose func(ui.Event)
|
||||
onClose func()
|
||||
}
|
||||
|
||||
func CreateCheckDialog(title, username, password string) *CheckDialog {
|
||||
dlg := new(CheckDialog)
|
||||
|
||||
sWidth, sHeight := ui.ScreenSize()
|
||||
wWidth, wHeight := 40, 5
|
||||
dlg.View = ui.AddWindow(sWidth/2-wWidth/2, sHeight/2-wHeight/2, wWidth, wHeight, title)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
defer ui.WindowManager().EndUpdate()
|
||||
|
||||
dlg.View.SetModal(true)
|
||||
dlg.View.SetSizable(false)
|
||||
dlg.View.SetTitleButtons(ui.ButtonDefault)
|
||||
dlg.View.SetPack(ui.Vertical)
|
||||
|
||||
textfrm := ui.CreateFrame(dlg.View, 1, 1, ui.BorderNone, ui.Fixed)
|
||||
textfrm.SetPaddings(1, 1)
|
||||
textfrm.SetPack(ui.Vertical)
|
||||
textfrm.SetGaps(2, 1)
|
||||
ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, " Please wait", ui.Fixed)
|
||||
|
||||
progress := ui.CreateProgressBar(textfrm, ui.AutoSize, ui.AutoSize, 1)
|
||||
progress.SetLimits(0, 100)
|
||||
|
||||
ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, "Connecting to login server...", ui.Fixed)
|
||||
|
||||
dlg.View.OnKeyDown(func(ev ui.Event, data interface{}) bool {
|
||||
if ev.Key == 0 && ev.Msg == "login-complete" {
|
||||
if dlg.beforeClose != nil {
|
||||
dlg.beforeClose(ev)
|
||||
}
|
||||
|
||||
ui.WindowManager().DestroyWindow(dlg.View)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
|
||||
closeFunc := dlg.onClose
|
||||
ui.WindowManager().EndUpdate()
|
||||
if closeFunc != nil {
|
||||
closeFunc()
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, nil)
|
||||
|
||||
go func() {
|
||||
if ok, err := checkLogin(username, password); ok {
|
||||
ui.PutEvent(ui.Event{Type: ui.EventKey, Msg: "login-complete"})
|
||||
} else {
|
||||
ui.PutEvent(ui.Event{Type: ui.EventKey, Msg: "login-complete", Err: err})
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for i := 0; i < 422; i += 1 {
|
||||
progress.SetValue(int(math.Floor(math.Log(float64(i)*8)*16 - 30)))
|
||||
time.Sleep(64 * time.Millisecond)
|
||||
ui.PutEvent(ui.Event{Type: ui.EventRedraw})
|
||||
}
|
||||
}()
|
||||
|
||||
return dlg
|
||||
}
|
85
pkg/login-app/cmd/dialog-errmsg.go
Normal file
85
pkg/login-app/cmd/dialog-errmsg.go
Normal file
@ -0,0 +1,85 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
ui "github.com/VladimirMarkelov/clui"
|
||||
term "github.com/nsf/termbox-go"
|
||||
)
|
||||
|
||||
type ErrMsgDialog struct {
|
||||
View *ui.Window
|
||||
|
||||
result int
|
||||
beforeClose func()
|
||||
onClose func()
|
||||
}
|
||||
|
||||
func CreateErrMsgDialog(title string, err error) *ErrMsgDialog {
|
||||
dlg := new(ErrMsgDialog)
|
||||
|
||||
sWidth, sHeight := ui.ScreenSize()
|
||||
wWidth, wHeight := 60, 10
|
||||
dlg.View = ui.AddWindow(sWidth/2-wWidth/2, sHeight/2-wHeight/2, wWidth, wHeight, title)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
defer ui.WindowManager().EndUpdate()
|
||||
|
||||
dlg.View.SetModal(true)
|
||||
dlg.View.SetSizable(false)
|
||||
dlg.View.SetTitleButtons(ui.ButtonDefault)
|
||||
dlg.View.SetPack(ui.Vertical)
|
||||
|
||||
textfrm := ui.CreateFrame(dlg.View, 1, 1, ui.BorderNone, ui.Fixed)
|
||||
textfrm.SetPaddings(1, 1)
|
||||
textfrm.SetPack(ui.Vertical)
|
||||
textfrm.SetGaps(2, 1)
|
||||
|
||||
lbl := ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, "An error occurs:", ui.Fixed)
|
||||
lbl.SetTextColor(ui.ColorRedBold)
|
||||
|
||||
tv := ui.CreateTextView(textfrm, ui.AutoSize, 4, ui.Fixed)
|
||||
tv.SetWordWrap(true)
|
||||
tv.SetText([]string{err.Error()})
|
||||
tv.SetTextColor(ui.ColorWhite)
|
||||
tv.SetBackColor(ui.ColorBlack)
|
||||
|
||||
ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, "Please try again.", ui.Fixed)
|
||||
|
||||
btnOk := ui.CreateButton(textfrm, 20, 4, "Ok", 1)
|
||||
|
||||
btnOk.OnClick(func(ev ui.Event) {
|
||||
if dlg.beforeClose != nil {
|
||||
dlg.beforeClose()
|
||||
}
|
||||
|
||||
ui.WindowManager().DestroyWindow(dlg.View)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
|
||||
closeFunc := dlg.onClose
|
||||
ui.WindowManager().EndUpdate()
|
||||
if closeFunc != nil {
|
||||
closeFunc()
|
||||
}
|
||||
})
|
||||
|
||||
dlg.View.OnKeyDown(func(ev ui.Event, data interface{}) bool {
|
||||
if ev.Key == term.KeyEnter {
|
||||
if dlg.beforeClose != nil {
|
||||
dlg.beforeClose()
|
||||
}
|
||||
|
||||
ui.WindowManager().DestroyWindow(dlg.View)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
|
||||
closeFunc := dlg.onClose
|
||||
ui.WindowManager().EndUpdate()
|
||||
if closeFunc != nil {
|
||||
closeFunc()
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, nil)
|
||||
|
||||
ui.ActivateControl(dlg.View, btnOk)
|
||||
|
||||
return dlg
|
||||
}
|
124
pkg/login-app/cmd/dialog-login.go
Normal file
124
pkg/login-app/cmd/dialog-login.go
Normal file
@ -0,0 +1,124 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
ui "github.com/VladimirMarkelov/clui"
|
||||
term "github.com/nsf/termbox-go"
|
||||
)
|
||||
|
||||
const (
|
||||
LoginOk = iota
|
||||
LoginCanceled
|
||||
LoginInvalid
|
||||
)
|
||||
|
||||
type LoginDialog struct {
|
||||
View *ui.Window
|
||||
Username string
|
||||
Password string
|
||||
Action int
|
||||
|
||||
result int
|
||||
beforeClose func()
|
||||
onClose func()
|
||||
onCheck func(string, string) bool
|
||||
}
|
||||
|
||||
func CreateLoginDialog(title string) *LoginDialog {
|
||||
dlg := new(LoginDialog)
|
||||
|
||||
sWidth, sHeight := ui.ScreenSize()
|
||||
wWidth, wHeight := 40, 15
|
||||
dlg.View = ui.AddWindow(sWidth/2-wWidth/2, sHeight/2-wHeight/2, wWidth, wHeight, title)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
defer ui.WindowManager().EndUpdate()
|
||||
|
||||
dlg.View.SetModal(true)
|
||||
dlg.View.SetSizable(false)
|
||||
dlg.View.SetTitleButtons(ui.ButtonDefault)
|
||||
dlg.View.SetPack(ui.Vertical)
|
||||
|
||||
userfrm := ui.CreateFrame(dlg.View, 1, 1, ui.BorderNone, ui.Fixed)
|
||||
userfrm.SetPaddings(1, 1)
|
||||
userfrm.SetPack(ui.Horizontal)
|
||||
userfrm.SetGaps(1, 0)
|
||||
ui.CreateLabel(userfrm, ui.AutoSize, ui.AutoSize, " Login", ui.Fixed)
|
||||
edUser := ui.CreateEditField(userfrm, 20, "", 1)
|
||||
|
||||
passfrm := ui.CreateFrame(dlg.View, 1, 1, ui.BorderNone, 1)
|
||||
passfrm.SetPaddings(1, 1)
|
||||
passfrm.SetPack(ui.Horizontal)
|
||||
passfrm.SetGaps(1, 0)
|
||||
ui.CreateLabel(passfrm, ui.AutoSize, ui.AutoSize, "Password", ui.Fixed)
|
||||
edPass := ui.CreateEditField(passfrm, 20, "", 1)
|
||||
edPass.SetPasswordMode(true)
|
||||
|
||||
filler := ui.CreateFrame(dlg.View, 1, 1, ui.BorderNone, 1)
|
||||
filler.SetPack(ui.Horizontal)
|
||||
lbRes := ui.CreateLabel(filler, ui.AutoSize, ui.AutoSize, "", 1)
|
||||
|
||||
blist := ui.CreateFrame(dlg.View, 1, 1, ui.BorderNone, ui.Fixed)
|
||||
blist.SetPack(ui.Horizontal)
|
||||
blist.SetPaddings(1, 1)
|
||||
btnOk := ui.CreateButton(blist, 20, 4, "Authenticate me", 1)
|
||||
|
||||
btnOk.OnClick(func(ev ui.Event) {
|
||||
if dlg.onCheck != nil && !dlg.onCheck(edUser.Title(), edPass.Title()) {
|
||||
lbRes.SetTitle("Invalid username or password")
|
||||
dlg.Action = LoginInvalid
|
||||
return
|
||||
}
|
||||
|
||||
dlg.Action = LoginOk
|
||||
if dlg.onCheck == nil {
|
||||
dlg.Username = edUser.Title()
|
||||
dlg.Password = edPass.Title()
|
||||
}
|
||||
|
||||
if dlg.beforeClose != nil {
|
||||
dlg.beforeClose()
|
||||
}
|
||||
ui.WindowManager().DestroyWindow(dlg.View)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
|
||||
closeFunc := dlg.onClose
|
||||
ui.WindowManager().EndUpdate()
|
||||
if closeFunc != nil {
|
||||
closeFunc()
|
||||
}
|
||||
})
|
||||
|
||||
dlg.View.OnKeyDown(func(ev ui.Event, data interface{}) bool {
|
||||
if ev.Key == term.KeyEnter {
|
||||
if edUser.Title() == "" {
|
||||
ui.ActivateControl(dlg.View, edUser)
|
||||
} else if edPass.Title() == "" {
|
||||
ui.ActivateControl(dlg.View, edPass)
|
||||
} else {
|
||||
if dlg.beforeClose != nil {
|
||||
dlg.beforeClose()
|
||||
}
|
||||
ui.WindowManager().DestroyWindow(dlg.View)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
|
||||
closeFunc := dlg.onClose
|
||||
ui.WindowManager().EndUpdate()
|
||||
if closeFunc != nil {
|
||||
closeFunc()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, nil)
|
||||
|
||||
edUser.OnChange(func(ev ui.Event) {
|
||||
lbRes.SetTitle("")
|
||||
})
|
||||
edPass.OnChange(func(ev ui.Event) {
|
||||
lbRes.SetTitle("")
|
||||
})
|
||||
|
||||
ui.ActivateControl(dlg.View, edUser)
|
||||
|
||||
return dlg
|
||||
}
|
50
pkg/login-app/cmd/dialog-reboot.go
Normal file
50
pkg/login-app/cmd/dialog-reboot.go
Normal file
@ -0,0 +1,50 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
ui "github.com/VladimirMarkelov/clui"
|
||||
)
|
||||
|
||||
type RebootDialog struct {
|
||||
View *ui.Window
|
||||
}
|
||||
|
||||
func CreateRebootDialog(title, login string) *RebootDialog {
|
||||
dlg := new(RebootDialog)
|
||||
|
||||
sWidth, sHeight := ui.ScreenSize()
|
||||
wWidth, wHeight := 50, 10
|
||||
dlg.View = ui.AddWindow(sWidth/2-wWidth/2, sHeight/2-wHeight/2, wWidth, wHeight, title)
|
||||
ui.WindowManager().BeginUpdate()
|
||||
defer ui.WindowManager().EndUpdate()
|
||||
|
||||
dlg.View.SetModal(true)
|
||||
dlg.View.SetSizable(false)
|
||||
dlg.View.SetTitleButtons(ui.ButtonDefault)
|
||||
dlg.View.SetPack(ui.Vertical)
|
||||
|
||||
textfrm := ui.CreateFrame(dlg.View, 1, 1, ui.BorderNone, ui.Fixed)
|
||||
textfrm.SetPaddings(1, 1)
|
||||
textfrm.SetPack(ui.Vertical)
|
||||
textfrm.SetGaps(2, 1)
|
||||
ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, "You are now successfully logged in as:", ui.Fixed)
|
||||
ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, login, ui.Fixed)
|
||||
|
||||
ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, "Your computer will automatically", ui.Fixed)
|
||||
ui.CreateLabel(textfrm, ui.AutoSize, ui.AutoSize, "reboot in a few seconds...", ui.Fixed)
|
||||
|
||||
progress := ui.CreateProgressBar(textfrm, ui.AutoSize, ui.AutoSize, 1)
|
||||
progress.SetLimits(0, 100)
|
||||
|
||||
go func() {
|
||||
for i := 0; i < 100; i += 1 {
|
||||
progress.SetValue(i)
|
||||
ui.PutEvent(ui.Event{Type: ui.EventRedraw})
|
||||
time.Sleep(64 * time.Millisecond)
|
||||
}
|
||||
ui.WindowManager().DestroyWindow(dlg.View)
|
||||
}()
|
||||
|
||||
return dlg
|
||||
}
|
@ -1,58 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
gc "github.com/rthornton128/goncurses"
|
||||
"os"
|
||||
|
||||
ui "github.com/VladimirMarkelov/clui"
|
||||
)
|
||||
|
||||
const URLLogin = "https://auth.adlin.nemunai.re/login"
|
||||
|
||||
func goLogin(stdscr *gc.Window, in chan gc.Key) (string, string, bool) {
|
||||
username, password := login(stdscr, in)
|
||||
var logged = false
|
||||
|
||||
validator := make(chan bool)
|
||||
validator_err := make(chan error)
|
||||
go func(username, password string, progress chan bool, err chan error) {
|
||||
st, errm := checkLogin(username, password)
|
||||
progress <- st
|
||||
err <- errm
|
||||
}(username, password, validator, validator_err)
|
||||
func askLogin() (lgd *LoginDialog) {
|
||||
lgd = CreateLoginDialog(" SRS AdLin - Login ")
|
||||
|
||||
if connection(stdscr, in, validator, validator_err) {
|
||||
e := <-validator_err
|
||||
return username, e.Error(), true
|
||||
} else {
|
||||
return goLogin(stdscr, in)
|
||||
lgd.beforeClose = func() {
|
||||
// Display next dialoag
|
||||
ckd := CreateCheckDialog(" SRS AdLin - Login ", lgd.Username, lgd.Password)
|
||||
|
||||
ckd.beforeClose = func(ev ui.Event) {
|
||||
if ev.Err == nil {
|
||||
logged = true
|
||||
CreateRebootDialog(" SRS AdLin - Login", lgd.Username)
|
||||
} else {
|
||||
errd := CreateErrMsgDialog(" SRS AdLin - Login ", ev.Err)
|
||||
errd.beforeClose = func() {
|
||||
askLogin()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func main() {
|
||||
stdscr, _ := gc.Init()
|
||||
defer gc.End()
|
||||
ui.InitLibrary()
|
||||
defer ui.DeinitLibrary()
|
||||
|
||||
// Set main properties
|
||||
gc.Cursor(0)
|
||||
gc.StartColor()
|
||||
gc.Raw(true)
|
||||
gc.Echo(false)
|
||||
stdscr.Keypad(true)
|
||||
askLogin()
|
||||
|
||||
// Define colors
|
||||
gc.InitPair(1, gc.C_WHITE, gc.C_BLUE)
|
||||
gc.InitPair(2, gc.C_GREEN, gc.C_BLACK)
|
||||
gc.InitPair(3, gc.C_CYAN, gc.C_BLACK)
|
||||
gc.InitPair(4, gc.C_RED, gc.C_BLACK)
|
||||
gc.InitPair(5, gc.C_BLACK, gc.C_WHITE)
|
||||
ui.MainLoop()
|
||||
|
||||
// Register pressed key through channel
|
||||
in := make(chan gc.Key)
|
||||
go func(w *gc.Window, ch chan<- gc.Key) {
|
||||
for {
|
||||
ch <- w.GetChar()
|
||||
}
|
||||
}(stdscr, in)
|
||||
|
||||
// Run!
|
||||
if username, ip, ok := goLogin(stdscr, in); ok {
|
||||
okreboot(stdscr, username, ip)
|
||||
if !logged {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -1,249 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
gc "github.com/rthornton128/goncurses"
|
||||
)
|
||||
|
||||
func login(stdscr *gc.Window, in chan gc.Key) (username, password string) {
|
||||
gc.Cursor(1)
|
||||
stdscr.Clear()
|
||||
|
||||
// Initialize the fields and Set field options
|
||||
fields := make([]*gc.Field, 3)
|
||||
fields[0], _ = gc.NewField(1, 28, 2, 12, 0, 0)
|
||||
defer fields[0].Free()
|
||||
fields[0].SetBackground(gc.ColorPair(5) | gc.A_UNDERLINE)
|
||||
fields[0].SetOptionsOff(gc.FO_AUTOSKIP)
|
||||
|
||||
fields[1], _ = gc.NewField(1, 28, 4, 12, 0, 0)
|
||||
defer fields[1].Free()
|
||||
fields[1].SetBackground(gc.ColorPair(5) | gc.A_UNDERLINE)
|
||||
fields[1].SetOptionsOff(gc.FO_PUBLIC)
|
||||
fields[1].SetOptionsOff(gc.FO_AUTOSKIP)
|
||||
|
||||
fields[2], _ = gc.NewField(1, 11, 7, 18, 0, 0)
|
||||
defer fields[2].Free()
|
||||
fields[2].SetBuffer("< Connect >")
|
||||
fields[2].SetBackground(gc.ColorPair(1))
|
||||
fields[2].SetOptionsOff(gc.FO_EDIT)
|
||||
fields[2].SetOptionsOff(gc.FO_AUTOSKIP)
|
||||
|
||||
// Create the form and post it
|
||||
form, _ := gc.NewForm(fields)
|
||||
defer form.Free()
|
||||
|
||||
// Create the window to be associated with the form
|
||||
rows, cols := stdscr.MaxYX()
|
||||
height, width := 14, 44
|
||||
y, x := (rows-height)/2, (cols-width)/2
|
||||
|
||||
mainwin, _ := gc.NewWindow(height, width, y, x)
|
||||
defer mainwin.Delete()
|
||||
defer mainwin.Erase()
|
||||
mainwin.Keypad(true)
|
||||
|
||||
// Set main window and sub window
|
||||
form.SetWindow(mainwin)
|
||||
form.SetSub(mainwin.Derived(8, 42, 3, 1))
|
||||
|
||||
// Print a border around the main window and print a title
|
||||
mainwin.Box(0, 0)
|
||||
|
||||
y, x = mainwin.MaxYX()
|
||||
title := "SRS ADLIN - Login"
|
||||
mainwin.ColorOn(2)
|
||||
mainwin.MovePrint(1, (x/2)-(len(title)/2), title)
|
||||
mainwin.ColorOff(1)
|
||||
mainwin.MoveAddChar(2, 0, gc.ACS_LTEE)
|
||||
mainwin.HLine(2, 1, gc.ACS_HLINE, x-2)
|
||||
mainwin.MoveAddChar(2, x-1, gc.ACS_RTEE)
|
||||
stdscr.Refresh()
|
||||
|
||||
form.Post()
|
||||
defer form.UnPost()
|
||||
|
||||
mainwin.MovePrint(5, 3, "Login:")
|
||||
mainwin.MovePrint(7, 3, "Password:")
|
||||
|
||||
form.Driver(gc.REQ_FIRST_FIELD)
|
||||
|
||||
stdscr.Refresh()
|
||||
mainwin.Refresh()
|
||||
|
||||
login:
|
||||
for {
|
||||
select {
|
||||
case ch := <-in:
|
||||
switch ch {
|
||||
case gc.KEY_DOWN, gc.KEY_TAB:
|
||||
form.Driver(gc.REQ_NEXT_FIELD)
|
||||
form.Driver(gc.REQ_END_LINE)
|
||||
case gc.KEY_UP:
|
||||
form.Driver(gc.REQ_PREV_FIELD)
|
||||
form.Driver(gc.REQ_END_LINE)
|
||||
case gc.KEY_BACKSPACE:
|
||||
form.Driver(gc.REQ_CLR_FIELD)
|
||||
case gc.KEY_RETURN:
|
||||
form.Driver(gc.REQ_NEXT_FIELD)
|
||||
form.Driver(gc.REQ_END_LINE)
|
||||
if len(strings.TrimSpace(fields[0].Buffer())) > 0 && len(strings.TrimSpace(fields[1].Buffer())) > 0 {
|
||||
break login
|
||||
}
|
||||
default:
|
||||
form.Driver(ch)
|
||||
}
|
||||
}
|
||||
mainwin.Refresh()
|
||||
}
|
||||
|
||||
username = strings.TrimSpace(fields[0].Buffer())
|
||||
password = strings.TrimSpace(fields[1].Buffer())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func connection(stdscr *gc.Window, in chan gc.Key, validator chan bool, validator_err chan error) (canContinue bool) {
|
||||
gc.Cursor(0)
|
||||
stdscr.Clear()
|
||||
|
||||
// Create the window to be associated with the form
|
||||
rows, cols := stdscr.MaxYX()
|
||||
height, width := 10, 60
|
||||
y, x := (rows-height)/2, (cols-width)/2
|
||||
|
||||
mainwin, _ := gc.NewWindow(height, width, y, x)
|
||||
defer mainwin.Delete()
|
||||
mainwin.Keypad(true)
|
||||
|
||||
// Print a border around the main window and print a title
|
||||
mainwin.Box(0, 0)
|
||||
|
||||
y, x = mainwin.MaxYX()
|
||||
title := "SRS ADLIN - Login"
|
||||
mainwin.ColorOn(2)
|
||||
mainwin.MovePrint(1, (x/2)-(len(title)/2), title)
|
||||
mainwin.ColorOff(2)
|
||||
mainwin.MoveAddChar(2, 0, gc.ACS_LTEE)
|
||||
mainwin.HLine(2, 1, gc.ACS_HLINE, x-2)
|
||||
mainwin.MoveAddChar(2, x-1, gc.ACS_RTEE)
|
||||
stdscr.Refresh()
|
||||
|
||||
mainwin.MovePrint(4, 4, " Please wait...")
|
||||
mainwin.ColorOn(3)
|
||||
mainwin.MovePrint(6, 2, "Connecting to login server...")
|
||||
mainwin.ColorOff(3)
|
||||
|
||||
stdscr.Refresh()
|
||||
mainwin.Refresh()
|
||||
|
||||
ticker := time.NewTicker(time.Millisecond * 150)
|
||||
|
||||
rotPos := 0
|
||||
loginloop:
|
||||
for {
|
||||
select {
|
||||
case ch := <-in:
|
||||
if gc.Char(ch) == gc.Char('r') {
|
||||
break loginloop
|
||||
}
|
||||
case st := <-validator:
|
||||
if st {
|
||||
canContinue = true
|
||||
break loginloop
|
||||
} else {
|
||||
e := <-validator_err
|
||||
|
||||
mainwin.ColorOn(4)
|
||||
mainwin.MovePrint(4, 2, e.Error())
|
||||
mainwin.ColorOff(4)
|
||||
ticker.Stop()
|
||||
|
||||
mainwin.MovePrint(7, 2, " Press any key to retry ")
|
||||
mainwin.Refresh()
|
||||
<-in
|
||||
|
||||
break loginloop
|
||||
}
|
||||
case <-ticker.C:
|
||||
switch rotPos += 1; rotPos {
|
||||
case 0, 4:
|
||||
mainwin.MovePrint(4, 4, "|")
|
||||
case 1, 5:
|
||||
mainwin.MovePrint(4, 4, "/")
|
||||
case 2, 6:
|
||||
mainwin.MovePrint(4, 4, "-")
|
||||
case 3, 7:
|
||||
mainwin.MovePrint(4, 4, "\\")
|
||||
default:
|
||||
mainwin.MovePrint(4, 4, "|")
|
||||
rotPos = 0
|
||||
}
|
||||
}
|
||||
mainwin.Refresh()
|
||||
}
|
||||
ticker.Stop()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func okreboot(stdscr *gc.Window, login string, ip string) {
|
||||
gc.Cursor(0)
|
||||
stdscr.Clear()
|
||||
|
||||
// Create the window to be associated with the form
|
||||
rows, cols := stdscr.MaxYX()
|
||||
height, width := 14, 42
|
||||
y, x := (rows-height)/2, (cols-width)/2
|
||||
|
||||
mainwin, _ := gc.NewWindow(height, width, y, x)
|
||||
defer mainwin.Delete()
|
||||
mainwin.Keypad(true)
|
||||
|
||||
// Print a border around the main window and print a title
|
||||
mainwin.Box(0, 0)
|
||||
|
||||
y, x = mainwin.MaxYX()
|
||||
title := "SRS ADLIN"
|
||||
mainwin.ColorOn(2)
|
||||
mainwin.MovePrint(1, (x/2)-(len(title)/2), title)
|
||||
mainwin.ColorOff(2)
|
||||
mainwin.MoveAddChar(2, 0, gc.ACS_LTEE)
|
||||
mainwin.HLine(2, 1, gc.ACS_HLINE, x-2)
|
||||
mainwin.MoveAddChar(2, x-1, gc.ACS_RTEE)
|
||||
stdscr.Refresh()
|
||||
|
||||
mainwin.ColorOn(2)
|
||||
mainwin.MovePrint(4, 2, "You are now successfully logged in as: ")
|
||||
mainwin.ColorOff(2)
|
||||
mainwin.ColorOn(3)
|
||||
mainwin.MovePrint(5, (x/2)-(len(login)/2), login)
|
||||
mainwin.ColorOff(3)
|
||||
|
||||
mainwin.MovePrint(8, 2, "Your computer will automatically")
|
||||
mainwin.MovePrint(9, 2, "reboot in a few seconds...")
|
||||
|
||||
mainwin.MovePrint(11, 2, "|------------------------------------|")
|
||||
|
||||
stdscr.Refresh()
|
||||
mainwin.Refresh()
|
||||
|
||||
ticker := time.NewTicker(time.Millisecond * 98)
|
||||
|
||||
pos := 0
|
||||
rebootloop:
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
mainwin.MovePrint(11, 3+pos, "*")
|
||||
pos += 1
|
||||
if pos > 36 {
|
||||
break rebootloop
|
||||
}
|
||||
}
|
||||
mainwin.Refresh()
|
||||
}
|
||||
ticker.Stop()
|
||||
}
|
Reference in New Issue
Block a user