-
Notifications
You must be signed in to change notification settings - Fork 3
/
logout.go
145 lines (119 loc) · 3.2 KB
/
logout.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package logout
import (
"fmt"
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"
"github.com/instill-ai/cli/internal/config"
"github.com/instill-ai/cli/pkg/cmdutil"
"github.com/instill-ai/cli/pkg/iostreams"
"github.com/instill-ai/cli/pkg/prompt"
)
type LogoutOptions struct {
IO *iostreams.IOStreams
Config func() (config.Config, error)
Hostname string
}
func NewCmdLogout(f *cmdutil.Factory, runF func(*LogoutOptions) error) *cobra.Command {
opts := &LogoutOptions{
IO: f.IOStreams,
Config: f.Config,
}
cmd := &cobra.Command{
Use: "logout",
Args: cobra.ExactArgs(0),
Short: "Log out of an Instill Core/Cloud host",
Long: heredoc.Doc(`Remove authentication for an Instill Core/Cloud host.
This command removes the authentication configuration for a host either specified
interactively or via --hostname.
`),
Example: heredoc.Doc(`
$ inst auth logout
# => select what host to log out of via a prompt
$ inst auth logout --hostname api.instill.tech
# => log out of specified host
`),
RunE: func(cmd *cobra.Command, args []string) error {
if opts.Hostname == "" && !opts.IO.CanPrompt() {
return cmdutil.FlagErrorf("--hostname required when not running interactively")
}
if runF != nil {
return runF(opts)
}
return logoutRun(opts)
},
}
cmd.Flags().StringVarP(&opts.Hostname, "hostname", "h", "", "The hostname of the Instill instance to log out of")
return cmd
}
func logoutRun(opts *LogoutOptions) error {
hostname := opts.Hostname
cfg, err := opts.Config()
if err != nil {
return err
}
candidates, err := cfg.Hosts()
// TODO filter candidates with oauth2 hostname only
if err != nil {
return err
}
if len(candidates) == 0 {
return fmt.Errorf("not logged in to any hosts")
}
if hostname == "" {
if len(candidates) == 1 {
hostname = candidates[0]
} else {
err = prompt.SurveyAskOne(&survey.Select{
Message: "Which account do you want to log out of?",
Options: candidates,
}, &hostname)
if err != nil {
return fmt.Errorf("could not prompt: %w", err)
}
}
} else {
var found bool
for _, c := range candidates {
if c == hostname {
found = true
break
}
}
if !found {
return fmt.Errorf("not logged into %s", hostname)
}
}
if err := cfg.CheckWriteable(hostname, ""); err != nil {
return err
}
if opts.IO.CanPrompt() {
var keepGoing bool
err := prompt.SurveyAskOne(&survey.Confirm{
Message: fmt.Sprintf("Are you sure you want to log out of %s?", hostname),
Default: true,
}, &keepGoing)
if err != nil {
return fmt.Errorf("could not prompt: %w", err)
}
if !keepGoing {
return nil
}
}
// TODO invalidate the token instead of removing the whole instance
err = cfg.UnsetHost(hostname)
if err != nil {
return fmt.Errorf("error unset hostname '%s' - %w", hostname, err)
}
err = cfg.Write()
if err != nil {
return fmt.Errorf("failed to write config, authentication configuration not updated: %w", err)
}
isTTY := opts.IO.IsStdinTTY() && opts.IO.IsStdoutTTY()
if isTTY {
cs := opts.IO.ColorScheme()
fmt.Fprintf(opts.IO.ErrOut, "%s Logged out of %s\n",
cs.SuccessIcon(), cs.Bold(hostname))
}
return nil
}