moved token requirement to metadata and provide fields based on that

This commit is contained in:
Cam Otts 2023-04-11 18:41:40 -05:00
parent af456d22d5
commit b7623f80f6
No known key found for this signature in database
GPG Key ID: 367B7C7EBD84A8BD
6 changed files with 97 additions and 39 deletions

View File

@ -9,6 +9,7 @@ import (
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"github.com/openziti/zrok/rest_client_zrok/account" "github.com/openziti/zrok/rest_client_zrok/account"
"github.com/openziti/zrok/rest_client_zrok/metadata"
"github.com/openziti/zrok/rest_model_zrok" "github.com/openziti/zrok/rest_model_zrok"
"github.com/openziti/zrok/tui" "github.com/openziti/zrok/tui"
"github.com/openziti/zrok/util" "github.com/openziti/zrok/util"
@ -22,7 +23,6 @@ func init() {
type inviteCommand struct { type inviteCommand struct {
cmd *cobra.Command cmd *cobra.Command
token string
tui inviteTui tui inviteTui
} }
@ -38,8 +38,6 @@ func newInviteCommand() *inviteCommand {
} }
cmd.Run = command.run cmd.Run = command.run
cmd.Flags().StringVar(&command.token, "token", "", "Invite token required when zrok running in token store mode")
return command return command
} }
@ -58,17 +56,27 @@ func (cmd *inviteCommand) run(_ *cobra.Command, _ []string) {
panic(err) panic(err)
} }
md, err := zrok.Metadata.Configuration(metadata.NewConfigurationParams())
if err != nil {
tui.Error("unable to get server metadata", err)
}
if md != nil {
cmd.tui.RequireToken(md.GetPayload().RegistrationRequiresToken)
}
if _, err := tea.NewProgram(&cmd.tui).Run(); err != nil { if _, err := tea.NewProgram(&cmd.tui).Run(); err != nil {
tui.Error("unable to run interface", err) tui.Error("unable to run interface", err)
os.Exit(1) os.Exit(1)
} }
if cmd.tui.done { if cmd.tui.done {
email := cmd.tui.inputs[0].Value() email := cmd.tui.emailInputs[0].Value()
token := cmd.tui.tokenInput.Value()
req := account.NewInviteParams() req := account.NewInviteParams()
req.Body = &rest_model_zrok.InviteRequest{ req.Body = &rest_model_zrok.InviteRequest{
Email: email, Email: email,
Token: cmd.token, Token: token,
} }
_, err = zrok.Account.Invite(req) _, err = zrok.Account.Invite(req)
if err != nil { if err != nil {
@ -83,7 +91,6 @@ func (cmd *inviteCommand) run(_ *cobra.Command, _ []string) {
func (cmd *inviteCommand) endpointError(apiEndpoint, _ string) { func (cmd *inviteCommand) endpointError(apiEndpoint, _ string) {
fmt.Printf("%v\n\n", tui.SeriousBusiness.Render("there was a problem creating an invitation!")) fmt.Printf("%v\n\n", tui.SeriousBusiness.Render("there was a problem creating an invitation!"))
fmt.Printf("you are trying to use the zrok service at: %v\n\n", tui.Code.Render(apiEndpoint)) fmt.Printf("you are trying to use the zrok service at: %v\n\n", tui.Code.Render(apiEndpoint))
fmt.Printf("%v\n\n", tui.Attention.Render("should you be using a --token? check with your instance administrator!"))
fmt.Printf("you can change your zrok service endpoint using this command:\n\n") fmt.Printf("you can change your zrok service endpoint using this command:\n\n")
fmt.Printf("%v\n\n", tui.Code.Render("$ zrok config set apiEndpoint <newEndpoint>")) fmt.Printf("%v\n\n", tui.Code.Render("$ zrok config set apiEndpoint <newEndpoint>"))
fmt.Printf("(where newEndpoint is something like: %v)\n\n", tui.Code.Render("https://some.zrok.io")) fmt.Printf("(where newEndpoint is something like: %v)\n\n", tui.Code.Render("https://some.zrok.io"))
@ -92,9 +99,12 @@ func (cmd *inviteCommand) endpointError(apiEndpoint, _ string) {
type inviteTui struct { type inviteTui struct {
focusIndex int focusIndex int
msg string msg string
inputs []textinput.Model emailInputs []textinput.Model
tokenInput textinput.Model
cursorMode textinput.CursorMode cursorMode textinput.CursorMode
done bool done bool
requireToken bool
maxIndex int
msgOk string msgOk string
msgMismatch string msgMismatch string
@ -110,7 +120,8 @@ type inviteTui struct {
func newInviteTui() inviteTui { func newInviteTui() inviteTui {
m := inviteTui{ m := inviteTui{
inputs: make([]textinput.Model, 2), emailInputs: make([]textinput.Model, 2),
maxIndex: 2,
} }
m.focusedStyle = tui.Attention.Copy() m.focusedStyle = tui.Attention.Copy()
m.blurredStyle = tui.Code.Copy() m.blurredStyle = tui.Code.Copy()
@ -125,7 +136,7 @@ func newInviteTui() inviteTui {
m.msgMismatch = m.errorStyle.Render("email is invalid or does not match confirmation...") m.msgMismatch = m.errorStyle.Render("email is invalid or does not match confirmation...")
var t textinput.Model var t textinput.Model
for i := range m.inputs { for i := range m.emailInputs {
t = textinput.New() t = textinput.New()
t.CursorStyle = m.cursorStyle t.CursorStyle = m.cursorStyle
t.CharLimit = 96 t.CharLimit = 96
@ -140,9 +151,13 @@ func newInviteTui() inviteTui {
t.Placeholder = "Confirm Email" t.Placeholder = "Confirm Email"
} }
m.inputs[i] = t m.emailInputs[i] = t
} }
m.tokenInput = textinput.New()
m.tokenInput.CursorStyle = m.cursorStyle
m.tokenInput.Placeholder = "Token"
return m return m
} }
@ -158,8 +173,8 @@ func (m *inviteTui) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case "tab", "shift+tab", "enter", "up", "down": case "tab", "shift+tab", "enter", "up", "down":
s := msg.String() s := msg.String()
if s == "enter" && m.focusIndex == len(m.inputs) { if s == "enter" && m.focusIndex == m.maxIndex {
if util.IsValidEmail(m.inputs[0].Value()) && m.inputs[0].Value() == m.inputs[1].Value() { if util.IsValidEmail(m.emailInputs[0].Value()) && m.emailInputs[0].Value() == m.emailInputs[1].Value() {
m.done = true m.done = true
return m, tea.Quit return m, tea.Quit
} }
@ -175,23 +190,34 @@ func (m *inviteTui) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.focusIndex++ m.focusIndex++
} }
if m.focusIndex > len(m.inputs) { if m.focusIndex > m.maxIndex {
m.focusIndex = 0 m.focusIndex = 0
} else if m.focusIndex < 0 { } else if m.focusIndex < 0 {
m.focusIndex = len(m.inputs) m.focusIndex = m.maxIndex
} }
cmds := make([]tea.Cmd, len(m.inputs)) cmds := make([]tea.Cmd, m.maxIndex)
for i := 0; i <= len(m.inputs)-1; i++ { for i := 0; i <= len(m.emailInputs)-1; i++ {
if i == m.focusIndex { if i == m.focusIndex {
cmds[i] = m.inputs[i].Focus() cmds[i] = m.emailInputs[i].Focus()
m.inputs[i].PromptStyle = m.focusedStyle m.emailInputs[i].PromptStyle = m.focusedStyle
m.inputs[i].TextStyle = m.focusedStyle m.emailInputs[i].TextStyle = m.focusedStyle
continue continue
} }
m.inputs[i].Blur() m.emailInputs[i].Blur()
m.inputs[i].PromptStyle = m.noStyle m.emailInputs[i].PromptStyle = m.noStyle
m.inputs[i].TextStyle = m.noStyle m.emailInputs[i].TextStyle = m.noStyle
}
if m.requireToken {
if m.focusIndex == 2 {
cmds[2] = m.tokenInput.Focus()
m.tokenInput.PromptStyle = m.focusedStyle
m.tokenInput.TextStyle = m.focusedStyle
} else {
m.tokenInput.Blur()
m.tokenInput.PromptStyle = m.noStyle
m.tokenInput.TextStyle = m.noStyle
}
} }
return m, tea.Batch(cmds...) return m, tea.Batch(cmds...)
@ -204,9 +230,12 @@ func (m *inviteTui) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} }
func (m *inviteTui) updateInputs(msg tea.Msg) tea.Cmd { func (m *inviteTui) updateInputs(msg tea.Msg) tea.Cmd {
cmds := make([]tea.Cmd, len(m.inputs)) cmds := make([]tea.Cmd, m.maxIndex)
for i := range m.inputs { for i := range m.emailInputs {
m.inputs[i], cmds[i] = m.inputs[i].Update(msg) m.emailInputs[i], cmds[i] = m.emailInputs[i].Update(msg)
}
if m.requireToken {
m.tokenInput, cmds[2] = m.tokenInput.Update(msg)
} }
return tea.Batch(cmds...) return tea.Batch(cmds...)
} }
@ -215,18 +244,30 @@ func (m inviteTui) View() string {
var b strings.Builder var b strings.Builder
b.WriteString(fmt.Sprintf("\n%v\n\n", m.msg)) b.WriteString(fmt.Sprintf("\n%v\n\n", m.msg))
for i := range m.inputs { for i := 0; i < len(m.emailInputs); i++ {
b.WriteString(m.inputs[i].View()) b.WriteString(m.emailInputs[i].View())
if i < len(m.inputs)-1 {
b.WriteRune('\n') b.WriteRune('\n')
} }
if m.requireToken {
b.WriteString(m.tokenInput.View())
b.WriteRune('\n')
} }
button := &m.blurredButton button := &m.blurredButton
if m.focusIndex == len(m.inputs) { if m.focusIndex == m.maxIndex {
button = &m.focusedButton button = &m.focusedButton
} }
_, _ = fmt.Fprintf(&b, "\n\n%s\n\n", *button) _, _ = fmt.Fprintf(&b, "\n\n%s\n\n", *button)
return b.String() return b.String()
} }
func (m *inviteTui) RequireToken(require bool) {
m.requireToken = require
if require {
m.maxIndex = 3
} else {
m.maxIndex = 2
}
}

View File

@ -22,9 +22,14 @@ func (ch *configurationHandler) Handle(_ metadata.ConfigurationParams) middlewar
if cfg.Admin != nil { if cfg.Admin != nil {
tou = cfg.Admin.TouLink tou = cfg.Admin.TouLink
} }
tokenRequired := false
if cfg.Registration != nil {
tokenRequired = cfg.Registration.TokenStrategy == "store"
}
data := &rest_model_zrok.Configuration{ data := &rest_model_zrok.Configuration{
Version: build.String(), Version: build.String(),
TouLink: tou, TouLink: tou,
RegistrationRequiresToken: tokenRequired,
} }
return metadata.NewConfigurationOK().WithPayload(data) return metadata.NewConfigurationOK().WithPayload(data)
} }

View File

@ -17,6 +17,9 @@ import (
// swagger:model configuration // swagger:model configuration
type Configuration struct { type Configuration struct {
// registration requires token
RegistrationRequiresToken bool `json:"registrationRequiresToken,omitempty"`
// tou link // tou link
TouLink string `json:"touLink,omitempty"` TouLink string `json:"touLink,omitempty"`

View File

@ -871,6 +871,9 @@ func init() {
"configuration": { "configuration": {
"type": "object", "type": "object",
"properties": { "properties": {
"registrationRequiresToken": {
"type": "boolean"
},
"touLink": { "touLink": {
"type": "string" "type": "string"
}, },
@ -2149,6 +2152,9 @@ func init() {
"configuration": { "configuration": {
"type": "object", "type": "object",
"properties": { "properties": {
"registrationRequiresToken": {
"type": "boolean"
},
"touLink": { "touLink": {
"type": "string" "type": "string"
}, },

View File

@ -553,6 +553,8 @@ definitions:
type: string type: string
touLink: touLink:
type: string type: string
registrationRequiresToken:
type: boolean
createFrontendRequest: createFrontendRequest:
type: object type: object

View File

@ -30,6 +30,7 @@
* *
* @property {string} version * @property {string} version
* @property {string} touLink * @property {string} touLink
* @property {boolean} registrationRequiresToken
*/ */
/** /**