diff --git a/README.rst b/README.rst index 98e3f0a4..b2249d44 100644 --- a/README.rst +++ b/README.rst @@ -211,7 +211,7 @@ Messages that were conveyed with the donations: - 25/01/2022: Stay away from `TheSignChef.com`_, ya hear, they don't pay what they owe to their employees. -.. _Application: https://stackoverflow.com/questions/12908881/how-to-copy-cookies-in-google-chrome + .. _`Buy me a cup of tea`: https://www.paypal.com/donate/?hosted_button_id=GUHCLSM7E54ZW .. _Telegram: https://t.me/slackdump .. _Slack: https://slackdump.herokuapp.com/ @@ -229,13 +229,12 @@ Messages that were conveyed with the donations: .. _slack export viewer: https://github.com/hfaran/slack-export-viewer .. _releases: https://github.com/rusq/slackdump/releases/ .. _Slackord2: https://github.com/thomasloupe/Slackord2 -.. _SlackLogViewer: https://github.com/thayakawa-gh/SlackLogViewer/actions/runs/3029568329 +.. _SlackLogViewer: https://github.com/thayakawa-gh/SlackLogViewer/releases .. bulletin board links .. _`TheSignChef.com`: https://www.glassdoor.com.au/Reviews/TheSignChef-com-Reviews-E793259.htm -.. _`Get cookies.txt Chrome extension`: https://chrome.google.com/webstore/detail/get-cookiestxt/bgaddhkoddajcdgocldbbfleckgcbcid .. |go ref| image:: https://pkg.go.dev/badge/github.com/rusq/slackdump/v2.svg :alt: Go Reference diff --git a/auth/auth.go b/auth/auth.go index fc068951..2a4e8d20 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -5,6 +5,7 @@ import ( "errors" "io" "net/http" + "strings" ) // Type is the auth type. @@ -45,7 +46,7 @@ func (c simpleProvider) Validate() error { if c.Token == "" { return ErrNoToken } - if len(c.Cookie) == 0 { + if IsClientToken(c.Token) && len(c.Cookie) == 0 { return ErrNoCookies } return nil @@ -99,3 +100,7 @@ func Save(w io.Writer, p Provider) error { return nil } + +func IsClientToken(tok string) bool { + return strings.HasPrefix(tok, "xoxc-") +} diff --git a/auth/auth_test.go b/auth/auth_test.go index 726e1e03..b2812feb 100644 --- a/auth/auth_test.go +++ b/auth/auth_test.go @@ -81,11 +81,18 @@ func TestSave(t *testing.T) { true, }, { - "cookies missing", - args{ValueAuth{simpleProvider{Token: "token_value", Cookie: []http.Cookie{}}}}, + "cookies missing on client token", + args{ValueAuth{simpleProvider{Token: "xoxc-blah", Cookie: []http.Cookie{}}}}, "", true, }, + { + "cookies missing on non-client token", + args{ValueAuth{simpleProvider{Token: "xoxp-blah", Cookie: []http.Cookie{}}}}, + `{"Token":"xoxp-blah","Cookie":[]} +`, + false, + }, { "token and cookie are missing", args{ValueAuth{simpleProvider{}}}, diff --git a/auth/browser/browser.go b/auth/browser/browser.go index cc57f921..730823f9 100644 --- a/auth/browser/browser.go +++ b/auth/browser/browser.go @@ -15,6 +15,8 @@ import ( "github.com/rusq/slackdump/v2/logger" ) +const slackDomain = ".slack.com" + // Client is the client for Browser Auth Provider. type Client struct { workspace string @@ -62,7 +64,7 @@ func (cl *Client) Authenticate(ctx context.Context) (string, []http.Cookie, erro _f = playwright.Float ) if err := context.AddCookies(playwright.BrowserContextAddCookiesOptionsCookies{ - Domain: _s(".slack.com"), + Domain: _s(slackDomain), Path: _s("/"), Name: _s("OptanonAlertBoxClosed"), Value: _s(time.Now().Add(-10 * time.Minute).Format(time.RFC3339)), @@ -77,7 +79,7 @@ func (cl *Client) Authenticate(ctx context.Context) (string, []http.Cookie, erro } page.On("close", func() { trace.Log(ctx, "user", "page closed"); close(cl.pageClosed) }) - uri := fmt.Sprintf("https://%s.slack.com", cl.workspace) + uri := fmt.Sprintf("https://%s"+slackDomain, cl.workspace) l().Debugf("opening browser URL=%s", uri) if _, err := page.Goto(uri); err != nil { @@ -143,9 +145,13 @@ func extractToken(uri string) (string, error) { } func convertCookies(pwc []playwright.Cookie) []http.Cookie { - var ret = make([]http.Cookie, len(pwc)) - for i, p := range pwc { - ret[i] = http.Cookie{ + var ret = make([]http.Cookie, 0, len(pwc)) + for _, p := range pwc { + if !strings.HasSuffix(p.Domain, slackDomain) { + // ignoring filth (thirdparty tracking cookies) + continue + } + ret = append(ret, http.Cookie{ Name: p.Name, Value: p.Value, Path: p.Path, @@ -155,7 +161,7 @@ func convertCookies(pwc []playwright.Cookie) []http.Cookie { Secure: p.Secure, HttpOnly: p.HttpOnly, SameSite: sameSite(p.SameSite), - } + }) } return ret } diff --git a/auth/value.go b/auth/value.go index a55885c5..bb9980e5 100644 --- a/auth/value.go +++ b/auth/value.go @@ -24,16 +24,19 @@ func NewValueAuth(token string, cookie string) (ValueAuth, error) { if token == "" { return ValueAuth{}, ErrNoToken } - if cookie == "" { - return ValueAuth{}, ErrNoCookies - } - return ValueAuth{simpleProvider{ + c := ValueAuth{simpleProvider{ Token: token, - Cookie: []http.Cookie{ + }} + if IsClientToken(token) { + if len(cookie) == 0 { + return ValueAuth{}, ErrNoCookies + } + c.Cookie = []http.Cookie{ makeCookie("d", cookie), makeCookie("d-s", fmt.Sprintf("%d", time.Now().Unix()-10)), - }, - }}, nil + } + } + return c, nil } func (ValueAuth) Type() Type { diff --git a/doc/login-manual.rst b/doc/login-manual.rst index f5eb2c55..46b90d73 100644 --- a/doc/login-manual.rst +++ b/doc/login-manual.rst @@ -16,19 +16,16 @@ TOKEN #. In Firefox, under `Tools -> Browser Tools -> Web Developer tools` in the menu bar #. In Chrome, click the 'three dots' button to the right of the URL Bar, then select 'More Tools -> Developer Tools' -#. Go to the Network tab -#. In the toolbar, switch to ``Fetch/XHR`` view. -#. Open any channel or private conversation in Slack. You'll see a - bunch of stuff appearing in Network panel. -#. In the list of requests, find the one starting with - ``channels.prefs.get?``, click it and click on *Headers* tab in the - opened pane. -#. Scroll down, until you see **Form Data** -#. Grab the **token:** value (it starts with ``xoxc-``), by right - clicking the value and choosing "Copy Value". +#. Switch to the console tab. +#. Paste the following snippet and press ENTER to execute:: -**If you don't see the token value** in Google Chrome - switch to `Payload` tab, -your token is waiting for you there. + JSON.parse(localStorage.localConfig_v2).teams[document.location.pathname.match(/^\/client\/(T[A-Z0-9]+)/)[1]].token + +#. Token value is printed right after the executed command (it starts with + "``xoxc-``"), save it somewhere for now. + +.. NOTE:: if you're having problems running the code snippet above, you can + get the token the conventional way, see Troubleshooting_ section below. COOKIE ++++++ @@ -83,6 +80,31 @@ Setting up the application #. Save the file and close the editor. +Troubleshooting +~~~~~~~~~~~~~~~ + +Getting token the hard way +++++++++++++++++++++++++++ + +#. Open your browser's *Developer Console*, as described in the TOKEN_ section + steps above. +#. Go to the Network tab +#. In the toolbar, switch to ``Fetch/XHR`` view. +#. Open any channel or private conversation in Slack. You'll see a + bunch of stuff appearing in Network panel. +#. In the list of requests, find the one starting with + ``channels.prefs.get?``, click it and click on *Headers* tab in the + opened pane. +#. Scroll down, until you see **Form Data** +#. Grab the **token:** value (it starts with "``xoxc-``"), by right + clicking the value and choosing "Copy Value". + +**If you don't see the token value** in Google Chrome - switch to `Payload` tab, +your token is waiting for you there. + + [Index_] -.. _Index: README.rst \ No newline at end of file +.. _Index: README.rst +.. _Application: https://stackoverflow.com/questions/12908881/how-to-copy-cookies-in-google-chrome +.. _`Get cookies.txt Chrome extension`: https://chrome.google.com/webstore/detail/get-cookiestxt/bgaddhkoddajcdgocldbbfleckgcbcid diff --git a/doc/usage-export.rst b/doc/usage-export.rst index 2dab01b4..9dfb8fc5 100644 --- a/doc/usage-export.rst +++ b/doc/usage-export.rst @@ -306,4 +306,4 @@ slack-like GUI. .. _Slackord2: https://github.com/thomasloupe/Slackord2 .. _issue: https://github.com/rusq/slackdump/issues .. _SlackLogViewer: https://github.com/thayakawa-gh/SlackLogViewer -.. _Download SlackLogViewer: https://github.com/thayakawa-gh/SlackLogViewer/actions/runs/3029568329 +.. _Download SlackLogViewer: https://github.com/thayakawa-gh/SlackLogViewer/releases diff --git a/export/export.go b/export/export.go index 3afad874..da2e0017 100644 --- a/export/export.go +++ b/export/export.go @@ -189,7 +189,7 @@ func (se *Export) exportConversation(ctx context.Context, userIdx structures.Use ctx, task := trace.NewTask(ctx, "export.conversation") defer task.End() - messages, err := se.sd.DumpRaw(ctx, ch.ID, se.opts.Oldest, se.opts.Latest, se.dl.ProcessFunc(ch.Name)) + messages, err := se.sd.DumpRaw(ctx, ch.ID, se.opts.Oldest, se.opts.Latest, se.dl.ProcessFunc(validName(ch))) if err != nil { return fmt.Errorf("failed to dump %q (%s): %w", ch.Name, ch.ID, err) } diff --git a/export/export_test.go b/export/export_test.go index bfabe337..b02def3f 100644 --- a/export/export_test.go +++ b/export/export_test.go @@ -194,6 +194,8 @@ func Test_serializeToFS(t *testing.T) { if err != nil { t.Fatal(err) } + defer arc.Close() + r, err := arc.Open("test.json") if err != nil { t.Fatal(err) diff --git a/export/index.go b/export/index.go index 07d25d41..4a7c43a8 100644 --- a/export/index.go +++ b/export/index.go @@ -52,7 +52,11 @@ func createIndex(channels []slack.Channel, users types.Users, currentUserID stri } var idx = index{ - Users: users, + Users: users, + Channels: []slack.Channel{}, + Groups: []slack.Channel{}, + MPIMs: []slack.Channel{}, + DMs: []DM{}, } for _, ch := range channels { diff --git a/fsadapter/zipfs.go b/fsadapter/zipfs.go index 283648bc..7cbd93eb 100644 --- a/fsadapter/zipfs.go +++ b/fsadapter/zipfs.go @@ -8,6 +8,7 @@ import ( "os" "path" "path/filepath" + "strings" "sync" "time" ) @@ -15,9 +16,10 @@ import ( var _ FS = &ZIP{} type ZIP struct { - zw *zip.Writer - mu sync.Mutex - f *os.File + zw *zip.Writer + mu sync.Mutex + f *os.File + seen map[string]bool // seen holds the list of seen directories. } func (z *ZIP) String() string { @@ -25,7 +27,7 @@ func (z *ZIP) String() string { } func NewZIP(zw *zip.Writer) *ZIP { - return &ZIP{zw: zw} + return &ZIP{zw: zw, seen: make(map[string]bool)} } func NewZipFile(filename string) (*ZIP, error) { @@ -34,11 +36,12 @@ func NewZipFile(filename string) (*ZIP, error) { return nil, err } zw := zip.NewWriter(f) - return &ZIP{zw: zw, f: f}, nil + return &ZIP{zw: zw, f: f, seen: make(map[string]bool)}, nil } func (*ZIP) normalizePath(p string) string { - return path.Join(filepath.SplitList(filepath.Clean(p))...) + split := strings.Split(filepath.Clean(p), string(os.PathSeparator)) + return path.Join(split...) } func (z *ZIP) Create(filename string) (io.WriteCloser, error) { @@ -55,13 +58,53 @@ func (z *ZIP) Create(filename string) (io.WriteCloser, error) { } func (z *ZIP) create(filename string) (io.Writer, error) { + if err := z.ensureDir(filename); err != nil { + return nil, err + } header := &zip.FileHeader{ Name: filename, Method: zip.Deflate, Modified: time.Now(), } return z.zw.CreateHeader(header) +} +func (z *ZIP) ensureDir(filename string) error { + if z.seen == nil { + z.seen = make(map[string]bool, 0) + } + var ensureFn = func(dir string) error { + if _, seen := z.seen[dir]; seen { + return nil + } + // not seen, create an empty directory. + if _, err := z.zw.Create(dir); err != nil { + return err + } + z.seen[dir] = true + return nil + } + dir, _ := path.Split(filename) + for _, d := range z.dirpath(dir) { + if err := ensureFn(d); err != nil { + return err + } + } + return nil +} + +func (*ZIP) dirpath(dir string) []string { + const sep = "/" + if len(dir) == 0 { + return nil + } + var ret []string + d := strings.TrimRight(dir, sep) + for len(d) > 0 { + ret = append([]string{strings.TrimRight(d, sep) + sep}, ret...) + d, _ = path.Split(strings.TrimRight(d, sep)) + } + return ret } func (z *ZIP) WriteFile(filename string, data []byte, _ os.FileMode) error { diff --git a/fsadapter/zipfs_test.go b/fsadapter/zipfs_test.go index 5d3fd094..ab59dbbd 100644 --- a/fsadapter/zipfs_test.go +++ b/fsadapter/zipfs_test.go @@ -8,6 +8,7 @@ import ( "io" "os" "path/filepath" + "reflect" "strings" "sync" "testing" @@ -199,3 +200,67 @@ func TestCreateConcurrency(t *testing.T) { } } } + +func TestZIP_normalizePath(t *testing.T) { + type args struct { + p string + } + tests := []struct { + name string + z *ZIP + args args + want string + }{ + { + "windows", + &ZIP{}, + args{filepath.Join("sample", "directory", "and", "file.txt")}, + "sample/directory/and/file.txt", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.z.normalizePath(tt.args.p); got != tt.want { + t.Errorf("ZIP.normalizePath() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestZIP_dirpath(t *testing.T) { + type args struct { + dir string + } + tests := []struct { + name string + z *ZIP + args args + want []string + }{ + { + "single", + &ZIP{}, + args{"foo/"}, + []string{"foo/"}, + }, + { + "single", + &ZIP{}, + args{"foo"}, + []string{"foo/"}, + }, + { + "two", + &ZIP{}, + args{"foo/bar"}, + []string{"foo/", "foo/bar/"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.z.dirpath(tt.args.dir); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ZIP.dirpath() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/go.mod b/go.mod index b1717cf2..77eb5d8e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/rusq/slackdump/v2 go 1.18 require ( - github.com/AlecAivazis/survey/v2 v2.3.5 + github.com/AlecAivazis/survey/v2 v2.3.6 github.com/MercuryEngineering/CookieMonster v0.0.0-20180304172713-1584578b3403 github.com/denisbrodbeck/machineid v1.0.1 github.com/fatih/color v1.13.0 @@ -12,13 +12,13 @@ require ( github.com/playwright-community/playwright-go v0.2000.1 github.com/rusq/dlog v1.3.3 github.com/rusq/osenv/v2 v2.0.1 - github.com/rusq/secure v0.0.3 + github.com/rusq/secure v0.0.4 github.com/rusq/tracer v1.0.1 github.com/schollz/progressbar/v3 v3.8.6 github.com/slack-go/slack v0.11.0 github.com/stretchr/testify v1.7.1 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 - golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 + golang.org/x/time v0.0.0-20220922220347-f3bd1da661af ) require ( @@ -27,17 +27,17 @@ require ( github.com/go-stack/stack v1.8.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.3.1 // indirect - golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect - golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 // indirect - golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/crypto v0.0.0-20221012134737-56aed061732a // indirect + golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 // indirect + golang.org/x/term v0.0.0-20220919170432-7a66f970e087 // indirect + golang.org/x/text v0.3.8 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f1e5b3fd..d60d328e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/AlecAivazis/survey/v2 v2.3.5 h1:A8cYupsAZkjaUmhtTYv3sSqc7LO5mp1XDfqe5E/9wRQ= github.com/AlecAivazis/survey/v2 v2.3.5/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= +github.com/AlecAivazis/survey/v2 v2.3.6 h1:NvTuVHISgTHEHeBFqt6BHOe4Ny/NwGZr7w+F8S9ziyw= +github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= github.com/MercuryEngineering/CookieMonster v0.0.0-20180304172713-1584578b3403 h1:EtZwYyLbkEcIt+B//6sujwRCnHuTEK3qiSypAX5aJeM= github.com/MercuryEngineering/CookieMonster v0.0.0-20180304172713-1584578b3403/go.mod h1:mM6WvakkX2m+NgMiPCfFFjwfH4KzENC07zeGEqq9U7s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= @@ -38,10 +40,14 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -62,6 +68,8 @@ github.com/rusq/osenv/v2 v2.0.1 h1:1LtNt8VNV/W86wb38Hyu5W3Rwqt/F1JNRGE+8GRu09o= github.com/rusq/osenv/v2 v2.0.1/go.mod h1:+wJBSisjNZpfoD961JzqjaM+PtaqSusO3b4oVJi7TFY= github.com/rusq/secure v0.0.3 h1:PcWc7devLyJfMk8KZW2qUQFwhH5ugme4ncbcGztsLPw= github.com/rusq/secure v0.0.3/go.mod h1:F1QilMKreuFRjov0UY7DZSIXn77/8RqMVGu2zV0RtqY= +github.com/rusq/secure v0.0.4 h1:svpiZHfHnx89eEDCCFI9OXG1Y8hL9kUWUG6fJbrWUOI= +github.com/rusq/secure v0.0.4/go.mod h1:F1QilMKreuFRjov0UY7DZSIXn77/8RqMVGu2zV0RtqY= github.com/rusq/slack v0.11.300 h1:s/1gVdKU+gD+3DUhAzMV6NwBGSUOP65J7QP0pB6EZRQ= github.com/rusq/slack v0.11.300/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/rusq/tracer v1.0.1 h1:5u4PCV8NGO97VuAINQA4gOVRkPoqHimLE2jpezRVNMU= @@ -81,6 +89,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg= +golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -103,20 +113,29 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 h1:Y7NOhdqIOU8kYI7BxsgL38d0ot0raxvcW+EMQU2QrT4= -golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= +golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 h1:OK7RB6t2WQX54srQQYSXMW8dF5C6/8+oA/s5QBmmto4= +golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 h1:Q5284mrmYTpACcm+eAKjKJH48BBwSyfJqmmGDTtT8Vc= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220919170432-7a66f970e087 h1:tPwmk4vmvVCMdr98VgL4JH+qZxPL8fqlUOHnyOM8N3w= +golang.org/x/term v0.0.0-20220919170432-7a66f970e087/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= diff --git a/internal/app/auth.go b/internal/app/auth.go index f0350117..cceb0a59 100644 --- a/internal/app/auth.go +++ b/internal/app/auth.go @@ -22,6 +22,9 @@ const ( credsFile = "provider.bin" ) +// isWSL is true if we're running in the WSL environment +var isWSL = os.Getenv("WSL_DISTRO_NAME") != "" + // SlackCreds holds the Token and Cookie reference. type SlackCreds struct { Token string @@ -58,7 +61,7 @@ func (c SlackCreds) Type(ctx context.Context) (auth.Type, error) { } func (c SlackCreds) IsEmpty() bool { - return c.Token == "" || c.Cookie == "" + return c.Token == "" || (auth.IsClientToken(c.Token) && c.Cookie == "") } // AuthProvider returns the appropriate auth Provider depending on the values @@ -85,12 +88,7 @@ func isExistingFile(name string) bool { } func ezLoginSupported() bool { - return runtime.GOARCH != "386" && !isWSL() -} - -// isWSL detects if we're running in WSL environment -func isWSL() bool { - return os.Getenv("WSL_DISTRO_NAME") != "" + return runtime.GOARCH != "386" && !isWSL } func ezLoginTested() bool { diff --git a/internal/app/auth_test.go b/internal/app/auth_test.go index c88f89a8..782642d5 100644 --- a/internal/app/auth_test.go +++ b/internal/app/auth_test.go @@ -55,16 +55,19 @@ func TestSlackCreds_Type(t *testing.T) { type args struct { ctx context.Context } - tests := []struct { + type test struct { name string fields fields args args want auth.Type wantErr bool - }{ - {"browser", fields{Token: "", Cookie: ""}, args{context.Background()}, auth.TypeBrowser, false}, + } + tests := []test{ {"value", fields{Token: "t", Cookie: "c"}, args{context.Background()}, auth.TypeValue, false}, - {"browser", fields{Token: "t", Cookie: testFile}, args{context.Background()}, auth.TypeCookieFile, false}, + {"cookie file", fields{Token: "t", Cookie: testFile}, args{context.Background()}, auth.TypeCookieFile, false}, + } + if !isWSL { + tests = append(tests, test{"browser", fields{Token: "", Cookie: ""}, args{context.Background()}, auth.TypeBrowser, false}) } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -95,9 +98,10 @@ func TestSlackCreds_IsEmpty(t *testing.T) { want bool }{ {"empty", fields{Token: "", Cookie: ""}, true}, - {"empty", fields{Token: "x", Cookie: ""}, true}, - {"empty", fields{Token: "", Cookie: "x"}, true}, - {"empty", fields{Token: "x", Cookie: "x"}, false}, + {"no token", fields{Token: "", Cookie: "x"}, true}, + {"xoxc: token and cookie present", fields{Token: "xoxc-", Cookie: "x"}, false}, + {"xoxc: no cookie is not ok", fields{Token: "xoxc-", Cookie: ""}, true}, + {"other: no cookie is ok", fields{Token: "xoxp-", Cookie: ""}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -124,7 +128,6 @@ func TestInitProvider(t *testing.T) { storedProv, _ := auth.NewValueAuth("xoxc", "xoxd") returnedProv, _ := auth.NewValueAuth("a", "b") - // using default filer type args struct { ctx context.Context @@ -463,24 +466,3 @@ func TestAuthReset(t *testing.T) { } }) } - -func Test_isWSL(t *testing.T) { - tests := []struct { - name string - wslDistroVal string - want bool - }{ - {"yes WSL", "Ubuntu", true}, - {"not WSL", "", false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - os.Setenv("WSL_DISTRO_NAME", tt.wslDistroVal) - defer os.Unsetenv("WSL_DISTRO_NAME") - - if got := isWSL(); got != tt.want { - t.Errorf("isWSL() = %v, want %v", got, tt.want) - } - }) - } -}