2022-04-02 16:30:55 +02:00
|
|
|
//go:build go1.18
|
2022-05-24 00:44:36 +02:00
|
|
|
// +build go1.18
|
2022-04-02 16:30:55 +02:00
|
|
|
|
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
|
|
|
stdContext "context"
|
|
|
|
|
|
|
|
"github.com/kataras/iris/v12/context"
|
|
|
|
"github.com/kataras/iris/v12/x/errors"
|
|
|
|
|
|
|
|
"github.com/kataras/jwt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// VerifiedToken holds the information about a verified token.
|
|
|
|
type VerifiedToken = jwt.VerifiedToken
|
|
|
|
|
|
|
|
// Provider is an interface of T which MUST be completed
|
|
|
|
// by a custom value type to provide user information to the Auth's
|
|
|
|
// JWT Token Signer and Verifier.
|
|
|
|
//
|
2022-04-02 20:14:46 +02:00
|
|
|
// A provider can optionally complete the Transformer, ClaimsProvider and
|
|
|
|
// ErrorHandler all in once when necessary.
|
|
|
|
// Set a provider using the AddProvider method of Auth type.
|
2022-04-07 00:56:42 +02:00
|
|
|
//
|
|
|
|
// Example can be found at: https://github.com/kataras/iris/tree/master/_examples/auth/auth/user_provider.go.
|
2022-04-02 16:30:55 +02:00
|
|
|
type Provider[T User] interface {
|
|
|
|
// Signin accepts a username (or email) and a password and should
|
|
|
|
// return a valid T value or an error describing
|
|
|
|
// the user authentication or verification reason of failure.
|
|
|
|
//
|
2022-04-07 00:56:42 +02:00
|
|
|
// The first input argument standard context can be
|
|
|
|
// casted to iris.Context if executed through Auth.SigninHandler.
|
|
|
|
//
|
|
|
|
// It's called on Auth.SigninHandler.
|
2022-04-02 16:30:55 +02:00
|
|
|
Signin(ctx stdContext.Context, username, password string) (T, error)
|
|
|
|
|
|
|
|
// ValidateToken accepts the standard JWT claims and the T value obtained
|
|
|
|
// by the Signin method and should return a nil error on validation success
|
|
|
|
// or a non-nil error for validation failure.
|
|
|
|
// It is mostly used to perform checks of the T value's struct fields or
|
|
|
|
// the standard claim's (e.g. origin jwt token id).
|
|
|
|
// It can be an empty method too which returns a nil error.
|
|
|
|
//
|
2022-04-07 00:56:42 +02:00
|
|
|
// The first input argument standard context can be
|
|
|
|
// casted to iris.Context if executed through Auth.VerifyHandler.
|
|
|
|
//
|
2022-04-02 20:14:46 +02:00
|
|
|
// It's caleld on Auth.VerifyHandler.
|
2022-04-02 16:30:55 +02:00
|
|
|
ValidateToken(ctx stdContext.Context, standardClaims StandardClaims, t T) error
|
|
|
|
|
|
|
|
// InvalidateToken is optional and can be used to allow tokens to be invalidated
|
|
|
|
// from server-side. Commonly, implement when a token and user pair is saved
|
|
|
|
// on a persistence storage and server can decide which token is valid or invalid.
|
|
|
|
// It can be an empty method too which returns a nil error.
|
|
|
|
//
|
2022-04-07 00:56:42 +02:00
|
|
|
// The first input argument standard context can be
|
|
|
|
// casted to iris.Context if executed through Auth.SignoutHandler.
|
|
|
|
//
|
2022-04-02 20:14:46 +02:00
|
|
|
// It's called on Auth.SignoutHandler.
|
2022-04-02 16:30:55 +02:00
|
|
|
InvalidateToken(ctx stdContext.Context, standardClaims StandardClaims, t T) error
|
|
|
|
// InvalidateTokens is like InvalidateToken but it should invalidate
|
|
|
|
// all tokens generated for a specific T value.
|
|
|
|
// It can be an empty method too which returns a nil error.
|
|
|
|
//
|
2022-04-07 00:56:42 +02:00
|
|
|
// The first input argument standard context can be
|
|
|
|
// casted to iris.Context if executed through Auth.SignoutAllHandler.
|
|
|
|
//
|
2022-04-02 20:14:46 +02:00
|
|
|
// It's called on Auth.SignoutAllHandler.
|
2022-04-02 16:30:55 +02:00
|
|
|
InvalidateTokens(ctx stdContext.Context, t T) error
|
|
|
|
}
|
|
|
|
|
|
|
|
// ClaimsProvider is an optional interface, which may not be used at all.
|
|
|
|
// If implemented by a Provider, it signs the jwt token
|
|
|
|
// using these claims to each of the following token types.
|
|
|
|
type ClaimsProvider interface {
|
|
|
|
GetAccessTokenClaims() StandardClaims
|
|
|
|
GetRefreshTokenClaims(accessClaims StandardClaims) StandardClaims
|
|
|
|
}
|
|
|
|
|
2022-04-02 20:14:46 +02:00
|
|
|
// Transformer is an optional interface which can be implemented by a Provider as well.
|
|
|
|
// Set a Transformer through Auth.SetTransformer or Auth.SetTransformerFunc or by implementing
|
|
|
|
// the Transform method inside a Provider which can be registered through the Auth.AddProvider
|
|
|
|
// method.
|
|
|
|
//
|
|
|
|
// A transformer is called on Auth.VerifyHandler before Provider.ValidateToken and it can
|
|
|
|
// be used to modify the T value based on the token's contents. It is mostly used
|
|
|
|
// to convert the json claims to T value manually, when they differ.
|
2022-04-07 00:56:42 +02:00
|
|
|
//
|
|
|
|
// The first input argument standard context can be
|
|
|
|
// casted to iris.Context if executed through Auth.VerifyHandler.
|
2022-04-02 16:30:55 +02:00
|
|
|
type Transformer[T User] interface {
|
|
|
|
Transform(ctx stdContext.Context, tok *VerifiedToken) (T, error)
|
|
|
|
}
|
|
|
|
|
2022-04-02 20:14:46 +02:00
|
|
|
// TransformerFunc completes the Transformer interface.
|
2022-04-02 16:30:55 +02:00
|
|
|
type TransformerFunc[T User] func(ctx stdContext.Context, tok *VerifiedToken) (T, error)
|
|
|
|
|
2022-04-02 20:14:46 +02:00
|
|
|
// Transform calls itself.
|
2022-04-02 16:30:55 +02:00
|
|
|
func (fn TransformerFunc[T]) Transform(ctx stdContext.Context, tok *VerifiedToken) (T, error) {
|
|
|
|
return fn(ctx, tok)
|
|
|
|
}
|
|
|
|
|
2022-04-02 20:14:46 +02:00
|
|
|
// ErrorHandler is an optional interface which can be implemented by a Provider as well.
|
|
|
|
//
|
|
|
|
// ErrorHandler is the interface which controls the HTTP errors on
|
|
|
|
// Auth.SigninHandler, Auth.VerifyHandler, Auth.SignoutHandler and
|
|
|
|
// Auth.SignoutAllHandler handelrs.
|
2022-04-02 16:30:55 +02:00
|
|
|
type ErrorHandler interface {
|
2022-04-02 20:14:46 +02:00
|
|
|
// InvalidArgument should handle any 400 (bad request) errors,
|
|
|
|
// e.g. invalid request body.
|
2022-04-02 16:30:55 +02:00
|
|
|
InvalidArgument(ctx *context.Context, err error)
|
2022-04-02 20:14:46 +02:00
|
|
|
// Unauthenticated should handle any 401 (unauthenticated) errors,
|
|
|
|
// e.g. user not found or invalid credentials.
|
2022-04-02 16:30:55 +02:00
|
|
|
Unauthenticated(ctx *context.Context, err error)
|
|
|
|
}
|
|
|
|
|
2022-04-02 20:14:46 +02:00
|
|
|
// DefaultErrorHandler is the default registered ErrorHandler which can be
|
|
|
|
// replaced through the Auth.SetErrorHandler method.
|
2022-04-02 16:30:55 +02:00
|
|
|
type DefaultErrorHandler struct{}
|
|
|
|
|
2022-04-02 20:14:46 +02:00
|
|
|
// InvalidArgument sends 400 (bad request) with "unable to parse body" as its message
|
|
|
|
// and the "err" value as its details.
|
2022-04-02 16:30:55 +02:00
|
|
|
func (e *DefaultErrorHandler) InvalidArgument(ctx *context.Context, err error) {
|
|
|
|
errors.InvalidArgument.Details(ctx, "unable to parse body", err.Error())
|
|
|
|
}
|
|
|
|
|
2022-04-02 20:14:46 +02:00
|
|
|
// Unauthenticated sends 401 (unauthenticated) with the "err" value as its message.
|
2022-04-02 16:30:55 +02:00
|
|
|
func (e *DefaultErrorHandler) Unauthenticated(ctx *context.Context, err error) {
|
|
|
|
errors.Unauthenticated.Err(ctx, err)
|
|
|
|
}
|