Skip to content

Commit

Permalink
feat(vpn-qr-code): design ui for both password and qr-code authentica…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
genshen committed Jun 13, 2024
1 parent 3103aff commit 0f80e46
Showing 1 changed file with 109 additions and 73 deletions.
182 changes: 109 additions & 73 deletions client-ui/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,32 +79,8 @@ func main() {
}
}

// vpn input
uiVpnEnable := newCheckbox("enable ustb vpn", true, nil)
uiVpnForceLogout := newCheckbox("", true, nil)
uiVpnHostEncrypt := newCheckbox("", true, nil)
uiVpnHostInput := &widget.Entry{PlaceHolder: "vpn hostname", Text: "n.ustb.edu.cn"}
uiVpnUsername := &widget.Entry{PlaceHolder: "vpn username", Text: ""}
uiVpnPassword := &widget.Entry{PlaceHolder: "vpn password", Text: "", Password: true}

loadVPNPreference(wssApp.Preferences(), uiVpnEnable, uiVpnForceLogout,
uiVpnHostEncrypt, uiVpnHostInput, uiVpnUsername, uiVpnPassword)

uiVpnEnable.OnChanged = func(checked bool) {
if checked {
uiVpnForceLogout.Enable()
uiVpnHostEncrypt.Enable()
uiVpnHostInput.Enable()
uiVpnUsername.Enable()
uiVpnPassword.Enable()
} else {
uiVpnForceLogout.Disable()
uiVpnHostEncrypt.Disable()
uiVpnHostInput.Disable()
uiVpnUsername.Disable()
uiVpnPassword.Disable()
}
}
// create vpn ui and necessary callbacks.
vpnUi, onLoadValue, onVpnClose := loadVpnUI(&wssApp)

btnStart := widget.NewButtonWithIcon("Start", theme.MailSendIcon(), nil)
btnStart.Importance = widget.HighImportance
Expand All @@ -128,14 +104,7 @@ func main() {
LocalHttpAddr: uiHttpLocalAddr.Text,
SkipTLSVerify: uiSkipTSLVerify.Checked,
},
UstbVpn: vpn.UstbVpn{
Enable: uiVpnEnable.Checked,
ForceLogout: uiVpnForceLogout.Checked,
HostEncrypt: uiVpnHostEncrypt.Checked,
TargetVpn: uiVpnHostInput.Text,
Username: uiVpnUsername.Text,
Password: uiVpnPassword.Text,
},
UstbVpn: onLoadValue(),
RemoteAddr: uiRemoteAddr.Text,
}
btnStatus = btnStarting
Expand Down Expand Up @@ -178,42 +147,15 @@ func main() {
return
}

tabs := container.NewAppTabs(
container.NewTabItemWithIcon(
"Basic",
theme.SettingsIcon(),
&widget.Form{Items: []*widget.FormItem{
{Text: "socks5 address", Widget: uiLocalAddr},
{Text: "remote address", Widget: uiRemoteAddr},
{Text: "auth token", Widget: uiAuthToken},
{Text: "http(s) proxy", Widget: uiHttpEnable},
{Text: "http(s) address", Widget: uiHttpLocalAddr},
{Text: "skip TSL verify", Widget: uiSkipTSLVerify},
}},
),
container.NewTabItemWithIcon(
"USTB VPN",
theme.AccountIcon(),
&widget.Form{Items: []*widget.FormItem{
{Text: "enable", Widget: uiVpnEnable},
{Text: "force logout", Widget: uiVpnForceLogout},
{Text: "host encrypt", Widget: uiVpnHostEncrypt},
{Text: "vpn host", Widget: uiVpnHostInput},
{Text: "username", Widget: uiVpnUsername},
{Text: "password", Widget: uiVpnPassword},
}},
),
container.NewTabItemWithIcon(
"QR Code",
theme.MoreHorizontalIcon(),
container.NewVBox(
LoadQRImage(),
widget.NewLabel("QR code scanned"),
widget.NewButton("Load/Reload QR Code", func() {}),
),
),
)
tabs.SetTabLocation(container.TabLocationTop)
basicUi := &widget.Form{Items: []*widget.FormItem{
{Text: "socks5 address", Widget: uiLocalAddr},
{Text: "remote address", Widget: uiRemoteAddr},
{Text: "auth token", Widget: uiAuthToken},
{Text: "http(s) proxy", Widget: uiHttpEnable},
{Text: "http(s) address", Widget: uiHttpLocalAddr},
{Text: "skip TSL verify", Widget: uiSkipTSLVerify},
}}

selectCopyProxyCommand := container.NewBorder(nil, nil, nil, nil,
NewWSelectWithCopyProxyCommand([]string{"git", "http/https", "ssh/sftp/scp"},
func(sel *widget.Select, value string) {
Expand All @@ -233,7 +175,8 @@ func main() {
)

w.SetContent(container.NewVBox(
widget.NewCard("Settings", "", tabs),
widget.NewCard("", "wssocks settings", basicUi), // wssocks basic ui
widget.NewCard("", "USTB VPN authentication", vpnUi), // vpn ui
btnStart,
selectCopyProxyCommand,
&widget.Separator{},
Expand Down Expand Up @@ -273,13 +216,106 @@ func main() {
handles.NotifyCloseWrapper()
}
saveBasicPreference(wssApp.Preferences(), uiLocalAddr, uiRemoteAddr, uiHttpLocalAddr, uiHttpEnable, uiSkipTSLVerify)
saveVPNPreference(wssApp.Preferences(), uiVpnEnable, uiVpnForceLogout,
uiVpnHostEncrypt, uiVpnHostInput, uiVpnUsername, uiVpnPassword)
onVpnClose()
})
//w.SetOnClosed() todo
w.ShowAndRun()
}

// loadVpnUI creates ui for ustb vpn, including auth method selection and the input box.
// it returns callback function: onAppClose for saving preference,
// loadUiValue for loading value from the input box.
func loadVpnUI(wssApp *fyne.App) (*fyne.Container, func() vpn.UstbVpn, func()) {
uiVpnEnable := newCheckbox("enable ustb vpn", true, nil)
uiVpnForceLogout := newCheckbox("", true, nil)
uiVpnHostEncrypt := newCheckbox("", true, nil)
uiVpnHostInput := &widget.Entry{PlaceHolder: "vpn hostname", Text: "n.ustb.edu.cn"}
uiVpnUsername := &widget.Entry{PlaceHolder: "vpn username", Text: ""}
uiVpnPassword := &widget.Entry{PlaceHolder: "vpn password", Text: "", Password: true}

// select auth method
uiVpnAuthMethod := widget.NewRadioGroup([]string{"Password", "QR Code"}, func(value string) {
// todo:
})
uiVpnAuthMethod.Horizontal = true
// vpn auth config buttons
uiBtnAuthPasswd := widget.NewButton("Config password auth", func() {
passwdAuthWindow := (*wssApp).NewWindow("password vpn auth")
passwdAuthWindow.SetContent(&widget.Form{Items: []*widget.FormItem{
{Text: "force logout", Widget: uiVpnForceLogout},
{Text: "host encrypt", Widget: uiVpnHostEncrypt},
{Text: "vpn host", Widget: uiVpnHostInput},
{Text: "username", Widget: uiVpnUsername},
{Text: "password", Widget: uiVpnPassword},
}})
passwdAuthWindow.Resize(fyne.NewSize(320, 0))
passwdAuthWindow.Show()
return
})
uiBtnAuthQrCode := widget.NewButton("Config QR Code auth", func() {
qrAuthWindow := (*wssApp).NewWindow("QR Code vpn auth")
qrAuthWindow.SetContent(container.NewVBox(
LoadQRImage(),
widget.NewLabel("QR code scanned"),
widget.NewButton("Load/Reload QR Code", func() {}),
))
qrAuthWindow.Show()
return
})

loadVPNPreference((*wssApp).Preferences(), uiVpnEnable, uiVpnForceLogout,
uiVpnHostEncrypt, uiVpnHostInput, uiVpnUsername, uiVpnPassword)

uiVpnEnable.OnChanged = func(checked bool) {
if checked {
uiVpnAuthMethod.Enable()
uiVpnForceLogout.Enable()
uiVpnHostEncrypt.Enable()
uiVpnHostInput.Enable()
uiVpnUsername.Enable()
uiVpnPassword.Enable()
uiBtnAuthPasswd.Enable()
uiBtnAuthQrCode.Enable()
} else {
uiVpnAuthMethod.Disable()
uiVpnForceLogout.Disable()
uiVpnHostEncrypt.Disable()
uiVpnHostInput.Disable()
uiVpnUsername.Disable()
uiVpnPassword.Disable()
uiBtnAuthPasswd.Disable()
uiBtnAuthQrCode.Disable()
}
}

// the vpn UI
vpnUi := container.NewVBox(
&widget.Form{Items: []*widget.FormItem{
{Text: "vpn enable", Widget: uiVpnEnable},
{Text: "auth method", Widget: uiVpnAuthMethod},
}},
container.NewGridWithColumns(2,
uiBtnAuthPasswd,
uiBtnAuthQrCode,
))

loadUiValues := func() vpn.UstbVpn {
return vpn.UstbVpn{
Enable: uiVpnEnable.Checked,
ForceLogout: uiVpnForceLogout.Checked,
HostEncrypt: uiVpnHostEncrypt.Checked,
TargetVpn: uiVpnHostInput.Text,
Username: uiVpnUsername.Text,
Password: uiVpnPassword.Text,
}
}
onVpnClose := func() {
saveVPNPreference((*wssApp).Preferences(), uiVpnEnable, uiVpnForceLogout,
uiVpnHostEncrypt, uiVpnHostInput, uiVpnUsername, uiVpnPassword)
}
return vpnUi, loadUiValues, onVpnClose
}

// NewWSelectWithCopyProxyCommand is copied from widget.NewSelect.
func NewWSelectWithCopyProxyCommand(options []string, changed func(sel *widget.Select, val string)) *widget.Select {
s := &widget.Select{
Expand Down

0 comments on commit 0f80e46

Please sign in to comment.