Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspaces UI etc #352

Merged
merged 12 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions auth/auth_ui/huh.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
// Huh is the Auth UI that uses the huh library to provide a terminal UI.
type Huh struct{}

var Theme = huh.ThemeBase16()

func (h *Huh) RequestWorkspace(w io.Writer) (string, error) {
var workspace string
err := huh.NewForm(huh.NewGroup(
Expand All @@ -22,7 +24,7 @@ func (h *Huh) RequestWorkspace(w io.Writer) (string, error) {
Value(&workspace).
Validate(valWorkspace).
Description("The workspace name is the part of the URL that comes before `.slack.com' in\nhttps://<workspace>.slack.com/. Both workspace name or URL are acceptable."),
)).Run()
)).WithTheme(Theme).Run()
if err != nil {
return "", err
}
Expand All @@ -44,7 +46,7 @@ func (*Huh) RequestCreds(w io.Writer, workspace string) (email string, passwd st
Placeholder("your slack password").
Validate(valRequired).EchoMode(huh.EchoModePassword),
),
)
).WithTheme(Theme)
err = f.Run()
return
}
Expand Down Expand Up @@ -137,7 +139,7 @@ func (*Huh) RequestLoginType(w io.Writer, workspace string) (LoginOpts, error) {
return ""
}
}, &ret.Type))
if err := huh.NewForm(huh.NewGroup(fields...)).Run(); err != nil {
if err := huh.NewForm(huh.NewGroup(fields...)).WithTheme(Theme).Run(); err != nil {
return ret, err
}
if ret.Type == LUserBrowser {
Expand Down Expand Up @@ -170,7 +172,7 @@ func chooseBrowser() (string, error) {
DescriptionFunc(func() string {
return browsers[selection].Path
}, &selection),
)).Run()
)).WithTheme(Theme).Run()
if err != nil {
return "", err
}
Expand All @@ -189,7 +191,7 @@ func (*Huh) ConfirmationCode(email string) (int, error) {
Description("Slack did not recognise the browser, and sent a confirmation code. Please enter the confirmation code below.").
Value(&strCode).
Validate(valSixDigits),
))
)).WithTheme(Theme)
if err := q.Run(); err != nil {
return 0, err
}
Expand Down
42 changes: 21 additions & 21 deletions auth/auth_ui/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@ var (
ErrRequired = errors.New("can not be empty")
)

func valURLSafe(s string) error {
for _, c := range s {
if !isRuneURLSafe(c) {
return ErrNotURLSafe
}
}
return nil
}
// func valURLSafe(s string) error {
// for _, c := range s {
// if !isRuneURLSafe(c) {
// return ErrNotURLSafe
// }
// }
// return nil
// }

func isRuneURLSafe(r rune) bool {
switch {
case 'a' <= r && r <= 'z':
return true
case 'A' <= r && r <= 'Z':
return true
case '0' <= r && r <= '9':
return true
case r == '-' || r == '.' || r == '_' || r == '~':
return true
}
return false
}
// func isRuneURLSafe(r rune) bool {
// switch {
// case 'a' <= r && r <= 'z':
// return true
// case 'A' <= r && r <= 'Z':
// return true
// case '0' <= r && r <= '9':
// return true
// case r == '-' || r == '.' || r == '_' || r == '~':
// return true
// }
// return false
// }

func valRequired(s string) error {
if s == "" {
Expand Down
6 changes: 5 additions & 1 deletion auth/browser/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ func (cl *Client) Authenticate(ctx context.Context) (string, []*http.Cookie, err
if err != nil {
return "", nil, err
}
defer pw.Stop()
defer func() {
if err := pw.Stop(); err != nil {
l().Printf("failed to stop playwright: %v", err)
}
}()

opts := playwright.BrowserTypeLaunchOptions{
Headless: _b(false),
Expand Down
3 changes: 1 addition & 2 deletions cmd/slackdump/internal/archive/search_wizard.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func wizSearch(ctx context.Context, cmd *base.Command, args []string) error {
return errors.New("select action")
}
if len(terms) == 0 {
return errors.New("search terms are not specified")
return errors.New("specify search terms in Search Options")
}
return nil
},
Expand Down Expand Up @@ -62,7 +62,6 @@ func searchCfg() cfgui.Configuration {
cfgui.ParamGroup{
Name: "Other parameters",
Params: []cfgui.Parameter{

{
Name: "Scope",
Description: "Choose the search scope.",
Expand Down
2 changes: 1 addition & 1 deletion cmd/slackdump/internal/bootstrap/slackdump.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func SlackdumpSession(ctx context.Context, opts ...slackdump.Option) (*slackdump
}

stdOpts = append(stdOpts, opts...)
return slackdump.New(
return slackdump.NewNoValidate(
ctx,
prov,
stdOpts...,
Expand Down
2 changes: 1 addition & 1 deletion cmd/slackdump/internal/diag/edge.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import (

var CmdEdge = &base.Command{
Run: runEdge,
Wizard: func(ctx context.Context, cmd *base.Command, args []string) error { panic("not implemented") },
UsageLine: "slack tools edge",
Short: "Edge test",
RequireAuth: true,
HideWizard: true,
Long: `
# Slack Edge API test tool

Expand Down
6 changes: 3 additions & 3 deletions cmd/slackdump/internal/diag/encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"os"
"strings"

"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
"github.com/ProtonMail/go-crypto/openpgp/packet"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/cfg"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/golang/base"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
)

// pub rsa4096 2020-03-22 [SC] [expires: 2029-03-21]
Expand Down
72 changes: 49 additions & 23 deletions cmd/slackdump/internal/diag/eztest.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net/http"
"os"

"github.com/playwright-community/playwright-go"
Expand All @@ -16,7 +17,6 @@ import (

var CmdEzTest = &base.Command{
Run: runEzLoginTest,
Wizard: func(ctx context.Context, cmd *base.Command, args []string) error { panic("not implemented") },
UsageLine: "slack tools eztest",
Short: "EZ-Login 3000 test",
Long: `
Expand All @@ -30,34 +30,49 @@ You will see "OK" in the end if there were no issues, otherwise an error will
be printed and the test will be terminated.
`,
CustomFlags: true,
PrintFlags: true,
}

type ezResult struct {
Engine string `json:"engine,omitempty"`
HasToken bool `json:"has_token,omitempty"`
HasCookies bool `json:"has_cookies,omitempty"`
Err *string `json:"error,omitempty"`
Engine string `json:"engine,omitempty"`
HasToken bool `json:"has_token,omitempty"`
HasCookies bool `json:"has_cookies,omitempty"`
Err *string `json:"error,omitempty"`
Credentials *Credentials `json:"credentials,omitempty"`
}

type Credentials struct {
Token string `json:"token,omitempty"`
Cookies []*http.Cookie `json:"cookie,omitempty"`
}

type eztestOpts struct {
printCreds bool
wsp string
legacy bool
}

var eztestFlags eztestOpts

func init() {
CmdEzTest.Flag.Usage = func() {
fmt.Fprint(os.Stdout, "usage: slackdump tools eztest [flags]\n\nFlags:\n")
CmdEzTest.Flag.PrintDefaults()
}
CmdEzTest.Flag.BoolVar(&eztestFlags.printCreds, "p", false, "print credentials")
CmdEzTest.Flag.BoolVar(&eztestFlags.legacy, "legacy-browser", false, "run with playwright")
CmdEzTest.Flag.StringVar(&eztestFlags.wsp, "w", "", "Slack `workspace` to login to.")
}

func runEzLoginTest(ctx context.Context, cmd *base.Command, args []string) error {
lg := logger.FromContext(ctx)

wsp := cmd.Flag.String("w", "", "Slack `workspace` to login to.")
legacy := cmd.Flag.Bool("legacy-browser", false, "run with playwright")

if err := cmd.Flag.Parse(args); err != nil {
base.SetExitStatus(base.SInvalidParameters)
return err
}

if *wsp == "" {
if eztestFlags.wsp == "" {
base.SetExitStatus(base.SInvalidParameters)
cmd.Flag.Usage()
return nil
Expand All @@ -67,10 +82,10 @@ func runEzLoginTest(ctx context.Context, cmd *base.Command, args []string) error
res ezResult
)

if *legacy {
res = tryPlaywrightAuth(ctx, *wsp)
if eztestFlags.legacy {
res = tryPlaywrightAuth(ctx, eztestFlags.wsp, eztestFlags.printCreds)
} else {
res = tryRodAuth(ctx, *wsp)
res = tryRodAuth(ctx, eztestFlags.wsp, eztestFlags.printCreds)
}

enc := json.NewEncoder(os.Stdout)
Expand All @@ -87,31 +102,36 @@ func runEzLoginTest(ctx context.Context, cmd *base.Command, args []string) error
return errors.New(*res.Err)
}
return nil

}

func tryPlaywrightAuth(ctx context.Context, wsp string) ezResult {
var res = ezResult{Engine: "playwright"}
func tryPlaywrightAuth(ctx context.Context, wsp string, populateCreds bool) ezResult {
var ret = ezResult{Engine: "playwright"}

if err := playwright.Install(&playwright.RunOptions{Browsers: []string{"firefox"}}); err != nil {
res.Err = ptr(fmt.Sprintf("playwright installation error: %s", err))
return res
ret.Err = ptr(fmt.Sprintf("playwright installation error: %s", err))
return ret
}

prov, err := auth.NewBrowserAuth(ctx, auth.BrowserWithWorkspace(wsp))
if err != nil {
res.Err = ptr(err.Error())
return res
ret.Err = ptr(err.Error())
return ret
}

res.HasToken = len(prov.SlackToken()) > 0
res.HasCookies = len(prov.Cookies()) > 0
return res
ret.HasToken = len(prov.SlackToken()) > 0
ret.HasCookies = len(prov.Cookies()) > 0
if populateCreds {
ret.Credentials = &Credentials{
Token: prov.SlackToken(),
Cookies: prov.Cookies(),
}
}
return ret
}

func ptr[T any](t T) *T { return &t }

func tryRodAuth(ctx context.Context, wsp string) ezResult {
func tryRodAuth(ctx context.Context, wsp string, populateCreds bool) ezResult {
ret := ezResult{Engine: "rod"}
prov, err := auth.NewRODAuth(ctx, auth.BrowserWithWorkspace(wsp))
if err != nil {
Expand All @@ -120,5 +140,11 @@ func tryRodAuth(ctx context.Context, wsp string) ezResult {
}
ret.HasCookies = len(prov.Cookies()) > 0
ret.HasToken = len(prov.SlackToken()) > 0
if populateCreds {
ret.Credentials = &Credentials{
Token: prov.SlackToken(),
Cookies: prov.Cookies(),
}
}
return ret
}
7 changes: 5 additions & 2 deletions cmd/slackdump/internal/diag/rawoutput.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (

var CmdRawOutput = &base.Command{
Run: nil, // populated by init to break the init cycle
Wizard: func(context.Context, *base.Command, []string) error { panic("not implemented") },
UsageLine: "slackdump tools rawoutput [flags] <id>",
Short: "record raw API output",
Long: `
Expand All @@ -39,6 +38,7 @@ Running this tool may be requested by developers.
PrintFlags: true,
RequireAuth: true,
Commands: nil,
HideWizard: true,
}

type rawOutputParams struct {
Expand Down Expand Up @@ -186,7 +186,10 @@ func sendReq(w io.Writer, cl *http.Client, ep string, v url.Values) (bool, error
log.Printf("error while retrieving body: %s", err)
}
if resp.StatusCode != http.StatusOK {
io.Copy(w, bytes.NewReader(data))
_, err := io.Copy(w, bytes.NewReader(data))
if err != nil {
return false, err
}
return false, fmt.Errorf("server NOT OK: %s", resp.Status)
}
if len(data) == 0 {
Expand Down
7 changes: 4 additions & 3 deletions cmd/slackdump/internal/diag/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import (
)

var CmdRecord = &base.Command{
UsageLine: "slackdump tools record",
Short: "chunk record commands",
Commands: []*base.Command{cmdRecordStream, cmdRecordState},
UsageLine: "slackdump tools record",
Short: "chunk record commands",
Commands: []*base.Command{cmdRecordStream, cmdRecordState},
HideWizard: true,
}

var cmdRecordStream = &base.Command{
Expand Down
4 changes: 3 additions & 1 deletion cmd/slackdump/internal/diag/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ func runSearch(ctx context.Context, cmd *base.Command, args []string) error {
lg.Printf("cursor %s", sm.NextCursor)
p.Cursor = sm.NextCursor

lim.Wait(ctx)
if err := lim.Wait(ctx); err != nil {
return err
}
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions cmd/slackdump/internal/diag/thread.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func generateThread(ctx context.Context, client *slack.Client, channelID string,
l := network.NewLimiter(network.Tier3, network.DefLimits.Tier3.Burst, int(network.DefLimits.Tier3.Boost))
pb := progressbar.Default(int64(numMsg))
pb.Describe("posting messages")
defer pb.Finish()
defer func() { _ = pb.Finish() }()
for i := 0; i < numMsg; i++ {
if err := network.WithRetry(ctx, l, 3, func() error {
_, _, err := client.PostMessageContext(ctx, channelID, slack.MsgOptionTS(ts), slack.MsgOptionText(fmt.Sprintf("message: %d", i), false))
Expand Down Expand Up @@ -144,7 +144,7 @@ func delMessages(ctx context.Context, client *slack.Client, channelID string, ms
pb := progressbar.Default(int64(len(msgs)))
pb.Describe("deleting messages")

defer pb.Finish()
defer func() { _ = pb.Finish() }()

l := network.NewLimiter(network.Tier3, network.DefLimits.Tier3.Burst, int(network.DefLimits.Tier3.Boost))
for _, m := range msgs {
Expand Down
Loading