auth0cliauthorizer

package module
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2022 License: MIT Imports: 16 Imported by: 0

README

auth0-cli-authorizer

implement the Device Authorization Flow on Auth0 to obtain and manage tokens from your CLI application

Setup

go get github.com/fabiofenoglio/auth0-cli-authorizer
Basic usage

With the default configuration, a call to Authorize() will automatically attempt to open a browser window and prefill with the user code.

package main

import (
	"context"
	"fmt"
	
	authorizer "github.com/fabiofenoglio/auth0-cli-authorizer"
)

func main() {

	auth, _ := authorizer.New(
		"https://<your-domain>.auth0.com", 
		"yourClientID", 
		"https://<your-audience>",
	)

	authorization, _ := auth.Authorize(context.TODO())

	fmt.Println("welcome " + authorization.User.Name + " !")
	// use authorization.Tokens.AccessToken from now on
}
Refresh token example
package main

import (
	"context"
	"encoding/json"
	"fmt"

	authorizer "github.com/fabiofenoglio/auth0-cli-authorizer"
)

func main() {
	// you can customize many options with authorizer.With[...]
	auth, _ := authorizer.New(
		"https://<your-domain>.auth0.com",
		"yourClientID",
		"https://<your-audience>",
		authorizer.WithRequireOfflineAccess(true), // also enabled by default
	)

	authorization, err := auth.Authorize(context.TODO())
	if err != nil {
		panic(err)
	}
	
	// ...
	// later on, if you store the refresh token and you want
	// to fetch a new access token:
	refreshed, _ := auth.Refresh(context.TODO(), authorization.Tokens.RefreshToken)

	pretty, _ := json.MarshalIndent(refreshed, "", "  ")
	fmt.Println(string(pretty))
}
Caching on local filesystem

If you enable a store option (like WithAppDataStore) the token will automatically be saved and restored from a local cache, optionally refreshing it as needed.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	authorizer "github.com/fabiofenoglio/auth0-cli-authorizer"
)

func main() {
	// you can customize many options with authorizer.With[...]
	auth, _ := authorizer.New(
		"https://<your-domain>.auth0.com",
		"yourClientID",
		"https://<your-audience>",
		// will require a refresh_token
		authorizer.WithRequireOfflineAccess(true),
		
		// will cache the token on filesystem
		// and refresh it automatically 
		// if it's expired or expires in less than 5 minutes
		authorizer.WithAppDataStore(5*time.Minute), 
	)

	authorization, err := auth.Authorize(context.TODO())
	if err != nil {
		panic(err)
	}

	// use authorization.Tokens.AccessToken from now on
	// if you run this program again after the first time
	// you will not be prompted for authorization again
	
	pretty, _ := json.MarshalIndent(authorization, "", "  ")
	fmt.Println(string(pretty))
}
Complete example
package main

import (
	"context"
	"encoding/json"
	"time"

	authorizer "github.com/fabiofenoglio/auth0-cli-authorizer"
	"github.com/sirupsen/logrus"
)

func main() {
	// you can pass a custom logger
	logger := logrus.New()
	logger.SetLevel(logrus.DebugLevel)
	logger.SetFormatter(&logrus.TextFormatter{
		DisableColors:   false,
		TimestampFormat: "2006-01-02 15:04:05",
		FullTimestamp:   true,
		PadLevelText:    true,
	})

	// you can customize many options with authorizer.With[...]
	auth, _ := authorizer.New(
		"https://<your-domain>.auth0.com",
		"yourClientID",
		"https://<your-audience>",
		authorizer.WithLogger(logger),
		
		// will require a refresh_token
		authorizer.WithRequireOfflineAccess(true),
		
		// will automatically open the browser if needed,
		// prefilled with the device code
		authorizer.WithAutoOpenBrowser(true),
		authorizer.WithPrefillDeviceCode(true),

		// will cache the token on filesystem
		// and refresh it automatically 
		// if it's expired or expires in less than 5 minutes
		authorizer.WithAppDataStore(5*time.Minute), 
	)

	authorization, err := auth.Authorize(context.TODO())
	if err != nil {
		panic(err)
	}
	// use authorization.Tokens.AccessToken from now on

	pretty, _ := json.MarshalIndent(authorization, "", "  ")
	logger.Info(string(pretty))
	
	// ...
	// if you store the refresh token and you want
	// to fetch a new access token:
	refreshed, _ := auth.Refresh(context.TODO(), authorization.Tokens.RefreshToken)

	pretty, _ = json.MarshalIndent(refreshed, "", "  ")
	logger.Info(string(pretty))
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Authentication

type Authentication struct {
	User   User   `json:"user"`
	Tokens Tokens `json:"tokens"`
}

type Authorizer

type Authorizer interface {
	Authorize(ctx context.Context) (Authentication, error)
	Refresh(ctx context.Context, refreshToken string) (Authentication, error)
	Logout() error
}

type DefaultImpl

type DefaultImpl struct {
	// contains filtered or unexported fields
}

func New

func New(domain, clientID, audience string, options ...Option) (*DefaultImpl, error)

func (*DefaultImpl) Authorize

func (a *DefaultImpl) Authorize(ctx context.Context) (Authentication, error)

func (*DefaultImpl) Logout added in v0.1.4

func (a *DefaultImpl) Logout() error

func (*DefaultImpl) Refresh

func (a *DefaultImpl) Refresh(ctx context.Context, refreshToken string) (Authentication, error)

type DeviceConfirmPrompt

type DeviceConfirmPrompt struct {
	DeviceCode              string `json:"device_code"`
	VerificationUri         string `json:"verification_uri"`
	VerificationUriComplete string `json:"verification_uri_complete"`
	ExpiresIn               int    `json:"expires_in"`
}

type DeviceConfirmPromptCallback

type DeviceConfirmPromptCallback func(DeviceConfirmPrompt) error

type HTTPClientCustomizer

type HTTPClientCustomizer func(c *http.Client)

type Logger

type Logger interface {
	Debug(args ...interface{})
	Info(args ...interface{})
	Warning(args ...interface{})
	Error(args ...interface{})
}

type Option

type Option interface {
	// contains filtered or unexported methods
}

func WithAppDataStore added in v0.1.2

func WithAppDataStore(minDuration time.Duration) Option

func WithAutoOpenBrowser

func WithAutoOpenBrowser(autoOpenBrowser bool) Option

func WithDeviceConfirmPromptCallback

func WithDeviceConfirmPromptCallback(callback DeviceConfirmPromptCallback) Option

func WithHTTPClientCustomizer

func WithHTTPClientCustomizer(customizer HTTPClientCustomizer) Option

func WithLogger

func WithLogger(l Logger) Option

func WithPrefillDeviceCode

func WithPrefillDeviceCode(prefillDeviceCode bool) Option

func WithRequireOfflineAccess

func WithRequireOfflineAccess(requireOfflineAccess bool) Option

type Tokens

type Tokens struct {
	AccessToken  string    `json:"access_token"`
	RefreshToken string    `json:"refresh_token"`
	IdToken      string    `json:"id_token"`
	ExpiresAt    time.Time `json:"expires_at"`
}

type User

type User struct {
	Nickname            string `json:"nickname"`
	Name                string `json:"name"`
	Picture             string `json:"picture"`
	Email               string `json:"email"`
	EmailVerified       bool   `json:"email_verified"`
	Sub                 string `json:"sub"`
	GivenName           string `json:"given_name"`
	FamilyName          string `json:"family_name"`
	MiddleName          string `json:"middle_name"`
	PreferredUsername   string `json:"preferred_username"`
	Profile             string `json:"profile"`
	Website             string `json:"website"`
	Gender              string `json:"gender"`
	Birthdate           string `json:"birthdate"`
	Zoneinfo            string `json:"zoneinfo"`
	Locale              string `json:"locale"`
	PhoneNumber         string `json:"phone_number"`
	PhoneNumberVerified bool   `json:"phone_number_verified"`
	Address             struct {
		Country string `json:"country"`
	} `json:"address"`
	UpdatedAt string `json:"updated_at"`

	Permissions []string `json:"permissions"`
}

Jump to

Keyboard shortcuts

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