Documentation
¶
Index ¶
- Constants
- Variables
- func ParseScope(scope string) ([]string, error)
- func Schema() (string, error)
- type AuthorizationCodeResponse
- type AuthorizationRequest
- type AuthorizationRequestError
- type AuthorizationRequestUpdate
- type AuthorizationResponseType
- type AuthorizationServerMetadata
- type ClientInfo
- func (client *ClientInfo) GQL() string
- func (client *ClientInfo) IsDevClient() bool
- func (client *ClientInfo) IsValid() error
- func (client *ClientInfo) IsValidRedirectURI(uri string) bool
- func (client *ClientInfo) Update(clientUpdate ClientInfoUpdate) *ClientInfo
- func (client *ClientInfo) ValidateScopes(scopes string) error
- type ClientInfoUpdate
- type ClientOption
- type ClientRegistrationError
- type ClientRegistrationRequest
- type ClientType
- type CodeChallengeMethod
- type DatabaseType
- type GrantType
- type OAuthConfig
- type OIDCProviderMetadata
- type Provider
- type ProviderData
- type RequestError
- type RequestErrorDetails
- type Scope
- type SubjectIdentifierType
- type TokenRequest
- type TokenRequestError
- type TokenResponse
- type User
- type UserData
Constants ¶
const AuthorizationCodeLength = 16
AuthorizationCodeLength TODO: Document code size
const ( // LocalhostRedirectURI is a special redirect URI value for local development. Exact matching // is not performed. Instead, any URI with host equal to 'localhost' is accepted. This is to ease // development efforts by not worrying about registering ports. LocalhostRedirectURI string = "localhost" )
const ( // MasterSystemFlag identifies values which are required // for operation of FTAuth. MasterSystemFlag byte = 1 << 7 // 128 )
Variables ¶
var ( // ValidScopeTokenRegex matches valid scope tokens as defined // in [RFC 6749 3.3](https://tools.ietf.org/html/rfc6749#section-3.3) ValidScopeTokenRegex = regexp.MustCompile(`^[\x21\x23-\x5B\x5D-\x7E]+$`) // ErrInvalidScopeFormat means the provided scope does not // conform to the proper format. ErrInvalidScopeFormat = errors.New("invalid scope format") // ErrInvalidScopeTokenFormat means the provided scope token // does not conform to the proper format. ErrInvalidScopeTokenFormat = errors.New("invalid scope token format") // ErrEmptyScope means no scope was provided. ErrEmptyScope = errors.New("empty scope") )
var ( //go:embed gql/fragments/AllAuthorizationRequestInfo.graphql AllAuthorizationRequestInfo string )
GraphQL embeds
var ( //go:embed gql/fragments/AllClientInfo.graphql AllClientInfo string )
GraphQL embeds
var ( //go:embed gql/fragments/AllScopeInfo.graphql AllScopeInfo string )
GraphQL embeds
var ( //go:embed gql/fragments/AllUserInfo.graphql AllUserInfo string )
GraphQL embeds
var ( // ErrInvalidRedirectURI identifies an invalid or missing redirect URI // per [RFC 6749 3.1.2.4](https://tools.ietf.org/html/rfc6749#section-3.1.2.4) ErrInvalidRedirectURI = errors.New("invalid redirect uri") )
var ( // ValidRequestErrorFieldRegex represents the range of characters allowed in // a field of a request error redirect query parameter per // [RFC 6749 4.2.2.1](https://tools.ietf.org/html/rfc6749#section-4.2.2.1) ValidRequestErrorFieldRegex = regexp.MustCompile(`^[\x21\x23-\x5B\x5D-\x7E]+$`) )
Functions ¶
func ParseScope ¶
ParseScope ensures the provided scope string contains a valid list of scope tokens. If so, the list of scope tokens is returned. If not, an error is returned.
Types ¶
type AuthorizationCodeResponse ¶
type AuthorizationCodeResponse struct { // The authorization code of length AuthorizationCodeLength Code string // The state sent by the client with the initial request. // This must be identical to the request state for the // response to be considered valid by the client. State string }
AuthorizationCodeResponse contains the authorization response to the client in response to an authorization code request.
type AuthorizationRequest ¶
type AuthorizationRequest struct { ID string `json:"id"` // The session ID ClientID string `json:"client_id"` Scope []*Scope `json:"scope"` State string `json:"state"` RedirectURI string `json:"redirect_uri"` Code string `json:"code"` Expiry time.Time `json:"expiry"` CodeChallenge string `json:"code_challenge"` CodeChallengeMethod CodeChallengeMethod `json:"code_challenge_method"` UserID string `json:"user_id"` }
AuthorizationRequest holds the request sent to the authorization endpoint.
func (*AuthorizationRequest) GQL ¶
func (request *AuthorizationRequest) GQL() string
GQL returns the GraphQL representation.
func (*AuthorizationRequest) ToUpdate ¶
func (request *AuthorizationRequest) ToUpdate() *AuthorizationRequestUpdate
ToUpdate returns the values to use for an update to an AuthorizationRequest.
type AuthorizationRequestError ¶
type AuthorizationRequestError string
AuthorizationRequestError represents an error during an authorization request.
const ( // AuthorizationRequestErrInvalidRequest means the request is missing a required parameter, includes an // invalid parameter value, includes a parameter more than once, or is otherwise malformed. AuthorizationRequestErrInvalidRequest AuthorizationRequestError = "invalid_request" // using this method. AuthorizationRequestErrUnauthorizedClient AuthorizationRequestError = "unauthorized_client" // AuthorizationRequestErrAccessDenied means the resource owner or authorization server denied the request. AuthorizationRequestErrAccessDenied AuthorizationRequestError = "access_denied" // AuthorizationRequestErrUnsupportedResponseType means the authorization server does not support // obtaining an access token using this method. AuthorizationRequestErrUnsupportedResponseType AuthorizationRequestError = "unsupported_response_type" // AuthorizationRequestErrInvalidScope means the requested scope is invalid, unknown, or malformed. AuthorizationRequestErrInvalidScope AuthorizationRequestError = "invalid_scope" // AuthorizationRequestErrServerError The authorization server encountered an unexpected // condition that prevented it from fulfilling the request. // (This error code is needed because a 500 Internal Server Error HTTP status code // cannot be returned to the client via an HTTP redirect.) AuthorizationRequestErrServerError AuthorizationRequestError = "server_error" // to handle the request due to a temporary overloading or maintenance of the server. // (This error code is needed because a 503 Service Unavailable HTTP status code cannot // be returned to the client via an HTTP redirect.) AuthorizationRequestErrTemporarilyUnavailable AuthorizationRequestError = "temporarily_unavailable" )
func (AuthorizationRequestError) Description ¶
func (err AuthorizationRequestError) Description(details RequestErrorDetails) string
Description returns the optional "error_description" string which assists client developers in debugging error codes by providing additional information.
func (AuthorizationRequestError) IsValid ¶
func (err AuthorizationRequestError) IsValid() bool
IsValid returns true if this error code is valid.
func (AuthorizationRequestError) URI ¶
func (err AuthorizationRequestError) URI() string
URI returns the optional "error_uri" parameter string which provides a URL where client developers can go to get more information about a particular error.
type AuthorizationRequestUpdate ¶
type AuthorizationRequestUpdate struct {
UserID string `json:"user_id"`
}
AuthorizationRequestUpdate holds an update to an AuthorizationRequest.
func (*AuthorizationRequestUpdate) GQL ¶
func (u *AuthorizationRequestUpdate) GQL() string
GQL returns the GraphQL representation.
type AuthorizationResponseType ¶
type AuthorizationResponseType string
AuthorizationResponseType informs the server by which means to respond to an authorization request. RFC6749 supports two core types:
- "code" for requesting an authorization code
- "token" for requesting an access token (implicit grant)
const ( // AuthorizationResponseTypeCode is used with the authorization code flow. AuthorizationResponseTypeCode AuthorizationResponseType = "code" // AuthorizationResponseTypeToken is used with the implicit code flow. // As this has important security implications and is omitted in OAuth 2.1, // we have chosen to deprecate it in FTAuth. AuthorizationResponseTypeToken AuthorizationResponseType = "token" )
func (AuthorizationResponseType) IsValid ¶
func (typ AuthorizationResponseType) IsValid() bool
IsValid returns true if this response type is supported.
type AuthorizationServerMetadata ¶
type AuthorizationServerMetadata struct { Issuer string `json:"issuer"` // Required, the auth server's issuer identifier AuthorizationEndpoint string `json:"authorization_endpoint"` // Required, URL of the auth server's authorization endpoint TokenEndpoint string `json:"token_endpoint"` // Required, URL of the auth server's token endpoint JwksURI string `json:"jwks_uri,omitempty"` // Optional, URL of the auth server's JWK Set document RegistrationEndpoint string `json:"registration_endpoint,omitempty"` // Optional, URL of dynamic client registration endpoint ScopesSupported []string `json:"scopes_supported"` // Recommended, JSON array containing valid "scope" GrantTypesSupported []GrantType `json:"grant_types_supported"` // JSON array containing a list of the OAuth 2.0 grant type values ResponseTypesSupported []AuthorizationResponseType `json:"response_types_supported"` // Required, JSON array containing "response_type" values ResponseModesSupported []string `json:"response_modes_supported"` // JSON array containing a list of the OAuth 2.0 "response_mode" values AuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"` // JSON array containing a list of client authentication methods supported AlgorithmsSupported []jwt.Algorithm `json:"token_endpoint_auth_signing_alg_values_supported"` // JSON array containing a list of the JWS signing algorithms CodeChallengeMethodsSupported []CodeChallengeMethod `json:"code_challenge_methods_supported"` // JSON array of PKCE code challenge methods supported }
AuthorizationServerMetadata holds metadata related to this authorization server which is returned to clients requesting information via RFC 8414: https://tools.ietf.org/html/rfc8414
type ClientInfo ¶
type ClientInfo struct { ID string `json:"id"` // A UUID v4 string which uniquely idenitifes a particular client. Name string `json:"name"` Type ClientType `json:"type"` Secret string `json:"secret,omitempty"` SecretExpiry *time.Time `json:"secret_expires_at,omitempty"` // Required if client_secret is issued. Time at which secret expires or 0 for no expiry. RedirectURIs []string `json:"redirect_uris"` Scopes []*Scope `json:"scopes"` JWKsURI string `json:"jwks_uri,omitempty"` LogoURI string `json:"logo_uri,omitempty"` GrantTypes []GrantType `json:"grant_types"` AccessTokenLife int `json:"access_token_life"` // Lifetime of access token, in seconds RefreshTokenLife int `json:"refresh_token_life"` // Lifetime of refresh token, in seconds Providers []Provider `json:"providers"` }
ClientInfo holds all relevant information about a client.
func NewClient ¶
func NewClient( name string, typ ClientType, redirectUris []string, scopes []*Scope, jwksURI, logoURI string, accessTokenLife, refreshTokenLife int, providers []Provider, ) (*ClientInfo, error)
NewClient creates a new client with the provided values. This is the preferred method for creating a client, since it will populate some required values for you.
func (*ClientInfo) GQL ¶
func (client *ClientInfo) GQL() string
GQL returns the GraphQL representation.
func (*ClientInfo) IsDevClient ¶
func (client *ClientInfo) IsDevClient() bool
IsDevClient returns true if the client permits localhost redirect URIs.
func (*ClientInfo) IsValid ¶
func (client *ClientInfo) IsValid() error
IsValid checks whether the client info has required and valid parameters, returning an error if not.
func (*ClientInfo) IsValidRedirectURI ¶
func (client *ClientInfo) IsValidRedirectURI(uri string) bool
IsValidRedirectURI returns true if the given URI is a localhost URI or matches one of the registered URIs.
func (*ClientInfo) Update ¶
func (client *ClientInfo) Update(clientUpdate ClientInfoUpdate) *ClientInfo
Update creates a new copy of client and updates fields from clientUpdate. If clientUpdate is empty, no new copy is created, and the original instance is returned.
func (*ClientInfo) ValidateScopes ¶
func (client *ClientInfo) ValidateScopes(scopes string) error
ValidateScopes affirms whether the client supports the given scopes.
type ClientInfoUpdate ¶
type ClientInfoUpdate struct { ID string `json:"id"` Name *string `json:"client_name,omitempty"` RedirectURIs *[]string `json:"redirect_uris,omitempty"` Scopes *[]*Scope `json:"scopes,omitempty"` JWKsURI *string `json:"jwks_uri,omitempty"` LogoURI *string `json:"logo_uri,omitempty"` AccessTokenLife *int `json:"access_token_life,omitempty"` RefreshTokenLife *int `json:"refresh_token_life,omitempty"` Providers *[]Provider `json:"providers,omitempty"` }
ClientInfoUpdate holds updateable parameters for ClientInfo.
func (*ClientInfoUpdate) GQL ¶
func (clientUpdate *ClientInfoUpdate) GQL() string
GQL returns the GraphQL representation.
type ClientOption ¶
type ClientOption byte
ClientOption is a bitmask for different client flags.
const ( ClientOptionNone ClientOption = 0 ClientOptionAdmin ClientOption = (1 << iota) // the admin client )
Flags for clients
type ClientRegistrationError ¶
type ClientRegistrationError string
ClientRegistrationError is an error that occurred during the client registration process.
const ( ClientRegistrationErrorInvalidRedirectURI ClientRegistrationError = "invalid_redirect_uri" ClientRegistrationErrorInvalidClientMetadata ClientRegistrationError = "invalid_client_metadata" ClientRegistrationErrorInvalidSoftwareStatement ClientRegistrationError = "invalid_software_statement" ClientRegistrationErrorUnapprovedSoftwareStatement ClientRegistrationError = "unapproved_software_statement" )
Valid client registration errors as defined by RFC 7591.
func (ClientRegistrationError) Description ¶
func (err ClientRegistrationError) Description(invalidParameter string) string
Description returns details about the error that occurred.
type ClientRegistrationRequest ¶
type ClientRegistrationRequest struct { Name string `json:"name"` Type ClientType `json:"type"` RedirectURIs []string `json:"redirect_uris"` Scopes []string `json:"scopes"` }
ClientRegistrationRequest is a dynamic request for a new client with the given properties.
type ClientType ¶
type ClientType string
ClientType identifies the level of confidentiality the client can maintain. For applications that can keep a secret, ClientTypeConfidential is used. For those that can't, like web browser-based apps, ClientTypePublic is used instead.
See RFC 6749 2.1
const ( // ClientTypeConfidential identifies a client that can // keep its credentials confidential. // // Examples typically include servers which have restricted // access to the client credentials, or web apps which // maintain their secrets on a secure server. ClientTypeConfidential ClientType = "confidential" // ClientTypePublic identifies a client that cannot // keep its credentials confidential. // // Examples typically include SPAs and native apps // which cannot store secure information. ClientTypePublic ClientType = "public" )
type CodeChallengeMethod ¶
type CodeChallengeMethod string
CodeChallengeMethod is the type of code challenge used for PKCE
const ( // CodeChallengeMethodSHA256 uses the SHA256 hash of the code challenge. CodeChallengeMethodSHA256 CodeChallengeMethod = "S256" // CodeChallengeMethodPlain uses the plaintext of the code challenge. // Only S256 is supported in FTAuth, although the PKCE RFC supports // this method as well. CodeChallengeMethodPlain CodeChallengeMethod = "plain" )
func (CodeChallengeMethod) IsValid ¶
func (method CodeChallengeMethod) IsValid() bool
IsValid returns whether or not this method is supported.
type DatabaseType ¶
type DatabaseType string
DatabaseType represents the backend for the database.
const ( DatabaseTypePostgres DatabaseType = "postgres" DatabaseTypeOracle DatabaseType = "oracle" )
The different supported database backends.
type GrantType ¶
type GrantType string
GrantType identifies the method by which token exchange will occur with the client.
const ( // GrantTypeAuthorizationCode represents the authorization code flow GrantTypeAuthorizationCode GrantType = "authorization_code" // GrantTypeClientCredentials represents the client credentials flow GrantTypeClientCredentials GrantType = "client_credentials" // GrantTypeRefreshToken uses a refresh token to retrieve an access token. GrantTypeRefreshToken GrantType = "refresh_token" // GrantTypeResourceOwnerPasswordCredentials uses a username/password combo to obtain an // access token. While this was removed from OAuth 2.1 due to its inherent lack of security, // for developers who control both the client and resource server, this provides a more // convenient and customizable means of authenticating users without many of the risks. GrantTypeResourceOwnerPasswordCredentials GrantType = "password" )
type OAuthConfig ¶
type OAuthConfig struct { Provider Provider JWKSet *jwt.KeySet JWKSetURL string *oauth2.Config // contains filtered or unexported fields }
OAuthConfig holds information needed for performing an OAuth flow.
func (*OAuthConfig) DownloadJWKsIfAvailable ¶
func (config *OAuthConfig) DownloadJWKsIfAvailable() error
DownloadJWKsIfAvailable downloads the keyset, if available, and not already downloaded.
type OIDCProviderMetadata ¶
type OIDCProviderMetadata struct { Issuer string `json:"issuer"` // Required, the auth server's issuer identifier AuthorizationEndpoint string `json:"authorization_endpoint"` // Required, URL of the auth server's authorization endpoint TokenEndpoint string `json:"token_endpoint"` // Required, URL of the auth server's token endpoint UserInfoEndpoint string `json:"userinfo_endpoint"` // Recommended, URL of the OP's UserInfo Endpoint JwksURI string `json:"jwks_uri,omitempty"` // Required, URL of the auth server's JWK Set document RegistrationEndpoint string `json:"registration_endpoint,omitempty"` // Recommended, URL of dynamic client registration endpoint ScopesSupported []string `json:"scopes_supported"` // Recommended, JSON array containing valid "scope" GrantTypesSupported []GrantType `json:"grant_types_supported"` // JSON array containing a list of the OAuth 2.0 grant type values ResponseTypesSupported []AuthorizationResponseType `json:"response_types_supported"` // Required, JSON array containing "response_type" values ResponseModesSupported []string `json:"response_modes_supported"` // JSON array containing a list of the OAuth 2.0 "response_mode" values AuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"` // JSON array containing a list of client authentication methods supported AlgorithmsSupported []jwt.Algorithm `json:"token_endpoint_auth_signing_alg_values_supported"` // JSON array containing a list of the JWS signing algorithms CodeChallengeMethodsSupported []CodeChallengeMethod `json:"code_challenge_methods_supported"` // JSON array of PKCE code challenge methods supported IdTokenSigningAlgValuesSupported []jwt.Algorithm `json:"id_token_signing_alg_values_supported"` // Required, JSON array containing a list of the JWS signing algorithms supported for the ID Token SubjectTypesSupported []SubjectIdentifierType `json:"subject_types_supported"` // Required, SON array containing a list of the Subject Identifier types }
type Provider ¶
type Provider string
Provider represents the authentication provider, i.e. Google or Microsoft.
type ProviderData ¶
ProviderData holds provider-specific information
type RequestError ¶
type RequestError interface { IsValid() bool Description(details RequestErrorDetails) string URI() string }
RequestError provides an interface that errors should conform to to ensure that all information is available for the enumerations.
type RequestErrorDetails ¶
RequestErrorDetails holds detailed information about why the request failed. This provides additional debugging information for client developers but is not required per OAuth specs.
type Scope ¶
type Scope struct { ID string `json:"id,omitempty"` Name string `json:"name"` Ruleset string `json:"ruleset,omitempty"` // Set of rules }
Scope identifies an access scope for a client
func ScopesToModel ¶
ScopesToModel converts a string array to Scope model objects.
type SubjectIdentifierType ¶
type SubjectIdentifierType string
const ( SubjectIdentifierTypePublic SubjectIdentifierType = "public" SubjectIdentifierTypePairwise SubjectIdentifierType = "pairwise" )
type TokenRequest ¶
type TokenRequest struct { GrantType GrantType `json:"grant_type"` Code string `json:"code"` RedirectURI string `json:"redirect_uri"` ClientID string `json:"client_id"` CodeVerifier string `json:"code_verifier"` Scope string `json:"scope"` }
TokenRequest holds information for the request of an access token. This request is made through the /token endpoint using an authorization code provided by the /authorize endpoint.
type TokenRequestError ¶
type TokenRequestError string
TokenRequestError represents an error during the token request.
const ( // TokenRequestErrInvalidRequest means he request is missing a required parameter, // includes an unsupported parameter value (other than grant type), repeats a parameter, // includes multiple credentials, utilizes more than one mechanism for authenticating the // client, or is otherwise malformed. TokenRequestErrInvalidRequest TokenRequestError = "invalid_request" // TokenRequestErrInvalidClient means client authentication failed (e.g., unknown client, no // client authentication included, or unsupported authentication method). TokenRequestErrInvalidClient TokenRequestError = "invalid_client" // TokenRequestErrInvalidGrant means the provided authorization grant (e.g. authorization // code) or refresh token is invalid, expired, revoked, does not match the redirection // URI used in the authorization request, or was issued to another client. TokenRequestErrInvalidGrant TokenRequestError = "invalid_grant" // this authorization grant type. TokenRequestErrUnauthorizedClient TokenRequestError = "unauthorized_client" // TokenRequestErrUnsupportedGrantType means the authorization grant type is not supported // by the authorization server. TokenRequestErrUnsupportedGrantType TokenRequestError = "unsupported_grant_type" // TokenRequestErrInvalidScope means the requested scope is invalid, unknown, malformed, // or exceeds the scope granted by the resource owner. TokenRequestErrInvalidScope TokenRequestError = "invalid_scope" // TokenRequestErrInvalidDPoP means the client has provided an invalid DPoP proof TokenRequestErrInvalidDPoP TokenRequestError = "invalid_dpop_proof" )
func (TokenRequestError) Description ¶
func (err TokenRequestError) Description(details RequestErrorDetails) string
Description returns the optional "error_description" string which assists client developers in debugging error codes by providing additional information.
func (TokenRequestError) IsValid ¶
func (err TokenRequestError) IsValid() bool
IsValid returns true if this error code is valid.
func (TokenRequestError) StatusCode ¶
func (err TokenRequestError) StatusCode() int
StatusCode returns the HTTP status code which should be returned for this error. The OAuth protocol allows for only 400 & 401 status codes for error responses.
func (TokenRequestError) URI ¶
func (err TokenRequestError) URI() string
URI returns the optional "error_uri" parameter string which provides a URL where client developers can go to get more information about a particular error.
type TokenResponse ¶
type TokenResponse struct { // The access token AccessToken string `json:"access_token"` // The type of token (always JWT for FTAuth) TokenType string `json:"token_type"` // The refresh token RefreshToken string `json:"refresh_token"` // The life of the token ExpiresIn int `json:"expires_in"` }
TokenResponse contains the access and refresh tokens generated through the implicit flow or token refresh.
type User ¶
type User struct { ID string `json:"id"` // uuid Subject string `json:"sub,omitempty"` ClientID string `json:"client_id"` Username string `json:"username,omitempty"` PasswordHash string `json:"password_hash,omitempty"` FirstName string `json:"first_name,omitempty"` LastName string `json:"last_name,omitempty"` Email string `json:"email,omitempty"` PhoneNumber string `json:"phone_number,omitempty"` Scopes []*Scope `json:"scopes,omitempty"` ProviderData []ProviderData `json:"-"` }
User is a user/resource owner.
func (*User) ToUserData ¶
ToUserData converts a user object to a user data object for sharing.
type UserData ¶
type UserData struct { ID string `json:"id"` // uuid ClientID string `json:"client_id"` Subject string `json:"sub,omitempty"` Username string `json:"username,omitempty"` FirstName string `json:"first_name,omitempty"` LastName string `json:"last_name,omitempty"` Email string `json:"email,omitempty"` PhoneNumber string `json:"phone_number,omitempty"` Scopes []*Scope `json:"scopes,omitempty"` ProviderData []ProviderData `json:"provider_data,omitempty"` }
UserData holds the key user data for sharing externally.