Repository: grpc/grpc-go
File: credentials/jwt/token_file_call_creds_ext_test.go (Go)

Code before:
	token := createTestJWT(t, time.Now().Add(time.Hour))
	tokenFile := writeTempTokenFile(t, token)

	jwtCreds, err := jwt.NewTokenFileCallCredentials(tokenFile)
	if err != nil {
		t.Fatalf("NewTokenFileCallCredentials(%q) failed: %v", tokenFile, err)
	}

	ss := &stubserver.StubServer{}
	if err := ss.StartServer(grpc.Creds(insecure.NewCredentials())); err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}
	defer ss.Stop()

	cc, err := grpc.NewClient(ss.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		t.Fatalf("grpc.NewClient(%q) failed: %v", ss.Address, err)
	}
	defer cc.Close()

	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()

	client := testgrpc.NewTestServiceClient(cc)
	_, err = client.EmptyCall(ctx, &testpb.Empty{}, grpc.PerRPCCredentials(jwtCreds))

	if err == nil || !strings.Contains(err.Error(), "cannot send secure credentials on an insecure connection") {
		t.Fatalf("EmptyCall() error = %v; want error containing %q", err, "cannot send secure credentials on an insecure connection")
	}
}

// TestJWTCallCredentials_InsecureTransport_AsDialOption verifies that when JWT
// call credentials are passed as a dial option over an insecure transport, the
// client creation fails with a meaningful error.
func TestJWTCallCredentials_InsecureTransport_AsDialOption(t *testing.T) {
	token := createTestJWT(t, time.Now().Add(time.Hour))
	tokenFile := writeTempTokenFile(t, token)

	jwtCreds, err := jwt.NewTokenFileCallCredentials(tokenFile)
	if err != nil {
		t.Fatalf("NewTokenFileCallCredentials(%q) failed: %v", tokenFile, err)
	}

	ss := &stubserver.StubServer{}
	if err := ss.StartServer(grpc.Creds(insecure.NewCredentials())); err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}
	defer ss.Stop()

	_, err = grpc.NewClient(ss.Address,
		grpc.WithTransportCredentials(insecure.NewCredentials()),

Review comment (security):
Nit: Please consider defining a `const wantErr = "cannot send secure credentials on an insecure connection"`. That way, the subsequent conditional statement and the error string will be shorter and easier to read.

Code after:
// transport, the RPC fails with a meaningful error.
func TestJWTCallCredentials_InsecureTransport_AsCallOption(t *testing.T) {
	token := createTestJWT(t, time.Now().Add(time.Hour))
	tokenFile := writeTempTokenFile(t, token)

	jwtCreds, err := jwt.NewTokenFileCallCredentials(tokenFile)
	if err != nil {
		t.Fatalf("NewTokenFileCallCredentials(%q) failed: %v", tokenFile, err)
	}

	ss := &stubserver.StubServer{}
	if err := ss.StartServer(grpc.Creds(insecure.NewCredentials())); err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}
	defer ss.Stop()

	cc, err := grpc.NewClient(ss.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		t.Fatalf("grpc.NewClient(%q) failed: %v", ss.Address, err)
	}
	defer cc.Close()

	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()

	client := testgrpc.NewTestServiceClient(cc)
	_, err = client.EmptyCall(ctx, &testpb.Empty{}, grpc.PerRPCCredentials(jwtCreds))
	if err == nil || !strings.Contains(err.Error(), wantErr) {
		t.Fatalf("EmptyCall() error = %v; want error containing %q", err, wantErr)
	}
}

// TestJWTCallCredentials_InsecureTransport_AsDialOption verifies that when JWT
// call credentials are passed as a dial option over an insecure transport, the
// client creation fails with a meaningful error.
func TestJWTCallCredentials_InsecureTransport_AsDialOption(t *testing.T) {
	token := createTestJWT(t, time.Now().Add(time.Hour))
	tokenFile := writeTempTokenFile(t, token)

	jwtCreds, err := jwt.NewTokenFileCallCredentials(tokenFile)
	if err != nil {
		t.Fatalf("NewTokenFileCallCredentials(%q) failed: %v", tokenFile, err)
	}

	ss := &stubserver.StubServer{}
	if err := ss.StartServer(grpc.Creds(insecure.NewCredentials())); err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}
	defer ss.Stop()

	_, err = grpc.NewClient(ss.Address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(jwtCreds))