From 0cdbb710d27ef2bb576730a1ab2e0a20ebc0f61d Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Thu, 9 May 2024 13:29:41 -0700 Subject: [PATCH] add test for github redirect in auth_handler_test.go Co-authored-by: Joshua Casey --- .../endpoints/auth/auth_handler_test.go | 62 +++++++++++++++++++ internal/testutil/totp/totp_test.go | 1 - 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/internal/federationdomain/endpoints/auth/auth_handler_test.go b/internal/federationdomain/endpoints/auth/auth_handler_test.go index 52cd06b29..b805a3fbd 100644 --- a/internal/federationdomain/endpoints/auth/auth_handler_test.go +++ b/internal/federationdomain/endpoints/auth/auth_handler_test.go @@ -55,6 +55,8 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo ldapUpstreamResourceUID = "ldap-resource-uid" activeDirectoryUpstreamName = "some-active-directory-idp" activeDirectoryUpstreamResourceUID = "active-directory-resource-uid" + githubUpstreamName = "some-github-idp" + githubUpstreamResourceUID = "github-resource-uid" oidcUpstreamIssuer = "https://my-upstream-issuer.com" oidcUpstreamSubject = "abc123-some guid" // has a space character which should get escaped in URL @@ -291,6 +293,15 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo WithPasswordGrantError(errors.New("should not have used password grant on this instance")) } + upstreamGitHubIdentityProviderBuilder := func() *oidctestutil.TestUpstreamGitHubIdentityProviderBuilder { + return oidctestutil.NewTestUpstreamGitHubIdentityProviderBuilder(). + WithName(githubUpstreamName). + WithResourceUID(githubUpstreamResourceUID). + WithClientID("some-github-client-id"). + WithAuthorizationURL(upstreamAuthURL.String()). + WithScopes([]string{"scope1", "scope2"}) // the scopes to request when starting the upstream authorization flow + } + passwordGrantUpstreamOIDCIdentityProviderBuilder := func() *oidctestutil.TestUpstreamOIDCIdentityProviderBuilder { return oidctestutil.NewTestUpstreamOIDCIdentityProviderBuilder(). WithName(oidcPasswordGrantUpstreamName). @@ -463,6 +474,7 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo happyGetRequestPathForOIDCPasswordGrantUpstream := modifiedHappyGetRequestPath(map[string]string{"pinniped_idp_name": oidcPasswordGrantUpstreamName}) happyGetRequestPathForLDAPUpstream := modifiedHappyGetRequestPath(map[string]string{"pinniped_idp_name": ldapUpstreamName}) happyGetRequestPathForADUpstream := modifiedHappyGetRequestPath(map[string]string{"pinniped_idp_name": activeDirectoryUpstreamName}) + happyGetRequestPathForGithubUpstream := modifiedHappyGetRequestPath(map[string]string{"pinniped_idp_name": githubUpstreamName}) modifiedHappyGetRequestPathForOIDCUpstream := func(queryOverrides map[string]string) string { queryOverrides["pinniped_idp_name"] = oidcUpstreamName @@ -480,6 +492,10 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo queryOverrides["pinniped_idp_name"] = activeDirectoryUpstreamName return modifiedHappyGetRequestPath(queryOverrides) } + modifiedHappyGetRequestPathForGithubUpstream := func(queryOverrides map[string]string) string { + queryOverrides["pinniped_idp_name"] = githubUpstreamName + return modifiedHappyGetRequestPath(queryOverrides) + } happyGetRequestQueryMapForOIDCUpstream := modifiedQueryMap(happyGetRequestQueryMap, map[string]string{"pinniped_idp_name": oidcUpstreamName}) happyGetRequestQueryMapForOIDCPasswordGrantUpstream := modifiedQueryMap(happyGetRequestQueryMap, map[string]string{"pinniped_idp_name": oidcPasswordGrantUpstreamName}) @@ -533,6 +549,17 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo return urlWithQuery(upstreamAuthURL.String(), query) } + expectedRedirectLocationForUpstreamGithub := func(expectedUpstreamState string) string { + query := map[string]string{ + "response_type": "code", + "scope": "scope1 scope2", + "client_id": "some-github-client-id", + "state": expectedUpstreamState, + "redirect_uri": downstreamIssuer + "/callback", + } + return urlWithQuery(upstreamAuthURL.String(), query) + } + expectedHappyActiveDirectoryUpstreamCustomSession := &psession.CustomSessionData{ Username: happyLDAPUsernameFromAuthenticator, UpstreamUsername: happyLDAPUsernameFromAuthenticator, @@ -711,6 +738,41 @@ func TestAuthorizationEndpoint(t *testing.T) { //nolint:gocyclo wantUpstreamStateParamInLocationHeader: true, wantBodyStringWithLocationInHref: true, }, + { + name: "GitHub upstream browser flow happy path using GET without a CSRF cookie", + idps: testidplister.NewUpstreamIDPListerBuilder().WithGitHub(upstreamGitHubIdentityProviderBuilder().Build()), + generateCSRF: happyCSRFGenerator, + generatePKCE: happyPKCEGenerator, + generateNonce: happyNonceGenerator, + stateEncoder: happyStateEncoder, + cookieEncoder: happyCookieEncoder, + method: http.MethodGet, + path: happyGetRequestPathForGithubUpstream, + wantStatus: http.StatusSeeOther, + wantContentType: htmlContentType, + wantCSRFValueInCookieHeader: happyCSRF, + wantLocationHeader: expectedRedirectLocationForUpstreamGithub(expectedUpstreamStateParam(nil, "", githubUpstreamName, "github")), + wantUpstreamStateParamInLocationHeader: true, + wantBodyStringWithLocationInHref: true, + }, + { + name: "GitHub upstream browser flow happy path using GET without a CSRF cookie using a dynamic client", + idps: testidplister.NewUpstreamIDPListerBuilder().WithGitHub(upstreamGitHubIdentityProviderBuilder().Build()), + kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, + generateCSRF: happyCSRFGenerator, + generatePKCE: happyPKCEGenerator, + generateNonce: happyNonceGenerator, + stateEncoder: happyStateEncoder, + cookieEncoder: happyCookieEncoder, + method: http.MethodGet, + path: modifiedHappyGetRequestPathForGithubUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), + wantStatus: http.StatusSeeOther, + wantContentType: htmlContentType, + wantCSRFValueInCookieHeader: happyCSRF, + wantLocationHeader: expectedRedirectLocationForUpstreamGithub(expectedUpstreamStateParam(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}, "", githubUpstreamName, "github")), + wantUpstreamStateParamInLocationHeader: true, + wantBodyStringWithLocationInHref: true, + }, { name: "LDAP upstream browser flow happy path using GET without a CSRF cookie", idps: testidplister.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProviderBuilder().Build()), diff --git a/internal/testutil/totp/totp_test.go b/internal/testutil/totp/totp_test.go index 3fa0320b3..52d4ff197 100644 --- a/internal/testutil/totp/totp_test.go +++ b/internal/testutil/totp/totp_test.go @@ -35,7 +35,6 @@ func TestGenerateOTPCode(t *testing.T) { } for _, test := range tests { - // This line can be removed when we upgrade golangci-lint to 1.58.1 and go1.22+ test := test t.Run(test.name, func(t *testing.T) { t.Parallel()