apibase

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 28, 2023 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ClaimAccountID               = "id"
	ClaimEmail                   = "email"
	ClaimIssuer                  = "iss"
	ClaimAudience                = "aud"
	ClaimAudienceKeyID           = "akid"
	ClaimEncryptedAudienceSecret = "eas"
	ClaimLegacySecret            = "secret"
)
View Source
const (
	UserIDKey        = "userID"
	ClientSecretKey  = "clientSecret"
	ContextLoggerKey = "logger"
)
View Source
const (
	StatusOK     = "ok"
	StatusError  = "error"
	StatusFailed = "failed"
)

Variables

View Source
var (
	// ErrMissingSecretKey indicates Secret key is required
	ErrMissingSecretKey = errors.New("secret key is required")

	// ErrForbidden when HTTP status 403 is given
	ErrForbidden = errors.New("you don't have permission to access this resource")

	// ErrMissingAuthenticatorFunc indicates Authenticator is required
	ErrMissingAuthenticatorFunc = errors.New("ginJWTMiddleware.Authenticator func is undefined")

	// ErrMissingLoginValues indicates a user tried to authenticate without username or password
	ErrMissingLoginValues = errors.New("missing Username or Password")

	// ErrFailedAuthentication indicates authentication failed, could be faulty username or password
	ErrFailedAuthentication = errors.New("incorrect Username or Password")

	// ErrFailedTokenCreation indicates JWT Token failed to create, reason unknown
	ErrFailedTokenCreation = errors.New("failed to create JWT Token")

	// ErrExpiredToken indicates JWT token has expired. Can't refresh.
	ErrExpiredToken = errors.New("token is expired")

	// ErrEmptyAuthHeader can be thrown if authing with a HTTP header, the Auth header needs to be set
	ErrEmptyAuthHeader = errors.New("auth header is empty")

	// ErrMissingExpField missing exp field in token
	ErrMissingExpField = errors.New("missing exp field")

	// ErrWrongFormatOfExp field must be float64 format
	ErrWrongFormatOfExp = errors.New("exp must be float64 format")

	// ErrInvalidAuthHeader indicates auth header is invalid, could for example have the wrong Realm name
	ErrInvalidAuthHeader = errors.New("auth header is invalid")

	// ErrEmptyQueryToken can be thrown if authing with URL Query, the query token variable is empty
	ErrEmptyQueryToken = errors.New("query token is empty")

	// ErrEmptyCookieToken can be thrown if authing with a cookie, the token cookie is empty
	ErrEmptyCookieToken = errors.New("cookie token is empty")

	// ErrEmptyParamToken can be thrown if authing with parameter in path, the parameter in path is empty
	ErrEmptyParamToken = errors.New("parameter token is empty")

	// ErrInvalidSigningAlgorithm indicates signing algorithm is invalid, needs to be HS256, HS384, HS512, RS256, RS384 or RS512
	ErrInvalidSigningAlgorithm = errors.New("invalid signing algorithm")

	// ErrNoPrivKeyFile indicates that the given private key is unreadable
	ErrNoPrivKeyFile = errors.New("private key file unreadable")

	// ErrNoPubKeyFile indicates that the given public key is unreadable
	ErrNoPubKeyFile = errors.New("public key file unreadable")

	// ErrInvalidPrivKey indicates that the given private key is invalid
	ErrInvalidPrivKey = errors.New("private key invalid")

	// ErrInvalidPubKey indicates the the given public key is invalid
	ErrInvalidPubKey = errors.New("public key invalid")

	// IdentityKey default identity key
	IdentityKey = "identity"
)
View Source
var (
	ErrFailedToDecodeClientSecret  = errors.New("failed to decode client secret")
	ErrFailedToDecryptClientSecret = errors.New("failed to decrypt client secret")
)
View Source
var (
	ErrBadConfiguration = errors.New("bad configuration")
)

Functions

func AbortWithError

func AbortWithError(c *gin.Context, code int, message string, errors ...error)

func AbortWithInternalServerError

func AbortWithInternalServerError(c *gin.Context, err error)

func AccessKeyMiddleware

func AccessKeyMiddleware(accessKeyStorage AccessKeyPersister, next gin.HandlerFunc) gin.HandlerFunc

func AuthenticationHandler

func AuthenticationHandler(accountBackend storage.IdentityBackend, acceptedAudiences []string, defaultAudience, defaultAudienceKey string) func(c *gin.Context) (any, error)

func AuthorisationHandler

func AuthorisationHandler(audiencePrivateKey []byte) func(data any, c *gin.Context) bool

func BindJSON

func BindJSON(c *gin.Context, obj any) error

func ContextLoggerHandler

func ContextLoggerHandler(c *gin.Context)

func CtxLogger

func CtxLogger(c *gin.Context) *zerolog.Logger

func DelegatedAccessKeyMiddleware

func DelegatedAccessKeyMiddleware(validatorURL string, next gin.HandlerFunc) (gin.HandlerFunc, error)

DelegatedAccessKeyMiddleware call an external signature validation service to confirm if the signature is valid. This is useful when a service doesn't have access to identity backend.

func ExtractSecret

func ExtractSecret(claims MapClaims, audiencePrivateKey []byte) (*model.AESKey, error)

func GetKeyID

func GetKeyID(key []byte) string

func GetManagedKey

func GetManagedKey(c *gin.Context) *model.AESKey

func GetSimpleStatusHandler

func GetSimpleStatusHandler(c *gin.Context)

GetSimpleStatusHandler godoc @Summary Get service health status @Description Get service health status. @Tags Monitoring @ID get-status @Produce json @Success 200 {object} object @Router /status [get]

func GetToken

func GetToken(c *gin.Context) string

GetToken help to get the JWT token string

func GetUserID

func GetUserID(c *gin.Context) string

func IdentityHandler

func IdentityHandler(c *gin.Context) any

func JSON

func JSON(c *gin.Context, code int, obj any)

JSON is a replacement for gin.Context.JSON. It uses the JSON wrapper defined in jsonw instead of the standard encoding.json, and also uses streaming.

func NewAdminAuthenticationHandler

func NewAdminAuthenticationHandler(cfg *koanf.Koanf, name string, resolver cmdbase.ParameterResolver) (gin.HandlerFunc, error)

func NewStaticAPIKeyAuthenticationHandler

func NewStaticAPIKeyAuthenticationHandler(cfg *koanf.Koanf, key string, mainAuthFunc gin.HandlerFunc,
	resolver cmdbase.ParameterResolver, identityBackend storage.IdentityBackend) (gin.HandlerFunc, error)

func ParseResponseMessage

func ParseResponseMessage(res *http.Response) string

func ReadAudiencePrivateKeyFromString

func ReadAudiencePrivateKeyFromString(val string) ([]byte, error)

func SetRequestLogger

func SetRequestLogger(config ...LoggerConfig) gin.HandlerFunc

SetRequestLogger initializes the logging middleware. This implementation was borrowed from github.com/gin-contrib/logger.

func SetupLogging

func SetupLogging(cfg *koanf.Koanf, prodMode bool) (io.Closer, error)

func Unauthorized

func Unauthorized(c *gin.Context, code int, message string)

Types

type AccessKeyPersister

type AccessKeyPersister interface {
	GetAccessKey(keyID string) (*model.AccessKey, error)
}

type AccountBackend

type AccountBackend interface {
	CreateAccount(account *account.Account) error

	GetAccount(email string) (account *account.Account, err error)
}

type GinJWTMiddleware

type GinJWTMiddleware struct {
	// Realm name to display to the user. Required.
	Realm string

	//Identifies principal that issued the JWT
	Issuer string

	// signing algorithm - possible values are HS256, HS384, HS512, RS256, RS384 or RS512
	// Optional, default is HS256.
	SigningAlgorithm string

	// Secret key used for signing. Required.
	Key []byte

	// Duration that a jwt token is valid. Optional, defaults to one hour.
	Timeout time.Duration

	// This field allows clients to refresh their token until MaxRefresh has passed.
	// Note that clients can refresh their token in the last moment of MaxRefresh.
	// This means that the maximum validity timespan for a token is TokenTime + MaxRefresh.
	// Optional, defaults to 0 meaning not refreshable.
	MaxRefresh time.Duration

	// Callback function that should perform the authentication of the user based on login info.
	// Must return user data as user identifier, it will be stored in Claim Array. Required.
	// Check error (e) to determine the appropriate error message.
	Authenticator func(c *gin.Context) (any, error)

	// Callback function that should perform the authorization of the authenticated user. Called
	// only after an authentication success. Must return true on success, false on failure.
	// Optional, default to success.
	Authorizator func(data any, c *gin.Context) bool

	// Callback function that will be called during login.
	// Using this function it is possible to add additional payload data to the webtoken.
	// The data is then made available during requests via c.Get("JWT_PAYLOAD").
	// Note that the payload is not encrypted.
	// The attributes mentioned on jwt.io can't be used as keys for the map.
	// Optional, by default no additional data will be set.
	PayloadFunc func(data any) MapClaims

	// User can define own Unauthorized func.
	Unauthorized func(*gin.Context, int, string)

	// User can define own LoginResponse func.
	LoginResponse func(*gin.Context, int, string, time.Time)

	// User can define own LogoutResponse func.
	LogoutResponse func(*gin.Context, int)

	// User can define own RefreshResponse func.
	RefreshResponse func(*gin.Context, int, string, time.Time)

	// Set the identity handler function
	IdentityHandler func(*gin.Context) any

	// Set the identity key
	IdentityKey string

	// TokenLookup is a string in the form of "<source>:<name>" that is used
	// to extract token from the request.
	// Optional. Default value "header:Authorization".
	// Possible values:
	// - "header:<name>"
	// - "query:<name>"
	// - "cookie:<name>"
	TokenLookup string

	// TokenHeadName is a string in the header. Default value is "Bearer"
	TokenHeadName string

	// TimeFunc provides the current time. You can override it to use another time value. This is useful for testing or if your server uses a different time zone than your tokens.
	TimeFunc func() time.Time

	// HTTP Status messages for when something in the JWT middleware fails.
	// Check error (e) to determine the appropriate error message.
	HTTPStatusMessageFunc func(e error, c *gin.Context) string

	// Private key file for asymmetric algorithms
	PrivKeyFile string

	// Public key file for asymmetric algorithms
	PubKeyFile string

	// Optionally return the token as a cookie
	SendCookie bool

	// Duration that a cookie is valid. Optional, by default equals to Timeout value.
	CookieMaxAge time.Duration

	// Allow insecure cookies for development over http
	SecureCookie bool

	// Allow cookies to be accessed client side for development
	CookieHTTPOnly bool

	// Allow cookie domain change for development
	CookieDomain string

	// SendAuthorization allow return authorization header for every request
	SendAuthorization bool

	// Disable abort() of context.
	DisabledAbort bool

	// CookieName allow cookie name change for development
	CookieName string

	// CookieSameSite allow use http.SameSite cookie param
	CookieSameSite http.SameSite
	// contains filtered or unexported fields
}

GinJWTMiddleware provides a Json-Web-Token authentication implementation. On failure, a 401 HTTP response is returned. On success, the wrapped middleware is called, and the userID is made available as c.Get("userID").(string). Users can get a token by posting a json request to LoginHandler. The token then needs to be passed in the Authentication header. Example: Authorization:Bearer XXX_TOKEN_XXX

func JWTMiddlewareWithTokenIssuance

func JWTMiddlewareWithTokenIssuance(realm, issuer string, authenticatorFn func(c *gin.Context) (any, error),
	audiencePrivateKey, rsaPrivateKeyFile, rsaPublicKeyFile string, timeout time.Duration, timeFunc func() time.Time) (*GinJWTMiddleware, error)

func JWTMiddlewareWithTokenVerification

func JWTMiddlewareWithTokenVerification(realm string, audiencePrivateKey string, rsaPublicKeyFile string, timeFunc func() time.Time) (*GinJWTMiddleware, error)

func New

New for check error with GinJWTMiddleware

func (*GinJWTMiddleware) CheckIfTokenExpire

func (mw *GinJWTMiddleware) CheckIfTokenExpire(c *gin.Context) (jwt.MapClaims, error)

CheckIfTokenExpire check if token expire

func (*GinJWTMiddleware) GetClaimsFromJWT

func (mw *GinJWTMiddleware) GetClaimsFromJWT(c *gin.Context) (MapClaims, error)

GetClaimsFromJWT get claims from JWT token

func (*GinJWTMiddleware) LoginHandler

func (mw *GinJWTMiddleware) LoginHandler(c *gin.Context)

LoginHandler can be used by clients to get a jwt token. Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}. Reply will be of the form {"token": "TOKEN"}.

func (*GinJWTMiddleware) LogoutHandler

func (mw *GinJWTMiddleware) LogoutHandler(c *gin.Context)

LogoutHandler can be used by clients to remove the jwt cookie (if set)

func (*GinJWTMiddleware) MiddlewareFunc

func (mw *GinJWTMiddleware) MiddlewareFunc() gin.HandlerFunc

MiddlewareFunc makes GinJWTMiddleware implement the Middleware interface.

func (*GinJWTMiddleware) MiddlewareInit

func (mw *GinJWTMiddleware) MiddlewareInit() error

MiddlewareInit initialize jwt configs.

func (*GinJWTMiddleware) ParseToken

func (mw *GinJWTMiddleware) ParseToken(c *gin.Context) (*jwt.Token, error)

ParseToken parse jwt token from gin context

func (*GinJWTMiddleware) ParseTokenString

func (mw *GinJWTMiddleware) ParseTokenString(token string) (*jwt.Token, error)

ParseTokenString parse jwt token string

func (*GinJWTMiddleware) RefreshHandler

func (mw *GinJWTMiddleware) RefreshHandler(c *gin.Context)

RefreshHandler can be used to refresh a token. The token still needs to be valid on refresh. Shall be put under an endpoint that is using the GinJWTMiddleware. Reply will be of the form {"token": "TOKEN"}.

func (*GinJWTMiddleware) RefreshToken

func (mw *GinJWTMiddleware) RefreshToken(c *gin.Context) (string, time.Time, error)

RefreshToken refresh token and check if token is expired

func (*GinJWTMiddleware) TokenGenerator

func (mw *GinJWTMiddleware) TokenGenerator(data any) (string, time.Time, error)

TokenGenerator method that clients can use to get a jwt token.

func (*GinJWTMiddleware) ValidateToken

func (mw *GinJWTMiddleware) ValidateToken(token string) (MapClaims, error)

ValidateToken can be used for non-standard authentication workflows, such as web socket based ones.

type LoggerConfig

type LoggerConfig struct {
	Logger         *zerolog.Logger
	HideUserID     bool
	SkipPath       []string
	SkipPathRegexp *regexp.Regexp
}

type LoginForm

type LoginForm struct {
	Username          string `form:"username" json:"username" binding:"required"`
	Password          string `form:"password" json:"password" binding:"required"`
	Audience          string `form:"audience" json:"audience"`
	AudiencePublicKey string `form:"audienceKey" json:"audienceKey"`
}

LoginForm form structure.

func (LoginForm) Bytes

func (lf LoginForm) Bytes() []byte

type MapClaims

type MapClaims map[string]any

MapClaims type that uses the map[string]any for JSON decoding This is the default claims type if you don't supply one

func ExtractClaims

func ExtractClaims(c *gin.Context) MapClaims

ExtractClaims help to extract the JWT claims

func ExtractClaimsFromToken

func ExtractClaimsFromToken(token *jwt.Token) MapClaims

ExtractClaimsFromToken help to extract the JWT claims from token

func Payload

func Payload(data any) MapClaims

type Response

type Response struct {
	Status  string   `json:"status,omitempty"`
	Message string   `json:"message,omitempty"`
	Errors  []string `json:"errors,omitempty"`
}

type SignatureValidationRequest

type SignatureValidationRequest struct {
	URL       string      `json:"url"`
	KeyID     string      `json:"key"`
	Signature string      `json:"sig"`
	Header    http.Header `json:"hdr"`
	Timestamp int64       `json:"ts"`
	BodyHash  string      `json:"hash,omitempty"`
}

type SignatureValidationResponse

type SignatureValidationResponse struct {
	Account string `json:"acct"`
}

Jump to

Keyboard shortcuts

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