Fetch pubkey on each request for authmw
This commit is contained in:
		@@ -8,37 +8,14 @@ import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"slices"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"git.t-juice.club/microfilm/auth"
 | 
			
		||||
	"github.com/golang-jwt/jwt/v5"
 | 
			
		||||
	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func VerifyToken(authURL string, permittedRoles []string) func(http.Handler) http.Handler {
 | 
			
		||||
	// Fetch current pubkey
 | 
			
		||||
	url := fmt.Sprintf("%s/key", authURL)
 | 
			
		||||
	req, err := http.NewRequest(http.MethodGet, url, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp, err := http.DefaultClient.Do(req)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
	defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
	var authResponse auth.PubkeyResponse
 | 
			
		||||
	decoder := json.NewDecoder(resp.Body)
 | 
			
		||||
	if err := decoder.Decode(&authResponse); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Parse pubkey
 | 
			
		||||
	pub, err := x509.ParsePKIXPublicKey(authResponse.PubKey)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fn := func(next http.Handler) http.Handler {
 | 
			
		||||
		fn := func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
			authHeader := r.Header.Get("Authorization")
 | 
			
		||||
@@ -61,6 +38,74 @@ func VerifyToken(authURL string, permittedRoles []string) func(http.Handler) htt
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Fetch current pubkey
 | 
			
		||||
			url := fmt.Sprintf("%s/key", authURL)
 | 
			
		||||
			ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
 | 
			
		||||
			defer cancel()
 | 
			
		||||
 | 
			
		||||
			req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				// TODO: Should log
 | 
			
		||||
				w.WriteHeader(http.StatusInternalServerError)
 | 
			
		||||
				errResp := &auth.ErrorResponse{
 | 
			
		||||
					Message: fmt.Sprintf("Error getting pubkey for token verification: %s", err),
 | 
			
		||||
					Status:  http.StatusUnauthorized,
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				encoder := json.NewEncoder(w)
 | 
			
		||||
				_ = encoder.Encode(&errResp)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			client := &http.Client{
 | 
			
		||||
				Transport: otelhttp.NewTransport(http.DefaultTransport),
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			resp, err := client.Do(req)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				// TODO: Should log
 | 
			
		||||
				w.WriteHeader(http.StatusInternalServerError)
 | 
			
		||||
				errResp := &auth.ErrorResponse{
 | 
			
		||||
					Message: fmt.Sprintf("Error getting pubkey for token verification: %s", err),
 | 
			
		||||
					Status:  http.StatusUnauthorized,
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				encoder := json.NewEncoder(w)
 | 
			
		||||
				_ = encoder.Encode(&errResp)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
			var authResponse auth.PubkeyResponse
 | 
			
		||||
			decoder := json.NewDecoder(resp.Body)
 | 
			
		||||
			if err := decoder.Decode(&authResponse); err != nil {
 | 
			
		||||
				// TODO: Should log
 | 
			
		||||
				w.WriteHeader(http.StatusInternalServerError)
 | 
			
		||||
				errResp := &auth.ErrorResponse{
 | 
			
		||||
					Message: fmt.Sprintf("Error getting pubkey for token verification: %s", err),
 | 
			
		||||
					Status:  http.StatusUnauthorized,
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				encoder := json.NewEncoder(w)
 | 
			
		||||
				_ = encoder.Encode(&errResp)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Parse pubkey
 | 
			
		||||
			pub, err := x509.ParsePKIXPublicKey(authResponse.PubKey)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				// TODO: Should log
 | 
			
		||||
				w.WriteHeader(http.StatusInternalServerError)
 | 
			
		||||
				errResp := &auth.ErrorResponse{
 | 
			
		||||
					Message: fmt.Sprintf("Error getting pubkey for token verification: %s", err),
 | 
			
		||||
					Status:  http.StatusUnauthorized,
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				encoder := json.NewEncoder(w)
 | 
			
		||||
				_ = encoder.Encode(&errResp)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Validate token
 | 
			
		||||
			tokenString := strings.Split(authHeader, " ")[1]
 | 
			
		||||
			token, err := jwt.ParseWithClaims(tokenString, &auth.MicrofilmClaims{}, func(t *jwt.Token) (interface{}, error) { return pub, nil })
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
package auth
 | 
			
		||||
 | 
			
		||||
const Version = "v0.1.3"
 | 
			
		||||
const Version = "v0.1.4"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user