re-enabling jwt on keymanager API (#13492)

* re-enabling jwt on keymanager API

* adding tests

* Update validator/rpc/intercepter.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* handling error in test

* remove debugging logs

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
This commit is contained in:
james-prysm 2024-01-22 16:16:10 -06:00 committed by GitHub
parent 4afb379f8d
commit 8dd5e96b29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 57 additions and 4 deletions

View File

@ -191,7 +191,6 @@ func createTokenString(jwtKey []byte) (string, error) {
return tokenString, nil
}
// DEPRECATED: associated to Initialize Web UI API
func createRandomJWTSecret() ([]byte, error) {
r := rand.NewGenerator()
jwtKey := make([]byte, 32)

View File

@ -40,8 +40,7 @@ func (s *Server) JwtHttpInterceptor(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// if it's not initialize or has a web prefix
if !strings.Contains(r.URL.Path, api.WebUrlPrefix+"initialize") && // ignore some routes
!strings.Contains(r.URL.Path, api.WebUrlPrefix+"health/logs") &&
strings.Contains(r.URL.Path, api.WebUrlPrefix) {
!strings.Contains(r.URL.Path, api.WebUrlPrefix+"health/logs") {
reqToken := r.Header.Get("Authorization")
if reqToken == "" {
http.Error(w, "unauthorized: no Authorization header passed. Please use an Authorization header with the jwt created in the prysm wallet", http.StatusUnauthorized)
@ -50,7 +49,7 @@ func (s *Server) JwtHttpInterceptor(next http.Handler) http.Handler {
token := strings.Split(reqToken, "Bearer ")[1]
_, err := jwt.Parse(token, s.validateJWT)
if err != nil {
http.Error(w, fmt.Errorf("unauthorized:could not parse JWT token: %v", err).Error(), http.StatusUnauthorized)
http.Error(w, fmt.Errorf("forbidden: could not parse JWT token: %v", err).Error(), http.StatusForbidden)
return
}
}

View File

@ -2,9 +2,12 @@ package rpc
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/golang-jwt/jwt/v4"
"github.com/prysmaticlabs/prysm/v4/api"
"github.com/prysmaticlabs/prysm/v4/testing/require"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
@ -67,3 +70,55 @@ func TestServer_JWTInterceptor_InvalidSigningType(t *testing.T) {
_, err := ss.validateJWT(token)
require.ErrorContains(t, "unexpected JWT signing method", err)
}
func TestServer_JwtHttpInterceptor(t *testing.T) {
jwtKey, err := createRandomJWTSecret()
require.NoError(t, err)
s := &Server{jwtSecret: jwtKey}
testHandler := s.JwtHttpInterceptor(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your test handler logic here
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte("Test Response"))
require.NoError(t, err)
}))
t.Run("no jwt was sent", func(t *testing.T) {
rr := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/eth/v1/keystores", nil)
require.NoError(t, err)
testHandler.ServeHTTP(rr, req)
require.Equal(t, http.StatusUnauthorized, rr.Code)
})
t.Run("wrong jwt was sent", func(t *testing.T) {
rr := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/eth/v1/keystores", nil)
require.NoError(t, err)
req.Header.Set("Authorization", "Bearer YOUR_JWT_TOKEN") // Replace with a valid JWT token
testHandler.ServeHTTP(rr, req)
require.Equal(t, http.StatusForbidden, rr.Code)
})
t.Run("jwt was sent", func(t *testing.T) {
rr := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, "/eth/v1/keystores", nil)
require.NoError(t, err)
token, err := createTokenString(jwtKey)
require.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+token) // Replace with a valid JWT token
testHandler.ServeHTTP(rr, req)
require.Equal(t, http.StatusOK, rr.Code)
})
t.Run("initialize does not need jwt", func(t *testing.T) {
rr := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, api.WebUrlPrefix+"initialize", nil)
require.NoError(t, err)
testHandler.ServeHTTP(rr, req)
require.Equal(t, http.StatusOK, rr.Code)
})
t.Run("health does not need jwt", func(t *testing.T) {
rr := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodGet, api.WebUrlPrefix+"health/logs", nil)
require.NoError(t, err)
testHandler.ServeHTTP(rr, req)
require.Equal(t, http.StatusOK, rr.Code)
})
}