@@ -8,6 +8,60 @@ import (
88 "github.com/spf13/cobra"
99)
1010
11+ type User struct {
12+ Username string
13+ Name string
14+ Owner bool
15+ Active bool
16+ LocalOnly bool
17+ }
18+
19+ var MsgLimitedAccess = "For security reasons, this command works only from the operating system terminal."
20+
21+ func getUsers () ([]User , error ) {
22+ resp , err := helper .GenericJSONGet ("auth" , "list" )
23+
24+ if err != nil {
25+ return nil , err
26+ }
27+
28+ var data * helper.Response
29+ var result []User
30+
31+ if resp .IsSuccess () {
32+ data = resp .Result ().(* helper.Response )
33+
34+ if data .Result != "ok" {
35+ err := fmt .Errorf ("error returned from Supervisor: %s" , data .Message )
36+ return nil , err
37+ }
38+
39+ for _ , user := range data .Data ["users" ].([]interface {}) {
40+ user := user .(map [string ]interface {})
41+ result = append (result , User {
42+ Username : user ["username" ].(string ),
43+ Name : user ["name" ].(string ),
44+ Owner : user ["is_owner" ].(bool ),
45+ Active : user ["is_active" ].(bool ),
46+ LocalOnly : user ["local_only" ].(bool ),
47+ })
48+ }
49+ } else {
50+ data = resp .Error ().(* helper.Response )
51+ err := fmt .Errorf ("error returned from Supervisor: %s" , data .Message )
52+ return nil , err
53+ }
54+
55+ return result , nil
56+ }
57+
58+ func listUsers (users []User ) {
59+ for i , user := range users {
60+ fmt .Printf ("- %d: %s (%s)\n " , i + 1 , user .Username , user .Name )
61+ fmt .Printf (" owner: %t, active: %t, local only: %t\n " , user .Owner , user .Active , user .LocalOnly )
62+ }
63+ }
64+
1165var authResetCmd = & cobra.Command {
1266 Use : "reset" ,
1367 Aliases : []string {"rst" , "change" },
@@ -19,6 +73,7 @@ only work on some locations. For example, the Operating System CLI.
1973` ,
2074 Example : `
2175 ha authentication reset --username "JohnDoe" --password "123SuperSecret!"
76+ ha authentication reset --interactive
2277` ,
2378 ValidArgsFunction : cobra .NoFileCompletions ,
2479 Args : cobra .NoArgs ,
@@ -40,9 +95,49 @@ only work on some locations. For example, the Operating System CLI.
4095 }
4196 }
4297
98+ interactive , _ := cmd .Flags ().GetBool ("interactive" )
99+ if interactive {
100+ // prompt for user if not given
101+ if options ["username" ] != nil && options ["username" ] != "" {
102+ fmt .Printf ("Changing password for user '%s'\n " , options ["username" ])
103+ } else {
104+ users , err := getUsers ()
105+ if err != nil {
106+ cmd .PrintErrln (MsgLimitedAccess )
107+ fmt .Println (err )
108+ ExitWithError = true
109+ return
110+ }
111+
112+ fmt .Println ("List of users:" )
113+ listUsers (users )
114+
115+ idx , err := helper .ReadInteger ("Select a user to reset the password for" , 3 , 1 , len (users ))
116+ if err != nil {
117+ fmt .Println ("Aborted: " , err )
118+ ExitWithError = true
119+ return
120+ }
121+
122+ user := users [idx - 1 ]
123+ fmt .Printf ("Changing password for user %d: %s (%s)\n " , idx , user .Username , user .Name )
124+ options ["username" ] = user .Username
125+ }
126+
127+ // prompt for password
128+ password , err := helper .ReadPassword (true )
129+ if err != nil {
130+ fmt .Printf ("Failed to set password: %v\n " , err )
131+ ExitWithError = true
132+ return
133+ }
134+ options ["password" ] = password
135+ }
136+
137+ // change the password
43138 resp , err := helper .GenericJSONPost (section , command , options )
44139 if err != nil {
45- cmd .PrintErrln ("this command is limited due to security reasons, and will only work on some locations. For example, the Operating System terminal." )
140+ cmd .PrintErrln (MsgLimitedAccess )
46141 fmt .Println (err )
47142 ExitWithError = true
48143 } else {
@@ -53,9 +148,10 @@ only work on some locations. For example, the Operating System CLI.
53148
54149func init () {
55150 authResetCmd .Flags ().String ("username" , "" , "Username to reset the password for" )
56- authResetCmd .Flags ().String ("password" , "" , "The new password to assign" )
57- authResetCmd .MarkFlagRequired ("username" )
58- authResetCmd .MarkFlagRequired ("password" )
151+ authResetCmd .Flags ().String ("password" , "" , "New password to assign. Ignored in interactive mode" )
152+ authResetCmd .Flags ().Bool ("interactive" , false , "Use interactive prompt for entering username and/or password" )
153+ authResetCmd .MarkFlagsOneRequired ("username" , "interactive" )
154+ authResetCmd .MarkFlagsOneRequired ("password" , "interactive" )
59155 authResetCmd .RegisterFlagCompletionFunc ("username" , cobra .NoFileCompletions )
60156 authResetCmd .RegisterFlagCompletionFunc ("password" , cobra .NoFileCompletions )
61157 authCmd .AddCommand (authResetCmd )
0 commit comments