github.com/verrazzano/verrazzano@v1.7.0/authproxy/src/auth/auth_test.go (about)

     1  // Copyright (c) 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package auth
     5  
     6  import (
     7  	"context"
     8  	"encoding/json"
     9  	"fmt"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"net/url"
    13  	"testing"
    14  
    15  	"github.com/coreos/go-oidc/v3/oidc"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/verrazzano/verrazzano/authproxy/internal/testutil/testserver"
    18  	"go.uber.org/zap"
    19  	"k8s.io/apimachinery/pkg/runtime"
    20  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    21  )
    22  
    23  type mockVerifier struct {
    24  	issuer string
    25  	token  string
    26  }
    27  
    28  var _ verifier = &mockVerifier{}
    29  
    30  func TestNewAuthenticator(t *testing.T) {
    31  	server := testserver.FakeOIDCProviderServer(t)
    32  
    33  	config := &OIDCConfiguration{
    34  		ExternalURL: server.URL,
    35  		ServiceURL:  server.URL,
    36  	}
    37  	client := fake.NewClientBuilder().Build()
    38  
    39  	authenticator, err := NewAuthenticator(config, zap.S(), client)
    40  	assert.NoError(t, err)
    41  	assert.NotNil(t, authenticator)
    42  	assert.Equal(t, config, authenticator.oidcConfig)
    43  	assert.Equal(t, client, authenticator.k8sClient)
    44  	assert.NotNil(t, authenticator.client)
    45  	assert.Implements(t, (*verifier)(nil), authenticator.verifier.Load())
    46  }
    47  
    48  // TestAuthenticaterRequest tests that the login redirect can be performed for a given request
    49  // GIVEN a request without an authorization header
    50  // WHEN the request is processed
    51  // THEN the redirect should occur
    52  func TestAuthenticateRequest(t *testing.T) {
    53  	const configURI = "/.well-known/openid-configuration"
    54  	const authURI = "/auth"
    55  	validToken := "token-valid"
    56  	issuer := "test-issuer"
    57  	testIssuerURL := fmt.Sprintf("http://%s", issuer)
    58  	testClientID := "test-client"
    59  
    60  	mockIdpServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    61  		assert.NotNil(t, r)
    62  		serverURL := fmt.Sprintf("http://%s", r.Host)
    63  		if r.RequestURI == configURI {
    64  			respMap := map[string]string{
    65  				"issuer":                 serverURL,
    66  				"authorization_endpoint": fmt.Sprintf("%s%s", serverURL, authURI),
    67  			}
    68  			resp, err := json.Marshal(respMap)
    69  			assert.Nil(t, err)
    70  			_, err = w.Write(resp)
    71  			assert.NoError(t, err)
    72  			w.Header().Add("Content-Type", runtime.ContentTypeJSON)
    73  		}
    74  	}))
    75  	provider, err := oidc.NewProvider(context.Background(), mockIdpServer.URL)
    76  	assert.Nil(t, err)
    77  	authenticator := OIDCAuthenticator{
    78  		Log: zap.S(),
    79  		oidcConfig: &OIDCConfiguration{
    80  			ServiceURL:  issuer,
    81  			ExternalURL: mockIdpServer.URL,
    82  			ClientID:    testClientID,
    83  		},
    84  		ExternalProvider: provider,
    85  	}
    86  	verifier := newMockVerifier(issuer, validToken)
    87  	authenticator.verifier.Store(verifier)
    88  	req, err := http.NewRequest(http.MethodGet, testIssuerURL, nil)
    89  	rw := httptest.NewRecorder()
    90  	assert.Nil(t, err)
    91  
    92  	// no auth header, expect redirect
    93  	continueProcessing, err := authenticator.AuthenticateRequest(req, rw)
    94  	assert.Nil(t, err)
    95  	assert.False(t, continueProcessing)
    96  	assert.Equal(t, http.StatusFound, rw.Code)
    97  
    98  	redirLocation := rw.Header().Get("Location")
    99  	assert.NotEmpty(t, redirLocation)
   100  	redirURL, err := url.Parse(redirLocation)
   101  	assert.Nil(t, err)
   102  	expectedRedirURL := fmt.Sprintf("%s%s", mockIdpServer.URL, authURI)
   103  	actualRedirURL := fmt.Sprintf("http://%s%s", redirURL.Host, redirURL.Path)
   104  	assert.Equal(t, expectedRedirURL, actualRedirURL)
   105  	assert.Equal(t, testClientID, redirURL.Query().Get("client_id"))
   106  	assert.Equal(t, "code", redirURL.Query().Get("response_type"))
   107  	assert.NotEmpty(t, redirURL.Query().Get("nonce"))
   108  }