From 3ccb09415b5236c50e2ff48a7c53493de8818c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Tue, 30 Apr 2024 10:55:22 +0200 Subject: [PATCH] Use a real Trino server for TLS integration test --- trino/etc/config.properties | 2 +- trino/etc/password-authenticator.properties | 2 + trino/etc/secrets/password.db | 1 + trino/integration_test.go | 21 ++- trino/integration_tls_test.go | 145 -------------------- 5 files changed, 24 insertions(+), 147 deletions(-) create mode 100644 trino/etc/password-authenticator.properties create mode 100644 trino/etc/secrets/password.db delete mode 100644 trino/integration_tls_test.go diff --git a/trino/etc/config.properties b/trino/etc/config.properties index 3eac336..d4d09aa 100644 --- a/trino/etc/config.properties +++ b/trino/etc/config.properties @@ -5,7 +5,7 @@ http-server.http.port=8080 discovery-server.enabled=true discovery.uri=http://localhost:8080 -http-server.authentication.type=JWT +http-server.authentication.type=PASSWORD,JWT http-server.authentication.jwt.key-file=/etc/trino/secrets/public_key.pem http-server.https.enabled=true http-server.https.port=8443 diff --git a/trino/etc/password-authenticator.properties b/trino/etc/password-authenticator.properties new file mode 100644 index 0000000..b9f5798 --- /dev/null +++ b/trino/etc/password-authenticator.properties @@ -0,0 +1,2 @@ +password-authenticator.name=file +file.password-file=/etc/trino/secrets/password.db diff --git a/trino/etc/secrets/password.db b/trino/etc/secrets/password.db new file mode 100644 index 0000000..0dc49d3 --- /dev/null +++ b/trino/etc/secrets/password.db @@ -0,0 +1 @@ +admin:$2y$10$xLVM/FUuZaNEmGOU3y7fjOLzRJOGItnTWTiFVKwIFX.ZMBctxl8gq diff --git a/trino/integration_test.go b/trino/integration_test.go index ecd8e08..4353a24 100644 --- a/trino/integration_test.go +++ b/trino/integration_test.go @@ -128,7 +128,7 @@ func TestMain(m *testing.M) { log.Fatalf("Timed out waiting for container to get ready: %s\nContainer logs:\n%s", err, logs) } *integrationServerFlag = "http://test@localhost:" + resource.GetPort("8080/tcp") - tlsServer = "https://test@localhost:" + resource.GetPort("8443/tcp") + tlsServer = "https://admin:admin@localhost:" + resource.GetPort("8443/tcp") http.DefaultTransport.(*http.Transport).TLSClientConfig, err = getTLSConfig(wd + "/etc/secrets") if err != nil { @@ -951,6 +951,25 @@ func generateToken() (string, error) { return signedToken, nil } +func TestIntegrationTLS(t *testing.T) { + if tlsServer == "" { + t.Skip("Skipping TLS test when using a custom integration server.") + } + + dsn := tlsServer + db := integrationOpen(t, dsn) + + defer db.Close() + row := db.QueryRow("SELECT 1") + var count int + if err := row.Scan(&count); err != nil { + t.Fatal(err) + } + if count != 1 { + t.Fatal("unexpected count=", count) + } +} + func contextSleep(ctx context.Context, d time.Duration) error { timer := time.NewTimer(100 * time.Millisecond) select { diff --git a/trino/integration_tls_test.go b/trino/integration_tls_test.go deleted file mode 100644 index 886b254..0000000 --- a/trino/integration_tls_test.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build go1.9 -// +build go1.9 - -package trino - -import ( - "bytes" - "crypto/tls" - "database/sql" - "io" - "net/http" - "net/http/httptest" - "net/url" - "strings" - "sync" - "testing" -) - -func TestIntegrationTLS(t *testing.T) { - if testing.Short() { - t.Skip("Skipping test in short mode.") - } - proxyServer := newTLSReverseProxy(t) - defer proxyServer.Close() - RegisterCustomClient("test_tls", proxyServer.Client()) - defer DeregisterCustomClient("test_tls") - dsn := proxyServer.URL + "?custom_client=test_tls" - testSimpleQuery(t, dsn) -} - -func TestIntegrationInsecureTLS(t *testing.T) { - if testing.Short() { - t.Skip("Skipping test in short mode.") - } - proxyServer := newTLSReverseProxy(t) - defer proxyServer.Close() - RegisterCustomClient("test_insecure_tls", &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - }, - }) - defer DeregisterCustomClient("test_insecure_tls") - dsn := proxyServer.URL + "?custom_client=test_insecure_tls" - testSimpleQuery(t, dsn) -} - -func testSimpleQuery(t *testing.T, dsn string) { - db, err := sql.Open("trino", dsn) - if err != nil { - t.Fatal(err) - } - defer db.Close() - row := db.QueryRow("SELECT 1") - var count int - if err = row.Scan(&count); err != nil { - t.Fatal(err) - } - if count != 1 { - t.Fatal("unexpected count=", count) - } -} - -// hax0r reverse tls proxy for integration tests - -// newTLSReverseProxy creates a TLS integration test server. -func newTLSReverseProxy(t *testing.T) *httptest.Server { - dsn := *integrationServerFlag - serverURL, _ := url.Parse(dsn) - cproxyURL := make(chan string, 1) - handler := newReverseProxyHandler(serverURL, cproxyURL) - srv := httptest.NewTLSServer(http.HandlerFunc(handler)) - cproxyURL <- srv.URL - close(cproxyURL) - proxyURL, _ := url.Parse(srv.URL) - proxyURL.User = serverURL.User - proxyURL.Path = serverURL.Path - proxyURL.RawPath = serverURL.RawPath - proxyURL.RawQuery = serverURL.RawQuery - srv.URL = proxyURL.String() - return srv -} - -// newReverseProxyHandler creates an http handler that proxies requests to the given serverUrl, and replaces URLs in responses with the first value sent to the cproxyURL channel. -func newReverseProxyHandler(serverURL *url.URL, cproxyURL chan string) http.HandlerFunc { - baseURL := []byte(serverURL.Scheme + "://" + serverURL.Host) - var proxyURL []byte - var onceProxyURL sync.Once - return func(w http.ResponseWriter, r *http.Request) { - onceProxyURL.Do(func() { - proxyURL = []byte(<-cproxyURL) - }) - target := *serverURL - target.User = nil - target.Path = r.URL.Path - target.RawPath = r.URL.RawPath - target.RawQuery = r.URL.RawQuery - req, err := http.NewRequest(r.Method, target.String(), r.Body) - if err != nil { - http.Error(w, err.Error(), http.StatusServiceUnavailable) - return - } - for k, v := range r.Header { - if strings.HasPrefix(k, "X-") { - req.Header[k] = v - } - } - client := *http.DefaultClient - client.Timeout = *integrationServerQueryTimeout - resp, err := client.Do(req) - if err != nil { - http.Error(w, err.Error(), http.StatusServiceUnavailable) - return - } - defer resp.Body.Close() - w.WriteHeader(resp.StatusCode) - pr, pw := io.Pipe() - go func() { - b, err := io.ReadAll(resp.Body) - if err != nil { - pw.CloseWithError(err) - return - } - b = bytes.Replace(b, baseURL, proxyURL, -1) - pw.Write(b) - pw.Close() - }() - io.Copy(w, pr) - } -}