4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-07-06 22:24:06 +00:00

Update dependencies and vendor (#1761)

This commit is contained in:
Wim
2022-03-12 19:41:07 +01:00
committed by GitHub
parent c30e90ff3f
commit b3be2e208c
93 changed files with 14302 additions and 13036 deletions

View File

@ -1,3 +1,4 @@
//go:build go1.15
// +build go1.15
package middleware
@ -5,12 +6,10 @@ package middleware
import (
"errors"
"fmt"
"net/http"
"reflect"
"strings"
"github.com/golang-jwt/jwt"
"github.com/labstack/echo/v4"
"net/http"
"reflect"
)
type (
@ -22,7 +21,8 @@ type (
// BeforeFunc defines a function which is executed just before the middleware.
BeforeFunc BeforeFunc
// SuccessHandler defines a function which is executed for a valid token.
// SuccessHandler defines a function which is executed for a valid token before middleware chain continues with next
// middleware or handler.
SuccessHandler JWTSuccessHandler
// ErrorHandler defines a function which is executed for an invalid token.
@ -32,6 +32,13 @@ type (
// ErrorHandlerWithContext is almost identical to ErrorHandler, but it's passed the current context.
ErrorHandlerWithContext JWTErrorHandlerWithContext
// ContinueOnIgnoredError allows the next middleware/handler to be called when ErrorHandlerWithContext decides to
// ignore the error (by returning `nil`).
// This is useful when parts of your site/api allow public access and some authorized routes provide extra functionality.
// In that case you can use ErrorHandlerWithContext to set a default public JWT token value in the request context
// and continue. Some logic down the remaining execution chain needs to check that (public) token value then.
ContinueOnIgnoredError bool
// Signing key to validate token.
// This is one of the three options to provide a token validation key.
// The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey.
@ -61,16 +68,26 @@ type (
// to extract token from the request.
// Optional. Default value "header:Authorization".
// Possible values:
// - "header:<name>"
// - "header:<name>" or "header:<name>:<cut-prefix>"
// `<cut-prefix>` is argument value to cut/trim prefix of the extracted value. This is useful if header
// value has static prefix like `Authorization: <auth-scheme> <authorisation-parameters>` where part that we
// want to cut is `<auth-scheme> ` note the space at the end.
// In case of JWT tokens `Authorization: Bearer <token>` prefix we cut is `Bearer `.
// If prefix is left empty the whole value is returned.
// - "query:<name>"
// - "param:<name>"
// - "cookie:<name>"
// - "form:<name>"
// Multiply sources example:
// - "header: Authorization,cookie: myowncookie"
// Multiple sources example:
// - "header:Authorization,cookie:myowncookie"
TokenLookup string
// TokenLookupFuncs defines a list of user-defined functions that extract JWT token from the given context.
// This is one of the two options to provide a token extractor.
// The order of precedence is user-defined TokenLookupFuncs, and TokenLookup.
// You can also provide both if you want.
TokenLookupFuncs []ValuesExtractor
// AuthScheme to be used in the Authorization header.
// Optional. Default value "Bearer".
AuthScheme string
@ -95,15 +112,13 @@ type (
}
// JWTSuccessHandler defines a function which is executed for a valid token.
JWTSuccessHandler func(echo.Context)
JWTSuccessHandler func(c echo.Context)
// JWTErrorHandler defines a function which is executed for an invalid token.
JWTErrorHandler func(error) error
JWTErrorHandler func(err error) error
// JWTErrorHandlerWithContext is almost identical to JWTErrorHandler, but it's passed the current context.
JWTErrorHandlerWithContext func(error, echo.Context) error
jwtExtractor func(echo.Context) (string, error)
JWTErrorHandlerWithContext func(err error, c echo.Context) error
)
// Algorithms
@ -120,13 +135,14 @@ var (
var (
// DefaultJWTConfig is the default JWT auth middleware config.
DefaultJWTConfig = JWTConfig{
Skipper: DefaultSkipper,
SigningMethod: AlgorithmHS256,
ContextKey: "user",
TokenLookup: "header:" + echo.HeaderAuthorization,
AuthScheme: "Bearer",
Claims: jwt.MapClaims{},
KeyFunc: nil,
Skipper: DefaultSkipper,
SigningMethod: AlgorithmHS256,
ContextKey: "user",
TokenLookup: "header:" + echo.HeaderAuthorization,
TokenLookupFuncs: nil,
AuthScheme: "Bearer",
Claims: jwt.MapClaims{},
KeyFunc: nil,
}
)
@ -163,7 +179,7 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.Claims == nil {
config.Claims = DefaultJWTConfig.Claims
}
if config.TokenLookup == "" {
if config.TokenLookup == "" && len(config.TokenLookupFuncs) == 0 {
config.TokenLookup = DefaultJWTConfig.TokenLookup
}
if config.AuthScheme == "" {
@ -176,25 +192,12 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
config.ParseTokenFunc = config.defaultParseToken
}
// Initialize
// Split sources
sources := strings.Split(config.TokenLookup, ",")
var extractors []jwtExtractor
for _, source := range sources {
parts := strings.Split(source, ":")
switch parts[0] {
case "query":
extractors = append(extractors, jwtFromQuery(parts[1]))
case "param":
extractors = append(extractors, jwtFromParam(parts[1]))
case "cookie":
extractors = append(extractors, jwtFromCookie(parts[1]))
case "form":
extractors = append(extractors, jwtFromForm(parts[1]))
case "header":
extractors = append(extractors, jwtFromHeader(parts[1], config.AuthScheme))
}
extractors, err := createExtractors(config.TokenLookup, config.AuthScheme)
if err != nil {
panic(err)
}
if len(config.TokenLookupFuncs) > 0 {
extractors = append(config.TokenLookupFuncs, extractors...)
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
@ -206,48 +209,54 @@ func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
if config.BeforeFunc != nil {
config.BeforeFunc(c)
}
var auth string
var err error
var lastExtractorErr error
var lastTokenErr error
for _, extractor := range extractors {
// Extract token from extractor, if it's not fail break the loop and
// set auth
auth, err = extractor(c)
if err == nil {
break
auths, err := extractor(c)
if err != nil {
lastExtractorErr = ErrJWTMissing // backwards compatibility: all extraction errors are same (unlike KeyAuth)
continue
}
for _, auth := range auths {
token, err := config.ParseTokenFunc(auth, c)
if err != nil {
lastTokenErr = err
continue
}
// Store user information from token into context.
c.Set(config.ContextKey, token)
if config.SuccessHandler != nil {
config.SuccessHandler(c)
}
return next(c)
}
}
// If none of extractor has a token, handle error
if err != nil {
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
}
if config.ErrorHandlerWithContext != nil {
return config.ErrorHandlerWithContext(err, c)
}
return err
}
token, err := config.ParseTokenFunc(auth, c)
if err == nil {
// Store user information from token into context.
c.Set(config.ContextKey, token)
if config.SuccessHandler != nil {
config.SuccessHandler(c)
}
return next(c)
// we are here only when we did not successfully extract or parse any of the tokens
err := lastTokenErr
if err == nil { // prioritize token errors over extracting errors
err = lastExtractorErr
}
if config.ErrorHandler != nil {
return config.ErrorHandler(err)
}
if config.ErrorHandlerWithContext != nil {
return config.ErrorHandlerWithContext(err, c)
tmpErr := config.ErrorHandlerWithContext(err, c)
if config.ContinueOnIgnoredError && tmpErr == nil {
return next(c)
}
return tmpErr
}
return &echo.HTTPError{
Code: ErrJWTInvalid.Code,
Message: ErrJWTInvalid.Message,
Internal: err,
// backwards compatible errors codes
if lastTokenErr != nil {
return &echo.HTTPError{
Code: ErrJWTInvalid.Code,
Message: ErrJWTInvalid.Message,
Internal: err,
}
}
return err // this is lastExtractorErr value
}
}
}
@ -289,59 +298,3 @@ func (config *JWTConfig) defaultKeyFunc(t *jwt.Token) (interface{}, error) {
return config.SigningKey, nil
}
// jwtFromHeader returns a `jwtExtractor` that extracts token from the request header.
func jwtFromHeader(header string, authScheme string) jwtExtractor {
return func(c echo.Context) (string, error) {
auth := c.Request().Header.Get(header)
l := len(authScheme)
if len(auth) > l+1 && strings.EqualFold(auth[:l], authScheme) {
return auth[l+1:], nil
}
return "", ErrJWTMissing
}
}
// jwtFromQuery returns a `jwtExtractor` that extracts token from the query string.
func jwtFromQuery(param string) jwtExtractor {
return func(c echo.Context) (string, error) {
token := c.QueryParam(param)
if token == "" {
return "", ErrJWTMissing
}
return token, nil
}
}
// jwtFromParam returns a `jwtExtractor` that extracts token from the url param string.
func jwtFromParam(param string) jwtExtractor {
return func(c echo.Context) (string, error) {
token := c.Param(param)
if token == "" {
return "", ErrJWTMissing
}
return token, nil
}
}
// jwtFromCookie returns a `jwtExtractor` that extracts token from the named cookie.
func jwtFromCookie(name string) jwtExtractor {
return func(c echo.Context) (string, error) {
cookie, err := c.Cookie(name)
if err != nil {
return "", ErrJWTMissing
}
return cookie.Value, nil
}
}
// jwtFromForm returns a `jwtExtractor` that extracts token from the form field.
func jwtFromForm(name string) jwtExtractor {
return func(c echo.Context) (string, error) {
field := c.FormValue(name)
if field == "" {
return "", ErrJWTMissing
}
return field, nil
}
}