github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/system/terminal/command_sudo.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2024, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 package terminal 20 21 import ( 22 "bytes" 23 "context" 24 "sync" 25 26 "github.com/spf13/cobra" 27 28 "github.com/e154/smart-home/common/events" 29 ) 30 31 type CommandSudo struct { 32 Out *bytes.Buffer 33 *sync.Mutex 34 cmd *cobra.Command 35 password *string 36 } 37 38 func NewCommandSudo() *CommandSudo { 39 buf := new(bytes.Buffer) 40 41 command := &CommandSudo{ 42 Out: buf, 43 password: new(string), 44 Mutex: &sync.Mutex{}, 45 } 46 47 cmdMode := &cobra.Command{ 48 Use: "sudo", 49 DisableAutoGenTag: true, 50 Short: "get superuser access rights", 51 Run: func(cmd *cobra.Command, args []string) { 52 var password = cmd.Flag("password").Value.String() 53 54 //log.Debugf("password: %s", password) 55 56 ctx := cmd.Context() 57 command, ok := ctx.Value("Command").(events.CommandTerminal) 58 if !ok { 59 cmd.OutOrStdout().Write([]byte("request rejected")) 60 return 61 } 62 63 options, ok := ctx.Value("Options").(CommandOptions) 64 if !ok { 65 cmd.OutOrStdout().Write([]byte("request rejected")) 66 return 67 } 68 69 if options.config.RootSecret == "" || options.config.RootSecret != password { 70 cmd.OutOrStdout().Write([]byte("request rejected")) 71 return 72 } 73 74 accessToken, err := options.jwtManager.Generate(command.User, true) 75 if err != nil { 76 cmd.OutOrStdout().Write([]byte("request rejected")) 77 log.Error(err.Error()) 78 return 79 } 80 81 cmd.OutOrStdout().Write([]byte("request processed successfully")) 82 options.eventBus.Publish("system/dashboard", events.EventDirectMessage{ 83 UserID: command.User.Id, 84 SessionID: command.SessionID, 85 Query: "update_access_token", 86 Message: UpdateAccessTokenMessage{ 87 AccessToken: accessToken, 88 }, 89 }) 90 }, 91 } 92 93 cmdMode.SetOut(command.Out) 94 cmdMode.SetErr(command.Out) 95 command.cmd = cmdMode 96 97 return command 98 } 99 100 func (c *CommandSudo) Execute(ctx context.Context, args ...string) (out string, err error) { 101 c.Lock() 102 defer c.Unlock() 103 c.Out.Reset() 104 c.cmd.ResetFlags() 105 c.cmd.Flags().StringVarP(c.password, "password", "p", "", "see the root_secret in configuration file or ROOT_SECRET in your environment") 106 c.cmd.SetArgs(args) 107 err = c.cmd.ExecuteContext(ctx) 108 out = c.Out.String() 109 return 110 } 111 112 func (c *CommandSudo) Help(ctx context.Context) (out string, err error) { 113 err = c.cmd.Help() 114 out = c.Out.String() 115 return 116 }