From 7fa029c3b3950e6663ac7f40f2378624f2d49eb2 Mon Sep 17 00:00:00 2001 From: eshitachandwani Date: Mon, 2 Dec 2024 10:56:07 +0530 Subject: [PATCH] added auth test --- test/proxy_test.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/test/proxy_test.go b/test/proxy_test.go index 0feb87637631..f98c8a5c0821 100644 --- a/test/proxy_test.go +++ b/test/proxy_test.go @@ -20,6 +20,7 @@ package test import ( "context" + "encoding/base64" "fmt" "net" "net/http" @@ -568,3 +569,98 @@ func (s) TestGrpcNewClientWithContextDialer(t *testing.T) { default: } } + +// TestBasicAuthInGrpcNewClientWithProxy tests grpc.NewClient with default i.e +// DNS resolver for targetURI and a proxy and verifies that it connects to proxy +// server and sends unresolved target URI in the HTTP CONNECT req and connects +// to backend. Also verifies that correct user info is sent in the CONNECT. +func (s) TestBasicAuthInGrpcNewClientWithProxy(t *testing.T) { + // Set up a channel to receive signals from OnClientResolution. + resolutionCh := make(chan bool, 1) + + // Overwrite OnClientResolution to send a signal to the channel. + origOnClientResolution := delegatingresolver.OnClientResolution + delegatingresolver.OnClientResolution = func(int) { + resolutionCh <- true + } + t.Cleanup(func() { delegatingresolver.OnClientResolution = origOnClientResolution }) + + // Create and start a backend server. + backendAddr := createAndStartBackendServer(t) + const ( + user = "notAUser" + password = "notAPassword" + ) + // Set up and start the proxy server. + proxyLis, errCh, doneCh, _ := setupProxy(t, backendAddr, false, func(req *http.Request) error { + if req.Method != http.MethodConnect { + return fmt.Errorf("unexpected Method %q, want %q", req.Method, http.MethodConnect) + } + if req.URL.Host != unresolvedTargetURI { + return fmt.Errorf("unexpected URL.Host %q, want %q", req.URL.Host, unresolvedTargetURI) + } + wantProxyAuthStr := "Basic " + base64.StdEncoding.EncodeToString([]byte(user+":"+password)) + if got := req.Header.Get("Proxy-Authorization"); got != wantProxyAuthStr { + gotDecoded, _ := base64.StdEncoding.DecodeString(got) + wantDecoded, _ := base64.StdEncoding.DecodeString(wantProxyAuthStr) + return fmt.Errorf("unexpected auth %q (%q), want %q (%q)", got, gotDecoded, wantProxyAuthStr, wantDecoded) + } + return nil + }) + + // Overwrite the proxy resolution function and restore it afterward. + hpfe := func(req *http.Request) (*url.URL, error) { + if req.URL.Host == unresolvedTargetURI { + u := url.URL{ + Scheme: "https", + Host: unresolvedProxyURI, + } + u.User = url.UserPassword(user, password) + return &u, nil + } + return nil, nil + } + defer overwriteAndRestore(hpfe)() + + // Set up a manual resolver for proxy resolution. + mrProxy := setupDNS(t) + + // Update the proxy resolver state with the proxy's address. + mrProxy.InitialState(resolver.State{ + Addresses: []resolver.Address{ + {Addr: proxyLis.Addr().String()}, + }, + }) + + // Dial to the proxy server. + ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) + defer cancel() + + conn, err := grpc.NewClient(unresolvedTargetURI, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + t.Fatalf("grpc.NewClient failed: %v", err) + } + defer conn.Close() + + // Send an RPC to the backend through the proxy. + client := testgrpc.NewTestServiceClient(conn) + if _, err := client.EmptyCall(ctx, &testgrpc.Empty{}); err != nil { + t.Errorf("EmptyCall failed: %v", err) + } + + // Verify if the proxy server encountered any errors. + select { + case err := <-errCh: + t.Fatalf("proxy server encountered an error: %v", err) + case <-doneCh: + t.Logf("proxy server succeeded") + } + + // Verify if OnClientResolution was triggered. + select { + case <-resolutionCh: + t.Error("Client-side resolution was unexpectedly called") + default: + // Success: OnClientResolution was not called. + } +}