Skip to content

Commit

Permalink
tool info auth
Browse files Browse the repository at this point in the history
  • Loading branch information
rusq committed Mar 25, 2024
1 parent 4581132 commit 84ed9b2
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 11 deletions.
12 changes: 6 additions & 6 deletions cmd/slackdump/internal/diag/eztest.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ be printed and the test will be terminated.
CustomFlags: true,
}

type result struct {
type ezResult struct {
Engine string `json:"engine,omitempty"`
HasToken bool `json:"has_token,omitempty"`
HasCookies bool `json:"has_cookies,omitempty"`
Expand Down Expand Up @@ -64,7 +64,7 @@ func runEzLoginTest(ctx context.Context, cmd *base.Command, args []string) error
}

var (
res result
res ezResult
)

if *legacy {
Expand All @@ -90,8 +90,8 @@ func runEzLoginTest(ctx context.Context, cmd *base.Command, args []string) error

}

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

if err := playwright.Install(&playwright.RunOptions{Browsers: []string{"firefox"}}); err != nil {
res.Err = ptr(fmt.Sprintf("playwright installation error: %s", err))
Expand All @@ -117,8 +117,8 @@ func ptr[T any](t T) *T {
return &t
}

func tryRodAuth(ctx context.Context, wsp string) result {
ret := result{Engine: "rod"}
func tryRodAuth(ctx context.Context, wsp string) ezResult {
ret := ezResult{Engine: "rod"}
prov, err := auth.NewRODAuth(ctx, auth.BrowserWithWorkspace(wsp))
if err != nil {
ret.Err = ptr(err.Error())
Expand Down
27 changes: 26 additions & 1 deletion cmd/slackdump/internal/diag/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package diag
import (
"context"
"encoding/json"
"io"
"os"

"github.com/rusq/slackdump/v3/cmd/slackdump/internal/diag/info"
Expand All @@ -14,14 +15,38 @@ var CmdInfo = &base.Command{
UsageLine: "slackdump tools info",
Short: "show information about Slackdump environment",
Run: runInfo,

Long: `# Info Command
**Info** shows information about Slackdump environment, such as local system paths, etc.
`,
}

var infoParams = struct {
auth bool
}{
auth: false,
}

func init() {
CmdInfo.Flag.BoolVar(&infoParams.auth, "auth", false, "show authentication diagnostic information")
}

func runInfo(ctx context.Context, cmd *base.Command, args []string) error {
enc := json.NewEncoder(os.Stdout)
switch {
case infoParams.auth:
return runAuthInfo(ctx, os.Stdout)
default:
return runGeneralInfo(ctx, os.Stdout)
}
}

func runAuthInfo(ctx context.Context, w io.Writer) error {
return info.CollectAuth(ctx, w)
}

func runGeneralInfo(_ context.Context, w io.Writer) error {
enc := json.NewEncoder(w)
enc.SetIndent("", " ")
if err := enc.Encode(info.Collect()); err != nil {
return err
Expand Down
62 changes: 62 additions & 0 deletions cmd/slackdump/internal/diag/info/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package info

import (
"context"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"text/tabwriter"

"github.com/rusq/encio"
"github.com/rusq/slackdump/v3/auth"
"github.com/rusq/slackdump/v3/cmd/slackdump/internal/cfg"
"github.com/rusq/slackdump/v3/internal/cache"
)

func CollectAuth(ctx context.Context, w io.Writer) error {
// lg := logger.FromContext(ctx)
fmt.Fprintln(os.Stderr, "To confirm the operation, please enter your OS password.")
if err := osValidateUser(ctx, os.Stderr); err != nil {
return err
}
m, err := cache.NewManager(cfg.CacheDir())
if err != nil {
return fmt.Errorf("cache error: %w", err)
}
cur, err := m.Current()
if err != nil {
return fmt.Errorf("cache error: %w", err)
}
fi, err := m.FileInfo(cur)
if err != nil {
return fmt.Errorf("cache error: %w", err)
}
f, err := encio.Open(filepath.Join(cfg.CacheDir(), fi.Name()))
if err != nil {
return fmt.Errorf("cache error: %w", err)
}
defer f.Close()
prov, err := auth.Load(f)
if err != nil {
return fmt.Errorf("cache error: %w", err)
}
if err := dumpCookiesMozilla(ctx, w, prov.Cookies()); err != nil {
return err
}
return nil
}

// dumpCookiesMozilla dumps cookies in Mozilla format.
func dumpCookiesMozilla(_ context.Context, w io.Writer, cookies []*http.Cookie) error {
tw := tabwriter.NewWriter(w, 0, 8, 0, '\t', 0)
defer tw.Flush()
fmt.Fprintf(tw, "# name@domain\tvalue_len\tflag\tpath\tsecure\texpiration\n")
for _, c := range cookies {
fmt.Fprintf(tw, "%s\t%9d\t%s\t%s\t%s\t%d\n",
c.Name+"@"+c.Domain, len(c.Value), "TRUE", c.Path, strings.ToUpper(fmt.Sprintf("%v", c.Secure)), c.Expires.Unix())
}
return nil
}
23 changes: 23 additions & 0 deletions cmd/slackdump/internal/diag/info/auth_posix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build !windows

package info

import (
"context"
"fmt"
"io"
"os"
"os/exec"
)

func osValidateUser(ctx context.Context, w io.Writer) error {
cmd := exec.CommandContext(ctx, "sudo", "-v")
cmd.Stdin = os.Stdin
cmd.Stdout = w
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return fmt.Errorf("authentication failed: %w", err)
}
return nil
}
63 changes: 63 additions & 0 deletions cmd/slackdump/internal/diag/info/auth_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//go:build windows

package info

import (
"context"
"fmt"
"io"
"syscall"
"unsafe"

"golang.org/x/term"
)

var (
advapi32 = syscall.NewLazyDLL("advapi32.dll")
procLogonUserW = advapi32.NewProc("LogonUserW")
)

func must[T any](t T, err error) T {
if err != nil {
panic(err)
}
return t
}

// Untested
func logonUser(username, domain, password string) (bool, error) {
var token syscall.Handle
r1, _, err := procLogonUserW.Call(
uintptr(unsafe.Pointer(must(syscall.UTF16PtrFromString(username)))),
uintptr(unsafe.Pointer(must(syscall.UTF16PtrFromString(domain)))),
uintptr(unsafe.Pointer(must(syscall.UTF16PtrFromString(password)))),
uintptr(2), // LOGON32_LOGON_INTERACTIVE
uintptr(0), // LOGON32_PROVIDER_DEFAULT
uintptr(unsafe.Pointer(&token)),
)
if r1 == 0 {
return false, err
}
defer syscall.CloseHandle(token)
return true, nil
}

func osValidateUser(_ context.Context, w io.Writer) error {
fmt.Fprint(w, "Enter username: ")
var username string
fmt.Scanln(&username)
fmt.Fprintf(w, "Enter password for %s: ", username)
password, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return fmt.Errorf("failed to read password: %w", err)
}
domain := "." // Use "." for local account
ok, err := logonUser(username, domain, string(password))
if err != nil {
return fmt.Errorf("authentication error: %w", err)
}
if !ok {
return fmt.Errorf("authentication failed")
}
return nil
}
6 changes: 3 additions & 3 deletions cmd/slackdump/internal/diag/rawoutput.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ Running this tool may be requested by developers.
Commands: nil,
}

type params struct {
type rawOutputParams struct {
output string

idOrURL string
}

var p params
var p rawOutputParams

func init() {
CmdRawOutput.Run = runRawOutput
Expand All @@ -74,7 +74,7 @@ const (
baseURL = domain + "/api/"
)

func run(ctx context.Context, p params) error {
func run(ctx context.Context, p rawOutputParams) error {
prov, err := auth.FromContext(ctx)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/rusq/fsadapter v1.0.1
github.com/rusq/osenv/v2 v2.0.1
github.com/rusq/slack v0.9.6-0.20240211120639-93c163940e55
github.com/rusq/slackauth v0.0.8
github.com/rusq/slackauth v0.1.1
github.com/rusq/tracer v1.0.1
github.com/schollz/progressbar/v3 v3.13.0
github.com/stretchr/testify v1.8.4
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/slack v0.9.6-0.20240211120639-93c163940e55 h1:JdOHVL0ES/T5bvEFmE
github.com/rusq/slack v0.9.6-0.20240211120639-93c163940e55/go.mod h1:9O0zQAFN6W47z4KpTQbe6vOHOzBO76vMg1+gthPwaTI=
github.com/rusq/slackauth v0.0.8 h1:qJVnEsfXeqQ32WsQUqigBA1yWJEOf1029/2at98qVog=
github.com/rusq/slackauth v0.0.8/go.mod h1:4fDQ7VFncP2F1k/oHPXCOjIVw//IkoJcu1Ho3tgxVi8=
github.com/rusq/slackauth v0.1.1 h1:nTAjZQ6UHoGzfV02IQQUyUrAR0JeEqfy6snD7D6cMzk=
github.com/rusq/slackauth v0.1.1/go.mod h1:0fWxVftSfAgULWCcflvy4q20/qY39aB8v0jLDaDLejM=
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 84ed9b2

Please sign in to comment.