snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
3
server/vendor/github.com/go-chi/jwtauth/.gitignore
generated
vendored
Normal file
3
server/vendor/github.com/go-chi/jwtauth/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
vendor/
|
||||
Gopkg.lock
|
||||
.idea/
|
||||
20
server/vendor/github.com/go-chi/jwtauth/LICENSE
generated
vendored
Normal file
20
server/vendor/github.com/go-chi/jwtauth/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2015-Present https://github.com/go-chi authors
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
111
server/vendor/github.com/go-chi/jwtauth/README.md
generated
vendored
Normal file
111
server/vendor/github.com/go-chi/jwtauth/README.md
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
# jwtauth - JWT authentication middleware for HTTP services
|
||||
|
||||
[![GoDoc Widget]][godoc]
|
||||
|
||||
The `jwtauth` http middleware package provides a simple way to verify a JWT token
|
||||
from a http request and send the result down the request context (`context.Context`).
|
||||
|
||||
Please note, `jwtauth` works with any Go http router, but resides under the go-chi group
|
||||
for maintenance and organization - its only 3rd party dependency is the underlying jwt library
|
||||
"github.com/lestrrat-go/jwx".
|
||||
|
||||
In a complete JWT-authentication flow, you'll first capture the token from a http
|
||||
request, decode it, verify it and then validate that its correctly signed and hasn't
|
||||
expired - the `jwtauth.Verifier` middleware handler takes care of all of that. The
|
||||
`jwtauth.Verifier` will set the context values on keys `jwtauth.TokenCtxKey` and
|
||||
`jwtauth.ErrorCtxKey`.
|
||||
|
||||
Next, it's up to an authentication handler to respond or continue processing after the
|
||||
`jwtauth.Verifier`. The `jwtauth.Authenticator` middleware responds with a 401 Unauthorized
|
||||
plain-text payload for all unverified tokens and passes the good ones through. You can
|
||||
also copy the Authenticator and customize it to handle invalid tokens to better fit
|
||||
your flow (ie. with a JSON error response body).
|
||||
|
||||
By default, the `Verifier` will search for a JWT token in a http request, in the order:
|
||||
|
||||
1. 'Authorization: BEARER T' request header
|
||||
2. 'jwt' Cookie value
|
||||
|
||||
The first JWT string that is found as an authorization header
|
||||
or cookie header is then decoded by the `lestrrat-go/jwx` library and a jwt.Token
|
||||
object is set on the request context. In the case of a signature decoding error
|
||||
the Verifier will also set the error on the request context.
|
||||
|
||||
The Verifier always calls the next http handler in sequence, which can either
|
||||
be the generic `jwtauth.Authenticator` middleware or your own custom handler
|
||||
which checks the request context jwt token and error to prepare a custom
|
||||
http response.
|
||||
|
||||
Note: jwtauth supports custom verification sequences for finding a token
|
||||
from a request by using the `Verify` middleware instantiator directly. The default
|
||||
`Verifier` is instantiated by calling `Verify(ja, TokenFromHeader, TokenFromCookie)`.
|
||||
|
||||
# Usage
|
||||
|
||||
See the full [example](https://github.com/go-chi/jwtauth/blob/master/_example/main.go).
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/jwtauth"
|
||||
)
|
||||
|
||||
var tokenAuth *jwtauth.JWTAuth
|
||||
|
||||
func init() {
|
||||
tokenAuth = jwtauth.New("HS256", []byte("secret"), nil)
|
||||
|
||||
// For debugging/example purposes, we generate and print
|
||||
// a sample jwt token with claims `user_id:123` here:
|
||||
_, tokenString, _ := tokenAuth.Encode(map[string]interface{}{"user_id": 123})
|
||||
fmt.Printf("DEBUG: a sample jwt is %s\n\n", tokenString)
|
||||
}
|
||||
|
||||
func main() {
|
||||
addr := ":3333"
|
||||
fmt.Printf("Starting server on %v\n", addr)
|
||||
http.ListenAndServe(addr, router())
|
||||
}
|
||||
|
||||
func router() http.Handler {
|
||||
r := chi.NewRouter()
|
||||
|
||||
// Protected routes
|
||||
r.Group(func(r chi.Router) {
|
||||
// Seek, verify and validate JWT tokens
|
||||
r.Use(jwtauth.Verifier(tokenAuth))
|
||||
|
||||
// Handle valid / invalid tokens. In this example, we use
|
||||
// the provided authenticator middleware, but you can write your
|
||||
// own very easily, look at the Authenticator method in jwtauth.go
|
||||
// and tweak it, its not scary.
|
||||
r.Use(jwtauth.Authenticator)
|
||||
|
||||
r.Get("/admin", func(w http.ResponseWriter, r *http.Request) {
|
||||
_, claims, _ := jwtauth.FromContext(r.Context())
|
||||
w.Write([]byte(fmt.Sprintf("protected area. hi %v", claims["user_id"])))
|
||||
})
|
||||
})
|
||||
|
||||
// Public routes
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("welcome anonymous"))
|
||||
})
|
||||
})
|
||||
|
||||
return r
|
||||
}
|
||||
```
|
||||
|
||||
# LICENSE
|
||||
|
||||
[MIT](/LICENSE)
|
||||
|
||||
[godoc]: https://godoc.org/github.com/go-chi/jwtauth
|
||||
[godoc widget]: https://godoc.org/github.com/go-chi/jwtauth?status.svg
|
||||
288
server/vendor/github.com/go-chi/jwtauth/jwtauth.go
generated
vendored
Normal file
288
server/vendor/github.com/go-chi/jwtauth/jwtauth.go
generated
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
package jwtauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lestrrat-go/jwx/jwa"
|
||||
"github.com/lestrrat-go/jwx/jwt"
|
||||
)
|
||||
|
||||
type JWTAuth struct {
|
||||
alg jwa.SignatureAlgorithm
|
||||
signKey interface{} // private-key
|
||||
verifyKey interface{} // public-key, only used by RSA and ECDSA algorithms
|
||||
verifier jwt.ParseOption
|
||||
}
|
||||
|
||||
var (
|
||||
TokenCtxKey = &contextKey{"Token"}
|
||||
ErrorCtxKey = &contextKey{"Error"}
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnauthorized = errors.New("token is unauthorized")
|
||||
ErrExpired = errors.New("token is expired")
|
||||
ErrNBFInvalid = errors.New("token nbf validation failed")
|
||||
ErrIATInvalid = errors.New("token iat validation failed")
|
||||
ErrNoTokenFound = errors.New("no token found")
|
||||
ErrAlgoInvalid = errors.New("algorithm mismatch")
|
||||
)
|
||||
|
||||
func New(alg string, signKey interface{}, verifyKey interface{}) *JWTAuth {
|
||||
ja := &JWTAuth{alg: jwa.SignatureAlgorithm(alg), signKey: signKey, verifyKey: verifyKey}
|
||||
|
||||
if ja.verifyKey != nil {
|
||||
ja.verifier = jwt.WithVerify(ja.alg, ja.verifyKey)
|
||||
} else {
|
||||
ja.verifier = jwt.WithVerify(ja.alg, ja.signKey)
|
||||
}
|
||||
|
||||
return ja
|
||||
}
|
||||
|
||||
// Verifier http middleware handler will verify a JWT string from a http request.
|
||||
//
|
||||
// Verifier will search for a JWT token in a http request, in the order:
|
||||
// 1. 'jwt' URI query parameter
|
||||
// 2. 'Authorization: BEARER T' request header
|
||||
// 3. Cookie 'jwt' value
|
||||
//
|
||||
// The first JWT string that is found as a query parameter, authorization header
|
||||
// or cookie header is then decoded by the `jwt-go` library and a *jwt.Token
|
||||
// object is set on the request context. In the case of a signature decoding error
|
||||
// the Verifier will also set the error on the request context.
|
||||
//
|
||||
// The Verifier always calls the next http handler in sequence, which can either
|
||||
// be the generic `jwtauth.Authenticator` middleware or your own custom handler
|
||||
// which checks the request context jwt token and error to prepare a custom
|
||||
// http response.
|
||||
func Verifier(ja *JWTAuth) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return Verify(ja, TokenFromHeader, TokenFromCookie)(next)
|
||||
}
|
||||
}
|
||||
|
||||
func Verify(ja *JWTAuth, findTokenFns ...func(r *http.Request) string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
hfn := func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
token, err := VerifyRequest(ja, r, findTokenFns...)
|
||||
ctx = NewContext(ctx, token, err)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
}
|
||||
return http.HandlerFunc(hfn)
|
||||
}
|
||||
}
|
||||
|
||||
func VerifyRequest(ja *JWTAuth, r *http.Request, findTokenFns ...func(r *http.Request) string) (jwt.Token, error) {
|
||||
var tokenString string
|
||||
|
||||
// Extract token string from the request by calling token find functions in
|
||||
// the order they where provided. Further extraction stops if a function
|
||||
// returns a non-empty string.
|
||||
for _, fn := range findTokenFns {
|
||||
tokenString = fn(r)
|
||||
if tokenString != "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
if tokenString == "" {
|
||||
return nil, ErrNoTokenFound
|
||||
}
|
||||
|
||||
return VerifyToken(ja, tokenString)
|
||||
}
|
||||
|
||||
func VerifyToken(ja *JWTAuth, tokenString string) (jwt.Token, error) {
|
||||
// Decode & verify the token
|
||||
token, err := ja.Decode(tokenString)
|
||||
if err != nil {
|
||||
return token, ErrorReason(err)
|
||||
}
|
||||
|
||||
if token == nil {
|
||||
return nil, ErrUnauthorized
|
||||
}
|
||||
|
||||
if err := jwt.Validate(token); err != nil {
|
||||
return token, ErrorReason(err)
|
||||
}
|
||||
|
||||
// Valid!
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (ja *JWTAuth) Encode(claims map[string]interface{}) (t jwt.Token, tokenString string, err error) {
|
||||
t = jwt.New()
|
||||
for k, v := range claims {
|
||||
t.Set(k, v)
|
||||
}
|
||||
payload, err := ja.sign(t)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
tokenString = string(payload)
|
||||
return
|
||||
}
|
||||
|
||||
func (ja *JWTAuth) Decode(tokenString string) (jwt.Token, error) {
|
||||
return ja.parse([]byte(tokenString))
|
||||
}
|
||||
|
||||
func (ja *JWTAuth) sign(token jwt.Token) ([]byte, error) {
|
||||
return jwt.Sign(token, ja.alg, ja.signKey)
|
||||
}
|
||||
|
||||
func (ja *JWTAuth) parse(payload []byte) (jwt.Token, error) {
|
||||
return jwt.Parse(payload, ja.verifier)
|
||||
}
|
||||
|
||||
// ErrorReason will normalize the error message from the underlining
|
||||
// jwt library
|
||||
func ErrorReason(err error) error {
|
||||
switch err.Error() {
|
||||
case "exp not satisfied", ErrExpired.Error():
|
||||
return ErrExpired
|
||||
case "iat not satisfied", ErrIATInvalid.Error():
|
||||
return ErrIATInvalid
|
||||
case "nbf not satisfied", ErrNBFInvalid.Error():
|
||||
return ErrNBFInvalid
|
||||
default:
|
||||
return ErrUnauthorized
|
||||
}
|
||||
}
|
||||
|
||||
// Authenticator is a default authentication middleware to enforce access from the
|
||||
// Verifier middleware request context values. The Authenticator sends a 401 Unauthorized
|
||||
// response for any unverified tokens and passes the good ones through. It's just fine
|
||||
// until you decide to write something similar and customize your client response.
|
||||
func Authenticator(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token, _, err := FromContext(r.Context())
|
||||
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), 401)
|
||||
return
|
||||
}
|
||||
|
||||
if token == nil || jwt.Validate(token) != nil {
|
||||
http.Error(w, http.StatusText(401), 401)
|
||||
return
|
||||
}
|
||||
|
||||
// Token is authenticated, pass it through
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func NewContext(ctx context.Context, t jwt.Token, err error) context.Context {
|
||||
ctx = context.WithValue(ctx, TokenCtxKey, t)
|
||||
ctx = context.WithValue(ctx, ErrorCtxKey, err)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func FromContext(ctx context.Context) (jwt.Token, map[string]interface{}, error) {
|
||||
token, _ := ctx.Value(TokenCtxKey).(jwt.Token)
|
||||
|
||||
var err error
|
||||
var claims map[string]interface{}
|
||||
|
||||
if token != nil {
|
||||
claims, err = token.AsMap(context.Background())
|
||||
if err != nil {
|
||||
return token, nil, err
|
||||
}
|
||||
} else {
|
||||
claims = map[string]interface{}{}
|
||||
}
|
||||
|
||||
err, _ = ctx.Value(ErrorCtxKey).(error)
|
||||
|
||||
return token, claims, err
|
||||
}
|
||||
|
||||
// UnixTime returns the given time in UTC milliseconds
|
||||
func UnixTime(tm time.Time) int64 {
|
||||
return tm.UTC().Unix()
|
||||
}
|
||||
|
||||
// EpochNow is a helper function that returns the NumericDate time value used by the spec
|
||||
func EpochNow() int64 {
|
||||
return time.Now().UTC().Unix()
|
||||
}
|
||||
|
||||
// ExpireIn is a helper function to return calculated time in the future for "exp" claim
|
||||
func ExpireIn(tm time.Duration) int64 {
|
||||
return EpochNow() + int64(tm.Seconds())
|
||||
}
|
||||
|
||||
// Set issued at ("iat") to specified time in the claims
|
||||
func SetIssuedAt(claims map[string]interface{}, tm time.Time) {
|
||||
claims["iat"] = tm.UTC().Unix()
|
||||
}
|
||||
|
||||
// Set issued at ("iat") to present time in the claims
|
||||
func SetIssuedNow(claims map[string]interface{}) {
|
||||
claims["iat"] = EpochNow()
|
||||
}
|
||||
|
||||
// Set expiry ("exp") in the claims
|
||||
func SetExpiry(claims map[string]interface{}, tm time.Time) {
|
||||
claims["exp"] = tm.UTC().Unix()
|
||||
}
|
||||
|
||||
// Set expiry ("exp") in the claims to some duration from the present time
|
||||
func SetExpiryIn(claims map[string]interface{}, tm time.Duration) {
|
||||
claims["exp"] = ExpireIn(tm)
|
||||
}
|
||||
|
||||
// TokenFromCookie tries to retreive the token string from a cookie named
|
||||
// "jwt".
|
||||
func TokenFromCookie(r *http.Request) string {
|
||||
cookie, err := r.Cookie("jwt")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return cookie.Value
|
||||
}
|
||||
|
||||
// TokenFromHeader tries to retreive the token string from the
|
||||
// "Authorization" reqeust header: "Authorization: BEARER T".
|
||||
func TokenFromHeader(r *http.Request) string {
|
||||
// Get token from authorization header.
|
||||
bearer := r.Header.Get("Authorization")
|
||||
if len(bearer) > 7 && strings.ToUpper(bearer[0:6]) == "BEARER" {
|
||||
return bearer[7:]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// TokenFromQuery tries to retreive the token string from the "jwt" URI
|
||||
// query parameter.
|
||||
//
|
||||
// To use it, build our own middleware handler, such as:
|
||||
//
|
||||
// func Verifier(ja *JWTAuth) func(http.Handler) http.Handler {
|
||||
// return func(next http.Handler) http.Handler {
|
||||
// return Verify(ja, TokenFromQuery, TokenFromHeader, TokenFromCookie)(next)
|
||||
// }
|
||||
// }
|
||||
func TokenFromQuery(r *http.Request) string {
|
||||
// Get token from query param named "jwt".
|
||||
return r.URL.Query().Get("jwt")
|
||||
}
|
||||
|
||||
// contextKey is a value for use with context.WithValue. It's used as
|
||||
// a pointer so it fits in an interface{} without allocation. This technique
|
||||
// for defining context keys was copied from Go 1.7's new use of context in net/http.
|
||||
type contextKey struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (k *contextKey) String() string {
|
||||
return "jwtauth context value " + k.name
|
||||
}
|
||||
Reference in New Issue
Block a user