Skip to content
Snippets Groups Projects
Commit 7ae5eed0 authored by Florent Gluck's avatar Florent Gluck
Browse files

Factorized quite a bit of code.

Reworked README.md's tutorial for creating live exams and added screenshots.
parent 8007c7f1
No related branches found
No related tags found
No related merge requests found
......@@ -94,6 +94,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
......@@ -380,6 +382,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
......
......@@ -2,11 +2,11 @@ package main
import (
"os"
"strings"
"errors"
"strconv"
"os/exec"
"nexus-client/exec"
u "nexus-client/utils"
g "nexus-client/globals"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
......@@ -14,45 +14,9 @@ import (
)
const (
ENV_NEXUS_SERVER = "NEXUS_SERVER"
ENV_NEXUS_CERT = "NEXUS_CERT"
WINDOW_TITLE = "Live Exam"
REMOTE_VIEWER_BINARY = "remote-viewer"
windowTitle = "Live Exam"
)
func checkRemoteViewer() error {
output, err := exec.Command(REMOTE_VIEWER_BINARY, "--version").Output()
if err != nil {
return errors.New(REMOTE_VIEWER_BINARY+" is missing. Please install it.")
}
out := string(output)
lines := strings.Split(out, "\n")
fields := strings.Split(lines[0], " ")
if len(fields) < 3 {
return errors.New("Failed extracting "+REMOTE_VIEWER_BINARY+" version number!")
}
// This is what we should get if remote-viewer is working properly.
if fields[0] == REMOTE_VIEWER_BINARY && fields[1] == "version" {
return nil
}
return errors.New("Failed extracting "+REMOTE_VIEWER_BINARY+" version number!")
}
func runRemoteViewer(hostname string, port string, pwd string, cert string) {
spice := "spice://"+hostname+"?tls-port="+port+"&password="+pwd
spiceCert := "--spice-ca-file="+cert
spiceSecure := "--spice-secure-channels=all"
// To exit fullscreen mode, either:
// - move the mouse to the middle of the top of the screen.
// - use ctrl+F12 as specified below
// To activate kiosk mode, add these options: "-k --kiosk-quit=on-disconnect"
cmd := exec.Command(REMOTE_VIEWER_BINARY, "--hotkeys=toggle-fullscreen=ctrl+f12", "-f", "-t", WINDOW_TITLE, spice, spiceCert, spiceSecure)
if err := cmd.Run(); err != nil {
u.PrintlnErr("Failed attaching to VM: "+err.Error())
}
}
// Returns true if the specified file exists, false otherwise.
func FileExists(filename string) bool {
info, err := os.Stat(filename)
......@@ -63,36 +27,36 @@ func FileExists(filename string) bool {
}
func main() {
server, found := os.LookupEnv(ENV_NEXUS_SERVER)
if err := exec.CheckRemoteViewer(); err != nil {
u.PrintlnErr(err.Error())
os.Exit(1)
}
server, found := os.LookupEnv(g.ENV_NEXUS_SERVER)
if !found {
u.PrintlnErr("Environment variable \""+ENV_NEXUS_SERVER+"\" must be set!")
u.PrintlnErr("Environment variable \""+g.ENV_NEXUS_SERVER+"\" must be set!")
u.PrintlnErr("It defines the nexus server to connect to.")
u.PrintlnErr("Example: export "+ENV_NEXUS_SERVER+"=192.168.1.42")
u.PrintlnErr("Example: export "+g.ENV_NEXUS_SERVER+"=192.168.1.42")
os.Exit(1)
}
pubCert, found := os.LookupEnv(ENV_NEXUS_CERT)
pubCert, found := os.LookupEnv(g.ENV_NEXUS_CERT)
if !found {
u.PrintlnErr("Environment variable \""+ENV_NEXUS_CERT+"\" must be set!")
u.PrintlnErr("Environment variable \""+g.ENV_NEXUS_CERT+"\" must be set!")
u.PrintlnErr("It specifies the path to the public certificate required for encrypted communications (TLS) with the nexus server.")
u.PrintlnErr("Example: export "+ENV_NEXUS_CERT+"=ca-cert.pem")
u.PrintlnErr("Example: export "+g.ENV_NEXUS_CERT+"=ca-cert.pem")
os.Exit(1)
}
if !FileExists(pubCert) {
if !u.FileExists(pubCert) {
u.PrintlnErr("Failed reading certificate \""+pubCert+"\"!")
os.Exit(1)
}
if err := checkRemoteViewer(); err != nil {
u.PrintlnErr(err.Error())
os.Exit(1)
}
app := app.New()
app.Settings().SetTheme(theme.LightTheme())
win := app.NewWindow(WINDOW_TITLE)
win := app.NewWindow(windowTitle)
portEntry := widget.NewEntry()
portEntry.Validator = func(val string) error {
......@@ -100,8 +64,8 @@ func main() {
if err != nil {
return errors.New("Please enter an integer")
}
if port < 1100 || port > 65535 {
return errors.New("Please enter a value within [1100,65535]")
if port < 1024 || port > 65535 {
return errors.New("Please enter a value within [1024,65535]")
}
return nil
}
......@@ -117,8 +81,8 @@ func main() {
{ Text: "Password", Widget: pwdEntry},
},
OnSubmit: func() {
runRemoteViewer(server, portEntry.Text, pwdEntry.Text, pubCert)
app.Quit()
port, _ := strconv.Atoi(portEntry.Text)
exec.RunRemoteViewer(server, pubCert, windowTitle, port, pwdEntry.Text, true)
},
SubmitText: "Connect",
}
......
......@@ -18,6 +18,8 @@ replace nexus-client/cmdUser => ../cmdUser
replace nexus-client/cmdVM => ../cmdVM
replace nexus-client/exec => ../exec
require (
github.com/go-resty/resty/v2 v2.7.0
github.com/peterh/liner v1.2.2
......@@ -39,4 +41,5 @@ require (
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1 // indirect
nexus-client/cmdToken v0.0.0-00010101000000-000000000000 // indirect
nexus-client/exec v0.0.0-00010101000000-000000000000 // indirect
)
......@@ -11,6 +11,7 @@ import (
"golang.org/x/term"
u "nexus-client/utils"
g "nexus-client/globals"
"nexus-client/exec"
"nexus-client/cmd"
"nexus-client/cmdLogin"
"nexus-client/cmdToken"
......@@ -32,13 +33,13 @@ var cmdList = []cmd.Command {
&cmdUser.SetCaps{"usersetcaps"},
&cmdVM.List{"vmlist"},
&cmdVM.ListStart{"vmliststart"},
&cmdVM.ListAttach{"vmlistattach"},
&cmdVM.ListStop{"vmliststop"},
&cmdVM.ListEdit{"vmlistedit"},
&cmdVM.ListEditAccess{"vmlisteditaccess"},
&cmdVM.ListDel{"vmlistdel"},
&cmdVM.ListExportDir{"vmlistexportdir"},
// &cmdVM.ListStart{"vmliststart"},
// &cmdVM.ListAttach{"vmlistattach"},
// &cmdVM.ListStop{"vmliststop"},
// &cmdVM.ListEdit{"vmlistedit"},
// &cmdVM.ListEditAccess{"vmlisteditaccess"},
// &cmdVM.ListDel{"vmlistdel"},
// &cmdVM.ListExportDir{"vmlistexportdir"},
&cmdVM.Cred2pdf{"vmcred2pdf"},
......@@ -59,6 +60,11 @@ var cmdList = []cmd.Command {
}
func main() {
if err := exec.CheckRemoteViewer(); err != nil {
u.PrintlnErr(err.Error())
os.Exit(1)
}
server, found := os.LookupEnv(g.ENV_NEXUS_SERVER)
if !found {
u.PrintlnErr("Environment variable \""+g.ENV_NEXUS_SERVER+"\" must be set!")
......@@ -123,7 +129,7 @@ func shell(token string) {
Type: "help" for help on commands
"ls" to list files in current directory
"ls dir" to list files in dir
"quit" to quit nexush`)
"quit" or "exit" to quit nexush`)
client := g.GetInstance().Client
......@@ -167,7 +173,7 @@ Type: "help" for help on commands
valid := false
switch {
case typedCmd == "quit":
case typedCmd == "quit" || typedCmd == "exit":
quit = true
case typedCmd == "help":
cmd.Help(cmdList, "")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment