auth

package
v1.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package auth holds the provider table and account auto-detection.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrOAuthNotConfigured: the provider has no OAuth client ID in this build.
	ErrOAuthNotConfigured = errors.New("oauth: no client ID is configured for this provider")
	ErrRedirectPortBusy   = errors.New("oauth: the sign-in's callback port is already in use")
	// ErrFlowExpired: the user did not finish signing in within FlowTimeout.
	ErrFlowExpired = errors.New("oauth: sign-in timed out")
	// ErrInvalidGrant: the token endpoint answered invalid_grant (revoked, expired or used).
	ErrInvalidGrant = errors.New("oauth: the authorization is no longer valid")
)
View Source
var ErrAccessDenied = errors.New("oauth: access was denied at the provider")

ErrAccessDenied: the user declined at the provider.

View Source
var ErrScopeMissing = errors.New("oauth: the sign-in did not grant the access this app needs")

ErrScopeMissing: the token response did not include the required scope.

View Source
var FlowTimeout = 10 * time.Minute

FlowTimeout bounds an authorization flow from StartFlow to the callback.

View Source
var MicrosoftClientID = "13d71f3b-e47d-4cf4-a28d-25f01bae45d4"

MicrosoftClientID is Godwit's public client in Microsoft Entra (no secret; PKCE with a loopback redirect). It is read when the outlook provider is built.

Functions

func Detect

func Detect(ctx context.Context, r Resolver, email string) (Provider, Source, error)

Detect finds the provider for email: domain table, then MX, then SRV, then a guess. DNS errors fall through; only a malformed address is an error.

Types

type DeviceFlow added in v1.1.0

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

DeviceFlow is one RFC 8628 device-authorization flow, polling the token endpoint while the user approves the code in a browser.

func StartDevice added in v1.1.0

func StartDevice(ctx context.Context, cfg OAuthConfig, hc *http.Client) (*DeviceFlow, error)

StartDevice requests a device code at cfg.DeviceURL and starts polling cfg.TokenURL in the background.

func (*DeviceFlow) AuthURL added in v1.1.0

func (f *DeviceFlow) AuthURL() string

AuthURL is the verification URL (verification_uri_complete when given, else verification_uri).

func (*DeviceFlow) Close added in v1.1.0

func (f *DeviceFlow) Close()

Close cancels polling; a pending Wait returns context.Canceled.

func (*DeviceFlow) UserCode added in v1.1.0

func (f *DeviceFlow) UserCode() string

UserCode is the short code shown to the user.

func (*DeviceFlow) Wait added in v1.1.0

func (f *DeviceFlow) Wait(ctx context.Context) (Grant, error)

Wait blocks until the device flow finishes or ctx is done, then closes the flow.

type Flow

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

Flow is one authorization-code flow with PKCE, waiting for the browser on a loopback listener.

func StartFlow

func StartFlow(cfg OAuthConfig, loginHint string, hc *http.Client) (*Flow, error)

StartFlow listens on 127.0.0.1 for the redirect and builds the authorization URL. The listener closes when the flow ends: callback handled, Wait's ctx done, FlowTimeout passed or Close.

func (*Flow) AuthURL

func (f *Flow) AuthURL() string

AuthURL is the address to open in the user's browser.

func (*Flow) Close

func (f *Flow) Close()

Close ends the flow (a pending Wait returns context.Canceled) and releases the listener.

func (*Flow) Wait

func (f *Flow) Wait(ctx context.Context) (Grant, error)

Wait returns the grant once the browser came back and the code was exchanged, or the flow's error. The listener is closed when it returns.

type Grant

type Grant struct {
	Email, RefreshToken, AccessToken string
	Expiry                           time.Time
	ClientID, Scope                  string // ClientID is only set for DynamicClient flows
}

Grant is the outcome of an authorization or a refresh. Secrets: never log it. Expiry is never zero: without expires_in it is 30 minutes after receipt.

func Refresh

func Refresh(ctx context.Context, cfg OAuthConfig, hc *http.Client, refreshToken string) (Grant, error)

Refresh trades refreshToken for a new access token. Grant.RefreshToken is "" unless the server rotated it; Grant.Email is "" without an id_token.

func RefreshForm added in v1.1.0

func RefreshForm(ctx context.Context, cfg OAuthConfig, hc *http.Client, refreshToken string) (Grant, error)

RefreshForm trades refreshToken for a new access token with a form POST that includes cfg.TokenParams. Grant.RefreshToken is "" unless the server rotated it.

type OAuthConfig

type OAuthConfig struct {
	ClientID, AuthURL, TokenURL string
	Scopes                      []string
	RedirectHost, RedirectPath  string            // "" = "localhost", "/callback"
	RedirectPort                int               // 0 = any free port; a client registered with one fixed port needs it
	AuthParams, TokenParams     map[string]string // extra authorize / token & refresh parameters
	DynamicClient               bool              // callback carries client_id; use it afterwards
	NoPrompt                    bool              // omit prompt=select_account
	Nonce                       bool              // send a random nonce on authorize
	RequireScope                string            // non-empty: token response scope must include it
	DeviceURL                   string            // non-empty: device-code flow
}

OAuthConfig describes a provider's OAuth 2.0 endpoints (flow lives elsewhere).

type Provider

type Provider struct {
	ID, Name   string
	Domains    []string
	IMAP, SMTP Server
	Login      string // app_password | authorization_code | client_password | password | oauth
	HelpURL    string
	OAuth      *OAuthConfig
}

func ByID

func ByID(id string) (Provider, bool)

func ListProviders

func ListProviders() []Provider

ListProviders returns the known providers in display order (no "other").

type Resolver

type Resolver interface {
	LookupMX(ctx context.Context, name string) ([]*net.MX, error)
	LookupSRV(ctx context.Context, service, proto, name string) (string, []*net.SRV, error)
}

Resolver is satisfied by *net.Resolver.

type Server

type Server struct {
	Host     string
	Port     int
	Security conn.Security
}

type Source

type Source string
const (
	SourceDomain Source = "domain"
	SourceMX     Source = "mx"
	SourceSRV    Source = "srv"
	SourceGuess  Source = "guess"
)

Jump to

Keyboard shortcuts

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