2020-07-02 17:50:05 +00:00
|
|
|
package client
|
2019-01-23 02:52:39 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
fix(grpcHeaders): accept values with "=" symbols (#8047)
* fix(grpcHeaders): accept values with equal signs
# What
Before this commit, it was not possible to pass in base64-encoded
content as a header value if it contained an equals sign. This commit
changes the behavior slightly. Rather than ignore key/value pairs where
the value happens to have an equals sign, we assume the first equals
sign delimits the key from the value and pass in the rest of the value
as-is.
Also, instead of printing the header name along with its value, we
print the name, so there is less risk of leaking information into logs
that shouldn't be there.
# Testing
This has not been tested in the context of the full validator client.
Instead, a small example was made to demonstrate the feasibility. The
example is shown here:
```go
package main
import (
"log"
"os"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/urfave/cli/v2"
)
type Config struct {
GrpcHeadersFlag string
}
func main() {
app := &cli.App{
Action: func(c *cli.Context) error {
for _, hdr := range strings.Split(c.String("grpc-headers"), ",") {
if hdr != "" {
ss := strings.Split(hdr, "=")
spew.Dump(ss[0])
spew.Dump(strings.Join(ss[1:], "="))
}
}
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "grpc-headers",
Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " +
"calls. Example: --grpc-headers=key=value",
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
```
Example invocation:
```command
❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)"
(string) (len=3) "key"
(string) (len=5) "value"
(string) (len=13) "Authorization"
(string) (len=22) "Basic aGVsbG86d29ybGQ="
```
* Adds tests to new gRPC header parsing code
* bazel run //:gazelle
2020-12-04 21:31:15 +00:00
|
|
|
"strings"
|
2019-01-23 02:52:39 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2021-09-17 19:20:50 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/runtime"
|
2020-07-21 13:02:21 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
|
|
|
|
"github.com/prysmaticlabs/prysm/shared/testutil/require"
|
2019-01-30 12:28:53 +00:00
|
|
|
logTest "github.com/sirupsen/logrus/hooks/test"
|
fix(grpcHeaders): accept values with "=" symbols (#8047)
* fix(grpcHeaders): accept values with equal signs
# What
Before this commit, it was not possible to pass in base64-encoded
content as a header value if it contained an equals sign. This commit
changes the behavior slightly. Rather than ignore key/value pairs where
the value happens to have an equals sign, we assume the first equals
sign delimits the key from the value and pass in the rest of the value
as-is.
Also, instead of printing the header name along with its value, we
print the name, so there is less risk of leaking information into logs
that shouldn't be there.
# Testing
This has not been tested in the context of the full validator client.
Instead, a small example was made to demonstrate the feasibility. The
example is shown here:
```go
package main
import (
"log"
"os"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/urfave/cli/v2"
)
type Config struct {
GrpcHeadersFlag string
}
func main() {
app := &cli.App{
Action: func(c *cli.Context) error {
for _, hdr := range strings.Split(c.String("grpc-headers"), ",") {
if hdr != "" {
ss := strings.Split(hdr, "=")
spew.Dump(ss[0])
spew.Dump(strings.Join(ss[1:], "="))
}
}
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "grpc-headers",
Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " +
"calls. Example: --grpc-headers=key=value",
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
```
Example invocation:
```command
❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)"
(string) (len=3) "key"
(string) (len=5) "value"
(string) (len=13) "Authorization"
(string) (len=22) "Basic aGVsbG86d29ybGQ="
```
* Adds tests to new gRPC header parsing code
* bazel run //:gazelle
2020-12-04 21:31:15 +00:00
|
|
|
"google.golang.org/grpc/metadata"
|
2019-01-23 02:52:39 +00:00
|
|
|
)
|
|
|
|
|
2021-09-17 19:20:50 +00:00
|
|
|
var _ runtime.Service = (*ValidatorService)(nil)
|
2020-11-27 18:28:45 +00:00
|
|
|
var _ GenesisFetcher = (*ValidatorService)(nil)
|
|
|
|
var _ SyncChecker = (*ValidatorService)(nil)
|
2019-04-20 11:24:40 +00:00
|
|
|
|
2019-02-22 15:11:26 +00:00
|
|
|
func TestStop_CancelsContext(t *testing.T) {
|
2019-01-23 02:52:39 +00:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
vs := &ValidatorService{
|
|
|
|
ctx: ctx,
|
|
|
|
cancel: cancel,
|
|
|
|
}
|
|
|
|
|
2020-07-21 13:02:21 +00:00
|
|
|
assert.NoError(t, vs.Stop())
|
2019-01-23 02:52:39 +00:00
|
|
|
|
|
|
|
select {
|
|
|
|
case <-time.After(1 * time.Second):
|
2020-02-14 16:46:55 +00:00
|
|
|
t.Error("Context not canceled within 1s")
|
2019-01-23 02:52:39 +00:00
|
|
|
case <-vs.ctx.Done():
|
|
|
|
}
|
|
|
|
}
|
2019-01-30 12:28:53 +00:00
|
|
|
|
|
|
|
func TestLifecycle(t *testing.T) {
|
|
|
|
hook := logTest.NewGlobal()
|
2019-04-26 06:24:01 +00:00
|
|
|
// Use canceled context so that the run function exits immediately..
|
2019-01-30 12:28:53 +00:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
cancel()
|
2019-02-14 20:51:40 +00:00
|
|
|
validatorService := &ValidatorService{
|
2020-10-14 22:20:20 +00:00
|
|
|
ctx: ctx,
|
|
|
|
cancel: cancel,
|
|
|
|
endpoint: "merkle tries",
|
|
|
|
withCert: "alice.crt",
|
2019-02-13 23:49:06 +00:00
|
|
|
}
|
2019-01-30 12:28:53 +00:00
|
|
|
validatorService.Start()
|
2020-07-21 13:02:21 +00:00
|
|
|
require.NoError(t, validatorService.Stop(), "Could not stop service")
|
2020-08-13 16:22:25 +00:00
|
|
|
require.LogsContain(t, hook, "Stopping service")
|
2019-01-30 12:28:53 +00:00
|
|
|
}
|
|
|
|
|
2019-02-22 15:11:26 +00:00
|
|
|
func TestLifecycle_Insecure(t *testing.T) {
|
2019-01-30 12:28:53 +00:00
|
|
|
hook := logTest.NewGlobal()
|
2019-04-26 06:24:01 +00:00
|
|
|
// Use canceled context so that the run function exits immediately.
|
2019-01-30 12:28:53 +00:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
cancel()
|
2019-02-14 20:51:40 +00:00
|
|
|
validatorService := &ValidatorService{
|
2020-10-14 22:20:20 +00:00
|
|
|
ctx: ctx,
|
|
|
|
cancel: cancel,
|
|
|
|
endpoint: "merkle tries",
|
2019-02-13 23:49:06 +00:00
|
|
|
}
|
2019-01-30 12:28:53 +00:00
|
|
|
validatorService.Start()
|
2020-08-13 16:22:25 +00:00
|
|
|
require.LogsContain(t, hook, "You are using an insecure gRPC connection")
|
2020-07-21 13:02:21 +00:00
|
|
|
require.NoError(t, validatorService.Stop(), "Could not stop service")
|
2020-08-13 16:22:25 +00:00
|
|
|
require.LogsContain(t, hook, "Stopping service")
|
2019-01-30 12:28:53 +00:00
|
|
|
}
|
|
|
|
|
2019-02-22 15:11:26 +00:00
|
|
|
func TestStatus_NoConnectionError(t *testing.T) {
|
2019-02-13 23:49:06 +00:00
|
|
|
validatorService := &ValidatorService{}
|
2020-07-21 13:02:21 +00:00
|
|
|
assert.ErrorContains(t, "no connection", validatorService.Status())
|
2019-01-30 12:28:53 +00:00
|
|
|
}
|
fix(grpcHeaders): accept values with "=" symbols (#8047)
* fix(grpcHeaders): accept values with equal signs
# What
Before this commit, it was not possible to pass in base64-encoded
content as a header value if it contained an equals sign. This commit
changes the behavior slightly. Rather than ignore key/value pairs where
the value happens to have an equals sign, we assume the first equals
sign delimits the key from the value and pass in the rest of the value
as-is.
Also, instead of printing the header name along with its value, we
print the name, so there is less risk of leaking information into logs
that shouldn't be there.
# Testing
This has not been tested in the context of the full validator client.
Instead, a small example was made to demonstrate the feasibility. The
example is shown here:
```go
package main
import (
"log"
"os"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/urfave/cli/v2"
)
type Config struct {
GrpcHeadersFlag string
}
func main() {
app := &cli.App{
Action: func(c *cli.Context) error {
for _, hdr := range strings.Split(c.String("grpc-headers"), ",") {
if hdr != "" {
ss := strings.Split(hdr, "=")
spew.Dump(ss[0])
spew.Dump(strings.Join(ss[1:], "="))
}
}
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "grpc-headers",
Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " +
"calls. Example: --grpc-headers=key=value",
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
```
Example invocation:
```command
❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)"
(string) (len=3) "key"
(string) (len=5) "value"
(string) (len=13) "Authorization"
(string) (len=22) "Basic aGVsbG86d29ybGQ="
```
* Adds tests to new gRPC header parsing code
* bazel run //:gazelle
2020-12-04 21:31:15 +00:00
|
|
|
|
|
|
|
func TestStart_GrpcHeaders(t *testing.T) {
|
|
|
|
hook := logTest.NewGlobal()
|
|
|
|
// Use canceled context so that the run function exits immediately.
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
cancel()
|
|
|
|
for input, output := range map[string][]string{
|
2020-12-11 18:31:35 +00:00
|
|
|
"should-break": {},
|
|
|
|
"key=value": {"key", "value"},
|
|
|
|
"": {},
|
|
|
|
",": {},
|
|
|
|
"key=value,Authorization=Q=": {
|
fix(grpcHeaders): accept values with "=" symbols (#8047)
* fix(grpcHeaders): accept values with equal signs
# What
Before this commit, it was not possible to pass in base64-encoded
content as a header value if it contained an equals sign. This commit
changes the behavior slightly. Rather than ignore key/value pairs where
the value happens to have an equals sign, we assume the first equals
sign delimits the key from the value and pass in the rest of the value
as-is.
Also, instead of printing the header name along with its value, we
print the name, so there is less risk of leaking information into logs
that shouldn't be there.
# Testing
This has not been tested in the context of the full validator client.
Instead, a small example was made to demonstrate the feasibility. The
example is shown here:
```go
package main
import (
"log"
"os"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/urfave/cli/v2"
)
type Config struct {
GrpcHeadersFlag string
}
func main() {
app := &cli.App{
Action: func(c *cli.Context) error {
for _, hdr := range strings.Split(c.String("grpc-headers"), ",") {
if hdr != "" {
ss := strings.Split(hdr, "=")
spew.Dump(ss[0])
spew.Dump(strings.Join(ss[1:], "="))
}
}
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "grpc-headers",
Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " +
"calls. Example: --grpc-headers=key=value",
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
```
Example invocation:
```command
❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)"
(string) (len=3) "key"
(string) (len=5) "value"
(string) (len=13) "Authorization"
(string) (len=22) "Basic aGVsbG86d29ybGQ="
```
* Adds tests to new gRPC header parsing code
* bazel run //:gazelle
2020-12-04 21:31:15 +00:00
|
|
|
"key", "value", "Authorization", "Q=",
|
|
|
|
},
|
2020-12-11 18:31:35 +00:00
|
|
|
"Authorization=this is a valid value": {
|
fix(grpcHeaders): accept values with "=" symbols (#8047)
* fix(grpcHeaders): accept values with equal signs
# What
Before this commit, it was not possible to pass in base64-encoded
content as a header value if it contained an equals sign. This commit
changes the behavior slightly. Rather than ignore key/value pairs where
the value happens to have an equals sign, we assume the first equals
sign delimits the key from the value and pass in the rest of the value
as-is.
Also, instead of printing the header name along with its value, we
print the name, so there is less risk of leaking information into logs
that shouldn't be there.
# Testing
This has not been tested in the context of the full validator client.
Instead, a small example was made to demonstrate the feasibility. The
example is shown here:
```go
package main
import (
"log"
"os"
"strings"
"github.com/davecgh/go-spew/spew"
"github.com/urfave/cli/v2"
)
type Config struct {
GrpcHeadersFlag string
}
func main() {
app := &cli.App{
Action: func(c *cli.Context) error {
for _, hdr := range strings.Split(c.String("grpc-headers"), ",") {
if hdr != "" {
ss := strings.Split(hdr, "=")
spew.Dump(ss[0])
spew.Dump(strings.Join(ss[1:], "="))
}
}
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "grpc-headers",
Usage: "A comma-separated list of key value pairs to pass as gRPC headers for all gRPC " +
"calls. Example: --grpc-headers=key=value",
},
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
```
Example invocation:
```command
❯ go run main.go --grpc-headers=key=value,Authorization="Basic $(echo -n hello:world | base64)"
(string) (len=3) "key"
(string) (len=5) "value"
(string) (len=13) "Authorization"
(string) (len=22) "Basic aGVsbG86d29ybGQ="
```
* Adds tests to new gRPC header parsing code
* bazel run //:gazelle
2020-12-04 21:31:15 +00:00
|
|
|
"Authorization", "this is a valid value",
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
validatorService := &ValidatorService{
|
|
|
|
ctx: ctx,
|
|
|
|
cancel: cancel,
|
|
|
|
endpoint: "merkle tries",
|
|
|
|
grpcHeaders: strings.Split(input, ","),
|
|
|
|
}
|
|
|
|
validatorService.Start()
|
|
|
|
md, _ := metadata.FromOutgoingContext(validatorService.ctx)
|
|
|
|
if input == "should-break" {
|
|
|
|
require.LogsContain(t, hook, "Incorrect gRPC header flag format. Skipping should-break")
|
|
|
|
} else if len(output) == 0 {
|
|
|
|
require.DeepEqual(t, md, metadata.MD(nil))
|
|
|
|
} else {
|
|
|
|
require.DeepEqual(t, md, metadata.Pairs(output...))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|