httpmw

package
v2.10.2 Latest Latest
Warning

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

Go to latest
Published: Apr 22, 2024 License: AGPL-3.0 Imports: 46 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Server headers.
	AccessControlAllowOriginHeader      = "Access-Control-Allow-Origin"
	AccessControlAllowCredentialsHeader = "Access-Control-Allow-Credentials"
	AccessControlAllowMethodsHeader     = "Access-Control-Allow-Methods"
	AccessControlAllowHeadersHeader     = "Access-Control-Allow-Headers"
	VaryHeader                          = "Vary"

	// Client headers.
	OriginHeader                      = "Origin"
	AccessControlRequestMethodsHeader = "Access-Control-Request-Methods"
	AccessControlRequestHeadersHeader = "Access-Control-Request-Headers"
)
View Source
const (
	SignedOutErrorMessage = "You are signed out or your session has expired. Please sign in again to continue."
)
View Source
const (
	// WorkspaceProxyAuthTokenHeader is the auth header used for requests from
	// external workspace proxies.
	//
	// The format of an external proxy token is:
	//     <proxy id>:<proxy secret>
	//
	//nolint:gosec
	WorkspaceProxyAuthTokenHeader = "Coder-External-Proxy-Token"
)

Variables

This section is empty.

Functions

func APIKey

func APIKey(r *http.Request) database.APIKey

APIKey returns the API key from the ExtractAPIKey handler.

func APIKeyFromRequest

func APIKeyFromRequest(ctx context.Context, db database.Store, sessionTokenFunc func(r *http.Request) string, r *http.Request) (*database.APIKey, codersdk.Response, bool)

func APIKeyOptional

func APIKeyOptional(r *http.Request) (database.APIKey, bool)

APIKeyOptional may return an API key from the ExtractAPIKey handler.

func APITokenFromRequest

func APITokenFromRequest(r *http.Request) string

APITokenFromRequest returns the api token from the request. Find the session token from: 1: The cookie 2. The coder_session_token query parameter 3. The custom auth header

API tokens for apps are read from workspaceapps/cookies.go.

func AsAuthzSystem

func AsAuthzSystem(mws ...func(http.Handler) http.Handler) func(http.Handler) http.Handler

AsAuthzSystem is a chained handler that temporarily sets the dbauthz context to System for the inner handlers, and resets the context afterwards.

TODO: Refactor the middleware functions to not require this. This is a bit of a kludge for now as some middleware functions require usage as a system user in some cases, but not all cases. To avoid large refactors, we use this middleware to temporarily set the context to a system.

func AttachRequestID

func AttachRequestID(next http.Handler) http.Handler

AttachRequestID adds a request ID to each HTTP request.

func CSPHeaders

func CSPHeaders(websocketHosts func() []string) func(next http.Handler) http.Handler

CSPHeaders returns a middleware that sets the Content-Security-Policy header for coderd. It takes a function that allows adding supported external websocket hosts. This is primarily to support the terminal connecting to a workspace proxy.

func CSRF

func CSRF(secureCookie bool) func(next http.Handler) http.Handler

CSRF is a middleware that verifies that a CSRF token is present in the request for non-GET requests. If enforce is false, then CSRF enforcement is disabled. We still want to include the CSRF middleware because it will set the CSRF cookie.

func Cors

func Cors(allowAll bool, origins ...string) func(next http.Handler) http.Handler

func CustomRedirectToLogin added in v2.5.0

func CustomRedirectToLogin(rw http.ResponseWriter, r *http.Request, redirect string, message string, code int)

CustomRedirectToLogin redirects the user to the login page with the `message` and `redirect` query parameters set, with a provided code

func EnsureXForwardedForHeader

func EnsureXForwardedForHeader(req *http.Request) error

EnsureXForwardedForHeader ensures that the request has an X-Forwarded-For header. It uses the following logic:

  1. If we have a direct connection (remoteAddr == proxyAddr), then set it to remoteAddr
  2. If we have a proxied connection (remoteAddr != proxyAddr) and X-Forwarded-For doesn't begin with remoteAddr, then overwrite it with remoteAddr,proxyAddr
  3. If we have a proxied connection (remoteAddr != proxyAddr) and X-Forwarded-For begins with remoteAddr, then append proxyAddr to the original X-Forwarded-For header
  4. If X-Forwarded-Proto is not set, then it will be set to "https" if req.TLS != nil, otherwise it will be set to "http"

func ExternalAuthParam added in v2.2.1

func ExternalAuthParam(r *http.Request) *externalauth.Config

func ExtractAPIKey

ExtractAPIKey requires authentication using a valid API key. It handles extending an API key if it comes close to expiry, updating the last used time in the database.

If the configuration specifies that the API key is optional, a nil API key and authz object may be returned. False is returned if a response was written to the request and the caller should give up. nolint:revive

func ExtractAPIKeyMW

func ExtractAPIKeyMW(cfg ExtractAPIKeyConfig) func(http.Handler) http.Handler

ExtractAPIKeyMW calls ExtractAPIKey with the given config on each request, storing the result in the request context.

func ExtractExternalAuthParam added in v2.2.1

func ExtractExternalAuthParam(configs []*externalauth.Config) func(next http.Handler) http.Handler

func ExtractGroupByNameParam

func ExtractGroupByNameParam(db database.Store) func(http.Handler) http.Handler

func ExtractGroupParam

func ExtractGroupParam(db database.Store) func(http.Handler) http.Handler

ExtraGroupParam grabs a group from the "group" URL parameter.

func ExtractOAuth2

func ExtractOAuth2(config promoauth.OAuth2Config, client *http.Client, authURLOpts map[string]string) func(http.Handler) http.Handler

ExtractOAuth2 is a middleware for automatically redirecting to OAuth URLs, and handling the exchange inbound. Any route that does not have a "code" URL parameter will be redirected. AuthURLOpts are passed to the AuthCodeURL function. If this is nil, the default option oauth2.AccessTypeOffline will be used.

func ExtractOAuth2ProviderApp added in v2.6.0

func ExtractOAuth2ProviderApp(db database.Store) func(http.Handler) http.Handler

ExtractOAuth2ProviderApp grabs an OAuth2 app from the "app" URL parameter. This middleware requires the API key middleware higher in the call stack for authentication.

func ExtractOAuth2ProviderAppSecret added in v2.6.0

func ExtractOAuth2ProviderAppSecret(db database.Store) func(http.Handler) http.Handler

ExtractOAuth2ProviderAppSecret grabs an OAuth2 app secret from the "app" and "secret" URL parameters. This middleware requires the ExtractOAuth2ProviderApp middleware higher in the stack

func ExtractOrganizationMemberParam

func ExtractOrganizationMemberParam(db database.Store) func(http.Handler) http.Handler

ExtractOrganizationMemberParam grabs a user membership from the "organization" and "user" URL parameter. This middleware requires the ExtractUser and ExtractOrganization middleware higher in the stack

func ExtractOrganizationParam

func ExtractOrganizationParam(db database.Store) func(http.Handler) http.Handler

ExtractOrganizationParam grabs an organization from the "organization" URL parameter. This middleware requires the API key middleware higher in the call stack for authentication.

func ExtractProvisionerDaemonAuthenticated added in v2.9.0

func ExtractProvisionerDaemonAuthenticated(opts ExtractProvisionerAuthConfig, psk string) func(next http.Handler) http.Handler

func ExtractRealIP

func ExtractRealIP(config *RealIPConfig) func(next http.Handler) http.Handler

ExtractRealIP is a middleware that uses headers from reverse proxies to propagate origin IP address information, when configured to do so.

func ExtractRealIPAddress

func ExtractRealIPAddress(config *RealIPConfig, req *http.Request) (net.IP, error)

ExtractRealIPAddress returns the original client address according to the configuration and headers. It does not mutate the original request.

func ExtractTemplateParam

func ExtractTemplateParam(db database.Store) func(http.Handler) http.Handler

ExtractTemplateParam grabs a template from the "template" URL parameter.

func ExtractTemplateVersionParam

func ExtractTemplateVersionParam(db database.Store) func(http.Handler) http.Handler

ExtractTemplateVersionParam grabs template version from the "templateversion" URL parameter.

func ExtractUserParam

func ExtractUserParam(db database.Store) func(http.Handler) http.Handler

ExtractUserParam extracts a user from an ID/username in the {user} URL parameter.

func ExtractWorkspaceAgentAndLatestBuild added in v2.10.0

func ExtractWorkspaceAgentAndLatestBuild(opts ExtractWorkspaceAgentAndLatestBuildConfig) func(http.Handler) http.Handler

ExtractWorkspaceAgentAndLatestBuild requires authentication using a valid agent token.

func ExtractWorkspaceAgentParam

func ExtractWorkspaceAgentParam(db database.Store) func(http.Handler) http.Handler

ExtractWorkspaceAgentParam grabs a workspace agent from the "workspaceagent" URL parameter.

func ExtractWorkspaceAndAgentParam

func ExtractWorkspaceAndAgentParam(db database.Store) func(http.Handler) http.Handler

ExtractWorkspaceAndAgentParam grabs a workspace and an agent from the "workspace_and_agent" URL parameter. `ExtractUserParam` must be called before this. This can be in the form of:

  • "<workspace-name>.[workspace-agent]" : If multiple agents exist
  • "<workspace-name>" : If one agent exists

func ExtractWorkspaceBuildParam

func ExtractWorkspaceBuildParam(db database.Store) func(http.Handler) http.Handler

ExtractWorkspaceBuildParam grabs workspace build from the "workspacebuild" URL parameter.

func ExtractWorkspaceParam

func ExtractWorkspaceParam(db database.Store) func(http.Handler) http.Handler

ExtractWorkspaceParam grabs a workspace from the "workspace" URL parameter.

func ExtractWorkspaceProxy

func ExtractWorkspaceProxy(opts ExtractWorkspaceProxyConfig) func(http.Handler) http.Handler

ExtractWorkspaceProxy extracts the external workspace proxy from the request using the external proxy auth token header.

func ExtractWorkspaceProxyParam

func ExtractWorkspaceProxyParam(db database.Store, deploymentID string, fetchPrimaryProxy func(ctx context.Context) (database.WorkspaceProxy, error)) func(http.Handler) http.Handler

ExtractWorkspaceProxyParam extracts a workspace proxy from an ID/name in the {workspaceproxy} URL parameter.

func ExtractWorkspaceResourceParam

func ExtractWorkspaceResourceParam(db database.Store) func(http.Handler) http.Handler

ExtractWorkspaceResourceParam grabs a workspace resource from the "provisionerjob" URL parameter.

func FilterUntrustedOriginHeaders

func FilterUntrustedOriginHeaders(config *RealIPConfig, req *http.Request)

FilterUntrustedOriginHeaders removes all known proxy headers from the request for untrusted origins, and ensures that only one copy of each proxy header is set.

func GroupParam

func GroupParam(r *http.Request) database.Group

GroupParam returns the group extracted via the ExtraGroupParam middleware.

func HSTS

func HSTS(next http.Handler, cfg HSTSConfig) http.Handler

HSTS will add the strict-transport-security header if enabled. This header forces a browser to always use https for the domain after it loads https once. Meaning: On first load of product.coder.com, they are redirected to https. On all subsequent loads, the client's local browser forces https. This prevents man in the middle.

This header only makes sense if the app is using tls.

Full header example: Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

func LatestBuild added in v2.10.0

func LatestBuild(r *http.Request) database.WorkspaceBuild

LatestBuild returns the Latest Build from the ExtractLatestBuild handler.

func Logger

func Logger(log slog.Logger) func(next http.Handler) http.Handler

func OAuth2ProviderApp added in v2.6.0

func OAuth2ProviderApp(r *http.Request) database.OAuth2ProviderApp

OAuth2ProviderApp returns the OAuth2 app from the ExtractOAuth2ProviderAppParam handler.

func OAuth2ProviderAppSecret added in v2.6.0

func OAuth2ProviderAppSecret(r *http.Request) database.OAuth2ProviderAppSecret

OAuth2ProviderAppSecret returns the OAuth2 app secret from the ExtractOAuth2ProviderAppSecretParam handler.

func OrganizationParam

func OrganizationParam(r *http.Request) database.Organization

OrganizationParam returns the organization from the ExtractOrganizationParam handler.

func ParseUUIDParam

func ParseUUIDParam(rw http.ResponseWriter, r *http.Request, param string) (uuid.UUID, bool)

ParseUUIDParam consumes a url parameter and parses it as a UUID.

func Prometheus

func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler

func ProvisionerDaemonAuthenticated added in v2.9.0

func ProvisionerDaemonAuthenticated(r *http.Request) bool

func RateLimit

func RateLimit(count int, window time.Duration) func(http.Handler) http.Handler

RateLimit returns a handler that limits requests per-minute based on IP, endpoint, and user ID (if available).

func Recover

func Recover(log slog.Logger) func(h http.Handler) http.Handler

func RedirectToLogin

func RedirectToLogin(rw http.ResponseWriter, r *http.Request, dashboardURL *url.URL, message string)

RedirectToLogin redirects the user to the login page with the `message` and `redirect` query parameters set.

If dashboardURL is nil, the redirect will be relative to the current request's host. If it is not nil, the redirect will be absolute with dashboard url as the host.

func ReportCLITelemetry

func ReportCLITelemetry(log slog.Logger, rep telemetry.Reporter) func(http.Handler) http.Handler

func RequestID

func RequestID(r *http.Request) uuid.UUID

RequestID returns the ID of the request.

func RequireAPIKeyOrProvisionerDaemonAuth added in v2.9.0

func RequireAPIKeyOrProvisionerDaemonAuth() func(http.Handler) http.Handler

RequireAPIKeyOrProvisionerDaemonAuth is middleware that should be inserted after optional ExtractAPIKey and ExtractProvisionerDaemonAuthenticated middlewares to ensure one of the two authentication methods is provided.

If both are provided, an error is returned to avoid misuse.

func RequireAPIKeyOrWorkspaceAgent

func RequireAPIKeyOrWorkspaceAgent() func(http.Handler) http.Handler

RequireAPIKeyOrWorkspaceAgent is middleware that should be inserted after optional ExtractAPIKey and ExtractWorkspaceAgent middlewares to ensure one of the two is provided.

If both are provided an error is returned to avoid misuse.

func RequireAPIKeyOrWorkspaceProxyAuth

func RequireAPIKeyOrWorkspaceProxyAuth() func(http.Handler) http.Handler

RequireAPIKeyOrWorkspaceProxyAuth is middleware that should be inserted after optional ExtractAPIKey and ExtractWorkspaceProxy middlewares to ensure one of the two authentication methods is provided.

If both are provided, an error is returned to avoid misuse.

func RequireExperiment added in v2.9.0

func RequireExperiment(experiments codersdk.Experiments, experiment codersdk.Experiment) func(next http.Handler) http.Handler

func SplitAPIToken

func SplitAPIToken(token string) (id string, secret string, err error)

SplitAPIToken verifies the format of an API key and returns the split ID and secret.

APIKeys are formatted: ${ID}-${SECRET}

func TemplateParam

func TemplateParam(r *http.Request) database.Template

TemplateParam returns the template from the ExtractTemplateParam handler.

func TemplateVersionParam

func TemplateVersionParam(r *http.Request) database.TemplateVersion

TemplateVersionParam returns the template version from the ExtractTemplateVersionParam handler.

func UserAuthorization

func UserAuthorization(r *http.Request) rbac.Subject

UserAuthorization returns the roles and scope used for authorization. Depends on the ExtractAPIKey handler.

func UserAuthorizationOptional

func UserAuthorizationOptional(r *http.Request) (rbac.Subject, bool)

UserAuthorizationOptional may return the roles and scope used for authorization. Depends on the ExtractAPIKey handler.

func UserParam

func UserParam(r *http.Request) database.User

UserParam returns the user from the ExtractUserParam handler.

func WorkspaceAgent

func WorkspaceAgent(r *http.Request) database.WorkspaceAgent

WorkspaceAgent returns the workspace agent from the ExtractAgent handler.

func WorkspaceAgentOptional

func WorkspaceAgentOptional(r *http.Request) (database.WorkspaceAgent, bool)

func WorkspaceAgentParam

func WorkspaceAgentParam(r *http.Request) database.WorkspaceAgent

WorkspaceAgentParam returns the workspace agent from the ExtractWorkspaceAgentParam handler.

func WorkspaceAppCors

func WorkspaceAppCors(regex *regexp.Regexp, app appurl.ApplicationURL) func(next http.Handler) http.Handler

func WorkspaceBuildParam

func WorkspaceBuildParam(r *http.Request) database.WorkspaceBuild

WorkspaceBuildParam returns the workspace build from the ExtractWorkspaceBuildParam handler.

func WorkspaceParam

func WorkspaceParam(r *http.Request) database.Workspace

WorkspaceParam returns the workspace from the ExtractWorkspaceParam handler.

func WorkspaceProxy

func WorkspaceProxy(r *http.Request) database.WorkspaceProxy

WorkspaceProxy returns the workspace proxy from the ExtractWorkspaceProxy middleware.

func WorkspaceProxyOptional

func WorkspaceProxyOptional(r *http.Request) (database.WorkspaceProxy, bool)

WorkspaceProxyOptional may return the workspace proxy from the ExtractWorkspaceProxy middleware.

func WorkspaceProxyParam

func WorkspaceProxyParam(r *http.Request) database.WorkspaceProxy

WorkspaceProxyParam returns the worksace proxy from the ExtractWorkspaceProxyParam handler.

func WorkspaceResourceParam

func WorkspaceResourceParam(r *http.Request) database.WorkspaceResource

ProvisionerJobParam returns the template from the ExtractTemplateParam handler.

Types

type CSPFetchDirective

type CSPFetchDirective string

CSPFetchDirective is the list of all constant fetch directives that can be used/appended to.

type ExtractAPIKeyConfig

type ExtractAPIKeyConfig struct {
	DB                          database.Store
	OAuth2Configs               *OAuth2Configs
	RedirectToLogin             bool
	DisableSessionExpiryRefresh bool

	// Optional governs whether the API key is optional. Use this if you want to
	// allow unauthenticated requests.
	//
	// If true and no session token is provided, nothing will be written to the
	// request context. Use the APIKeyOptional and UserAuthorizationOptional
	// functions to retrieve the API key and authorization instead of the
	// regular ones.
	//
	// If true and the API key is invalid (i.e. deleted, expired), the cookie
	// will be deleted and the request will continue. If the request is not a
	// cookie-based request, the request will be rejected with a 401.
	Optional bool

	// SessionTokenFunc is a custom function that can be used to extract the API
	// key. If nil, the default behavior is used.
	SessionTokenFunc func(r *http.Request) string

	// PostAuthAdditionalHeadersFunc is a function that can be used to add
	// headers to the response after the user has been authenticated.
	//
	// This is originally implemented to send entitlement warning headers after
	// a user is authenticated to prevent additional CLI invocations.
	PostAuthAdditionalHeadersFunc func(a rbac.Subject, header http.Header)
}

type ExtractProvisionerAuthConfig added in v2.9.0

type ExtractProvisionerAuthConfig struct {
	DB       database.Store
	Optional bool
}

type ExtractWorkspaceAgentAndLatestBuildConfig added in v2.10.0

type ExtractWorkspaceAgentAndLatestBuildConfig struct {
	DB database.Store
	// Optional indicates whether the middleware should be optional.  If true, any
	// requests without the a token or with an invalid token will be allowed to
	// continue and no workspace agent will be set on the request context.
	Optional bool
}

type ExtractWorkspaceProxyConfig

type ExtractWorkspaceProxyConfig struct {
	DB database.Store
	// Optional indicates whether the middleware should be optional. If true,
	// any requests without the external proxy auth token header will be
	// allowed to continue and no workspace proxy will be set on the request
	// context.
	Optional bool
}

type HSTSConfig

type HSTSConfig struct {
	// HeaderValue is an empty string if hsts header is disabled.
	HeaderValue string
}

func HSTSConfigOptions

func HSTSConfigOptions(maxAge int, options []string) (HSTSConfig, error)

type OAuth2Configs

type OAuth2Configs struct {
	Github promoauth.OAuth2Config
	OIDC   promoauth.OAuth2Config
}

OAuth2Configs is a collection of configurations for OAuth-based authentication. This should be extended to support other authentication types in the future.

func (*OAuth2Configs) IsZero

func (c *OAuth2Configs) IsZero() bool

type OAuth2State

type OAuth2State struct {
	Token       *oauth2.Token
	Redirect    string
	StateString string
}

func OAuth2

func OAuth2(r *http.Request) OAuth2State

OAuth2 returns the state from an oauth request.

type OrganizationMember added in v2.3.0

type OrganizationMember struct {
	database.OrganizationMember
	Username  string
	AvatarURL string
}

OrganizationMember is the database object plus the Username and Avatar URL. Including these in the middleware is preferable to a join at the SQL layer so that we can keep the autogenerated database types as they are.

func OrganizationMemberParam

func OrganizationMemberParam(r *http.Request) OrganizationMember

OrganizationMemberParam returns the organization membership that allowed the query from the ExtractOrganizationParam handler.

type RealIPConfig

type RealIPConfig struct {
	// TrustedOrigins is a list of networks that will be trusted. If
	// any non-trusted address supplies these headers, they will be
	// ignored.
	TrustedOrigins []*net.IPNet

	// TrustedHeaders lists headers that are trusted for forwarding
	// IP addresses. e.g. "CF-Connecting-IP", "True-Client-IP", etc.
	TrustedHeaders []string
}

RealIPConfig configures the search order for the function, which controls which headers to consider trusted.

func ParseRealIPConfig

func ParseRealIPConfig(headers, origins []string) (*RealIPConfig, error)

ParseRealIPConfig takes a raw string array of headers and origins to produce a config.

type RealIPState

type RealIPState struct {
	// Config is the configuration applied in the middleware. Consider
	// this read-only and do not modify.
	Config *RealIPConfig

	// OriginalRemoteAddr is the original RemoteAddr for the request.
	OriginalRemoteAddr string
}

RealIPState is the original state prior to modification by this middleware, useful for getting information about the connecting client if needed.

func RealIP

func RealIP(ctx context.Context) *RealIPState

FromContext retrieves the state from the given context.Context.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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