Skip to content

Commit

Permalink
Merge branch 'master' into workspace-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Oct 6, 2024
2 parents bab2bb3 + a15a1dc commit 2672e5f
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 23 deletions.
21 changes: 21 additions & 0 deletions auth/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,24 @@ func BrowserWithVerbose(b bool) Option {
o.browserOpts.verbose = b
}
}

// RODWithRODHeadlessTimeout sets the timeout for the headless browser
// interaction. It is a net time of headless browser interaction, without the
// browser starting time.
func RODWithRODHeadlessTimeout(d time.Duration) Option {
return func(o *options) {
if d <= 0 {
return
}
o.rodOpts.autoTimeout = d
}
}

// RODWithUserAgent sets the user agent string for the headless browser.
func RODWithUserAgent(ua string) Option {
return func(o *options) {
if ua != "" {
o.rodOpts.userAgent = ua
}
}
}
41 changes: 28 additions & 13 deletions auth/rod.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ import (
"fmt"
"io"
"os"
"time"

"github.com/rusq/slackauth"

"github.com/rusq/slackdump/v3/auth/auth_ui"
"github.com/rusq/slackdump/v3/logger"
)

// RODHeadlessTimeout is the default timeout for the headless login flow.
// It is a net time of headless browser interaction, without the browser
// starting time.
const RODHeadlessTimeout = 40 * time.Second

// RodAuth is an authentication provider that uses a headless or interactive
// browser to authenticate with Slack, depending on the user's choice. It uses
// rod library to drive the browser via the CDP protocol.
Expand All @@ -29,7 +35,9 @@ type RodAuth struct {
}

type rodOpts struct {
ui browserAuthUIExt
ui browserAuthUIExt
autoTimeout time.Duration
userAgent string
}

type browserAuthUIExt interface {
Expand All @@ -51,7 +59,9 @@ func NewRODAuth(ctx context.Context, opts ...Option) (RodAuth, error) {
r := RodAuth{
opts: options{
rodOpts: rodOpts{
ui: &auth_ui.Huh{},
ui: &auth_ui.Huh{},
autoTimeout: RODHeadlessTimeout,
userAgent: "", // slackauth default user agent.
},
},
}
Expand Down Expand Up @@ -79,18 +89,29 @@ func NewRODAuth(ctx context.Context, opts ...Option) (RodAuth, error) {
return r, err
}

cl, err := slackauth.New(
r.opts.workspace,
slackauth.WithChallengeFunc(r.opts.ui.ConfirmationCode),
slackauth.WithUserAgent(r.opts.userAgent),
slackauth.WithAutologinTimeout(r.opts.autoTimeout),
)
if err != nil {
return r, err
}
defer cl.Close()

lg := logger.FromContext(ctx)
var sp simpleProvider
switch resp {
case auth_ui.LInteractive:
lg.Printf("ℹ️ Initialising browser, once the browser appears, login as usual")
var err error
sp.Token, sp.Cookie, err = slackauth.Browser(ctx, r.opts.workspace)
sp.Token, sp.Cookie, err = cl.Manual(ctx)
if err != nil {
return r, err
}
case auth_ui.LHeadless:
sp, err = headlessFlow(ctx, r.opts.workspace, r.opts.ui)
sp, err = headlessFlow(ctx, cl, r.opts.workspace, r.opts.ui)
if err != nil {
return r, err
}
Expand All @@ -105,7 +126,7 @@ func NewRODAuth(ctx context.Context, opts ...Option) (RodAuth, error) {
}, nil
}

func headlessFlow(ctx context.Context, workspace string, ui browserAuthUIExt) (sp simpleProvider, err error) {
func headlessFlow(ctx context.Context, cl *slackauth.Client, workspace string, ui browserAuthUIExt) (sp simpleProvider, err error) {
username, password, err := ui.RequestCreds(os.Stdout, workspace)
if err != nil {
return sp, err
Expand All @@ -116,16 +137,10 @@ func headlessFlow(ctx context.Context, workspace string, ui browserAuthUIExt) (s
if password == "" {
return sp, fmt.Errorf("password cannot be empty")
}
logger.FromContext(ctx).Println("⏳ Logging in to Slack, depending on your connection speed, it will take 15-30 seconds...")
logger.FromContext(ctx).Println("⏳ Logging in to Slack, depending on your connection speed, it will take 25-40 seconds...")

var loginErr error
sp.Token, sp.Cookie, loginErr = slackauth.Headless(
ctx,
workspace,
username,
password,
slackauth.WithChallengeFunc(ui.ConfirmationCode),
)
sp.Token, sp.Cookie, loginErr = cl.Headless(ctx, username, password)
if loginErr != nil {
return sp, loginErr
}
Expand Down
17 changes: 11 additions & 6 deletions cmd/slackdump/internal/cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/rusq/osenv/v2"

"github.com/rusq/slackdump/v3/auth"
"github.com/rusq/slackdump/v3/auth/browser"
"github.com/rusq/slackdump/v3/internal/network"
"github.com/rusq/slackdump/v3/logger"
Expand All @@ -27,10 +28,12 @@ var (
ConfigFile string
Workspace string

SlackToken string
SlackCookie string
LoginTimeout time.Duration = browser.DefLoginTimeout
Limits = network.DefLimits
SlackToken string
SlackCookie string
LoginTimeout time.Duration = browser.DefLoginTimeout // overall login time.
HeadlessTimeout time.Duration = auth.RODHeadlessTimeout // net interaction time.
Limits = network.DefLimits
RODUserAgent string // when empty, slackauth uses the default user agent.
// playwright stuff
Browser browser.Browser
LegacyBrowser bool
Expand Down Expand Up @@ -90,10 +93,12 @@ func SetBaseFlags(fs *flag.FlagSet, mask FlagMask) {
fs.StringVar(&SlackToken, "token", osenv.Secret("SLACK_TOKEN", ""), "Slack `token`")
// COOKIE environment variable is deprecated and will be removed in v2.5.0, use SLACK_COOKIE instead.
fs.StringVar(&SlackCookie, "cookie", osenv.Secret("SLACK_COOKIE", osenv.Secret("COOKIE", "")), "d= cookie `value` or a path to a cookie.txt file\n(environment: SLACK_COOKIE)")
fs.Var(&Browser, "browser", "browser to use for EZ-Login 3000 (default: firefox)")
fs.Var(&Browser, "browser", "browser to use for legacy EZ-Login 3000 (default: firefox)")
fs.DurationVar(&LoginTimeout, "browser-timeout", LoginTimeout, "Browser login `timeout`")
fs.DurationVar(&HeadlessTimeout, "autologin-timeout", HeadlessTimeout, "headless autologin `timeout`, without the browser starting time, just the interaction time")
fs.BoolVar(&LegacyBrowser, "legacy-browser", false, "use legacy browser automation (playwright) for EZ-Login 3000")
fs.BoolVar(&ForceEnterprise, "enterprise", false, "enable Enteprise workarounds")
fs.BoolVar(&ForceEnterprise, "enterprise", false, "enable Enteprise module, you need to specify this option if you're using Slack Enterprise Grid")
fs.StringVar(&RODUserAgent, "user-agent", "", "override the user agent string for EZ-Login 3000")
}
if mask&OmitDownloadFlag == 0 {
fs.BoolVar(&DownloadFiles, "files", true, "enables file attachments (to disable, specify: -files=false)")
Expand Down
9 changes: 8 additions & 1 deletion cmd/slackdump/internal/workspace/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,14 @@ func init() {

// runWspNew authenticates in the new workspace.
func runWspNew(ctx context.Context, cmd *base.Command, args []string) error {
m, err := cache.NewManager(cfg.CacheDir(), cache.WithAuthOpts(auth.BrowserWithBrowser(cfg.Browser), auth.BrowserWithTimeout(cfg.LoginTimeout)))
m, err := cache.NewManager(
cfg.CacheDir(),
cache.WithAuthOpts(
auth.BrowserWithBrowser(cfg.Browser),
auth.BrowserWithTimeout(cfg.LoginTimeout),
auth.RODWithRODHeadlessTimeout(cfg.HeadlessTimeout),
auth.RODWithUserAgent(cfg.RODUserAgent),
))
if err != nil {
base.SetExitStatus(base.SCacheError)
return fmt.Errorf("error initialising workspace manager: %s", err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
github.com/rusq/osenv/v2 v2.0.1
github.com/rusq/rbubbles v0.0.2
github.com/rusq/slack v0.9.6-0.20240712095442-5a0e2e405a99
github.com/rusq/slackauth v0.1.2
github.com/rusq/slackauth v0.3.1
github.com/rusq/tracer v1.0.1
github.com/schollz/progressbar/v3 v3.13.0
github.com/stretchr/testify v1.9.0
Expand Down
10 changes: 8 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-rod/rod v0.116.1 h1:BDMZY3qm/14SmvHBV7DoFUhXeJ2MbUYgumQ88b+v2WE=
github.com/go-rod/rod v0.116.1/go.mod h1:3Ash9fYwznqz9S1uLQgQRStur4fCXjoxxGW+ym6TYjU=
github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA=
github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
Expand Down Expand Up @@ -133,8 +135,10 @@ 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.9.6-0.20240712095442-5a0e2e405a99 h1:dqEcNs9hMc2PiMwhw8+Zi3wF8GNUHIK5OItZ01iM0Vk=
github.com/rusq/slack v0.9.6-0.20240712095442-5a0e2e405a99/go.mod h1:9O0zQAFN6W47z4KpTQbe6vOHOzBO76vMg1+gthPwaTI=
github.com/rusq/slackauth v0.1.2 h1:A5Btp4EDw1TkeGG+84srMrkFQjKqwqEolrsoI3wAI94=
github.com/rusq/slackauth v0.1.2/go.mod h1:/+6JZULYSpWk7/Dc232132wF6UbFOLV8DhSz55zBcnw=
github.com/rusq/slackauth v0.1.1 h1:nTAjZQ6UHoGzfV02IQQUyUrAR0JeEqfy6snD7D6cMzk=
github.com/rusq/slackauth v0.1.1/go.mod h1:0fWxVftSfAgULWCcflvy4q20/qY39aB8v0jLDaDLejM=
github.com/rusq/slackauth v0.3.1 h1:lAFuMQMVfe2VGZVCd8Hrwhqfrd8cy6nOzG0mhX9BvSg=
github.com/rusq/slackauth v0.3.1/go.mod h1:/+6JZULYSpWk7/Dc232132wF6UbFOLV8DhSz55zBcnw=
github.com/rusq/tracer v1.0.1 h1:5u4PCV8NGO97VuAINQA4gOVRkPoqHimLE2jpezRVNMU=
github.com/rusq/tracer v1.0.1/go.mod h1:Rqu48C3/K8bA5NPmF20Hft73v431MQIdM+Co+113pME=
github.com/schollz/progressbar/v3 v3.13.0 h1:9TeeWRcjW2qd05I8Kf9knPkW4vLM/hYoa6z9ABvxje8=
Expand All @@ -157,6 +161,8 @@ github.com/ysmood/gotrace v0.6.0 h1:SyI1d4jclswLhg7SWTL6os3L1WOKeNn/ZtzVQF8QmdY=
github.com/ysmood/gotrace v0.6.0/go.mod h1:TzhIG7nHDry5//eYZDYcTzuJLYQIkykJzCRIo4/dzQM=
github.com/ysmood/gson v0.7.3 h1:QFkWbTH8MxyUTKPkVWAENJhxqdBa4lYTQWqZCiLG6kE=
github.com/ysmood/gson v0.7.3/go.mod h1:3Kzs5zDl21g5F/BlLTNcuAGAYLKt2lV5G8D1zF3RNmg=
github.com/ysmood/leakless v0.8.0 h1:BzLrVoiwxikpgEQR0Lk8NyBN5Cit2b1z+u0mgL4ZJak=
github.com/ysmood/leakless v0.8.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
github.com/ysmood/leakless v0.9.0 h1:qxCG5VirSBvmi3uynXFkcnLMzkphdh3xx5FtrORwDCU=
github.com/ysmood/leakless v0.9.0/go.mod h1:R8iAXPRaG97QJwqxs74RdwzcRHT1SWCGTNqY8q0JvMQ=
github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
Expand Down

0 comments on commit 2672e5f

Please sign in to comment.