login-app: move as linuxkit pkg
This commit is contained in:
parent
f2aae0ccd2
commit
2357798b8f
7 changed files with 27 additions and 1 deletions
25
pkg/login-app/Dockerfile
Normal file
25
pkg/login-app/Dockerfile
Normal file
|
@ -0,0 +1,25 @@
|
|||
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
|
||||
|
||||
WORKDIR /go/src/login-app
|
||||
|
||||
ADD cmd ./
|
||||
|
||||
RUN go get -d -v
|
||||
RUN go build -v -tags netgo -ldflags '-w -extldflags "-static -lpanelw -lncursesw"'
|
||||
|
||||
|
||||
FROM alpine
|
||||
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"]
|
2
pkg/login-app/build.yml
Normal file
2
pkg/login-app/build.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
image: adlin-login-app
|
||||
network: true
|
BIN
pkg/login-app/cmd/login-app
Executable file
BIN
pkg/login-app/cmd/login-app
Executable file
Binary file not shown.
28
pkg/login-app/cmd/login.go
Normal file
28
pkg/login-app/cmd/login.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func checkLogin(username, password string) (bool, error) {
|
||||
j, err := json.Marshal(map[string]string{
|
||||
"username": username,
|
||||
"password": password,
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
resp, err := http.Post(URLLogin, "application/json", bytes.NewReader(j))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
cnt, _ := ioutil.ReadAll(resp.Body)
|
||||
return resp.StatusCode == http.StatusOK, errors.New(string(cnt))
|
||||
}
|
58
pkg/login-app/cmd/main.go
Normal file
58
pkg/login-app/cmd/main.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
gc "github.com/rthornton128/goncurses"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
if connection(stdscr, in, validator, validator_err) {
|
||||
e := <- validator_err
|
||||
return username, e.Error(), true
|
||||
} else {
|
||||
return goLogin(stdscr, in)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
stdscr, _ := gc.Init()
|
||||
defer gc.End()
|
||||
|
||||
// Set main properties
|
||||
gc.Cursor(0)
|
||||
gc.StartColor()
|
||||
gc.Raw(true)
|
||||
gc.Echo(false)
|
||||
stdscr.Keypad(true)
|
||||
|
||||
// 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)
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
248
pkg/login-app/cmd/windows.go
Normal file
248
pkg/login-app/cmd/windows.go
Normal file
|
@ -0,0 +1,248 @@
|
|||
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, 24, 2, 15, 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, 24, 4, 15, 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, 4, "Login:")
|
||||
mainwin.MovePrint(7, 4, "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(6, 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 a new issue