diff --git a/validator/rpc/BUILD.bazel b/validator/rpc/BUILD.bazel index 01ee43247b..82baf1c9ff 100644 --- a/validator/rpc/BUILD.bazel +++ b/validator/rpc/BUILD.bazel @@ -33,7 +33,6 @@ go_library( "//proto/prysm/v1alpha1:go_default_library", "//proto/prysm/v1alpha1/validator-client:go_default_library", "//runtime/version:go_default_library", - "//time:go_default_library", "//validator/accounts:go_default_library", "//validator/accounts/iface:go_default_library", "//validator/accounts/petnames:go_default_library", @@ -93,7 +92,6 @@ go_test( "//testing/assert:go_default_library", "//testing/mock:go_default_library", "//testing/require:go_default_library", - "//time:go_default_library", "//validator/accounts:go_default_library", "//validator/accounts/iface:go_default_library", "//validator/accounts/wallet:go_default_library", diff --git a/validator/rpc/auth_token.go b/validator/rpc/auth_token.go index 60ed5665fd..638d2e7965 100644 --- a/validator/rpc/auth_token.go +++ b/validator/rpc/auth_token.go @@ -9,31 +9,24 @@ import ( "net/url" "os" "path/filepath" - "strconv" "strings" - "time" "github.com/golang-jwt/jwt" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/crypto/rand" "github.com/prysmaticlabs/prysm/io/file" pb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/validator-client" - prysmTime "github.com/prysmaticlabs/prysm/time" "github.com/prysmaticlabs/prysm/validator/accounts/wallet" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" ) -var ( - tokenExpiryLength = time.Hour -) - const ( authTokenFileName = "auth-token" ) -// CreateAuthToken generates a new jwt key, token, and expiration and writes them +// CreateAuthToken generates a new jwt key, token and writes them // to a file in the specified directory. Also, it logs out a prepared URL // for the user to navigate to and authenticate with the Prysm web interface. func CreateAuthToken(walletDirPath, validatorWebAddr string) error { @@ -41,16 +34,16 @@ func CreateAuthToken(walletDirPath, validatorWebAddr string) error { if err != nil { return err } - token, expr, err := createTokenString(jwtKey) + token, err := createTokenString(jwtKey) if err != nil { return err } authTokenPath := filepath.Join(walletDirPath, authTokenFileName) log.Infof("Generating auth token and saving it to %s", authTokenPath) - if err := saveAuthToken(walletDirPath, jwtKey, token, expr); err != nil { + if err := saveAuthToken(walletDirPath, jwtKey, token); err != nil { return err } - logValidatorWebAuth(validatorWebAddr, token, expr) + logValidatorWebAuth(validatorWebAddr, token) return nil } @@ -72,61 +65,51 @@ func (s *Server) Initialize(_ context.Context, _ *emptypb.Empty) (*pb.Initialize // user via stdout and the validator client should then attempt to open the default // browser. The web interface authenticates by looking for this token in the query parameters // of the URL. This token is then used as the bearer token for jwt auth. -func (s *Server) initializeAuthToken(walletDir string) (string, uint64, error) { +func (s *Server) initializeAuthToken(walletDir string) (string, error) { authTokenFile := filepath.Join(walletDir, authTokenFileName) if file.FileExists(authTokenFile) { // #nosec G304 f, err := os.Open(authTokenFile) if err != nil { - return "", 0, err + return "", err } r := bufio.NewReader(f) jwtKeyHex, err := r.ReadString('\n') if err != nil { - return "", 0, err + return "", err } jwtKey, err := hex.DecodeString(strings.TrimSpace(jwtKeyHex)) if err != nil { - return "", 0, err + return "", err } - token, err := r.ReadString('\n') + token, _, err := r.ReadLine() if err != nil { - return "", 0, err - } - exprBytes, _, err := r.ReadLine() - if err != nil { - return "", 0, err - } - exprIntStr := strings.TrimSpace(string(exprBytes)) - expiration, err := strconv.ParseUint(exprIntStr, 10, 64) - if err != nil { - return "", 0, err + return "", err } s.jwtKey = jwtKey - return strings.TrimSpace(token), expiration, nil + return strings.TrimSpace(string(token)), nil } jwtKey, err := createRandomJWTSecret() if err != nil { - return "", 0, err + return "", err } s.jwtKey = jwtKey - token, expiration, err := createTokenString(s.jwtKey) + token, err := createTokenString(s.jwtKey) if err != nil { - return "", 0, err + return "", err } - if err := saveAuthToken(walletDir, jwtKey, token, expiration); err != nil { - return "", 0, err + if err := saveAuthToken(walletDir, jwtKey, token); err != nil { + return "", err } - return token, expiration, nil + return token, nil } -func logValidatorWebAuth(validatorWebAddr, token string, expr uint64) { - webAuthURLTemplate := "http://%s/initialize?token=%s&expiration=%d" +func logValidatorWebAuth(validatorWebAddr, token string) { + webAuthURLTemplate := "http://%s/initialize?token=%s" webAuthURL := fmt.Sprintf( webAuthURLTemplate, validatorWebAddr, url.QueryEscape(token), - expr, ) log.Infof( "Once your validator process is runinng, navigate to the link below to authenticate with " + @@ -135,7 +118,7 @@ func logValidatorWebAuth(validatorWebAddr, token string, expr uint64) { log.Info(webAuthURL) } -func saveAuthToken(walletDirPath string, jwtKey []byte, token string, expiration uint64) error { +func saveAuthToken(walletDirPath string, jwtKey []byte, token string) error { hashFilePath := filepath.Join(walletDirPath, authTokenFileName) bytesBuf := new(bytes.Buffer) if _, err := bytesBuf.Write([]byte(fmt.Sprintf("%x", jwtKey))); err != nil { @@ -150,26 +133,18 @@ func saveAuthToken(walletDirPath string, jwtKey []byte, token string, expiration if _, err := bytesBuf.Write([]byte("\n")); err != nil { return err } - if _, err := bytesBuf.Write([]byte(fmt.Sprintf("%d", expiration))); err != nil { - return err - } return file.WriteFile(hashFilePath, bytesBuf.Bytes()) } -// Creates a JWT token string using the JWT key with an expiration timestamp. -func createTokenString(jwtKey []byte) (string, uint64, error) { - // Create a new token object, specifying signing method and the claims - // you would like it to contain. - expirationTime := prysmTime.Now().Add(tokenExpiryLength) - token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{ - ExpiresAt: expirationTime.Unix(), - }) +// Creates a JWT token string using the JWT key. +func createTokenString(jwtKey []byte) (string, error) { + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{}) // Sign and get the complete encoded token as a string using the secret tokenString, err := token.SignedString(jwtKey) if err != nil { - return "", 0, err + return "", err } - return tokenString, uint64(expirationTime.Unix()), nil + return tokenString, nil } func createRandomJWTSecret() ([]byte, error) { diff --git a/validator/rpc/auth_token_test.go b/validator/rpc/auth_token_test.go index 0a4f4fd051..aff688d1a9 100644 --- a/validator/rpc/auth_token_test.go +++ b/validator/rpc/auth_token_test.go @@ -26,7 +26,7 @@ func TestServer_AuthenticateUsingExistingToken(t *testing.T) { t.Cleanup(func() { require.NoError(t, os.RemoveAll(walletDir)) }) - token, _, err := srv.initializeAuthToken(walletDir) + token, err := srv.initializeAuthToken(walletDir) require.NoError(t, err) require.Equal(t, true, len(srv.jwtKey) > 0) @@ -47,7 +47,7 @@ func TestServer_AuthenticateUsingExistingToken(t *testing.T) { // Next up, we make the same request but reinitialize the server and we should still // pass with the same auth token. srv = &Server{} - _, _, err = srv.initializeAuthToken(walletDir) + _, err = srv.initializeAuthToken(walletDir) require.NoError(t, err) require.Equal(t, true, len(srv.jwtKey) > 0) _, err = srv.JWTInterceptor()(ctx, "xyz", unaryInfo, unaryHandler) @@ -62,13 +62,13 @@ func Test_initializeAuthToken(t *testing.T) { t.Cleanup(func() { require.NoError(t, os.RemoveAll(walletDir)) }) - token, _, err := srv.initializeAuthToken(walletDir) + token, err := srv.initializeAuthToken(walletDir) require.NoError(t, err) require.Equal(t, true, len(srv.jwtKey) > 0) // Initializing second time, we generate something from the initial file. srv2 := &Server{} - token2, _, err := srv2.initializeAuthToken(walletDir) + token2, err := srv2.initializeAuthToken(walletDir) require.NoError(t, err) require.Equal(t, true, bytes.Equal(srv.jwtKey, srv2.jwtKey)) require.Equal(t, token, token2) @@ -78,7 +78,7 @@ func Test_initializeAuthToken(t *testing.T) { require.NoError(t, os.RemoveAll(walletDir)) srv3 := &Server{} walletDir = setupWalletDir(t) - token3, _, err := srv3.initializeAuthToken(walletDir) + token3, err := srv3.initializeAuthToken(walletDir) require.NoError(t, err) require.Equal(t, true, len(srv.jwtKey) > 0) require.NotEqual(t, token, token3) diff --git a/validator/rpc/intercepter_test.go b/validator/rpc/intercepter_test.go index aa79f43cf8..578329551d 100644 --- a/validator/rpc/intercepter_test.go +++ b/validator/rpc/intercepter_test.go @@ -6,7 +6,6 @@ import ( "github.com/golang-jwt/jwt" "github.com/prysmaticlabs/prysm/testing/require" - "github.com/prysmaticlabs/prysm/time" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) @@ -23,7 +22,7 @@ func TestServer_JWTInterceptor_Verify(t *testing.T) { unaryHandler := func(ctx context.Context, req interface{}) (interface{}, error) { return nil, nil } - token, _, err := createTokenString(s.jwtKey) + token, err := createTokenString(s.jwtKey) require.NoError(t, err) ctxMD := map[string][]string{ "authorization": {"Bearer " + token}, @@ -50,7 +49,7 @@ func TestServer_JWTInterceptor_BadToken(t *testing.T) { badServer := Server{ jwtKey: []byte("badTestKey"), } - token, _, err := createTokenString(badServer.jwtKey) + token, err := createTokenString(badServer.jwtKey) require.NoError(t, err) ctxMD := map[string][]string{ "authorization": {"Bearer " + token}, @@ -63,11 +62,8 @@ func TestServer_JWTInterceptor_BadToken(t *testing.T) { func TestServer_JWTInterceptor_InvalidSigningType(t *testing.T) { ss := &Server{jwtKey: make([]byte, 32)} - expirationTime := time.Now().Add(tokenExpiryLength) // Use a different signing type than the expected, HMAC. - token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.StandardClaims{ - ExpiresAt: expirationTime.Unix(), - }) + token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.StandardClaims{}) _, err := ss.validateJWT(token) require.ErrorContains(t, "unexpected JWT signing method", err) } diff --git a/validator/rpc/server.go b/validator/rpc/server.go index 083ba1feff..580530e4f4 100644 --- a/validator/rpc/server.go +++ b/validator/rpc/server.go @@ -189,13 +189,13 @@ func (s *Server) Start() { } }() log.WithField("address", address).Info("gRPC server listening on address") - token, expr, err := s.initializeAuthToken(s.walletDir) + token, err := s.initializeAuthToken(s.walletDir) if err != nil { log.Errorf("Could not initialize web auth token: %v", err) return } validatorWebAddr := fmt.Sprintf("%s:%d", s.validatorGatewayHost, s.validatorGatewayPort) - logValidatorWebAuth(validatorWebAddr, token, expr) + logValidatorWebAuth(validatorWebAddr, token) } // Stop the gRPC server.