mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 07:03:58 -05:00
* Ran gopls modernize to fix everything go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./... * Override rules_go provided dependency for golang.org/x/tools to v0.38.0. To update this, checked out rules_go, then ran `bazel run //go/tools/releaser -- upgrade-dep -mirror=false org_golang_x_tools` and copied the patches. * Fix buildtag violations and ignore buildtag violations in external * Introduce modernize analyzer package. * Add modernize "any" analyzer. * Fix violations of any analyzer * Add modernize "appendclipped" analyzer. * Fix violations of appendclipped * Add modernize "bloop" analyzer. * Add modernize "fmtappendf" analyzer. * Add modernize "forvar" analyzer. * Add modernize "mapsloop" analyzer. * Add modernize "minmax" analyzer. * Fix violations of minmax analyzer * Add modernize "omitzero" analyzer. * Add modernize "rangeint" analyzer. * Fix violations of rangeint. * Add modernize "reflecttypefor" analyzer. * Fix violations of reflecttypefor analyzer. * Add modernize "slicescontains" analyzer. * Add modernize "slicessort" analyzer. * Add modernize "slicesdelete" analyzer. This is disabled by default for now. See https://go.dev/issue/73686. * Add modernize "stringscutprefix" analyzer. * Add modernize "stringsbuilder" analyzer. * Fix violations of stringsbuilder analyzer. * Add modernize "stringsseq" analyzer. * Add modernize "testingcontext" analyzer. * Add modernize "waitgroup" analyzer. * Changelog fragment * gofmt * gazelle * Add modernize "newexpr" analyzer. * Disable newexpr until go1.26 * Add more details in WORKSPACE on how to update the override * @nalepae feedback on min() * gofmt * Fix violations of forvar
234 lines
7.4 KiB
Go
234 lines
7.4 KiB
Go
package rpc
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"context"
|
|
"encoding/hex"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/OffchainLabs/prysm/v7/api"
|
|
"github.com/OffchainLabs/prysm/v7/io/file"
|
|
"github.com/OffchainLabs/prysm/v7/testing/require"
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
"github.com/golang-jwt/jwt/v4"
|
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/metadata"
|
|
)
|
|
|
|
func setupWalletDir(t testing.TB) string {
|
|
walletDir := filepath.Join(t.TempDir(), "wallet")
|
|
require.NoError(t, os.MkdirAll(walletDir, os.ModePerm))
|
|
return walletDir
|
|
}
|
|
|
|
func TestServer_AuthenticateUsingExistingToken(t *testing.T) {
|
|
// Initializing for the first time, there is no auth token file in
|
|
// the wallet directory, so we generate a jwt token and secret from scratch.
|
|
walletDir := setupWalletDir(t)
|
|
authTokenPath := filepath.Join(walletDir, api.AuthTokenFileName)
|
|
srv := &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
|
|
err := srv.initializeAuthToken()
|
|
require.NoError(t, err)
|
|
|
|
unaryInfo := &grpc.UnaryServerInfo{
|
|
FullMethod: "Proto.CreateWallet",
|
|
}
|
|
unaryHandler := func(ctx context.Context, req any) (any, error) {
|
|
return nil, nil
|
|
}
|
|
ctxMD := map[string][]string{
|
|
"authorization": {"Bearer " + srv.authToken},
|
|
}
|
|
ctx := t.Context()
|
|
ctx = metadata.NewIncomingContext(ctx, ctxMD)
|
|
_, err = srv.AuthTokenInterceptor()(ctx, "xyz", unaryInfo, unaryHandler)
|
|
require.NoError(t, err)
|
|
|
|
// Next up, we make the same request but reinitialize the server and we should still
|
|
// pass with the same auth token.
|
|
srv = &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
err = srv.initializeAuthToken()
|
|
require.NoError(t, err)
|
|
_, err = srv.AuthTokenInterceptor()(ctx, "xyz", unaryInfo, unaryHandler)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestServer_RefreshAuthTokenOnFileChange(t *testing.T) {
|
|
// Initializing for the first time, there is no auth token file in
|
|
// the wallet directory, so we generate a jwt token and secret from scratch.
|
|
walletDir := setupWalletDir(t)
|
|
authTokenPath := filepath.Join(walletDir, api.AuthTokenFileName)
|
|
srv := &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
|
|
err := srv.initializeAuthToken()
|
|
require.NoError(t, err)
|
|
currentToken := srv.authToken
|
|
|
|
ctx, cancel := context.WithCancel(t.Context())
|
|
defer cancel()
|
|
go srv.refreshAuthTokenFromFileChanges(ctx, srv.authTokenPath)
|
|
|
|
// Wait for service to be ready.
|
|
time.Sleep(time.Millisecond * 250)
|
|
|
|
// Update the auth token file with a new secret.
|
|
require.NoError(t, CreateAuthToken(srv.authTokenPath, "localhost:7500"))
|
|
|
|
// The service should have picked up the file change and set the jwt secret to the new one.
|
|
time.Sleep(time.Millisecond * 500)
|
|
newToken := srv.authToken
|
|
require.Equal(t, true, currentToken != newToken)
|
|
err = os.Remove(srv.authTokenPath)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// TODO: remove this test when legacy files are removed
|
|
func TestServer_LegacyTokensStillWork(t *testing.T) {
|
|
hook := logTest.NewGlobal()
|
|
// Initializing for the first time, there is no auth token file in
|
|
// the wallet directory, so we generate a jwt token and secret from scratch.
|
|
walletDir := setupWalletDir(t)
|
|
authTokenPath := filepath.Join(walletDir, api.AuthTokenFileName)
|
|
|
|
bytesBuf := new(bytes.Buffer)
|
|
_, err := bytesBuf.WriteString("b5bbbaf533b625a93741978857f13d7adeca58445a1fb00ecf3373420b92776c")
|
|
require.NoError(t, err)
|
|
_, err = bytesBuf.WriteString("\n")
|
|
require.NoError(t, err)
|
|
_, err = bytesBuf.WriteString("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.MxwOozSH-TLbW_XKepjyYDHm2IT8Ki0tD3AHuajfNMg")
|
|
require.NoError(t, err)
|
|
_, err = bytesBuf.WriteString("\n")
|
|
require.NoError(t, err)
|
|
err = file.MkdirAll(walletDir)
|
|
require.NoError(t, err)
|
|
|
|
err = file.WriteFile(authTokenPath, bytesBuf.Bytes())
|
|
require.NoError(t, err)
|
|
|
|
srv := &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
|
|
err = srv.initializeAuthToken()
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, hexutil.Encode(srv.jwtSecret), "0xb5bbbaf533b625a93741978857f13d7adeca58445a1fb00ecf3373420b92776c")
|
|
require.Equal(t, srv.authToken, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.MxwOozSH-TLbW_XKepjyYDHm2IT8Ki0tD3AHuajfNMg")
|
|
|
|
f, err := os.Open(filepath.Clean(srv.authTokenPath))
|
|
require.NoError(t, err)
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
var lines []string
|
|
|
|
// Scan the file and collect lines, excluding empty lines
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if strings.TrimSpace(line) != "" {
|
|
lines = append(lines, line)
|
|
}
|
|
}
|
|
require.Equal(t, len(lines), 2)
|
|
require.LogsContain(t, hook, "Auth token does not follow our standards and should be regenerated")
|
|
// Check for scanning errors
|
|
err = scanner.Err()
|
|
require.NoError(t, err)
|
|
err = f.Close()
|
|
require.NoError(t, err)
|
|
|
|
err = os.Remove(srv.authTokenPath)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// TODO: remove this test when legacy files are removed
|
|
func TestServer_LegacyTokensBadSecret(t *testing.T) {
|
|
// Initializing for the first time, there is no auth token file in
|
|
// the wallet directory, so we generate a jwt token and secret from scratch.
|
|
walletDir := setupWalletDir(t)
|
|
authTokenPath := filepath.Join(walletDir, api.AuthTokenFileName)
|
|
|
|
bytesBuf := new(bytes.Buffer)
|
|
_, err := bytesBuf.WriteString("----------------")
|
|
require.NoError(t, err)
|
|
_, err = bytesBuf.WriteString("\n")
|
|
require.NoError(t, err)
|
|
_, err = bytesBuf.WriteString("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.MxwOozSH-TLbW_XKepjyYDHm2IT8Ki0tD3AHuajfNMg")
|
|
require.NoError(t, err)
|
|
_, err = bytesBuf.WriteString("\n")
|
|
require.NoError(t, err)
|
|
err = file.MkdirAll(walletDir)
|
|
require.NoError(t, err)
|
|
|
|
err = file.WriteFile(authTokenPath, bytesBuf.Bytes())
|
|
require.NoError(t, err)
|
|
|
|
srv := &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
|
|
err = srv.initializeAuthToken()
|
|
require.ErrorContains(t, "could not decode JWT secret", err)
|
|
}
|
|
|
|
func Test_initializeAuthToken(t *testing.T) {
|
|
// Initializing for the first time, there is no auth token file in
|
|
// the wallet directory, so we generate a jwt token and secret from scratch.
|
|
walletDir := setupWalletDir(t)
|
|
authTokenPath := filepath.Join(walletDir, api.AuthTokenFileName)
|
|
srv := &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
err := srv.initializeAuthToken()
|
|
require.NoError(t, err)
|
|
|
|
// Initializing second time, we generate something from the initial file.
|
|
srv2 := &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
err = srv2.initializeAuthToken()
|
|
require.NoError(t, err)
|
|
require.Equal(t, srv.authToken, srv2.authToken)
|
|
|
|
// Deleting the auth token and re-initializing means we create a jwt token
|
|
// and secret from scratch again.
|
|
walletDir = setupWalletDir(t)
|
|
authTokenPath = filepath.Join(walletDir, api.AuthTokenFileName)
|
|
srv3 := &Server{
|
|
authTokenPath: authTokenPath,
|
|
}
|
|
|
|
err = srv3.initializeAuthToken()
|
|
require.NoError(t, err)
|
|
require.NotEqual(t, srv.authToken, srv3.authToken)
|
|
}
|
|
|
|
// "createTokenString" now uses jwt.RegisteredClaims instead of jwt.StandardClaims (deprecated),
|
|
// make sure empty jwt.RegisteredClaims and empty jwt.StandardClaims generates the same token.
|
|
func Test_UseRegisteredClaimInsteadOfStandClaims(t *testing.T) {
|
|
jwtsecret, err := hex.DecodeString("12345678900123456789abcdeffedcba")
|
|
require.NoError(t, err)
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{}) // jwt.StandardClaims is deprecated
|
|
wantedTokenString, err := token.SignedString(jwtsecret)
|
|
require.NoError(t, err)
|
|
|
|
gotTokenString, err := createTokenString(jwtsecret)
|
|
require.NoError(t, err)
|
|
|
|
if wantedTokenString != gotTokenString {
|
|
t.Errorf("%s != %s", wantedTokenString, gotTokenString)
|
|
}
|
|
}
|