Skip to content

Commit

Permalink
Merge pull request #263 from rusq/i262
Browse files Browse the repository at this point in the history
Support for login email challenge
  • Loading branch information
rusq authored Jan 8, 2024
2 parents afe9f08 + 0deb05b commit 252d84b
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 22 deletions.
6 changes: 6 additions & 0 deletions auth/auth_ui/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,9 @@ func prompt(w io.Writer, prompt string, readlnFn func(*os.File) (string, error))
fmt.Fprintln(w, "input cannot be empty")
}
}

func (*CLI) ConfirmationCode(email string) (code int, err error) {
fmt.Printf("Enter confirmation code sent to %s: ", email)
_, err = fmt.Fscanf(os.Stdin, "%d", &code)
return
}
29 changes: 29 additions & 0 deletions auth/auth_ui/huh.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"fmt"
"io"
"regexp"
"strconv"

"github.com/charmbracelet/huh"
)
Expand Down Expand Up @@ -102,3 +104,30 @@ func valSepEaster() func(v int) error {
return nil
}
}

func (*Huh) ConfirmationCode(email string) (int, error) {
var strCode string
q := huh.NewInput().
CharLimit(6).
Title(fmt.Sprintf("Enter confirmation code sent to %s", email)).
Description("Slack did not recognise the browser, and sent a confirmation code. Please enter the confirmation code below.").
Value(&strCode).
Validate(valSixDigits)
if err := q.Run(); err != nil {
return 0, err
}
code, err := strconv.Atoi(strCode)
if err != nil {
return 0, err
}
return code, nil
}

var numChlgRE = regexp.MustCompile(`^\d{6}$`)

func valSixDigits(s string) error {
if numChlgRE.MatchString(s) {
return nil
}
return errors.New("confirmation code must be a sequence of six digits")
}
47 changes: 47 additions & 0 deletions auth/auth_ui/huh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package auth_ui

import "testing"

func Test_valSixDigits(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
"empty",
args{""},
true,
},
{
"too short",
args{"12345"},
true,
},
{
"too long",
args{"1234567"},
true,
},
{
"not a number",
args{"123456a"},
true,
},
{
"valid",
args{"123456"},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := valSixDigits(tt.args.s); (err != nil) != tt.wantErr {
t.Errorf("valSixDigits() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
52 changes: 31 additions & 21 deletions auth/rod.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import (
"fmt"
"io"
"os"
"time"

"github.com/charmbracelet/huh/spinner"
"github.com/rusq/slackauth"
"github.com/rusq/slackdump/v2/auth/auth_ui"
)
Expand All @@ -29,10 +27,9 @@ type browserAuthUIExt interface {
BrowserAuthUI
RequestLoginType(w io.Writer) (int, error)
RequestCreds(w io.Writer, workspace string) (email string, passwd string, err error)
ConfirmationCode(email string) (code int, err error)
}

const expectedLoginDuration = 16 * time.Second

func NewRODAuth(ctx context.Context, opts ...Option) (RodAuth, error) {
r := RodAuth{
opts: options{
Expand Down Expand Up @@ -74,26 +71,10 @@ func NewRODAuth(ctx context.Context, opts ...Option) (RodAuth, error) {
return r, err
}
case auth_ui.LoginEmail:
username, password, err := r.opts.ui.RequestCreds(os.Stdout, r.opts.workspace)
sp, err = headlessFlow(ctx, r.opts.workspace, r.opts.ui)
if err != nil {
return r, err
}
if username == "" {
return r, fmt.Errorf("email cannot be empty")
}
if password == "" {
return r, fmt.Errorf("password cannot be empty")
}
var loginErr error
spin := spinner.New().Title("Logging in...").Action(func() {
sp.Token, sp.Cookie, loginErr = slackauth.Headless(ctx, r.opts.workspace, username, password)
})
if err := spin.Run(); err != nil {
return r, err
}
if loginErr != nil {
return r, loginErr
}
fmt.Fprintln(os.Stderr, "authenticated.")
case auth_ui.LoginCancel:
return r, ErrCancelled
Expand All @@ -103,3 +84,32 @@ func NewRODAuth(ctx context.Context, opts ...Option) (RodAuth, error) {
simpleProvider: sp,
}, nil
}

func headlessFlow(ctx context.Context, workspace string, ui browserAuthUIExt) (sp simpleProvider, err error) {
username, password, err := ui.RequestCreds(os.Stdout, workspace)
if err != nil {
return sp, err
}
if username == "" {
return sp, fmt.Errorf("email cannot be empty")
}
if password == "" {
return sp, fmt.Errorf("password cannot be empty")
}
fmt.Println("Logging in to Slack, depending on your connection speed, it will take 15-30 seconds...")

var loginErr error
sp.Token, sp.Cookie, loginErr = slackauth.Headless(
ctx,
workspace,
username,
password,
slackauth.WithChallengeFunc(ui.ConfirmationCode),
)
if loginErr != nil {
return sp, loginErr
}

fmt.Fprintln(os.Stderr, "authenticated.")
return
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/rusq/dlog v1.4.0
github.com/rusq/osenv/v2 v2.0.1
github.com/rusq/secure v0.0.4
github.com/rusq/slackauth v0.0.5
github.com/rusq/slackauth v0.0.6
github.com/rusq/tracer v1.0.1
github.com/schollz/progressbar/v3 v3.13.0
github.com/slack-go/slack v0.12.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ github.com/rusq/slackauth v0.0.4 h1:AMR0bRTHM7Kg2N14bPWm8bG+J5hXOoLrgiGUmFaBsMU=
github.com/rusq/slackauth v0.0.4/go.mod h1:zb1PJY2+8uEqn0RiWuRjnd+ZFwwfnvA5xrGoooVUgNY=
github.com/rusq/slackauth v0.0.5 h1:qhRkhLa+tS60OGPhzlO/mXbQiWxnzPkoVixqy18n7eI=
github.com/rusq/slackauth v0.0.5/go.mod h1:zb1PJY2+8uEqn0RiWuRjnd+ZFwwfnvA5xrGoooVUgNY=
github.com/rusq/slackauth v0.0.6 h1:vV4kg3lRKV+oiHVAWxyKXa9aoRU4XwT5pSQ0mlo9OSM=
github.com/rusq/slackauth v0.0.6/go.mod h1:zb1PJY2+8uEqn0RiWuRjnd+ZFwwfnvA5xrGoooVUgNY=
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 Down

0 comments on commit 252d84b

Please sign in to comment.