mirror of
https://github.com/openziti/zrok.git
synced 2024-11-25 01:23:49 +01:00
moved token requirement to metadata and provide fields based on that
This commit is contained in:
parent
af456d22d5
commit
b7623f80f6
@ -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"
|
||||||
@ -21,9 +22,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type inviteCommand struct {
|
type inviteCommand struct {
|
||||||
cmd *cobra.Command
|
cmd *cobra.Command
|
||||||
token string
|
tui inviteTui
|
||||||
tui inviteTui
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInviteCommand() *inviteCommand {
|
func newInviteCommand() *inviteCommand {
|
||||||
@ -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,18 +91,20 @@ 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"))
|
||||||
}
|
}
|
||||||
|
|
||||||
type inviteTui struct {
|
type inviteTui struct {
|
||||||
focusIndex int
|
focusIndex int
|
||||||
msg string
|
msg string
|
||||||
inputs []textinput.Model
|
emailInputs []textinput.Model
|
||||||
cursorMode textinput.CursorMode
|
tokenInput textinput.Model
|
||||||
done bool
|
cursorMode textinput.CursorMode
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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"`
|
||||||
|
|
||||||
|
@ -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"
|
||||||
},
|
},
|
||||||
|
@ -553,6 +553,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
touLink:
|
touLink:
|
||||||
type: string
|
type: string
|
||||||
|
registrationRequiresToken:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
createFrontendRequest:
|
createFrontendRequest:
|
||||||
type: object
|
type: object
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
*
|
*
|
||||||
* @property {string} version
|
* @property {string} version
|
||||||
* @property {string} touLink
|
* @property {string} touLink
|
||||||
|
* @property {boolean} registrationRequiresToken
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user