Documentation
¶
Index ¶
- Constants
- Variables
- func AuthMiddleware(cfg MiddlewareConfig) heligo.Middleware
- func DeferPreparation(next heligo.Handler) heligo.Handler
- func GenerateToken(role, secret string, expiry ...time.Duration) (string, error)
- func IsAuthenticated(w http.ResponseWriter) bool
- func LimitBody(w http.ResponseWriter, body io.ReadCloser, max int64) io.ReadCloser
- func Middleware(cfg MiddlewareConfig, forceDBE bool, getDBName GetDatabaseNameFn) heligo.Middleware
- func WithAuthenticated(w http.ResponseWriter, authenticated bool) http.ResponseWriter
- type Claims
- type Error
- type ErrorWriter
- type GetDatabaseNameFn
- type JWTConfig
- type JWTError
- type JWTVerifier
- type MiddlewareConfig
- type RoleClaimKey
- type Session
- type SessionList
- type SessionManager
- type SessionStatistics
Constants ¶
const DefaultMaxSessions = 10000
DefaultMaxSessions bounds the session map when no MaxSessions is configured
const DefaultRoleClaimKey = "$.role"
DefaultRoleClaimKey is PostgREST's default jwt-role-claim-key.
Variables ¶
var ErrJWTExpired = claimsError("JWT expired")
ErrJWTExpired is the claims error of an expired token.
var ErrJWTSecretMissing = errors.New("bearer token refused: no JWTSecret is configured")
ErrJWTSecretMissing refuses a bearer token when no key is configured: with no secret (possible when LoginMode is "none") a token would be verified against the empty HMAC key, which anyone can sign with.
Functions ¶
func AuthMiddleware ¶ added in v0.10.2
func AuthMiddleware(cfg MiddlewareConfig) heligo.Middleware
AuthMiddleware authenticates a request like Middleware — the same token verification and anonymous-access rules — but takes no session and no database connection. It is for routes that never touch the database, such as POST /jq: under Middleware each call would hold a pool connection, with its SET ROLE, for a handler that does not use it.
func DeferPreparation ¶ added in v0.11.0
DeferPreparation marks the routes whose handlers reach the database through the query executor (records and functions): Middleware lets the role, the claims and the access mode of their requests travel with their first statement instead of applying them up front (see database.PrepareRequest). It goes before Middleware.
func GenerateToken ¶
GenerateToken creates a signed JWT for the given role. If expiry > 0, the token will include exp and iat claims. If expiry == 0, the token has no expiration (for testing or long-lived tokens).
func IsAuthenticated ¶ added in v0.11.0
func IsAuthenticated(w http.ResponseWriter) bool
IsAuthenticated reports whether w was marked by WithAuthenticated, here or below the writers that wrap it.
func LimitBody ¶ added in v0.8.3
func LimitBody(w http.ResponseWriter, body io.ReadCloser, max int64) io.ReadCloser
LimitBody caps the request body at max bytes. A non-positive max means unlimited, as RequestMaxBytes documents: MaxBytesReader(0) would instead fail on the first byte and block every request with a body.
func Middleware ¶
func Middleware(cfg MiddlewareConfig, forceDBE bool, getDBName GetDatabaseNameFn) heligo.Middleware
func WithAuthenticated ¶ added in v0.11.0
func WithAuthenticated(w http.ResponseWriter, authenticated bool) http.ResponseWriter
WithAuthenticated marks w as the response of an authenticated request, or returns it as it is.
Types ¶
type Claims ¶
type Claims struct {
Role string `json:"role"`
Id string `json:"id"`
jwt.RegisteredClaims
RawClaims string `json:"-"`
// contains filtered or unexported fields
}
type Error ¶ added in v0.11.0
type Error struct {
Status int
// Code is PostgREST's code for the refusal (PGRST301, ...), "" for none
Code string
Message string
// Challenge is the WWW-Authenticate value of a 401, "" for none
Challenge string
// Details are reported when errors are verbose, else the cause's message
Details string
// Err is the cause
Err error
}
Error is a refusal the middleware decides itself, before the database has a say: a missing or invalid token, an unknown database, a pool that hands out no connection. The errors the database raises while the request is prepared (the role switch) travel as they are, and get the status of every other database error.
type ErrorWriter ¶ added in v0.11.0
ErrorWriter writes the response of a request the middleware refuses. authenticated says whether the request runs as a role other than the anonymous one, which decides the status of an insufficient privilege.
type JWTConfig ¶ added in v0.11.0
type JWTConfig struct {
Secret string // PostgREST's jwt-secret: a passphrase, a JWK or a JWK set
SecretIsBase64 bool // jwt-secret-is-base64
Aud string // jwt-aud, "" for any audience
RoleClaimKey string // jwt-role-claim-key, "" for "$.role"
Keys string // the key catalog, verifying instead of Secret when set
}
JWTConfig is the JWT part of the server configuration.
type JWTError ¶ added in v0.11.0
JWTError is a token that failed verification: PostgREST's PGRST301 (the token cannot be decoded or no key verifies it) and PGRST303 (its claims are invalid), with the same messages (Error.hs, ErrorBody JwtError). Both are a 401 for an invalid token, the case for which PostgREST answers with WWW-Authenticate: Bearer error="invalid_token", error_description=<Message>. Other authentication errors, such as a missing anonymous role, are not JWTErrors.
type JWTVerifier ¶ added in v0.11.0
type JWTVerifier struct {
// contains filtered or unexported fields
}
JWTVerifier verifies bearer tokens and maps their claims, as PostgREST's Auth/Jwt.hs does.
func NewJWTVerifier ¶ added in v0.11.0
func NewJWTVerifier(cfg JWTConfig) (*JWTVerifier, error)
NewJWTVerifier checks the JWT configuration and builds its verifier.
func (*JWTVerifier) RoleClaimKey ¶ added in v0.11.0
func (v *JWTVerifier) RoleClaimKey() *RoleClaimKey
RoleClaimKey is the parsed role claim key.
func (*JWTVerifier) SigningSecret ¶ added in v0.11.0
func (v *JWTVerifier) SigningSecret() string
SigningSecret is the HMAC key that GenerateToken signs with: the secret, base64-decoded when JWTSecretIsBase64 is set, or the one oct key that verifies HS256 when the secret is a JWK or a JWK set; "" when there is none.
func (*JWTVerifier) SignsWithCatalogKey ¶ added in v0.11.0
func (v *JWTVerifier) SignsWithCatalogKey() bool
SignsWithCatalogKey says whether the tokens signed with SigningSecret, which carry no kid, verify against the JWTKeys catalog: the secret is one of its oct keys.
type MiddlewareConfig ¶
type MiddlewareConfig interface {
GetDatabase(context.Context, string) (*database.Database, error)
JWTVerifier() *JWTVerifier
AllowAnon() bool
AnonRole() string
RequestMaxBytes() int64
SessionManager() *SessionManager
GetLogger() *logging.Logger
// AuthErrorWriter writes the refusals of the middleware the way the API
// writes its errors; nil writes a bare {"error": ...}
AuthErrorWriter() ErrorWriter
}
type RoleClaimKey ¶ added in v0.11.0
type RoleClaimKey struct {
// contains filtered or unexported fields
}
RoleClaimKey locates the role in the JWT claims, PostgREST's jwt-role-claim-key. PostgREST 16 reads it as a JSONPath query (RFC 9535, Config/JSPath.hs, with the aeson-jsonpath library); smoothdb reads the subset that the identity providers need and PostgREST documents and tests: $, .name, ['name'] and ["name"], [index], and one filter on the current element, [?@ == "text"], [?@ != "text"] or [?search(@, "regex")]. A key with any other JSONPath construct is refused at startup, naming it, so that the divergence from PostgREST is never a different role at runtime. A key that does not start with "$" is read with the JSPath DSL of PostgREST 15 and earlier (Config/DeprecatedJSPath.hs), which 16.4 still accepts with a warning.
func ParseRoleClaimKey ¶ added in v0.11.0
func ParseRoleClaimKey(s string) (*RoleClaimKey, error)
ParseRoleClaimKey parses a jwt-role-claim-key value; an empty one is the default.
func (*RoleClaimKey) Deprecated ¶ added in v0.11.0
func (k *RoleClaimKey) Deprecated() bool
Deprecated says whether the key uses the JSPath DSL of PostgREST 15.
func (*RoleClaimKey) String ¶ added in v0.11.0
func (k *RoleClaimKey) String() string
type Session ¶
type Session struct {
Claims *Claims
LastUsedAt time.Time
Db *database.Database
DbConn *database.DbPoolConn
// contains filtered or unexported fields
}
A Session for SmoothDB is the way to cache information about a user and his connection to a database
type SessionList ¶
type SessionList struct {
// contains filtered or unexported fields
}
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages user sessions and monitors them efficiently. When disabled, it simply returns Sessions without managing or monitoring.
func NewSessionManager ¶
func NewSessionManager(logger *logging.Logger, enabled bool, shutdown chan struct{}) *SessionManager
func (*SessionManager) SetMaxSessions ¶ added in v0.8.3
func (sm *SessionManager) SetMaxSessions(n int)
SetMaxSessions bounds the number of stored sessions (non-positive: default)
func (*SessionManager) Statistics ¶
func (sm *SessionManager) Statistics() SessionStatistics