slackauth

package module
v1.0.2-custom Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2024 License: MIT Imports: 15 Imported by: 0

README

= Slackauth
:hide-uri-scheme:

Slackauth is an experimental Slack authentication library using
https://github.com/go-rod/rod[Rod] library.

The advantage over the Playwright is that rod utilises 
https://chromedevtools.github.io/devtools-protocol/[CDP], which is faster
and does not require nodejs.  The drawback is that it can't use Firefox.

https://pkg.go.dev/github.com/rusq/slackauth[Go package documentation]

== Types of login

The library implements two types of Login:

1. Interactive
2. Headless

=== Interactive

In the Interactive mode, the browser opens on the address of the Slack
workspace, and user needs to follow the usual authentication flow, it could be
a Email/Password, SSO, Google, etc.

Call the `slackauth.Browser` function to start the Interactive login.  It will
block until the timeout expires or the user does something, i.e. logs in or
closes the page/browser.

The library detects if the user closes the tab with Slack website or the
browser, in this case the function returns an error.  It doesn't track the
website that user is on, so user can navigate away and browse the web, if they
decide so, until the timeout destroys the browser.

==== Example

[source,go]
----
func browserLogin(ctx context.Context) {
	const workspace = "some workspace"
	ctx, cancel := context.WithTimeoutCause(ctx, 180*time.Second, errors.New("user too slow"))
	defer cancel()

	token, cookies, err := slackauth.Browser(ctx, workspace, slackauth.WithNoConsentPrompt())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(token)
	fmt.Println(cookies)
}
----

=== Headless

In the Headless mode, the browser is not visible to the user, and the
authentication flow is automated.  The user needs to provide the workspace,
email and password, and the library will do the rest.

Call the `slackauth.Headless` function to start the Headless login.  It will
block until login succeeds or fails.

There's a special case when Slack does not recognise the browser and asks the
user to enter the confirmation code that was sent on the user's email.  In
this case, Headless calls the provided interactive challenge function (see the
`WithChallengeFunc` option) and waits for the user to enter the code.  After
the user enters the code, it will be passed to the page and the login process
will continue.

There's the fallback challenge function, but it's simple and ugly, so you're
encouraged to provide your own beautiful one.

Overall, headless login looks nicer, but more fragile - it will start failing
should Slack decide to change the login elements.

==== Example

[source,go]
----
func autoLogin(ctx context.Context) {
	ctx, cancel := context.WithTimeoutCause(ctx, 180*time.Second, errors.New("user too slow"))
	defer cancel()

	workspace := envOrScan("AUTH_WORKSPACE", "Enter workspace: ")
	username := envOrScan("EMAIL", "Enter email: ")
	password := envOrScan("PASSWORD", "Enter password: ")

	token, cookies, err := slackauth.Headless(ctx, workspace, username, password, slackauth.WithDebug(), slackauth.WithNoConsentPrompt())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(token)
	fmt.Println(cookies)
}

func envOrScan(env, prompt string) string {
	v := os.Getenv(env)
	if v != "" {
		return v
	}
	for v == "" {
		fmt.Print(prompt)
		fmt.Scanln(&v)
	}
	return v
}
----

== References
- https://pkg.go.dev/github.com/rusq/slackauth[slackauth package documentation]
- https://go-rod.github.io/[Rod documentation]
- https://chromedevtools.github.io/devtools-protocol/1-3/[Chrome DevTools Protocol (stable, 1.3)]

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidCredentials indicates that the credentials were invalid.
	ErrInvalidCredentials = errors.New("invalid credentials")
	// ErrLoginError indicates that some error of unknown nature occurred
	// during login.
	ErrLoginError = errors.New("slack reported an error during login")
	// ErrWorkspaceNotFound indicates that the workspace name was invalid.
	ErrWorkspaceNotFound = errors.New("workspace not found")
)

Functions

func Browser

func Browser(ctx context.Context, workspace string, opt ...Option) (string, []*http.Cookie, error)

Browser initiates a login flow in a browser.

func Headless

func Headless(ctx context.Context, workspace, email, password string, opt ...Option) (string, []*http.Cookie, error)

Headless logs the user in headlessly, without opening the browser UI. It is only suitable for user/email login method, as it does not require any additional user interaction.

func SimpleChallengeFn

func SimpleChallengeFn(email string) (int, error)

SimpleChallengeFn is a simple challenge function that reads a single integer from stdin. It is used as a default challenge function when none is provided.

Types

type ErrBadWorkspace

type ErrBadWorkspace struct {
	Name string
}

ErrBadWorkspace is returned when the workspace name is invalid.

func (ErrBadWorkspace) Error

func (e ErrBadWorkspace) Error() string

type ErrBrowser

type ErrBrowser struct {
	Err      error
	FailedTo string
}

ErrBrowser indicates the error with browser interaction.

func (ErrBrowser) Error

func (e ErrBrowser) Error() string

type Logger

type Logger interface {
	// Debug logs a debug message.
	Debug(msg string, keyvals ...interface{})
}

type Option

type Option func(*options)

func WithChallengeFunc

func WithChallengeFunc(fn func(email string) (code int, err error)) Option

WithChallengeFunc sets the function that is called when slack does not recognise the browser and challenges the user with a code sent to email. All the function has to do is to accept the user input and return the code.

See SimpleChallengeFn(#SimpleChallengeFn) for an example.

func WithCookie

func WithCookie(cookie ...*http.Cookie) Option

WithCookie adds a cookie to the request.

func WithDebug

func WithDebug(b bool) Option

WithDebug enables debug logging.

func WithLogger

func WithLogger(l Logger) Option

func WithNoConsentPrompt

func WithNoConsentPrompt() Option

WithNoConsentPrompt adds a cookie that disables the Cookie Consent banner.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL