From f28da14d98b98e146b2d699ccfed7a6d78847e0b Mon Sep 17 00:00:00 2001 From: vilmibm Date: Wed, 1 Mar 2023 05:22:09 +0000 Subject: [PATCH] pubkey validation --- cmd/welcome/main.go | 57 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/cmd/welcome/main.go b/cmd/welcome/main.go index d118c5e..6b39555 100644 --- a/cmd/welcome/main.go +++ b/cmd/welcome/main.go @@ -9,6 +9,7 @@ import ( "strings" "git.tilde.town/tildetown/town/invites" + "git.tilde.town/tildetown/town/sshkey" "git.tilde.town/tildetown/town/stats" "github.com/AlecAivazis/survey/v2" "github.com/charmbracelet/lipgloss" @@ -34,10 +35,9 @@ func surveyIconSet(icons *survey.IconSet) { } func promptCode() (code string, err error) { - codePrompt := &survey.Input{ + err = survey.AskOne(&survey.Input{ Message: "invite code?", - } - err = survey.AskOne(codePrompt, &code, + }, &code, survey.WithValidator(survey.Required), survey.WithIcons(surveyIconSet)) code = strings.TrimSpace(code) @@ -45,11 +45,12 @@ func promptCode() (code string, err error) { } func promptUsername(townData stats.TildeData) (un string, err error) { + // copied from /etc/adduser.conf usernameRE := regexp.MustCompile(`^[a-z][-a-z0-9_]*$`) - unPrompt := &survey.Input{ - Message: "desired username?", - } - err = survey.AskOne(unPrompt, &un, + err = survey.AskOne( + &survey.Input{ + Message: "desired username?", + }, &un, survey.WithValidator(survey.Required), survey.WithIcons(surveyIconSet), survey.WithValidator(func(val interface{}) error { @@ -82,11 +83,11 @@ func promptUsername(townData stats.TildeData) (un string, err error) { } func promptEmail(defaultEmail string) (email string, err error) { - emailPrompt := &survey.Input{ - Message: "e-mail (for account recovery only)?", - Default: defaultEmail, - } - err = survey.AskOne(emailPrompt, &email, + err = survey.AskOne( + &survey.Input{ + Message: "e-mail (for account recovery only)?", + Default: defaultEmail, + }, &email, survey.WithValidator(survey.Required), survey.WithIcons(surveyIconSet), survey.WithValidator(func(val interface{}) error { @@ -106,6 +107,30 @@ func promptEmail(defaultEmail string) (email string, err error) { return "", nil } +func promptKey() (key string, err error) { + err = survey.AskOne( + &survey.Input{ + Message: "SSH public key?", + }, &key, + survey.WithValidator(survey.Required), + survey.WithIcons(surveyIconSet), + survey.WithValidator(func(v interface{}) error { + key := v.(string) + valid, err := sshkey.ValidKey(key) + if err != nil { + return fmt.Errorf("failed to validate key: %w", err) + } + + if !valid { + return errors.New("that doesn't seem like a valid SSH key. try another public key?") + } + + return nil + })) + + return +} + func _main() error { townData, err := stats.Stats() if err != nil { @@ -156,7 +181,13 @@ func _main() error { return err } - // TODO collect public key + data.PubKey, err = promptKey() + if err != nil { + return err + } + + // TODO should I allow a review+edit step? + // TODO have enough to make account; can now do that // TODO assuming account creation succeeded, mark invite as used