mirror of
				https://github.com/ClusterCockpit/cc-metric-store.git
				synced 2025-11-04 02:35:08 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			57 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			57 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package api
 | 
						|
 | 
						|
import (
 | 
						|
	"crypto/ed25519"
 | 
						|
	"errors"
 | 
						|
	"net/http"
 | 
						|
	"strings"
 | 
						|
	"sync"
 | 
						|
 | 
						|
	"github.com/golang-jwt/jwt/v4"
 | 
						|
)
 | 
						|
 | 
						|
func authHandler(next http.Handler, publicKey ed25519.PublicKey) http.Handler {
 | 
						|
	cacheLock := sync.RWMutex{}
 | 
						|
	cache := map[string]*jwt.Token{}
 | 
						|
 | 
						|
	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
 | 
						|
		authheader := r.Header.Get("Authorization")
 | 
						|
		if authheader == "" || !strings.HasPrefix(authheader, "Bearer ") {
 | 
						|
			http.Error(rw, "Use JWT Authentication", http.StatusUnauthorized)
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		rawtoken := authheader[len("Bearer "):]
 | 
						|
		cacheLock.RLock()
 | 
						|
		token, ok := cache[rawtoken]
 | 
						|
		cacheLock.RUnlock()
 | 
						|
		if ok && token.Claims.Valid() == nil {
 | 
						|
			next.ServeHTTP(rw, r)
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		// The actual token is ignored for now.
 | 
						|
		// In case expiration and so on are specified, the Parse function
 | 
						|
		// already returns an error for expired tokens.
 | 
						|
		var err error
 | 
						|
		token, err = jwt.Parse(rawtoken, func(t *jwt.Token) (interface{}, error) {
 | 
						|
			if t.Method != jwt.SigningMethodEdDSA {
 | 
						|
				return nil, errors.New("only Ed25519/EdDSA supported")
 | 
						|
			}
 | 
						|
 | 
						|
			return publicKey, nil
 | 
						|
		})
 | 
						|
		if err != nil {
 | 
						|
			http.Error(rw, err.Error(), http.StatusUnauthorized)
 | 
						|
			return
 | 
						|
		}
 | 
						|
 | 
						|
		cacheLock.Lock()
 | 
						|
		cache[rawtoken] = token
 | 
						|
		cacheLock.Unlock()
 | 
						|
 | 
						|
		// Let request through...
 | 
						|
		next.ServeHTTP(rw, r)
 | 
						|
	})
 | 
						|
}
 |