diff --git a/go.mod b/go.mod index f4371982..aeb037a6 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/hashicorp/golang-lru v0.5.3 github.com/hpcloud/tail v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 - github.com/keybase/go-keybase-chat-bot v0.0.0-20200207200343-9aca502dc88a + github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e github.com/labstack/echo/v4 v4.1.13 github.com/lrstanley/girc v0.0.0-20190801035559-4fc93959e1a7 github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20190210153444-cc9d05784d5d diff --git a/go.sum b/go.sum index 5b569d1c..ba42345f 100644 --- a/go.sum +++ b/go.sum @@ -102,8 +102,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro= github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= -github.com/keybase/go-keybase-chat-bot v0.0.0-20200207200343-9aca502dc88a h1:vwIVtvtOEn0edqYFeSTklvSmZG9WrnG5EywouKzZs1s= -github.com/keybase/go-keybase-chat-bot v0.0.0-20200207200343-9aca502dc88a/go.mod h1:vNc28YFzigVJod0j5EbuTtRIe7swx8vodh2yA4jZ2s8= +github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e h1:KbPTfR/PYuau1IzKoE4lnd8yby5I2pBj+VR6fSVbYU8= +github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e/go.mod h1:vNc28YFzigVJod0j5EbuTtRIe7swx8vodh2yA4jZ2s8= github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999 h1:2d+FLQbz4xRTi36DO1qYNUwfORax9XcQ0jhbO81Vago= github.com/keybase/go-ps v0.0.0-20161005175911-668c8856d999/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= diff --git a/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/kbchat.go b/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/kbchat.go index 0a74dd90..de76e75a 100644 --- a/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/kbchat.go +++ b/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/kbchat.go @@ -8,12 +8,13 @@ import ( "io" "io/ioutil" "log" + "os" "os/exec" - "strings" "sync" "time" "github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1" + "github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1" "github.com/keybase/go-keybase-chat-bot/kbchat/types/stellar1" ) @@ -29,30 +30,39 @@ type API struct { } func getUsername(runOpts RunOptions) (username string, err error) { - p := runOpts.Command("status") + p := runOpts.Command("whoami", "-json") output, err := p.StdoutPipe() if err != nil { return "", err } + p.ExtraFiles = []*os.File{output.(*os.File)} if err = p.Start(); err != nil { return "", err } doneCh := make(chan error) go func() { - scanner := bufio.NewScanner(output) - if !scanner.Scan() { - doneCh <- errors.New("unable to find Keybase username") + defer func() { close(doneCh) }() + statusJSON, err := ioutil.ReadAll(output) + if err != nil { + doneCh <- fmt.Errorf("error reading whoami output: %v", err) return } - text := scanner.Text() - toks := strings.Fields(text) - if len(toks) != 2 { - doneCh <- fmt.Errorf("invalid Keybase username output: %q", text) + var status keybase1.CurrentStatus + if err := json.Unmarshal(statusJSON, &status); err != nil { + doneCh <- fmt.Errorf("invalid whoami JSON %q: %v", statusJSON, err) return } - username = toks[1] - doneCh <- nil + if status.LoggedIn && status.User != nil { + username = status.User.Username + doneCh <- nil + } else { + doneCh <- fmt.Errorf("unable to authenticate to keybase service: logged in: %v user: %+v", status.LoggedIn, status.User) + } + // Cleanup the command + if err := p.Wait(); err != nil { + log.Printf("unable to wait for cmd: %v", err) + } }() select { @@ -176,6 +186,7 @@ func (a *API) startPipes() (err error) { if err != nil { return err } + a.apiCmd.ExtraFiles = []*os.File{output.(*os.File)} if err := a.apiCmd.Start(); err != nil { return err } @@ -360,7 +371,14 @@ func (a *API) Listen(opts ListenOptions) (*NewSubscription, error) { a.registerSubscription(sub) pause := 2 * time.Second readScanner := func(boutput *bufio.Scanner) { + defer func() { done <- struct{}{} }() for { + select { + case <-shutdownCh: + log.Printf("readScanner: received shutdown") + return + default: + } boutput.Scan() t := boutput.Text() var typeHolder TypeHolder @@ -413,12 +431,17 @@ func (a *API) Listen(opts ListenOptions) (*NewSubscription, error) { continue } } - done <- struct{}{} } attempts := 0 maxAttempts := 1800 go func() { + defer func() { + close(newMsgsCh) + close(newConvsCh) + close(newWalletCh) + close(errorCh) + }() for { select { case <-shutdownCh: @@ -428,6 +451,9 @@ func (a *API) Listen(opts ListenOptions) (*NewSubscription, error) { } if attempts >= maxAttempts { + if err := a.LogSend("Listen: failed to auth, giving up"); err != nil { + log.Printf("Listen: logsend failed to send: %v", err) + } panic("Listen: failed to auth, giving up") } attempts++ @@ -456,8 +482,10 @@ func (a *API) Listen(opts ListenOptions) (*NewSubscription, error) { time.Sleep(pause) continue } + p.ExtraFiles = []*os.File{stderr.(*os.File), output.(*os.File)} boutput := bufio.NewScanner(output) if err := p.Start(); err != nil { + log.Printf("Listen: failed to make listen scanner: %s", err) time.Sleep(pause) continue @@ -505,6 +533,11 @@ func (a *API) Shutdown() error { for _, sub := range a.subscriptions { sub.Shutdown() } + if a.apiCmd != nil { + if err := a.apiCmd.Wait(); err != nil { + return err + } + } if a.runOpts.Oneshot != nil { err := a.runOpts.Command("logout", "--force").Run() diff --git a/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/team.go b/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/team.go index 0f9d9524..71ec37d3 100644 --- a/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/team.go +++ b/vendor/github.com/keybase/go-keybase-chat-bot/kbchat/team.go @@ -1,8 +1,10 @@ package kbchat import ( + "bytes" "encoding/json" "fmt" + "log" "strings" "github.com/keybase/go-keybase-chat-bot/kbchat/types/keybase1" @@ -27,13 +29,18 @@ func (a *API) ListMembersOfTeam(teamName string) (res keybase1.TeamMembersDetail apiInput := fmt.Sprintf(`{"method": "list-team-memberships", "params": {"options": {"team": "%s"}}}`, teamName) cmd := a.runOpts.Command("team", "api") cmd.Stdin = strings.NewReader(apiInput) - bytes, err := cmd.CombinedOutput() + var stderr bytes.Buffer + cmd.Stderr = &stderr + output, err := cmd.Output() if err != nil { return res, APIError{err} } + if stderr.Len() != 0 { + log.Printf("ListMembersOfTeam error: %s", stderr.String()) + } members := ListTeamMembers{} - err = json.Unmarshal(bytes, &members) + err = json.Unmarshal(output, &members) if err != nil { return res, UnmarshalError{err} } @@ -47,13 +54,18 @@ func (a *API) ListUserMemberships(username string) ([]keybase1.AnnotatedMemberIn apiInput := fmt.Sprintf(`{"method": "list-user-memberships", "params": {"options": {"username": "%s"}}}`, username) cmd := a.runOpts.Command("team", "api") cmd.Stdin = strings.NewReader(apiInput) - bytes, err := cmd.CombinedOutput() + var stderr bytes.Buffer + cmd.Stderr = &stderr + output, err := cmd.Output() if err != nil { return nil, APIError{err} } + if stderr.Len() != 0 { + log.Printf("ListUserMemberships error: %s", stderr.String()) + } members := ListUserMemberships{} - err = json.Unmarshal(bytes, &members) + err = json.Unmarshal(output, &members) if err != nil { return nil, UnmarshalError{err} } diff --git a/vendor/modules.txt b/vendor/modules.txt index ad37c05c..25d1db1a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -77,7 +77,7 @@ github.com/hashicorp/hcl/json/token github.com/jpillora/backoff # github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 github.com/kardianos/osext -# github.com/keybase/go-keybase-chat-bot v0.0.0-20200207200343-9aca502dc88a +# github.com/keybase/go-keybase-chat-bot v0.0.0-20200226211841-4e48f3eaef3e github.com/keybase/go-keybase-chat-bot/kbchat github.com/keybase/go-keybase-chat-bot/kbchat/types/chat1 github.com/keybase/go-keybase-chat-bot/kbchat/types/gregor1