//go:build integration // +build integration package test import ( "context" "net/http" "strconv" "testing" "time" auth "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" "github.com/oauth2-proxy/mockoidc" playwright "github.com/playwright-community/playwright-go" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/testcontainers/testcontainers-go" "github.com/xlgmokha/x/pkg/env" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) func environmentVariables(srv *web.OIDCServer) map[string]string { return map[string]string{ "APP_ENV": "test", "DEBUG": env.Fetch("DEBUG", ""), "HMAC_SESSION_SECRET": "secret", "OAUTH_CLIENT_ID": srv.MockOIDC.ClientID, "OAUTH_CLIENT_SECRET": srv.MockOIDC.ClientSecret, "OIDC_ISSUER": srv.Issuer(), } } func TestContainer(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() srv := web.NewOIDCServer(t) defer srv.Close() container := NewContainer(t, ctx, environmentVariables(srv)) defer testcontainers.TerminateContainer(container) require.True(t, container.IsRunning()) sparkleEndpoint, err := container.PortEndpoint(ctx, "8080", "http") require.NoError(t, err) envoyEndpoint, err := container.PortEndpoint(ctx, "10000", "http") require.NoError(t, err) envoyAdminEndpoint, err := container.PortEndpoint(ctx, "9901", "http") require.NoError(t, err) authzdEndpoint, err := container.PortEndpoint(ctx, "10003", "") require.NoError(t, err) for _, publicPath := range []string{ envoyAdminEndpoint + "/", envoyEndpoint + "/", envoyEndpoint + "/application.js", envoyEndpoint + "/favicon.ico", envoyEndpoint + "/favicon.png", envoyEndpoint + "/health", envoyEndpoint + "/index.html", envoyEndpoint + "/logo.png", sparkleEndpoint + "/", sparkleEndpoint + "/favicon.ico", srv.DiscoveryEndpoint(), } { t.Run(publicPath, func(t *testing.T) { assert.Equal(t, http.StatusOK, HttpGet(t, ctx, publicPath).StatusCode) }) } t.Run("envoy.yaml", func(t *testing.T) { response := HttpGet(t, ctx, envoyAdminEndpoint+"/config_dump") require.Equal(t, http.StatusOK, response.StatusCode) body := JSONBody[map[string]interface{}](t, response) assert.NotEmpty(t, "listener_0", body["configs"]) }) t.Run("authzd", func(t *testing.T) { t.Run("responds to a GRPC request", func(t *testing.T) { connection, err := grpc.NewClient(authzdEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) defer connection.Close() client := auth.NewAuthorizationClient(connection) response, err := client.Check(t.Context(), &auth.CheckRequest{ Attributes: &auth.AttributeContext{ Request: &auth.AttributeContext_Request{ Http: &auth.AttributeContext_HttpRequest{ Method: "GET", Path: "/", }, }, }, }) require.NoError(t, err) assert.NotNil(t, response.GetOkResponse()) }) }) WithUI(t, func(browser playwright.Browser) { page, err := browser.NewPage() require.NoError(t, err) t.Run("initiates an OIDC login", func(t *testing.T) { require.NoError(t, page.Context().ClearCookies()) response, err := page.Goto(envoyEndpoint + "/") require.NoError(t, err) assert.True(t, response.Ok()) t.Run("redirects to the OpenID Connect Provider", func(t *testing.T) { t.Skip() code := strconv.FormatInt(time.Now().Unix(), 10) srv.MockOIDC.QueueUser(mockoidc.DefaultUser()) srv.MockOIDC.QueueCode(code) require.NoError(t, page.GetByText("Login").Click()) assert.Contains(t, page.URL(), envoyEndpoint+"/callback?code="+code) content, err := page.Content() require.NoError(t, err) assert.Contains(t, content, "Share your gratitude") }) }) }) }