portier

package module
v0.0.0-...-5355067 Latest Latest
Warning

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

Go to latest
Published: Jan 23, 2024 License: MIT Imports: 15 Imported by: 1

README

portier-go

A Portier client library for Go.

Go Reference

Documentation

Overview

Package portier implements a client for the Portier protocol.

The primary interface of this package is the Client, created via NewClient.

Some data storage is needed to implement the protocol. This is used for tracking short-lived login sessions, and caching of basic HTTP GET requests. The Store interface facilitates this, and by default, an in-memory store is used. This will work fine for simple single-process applications, but if you intend to run multiple workers, an alternative Store must be implemented. (In the future, we may offer some alternatives for common databases. Contributions are welcome!)

Some applications may need more than a single Client / Config, for example because they serve multiple domains. In this case, we recommended creating short-lived Clients and sharing the Store between them.

Index

Constants

View Source
const (
	ResponseModeFormPost = "form_post"
	ResponseModeFragment = "fragment"
)

Valid Config.ResponseMode values.

View Source
const (
	DefaultBroker       = "https://broker.portier.io"
	DefaultResponseMode = ResponseModeFormPost
	DefaultLeeway       = time.Duration(3) * time.Minute
	DefaultHTTPTimeout  = time.Duration(10) * time.Second
)

Defaults for Config fields.

Variables

This section is empty.

Functions

func GenerateNonce

func GenerateNonce() string

GenerateNonce returns a hex string of 128-bits secure random data.

This is the default implementation used by a Store.NewNonce to generate nonces (numbers used once). This function panics if the RNG fails.

func SimpleFetch

func SimpleFetch(client *http.Client, url string, data interface{}) (time.Duration, error)

SimpleFetch is a simple http.Client.Get wrapper that also decodes the JSON response and parses the Cache-Control header. The returned Duration is the cache lifespan for storing the result.

This is the default implementation for cache misses in Store.Fetch.

Types

type AuthOption

type AuthOption = option.Interface

AuthOption is the interface for options accepted by StartAuth.

func WithState

func WithState(state string) AuthOption

WithState is used with StartAuth to add arbitrary state to the request, which is returned in the `state` query parameter to the redirect URI.

type Client

type Client interface {
	// StartAuth creates a login session for the given email, and returns a URL
	// to redirect the user agent (browser) to so authentication can continue.
	//
	// If performing the redirect in the HTTP response, the recommended method is
	// to send a 303 HTTP status code with the Location header set to the URL.
	// But other solutions are possible, such as fetching this URL using a
	// request from client-side JavaScript.
	//
	// Use a WithState option to add state to the request, which will be returned
	// as the `state` query parameter to the redirect URI.
	StartAuth(email string, options ...AuthOption) (string, error)

	// Verify takes an id_token and returns a verified email address.
	//
	// The id_token is delivered to the RedirectURI directly by the user agent
	// (browser). It is sent either via a HTTP POST with a form body, or in the
	// URL fragment, depending on Config.ResponseMode. (In the latter case,
	// additional client-side JavaScript is needed, because the URL fragment is
	// not sent to the server.) The default is HTTP POST.
	Verify(tokenStr string) (string, error)
}

Client is used to perform Portier authentication.

Whether a Client is safe for concurrent use by multiple goroutines depends on the Store used. The store is specified in Config in the call to NewClient. If no Store is specified, an in-memory store is created, which is safe for concurrent use.

func NewClient

func NewClient(cfg *Config) (Client, error)

NewClient constructs a Client from a Config.

type Config

type Config struct {
	Store
	Broker       string        // Origin of the broker to use
	RedirectURI  string        // Absolute URL to an app route that calls Verify
	ResponseMode string        // How to call RedirectURI: form_post or fragment
	Leeway       time.Duration // Time offset to allow when validating JWT claims
}

Config is used with NewClient to construct a Client.

The only required field is RedirectURI, which must be set to a route in your application that calls Client.Verify. For other fields, NewClient will fall back to defaults if they are zero.

type InvalidNonce

type InvalidNonce struct{}

InvalidNonce is returned by Store.ConsumeNonce when the nonce/email pair was not found in the store.

func (*InvalidNonce) Error

func (*InvalidNonce) Error() string

type Store

type Store interface {
	// Fetch requests a documents using HTTP GET, and additionally performs JSON
	// decoding and caching.
	//
	// Implementors should honor HTTP cache headers, with a sensibile minimum
	// (and possibly maximum) applied to the cache lifespan. See SimpleFetch for
	// a default fallback implementation that can be used on cache miss.
	//
	// The Client calls this method with the data parameter set to a double
	// pointer to a zero value of the type to unmarshal. The double pointer
	// allows the implementor to return a shared copy, discarding the zero value.
	// If no shared copy is available, the implementor can take ownership of the
	// zero value and fill it using json.Unmarshal.
	Fetch(url string, data interface{}) error

	// NewNonce generates a random nonce and stores the pair nonce/email.
	//
	// Most implementations should use the GenerateNonce helper, but are allowed
	// to use a different implementation to better fit the backing store. The
	// returned string should be in some URL safe format to prevent unnecessary
	// escaping.
	//
	// Implementors should not apply any limits to the amount of active nonces;
	// this is left to the application using the Client.
	NewNonce(email string) (string, error)

	// ConsumeNonce deletes the nonce/email pair if it exists, or returns an
	// InvalidNonce error if it does not. Other errors may be returned as needed.
	ConsumeNonce(nonce string, email string) error
}

Store is the backing store used by Client for two purposes:

- to fetch JSON documents using HTTP GET with additional caching, and

- to generate and manage nonces (numbers used once) used in authentication.

Whether a Store (and thus the Client using it) is safe for concurrent use is left to the implementation.

func NewMemoryStore

func NewMemoryStore(httpClient *http.Client) Store

NewMemoryStore creates a Store that keeps everything in-memory. This is the default Store implementation if a Client is used without explicitely specifying one.

When manually creating a store using this function, it is strongly recommended to configure the http.Client with a timeout. (See DefaultHTTPTimeout)

The in-memory store is safe for concurrent use by multiple goroutines.

Note that the cache in this store only grows. This is fine, because it is assumed the store is only used to periodically refresh a couple of documents of the Portier broker.

Note also that the in-memory store will only work as expected if there is only one application process.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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