From 610f886fd84f81dccb9feb4a59c23c6f08ed1c12 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Fri, 16 Jun 2023 14:48:01 -0700 Subject: [PATCH] Fix auth_handler_test.go --- internal/oidc/auth/auth_handler.go | 60 +- internal/oidc/auth/auth_handler_test.go | 554 ++++++++++-------- .../testutil/oidctestutil/oidctestutil.go | 10 +- 3 files changed, 364 insertions(+), 260 deletions(-) diff --git a/internal/oidc/auth/auth_handler.go b/internal/oidc/auth/auth_handler.go index 10e486bb2..6bb7ea092 100644 --- a/internal/oidc/auth/auth_handler.go +++ b/internal/oidc/auth/auth_handler.go @@ -56,23 +56,54 @@ func NewHandler( return httperr.Newf(http.StatusMethodNotAllowed, "%s (try GET or POST)", r.Method) } + requestedBrowserlessFlow := len(r.Header.Values(oidcapi.AuthorizeUsernameHeaderName)) > 0 || + len(r.Header.Values(oidcapi.AuthorizePasswordHeaderName)) > 0 + + // Need to parse the request params so we can get the IDP name. The style and text of the error is inspired by + // fosite's implementation of NewAuthorizeRequest(). Fosite only calls ParseMultipartForm() there. However, + // although ParseMultipartForm() calls ParseForm(), it swallows errors from ParseForm() sometimes. To avoid + // having any errors swallowed, we call both. When fosite calls ParseMultipartForm() later, it will be a noop. + if err := r.ParseForm(); err != nil { + oidc.WriteAuthorizeError(r, w, + oauthHelperWithoutStorage, + fosite.NewAuthorizeRequest(), + fosite.ErrInvalidRequest. + WithHint("Unable to parse form params, make sure to send a properly formatted query params or form request body."). + WithWrap(err).WithDebug(err.Error()), + requestedBrowserlessFlow) + return nil + } + if err := r.ParseMultipartForm(1 << 20); err != nil && err != http.ErrNotMultipart { + oidc.WriteAuthorizeError(r, w, + oauthHelperWithoutStorage, + fosite.NewAuthorizeRequest(), + fosite.ErrInvalidRequest. + WithHint("Unable to parse multipart HTTP body, make sure to send a properly formatted form request body."). + WithWrap(err).WithDebug(err.Error()), + requestedBrowserlessFlow) + return nil + } + // Note that the client might have used oidcapi.AuthorizeUpstreamIDPNameParamName and - // oidcapi.AuthorizeUpstreamIDPTypeParamName query params to request a certain upstream IDP. + // oidcapi.AuthorizeUpstreamIDPTypeParamName query (or form) params to request a certain upstream IDP. // The Pinniped CLI has been sending these params since v0.9.0. - idpNameQueryParamValue := r.URL.Query().Get(oidcapi.AuthorizeUpstreamIDPNameParamName) + idpNameQueryParamValue := r.Form.Get(oidcapi.AuthorizeUpstreamIDPNameParamName) oidcUpstream, ldapUpstream, err := chooseUpstreamIDP(idpNameQueryParamValue, idpFinder) if err != nil { - plog.WarningErr("authorize upstream config", err) - return httperr.Wrap(http.StatusUnprocessableEntity, err.Error(), err) + oidc.WriteAuthorizeError(r, w, + oauthHelperWithoutStorage, + fosite.NewAuthorizeRequest(), + fosite.ErrInvalidRequest. + WithHintf("%q param error: %s", oidcapi.AuthorizeUpstreamIDPNameParamName, err.Error()). + WithWrap(err).WithDebug(err.Error()), + requestedBrowserlessFlow) + return nil } if oidcUpstream != nil { - if len(r.Header.Values(oidcapi.AuthorizeUsernameHeaderName)) > 0 || - len(r.Header.Values(oidcapi.AuthorizePasswordHeaderName)) > 0 { + if requestedBrowserlessFlow { // The client set a username header, so they are trying to log in with a username/password. - return handleAuthRequestForOIDCUpstreamPasswordGrant( - r, - w, + return handleAuthRequestForOIDCUpstreamPasswordGrant(r, w, oauthHelperWithStorage, oidcUpstream.Provider, oidcUpstream.Transforms, @@ -91,8 +122,7 @@ func NewHandler( } // We know it's an AD/LDAP upstream. - if len(r.Header.Values(oidcapi.AuthorizeUsernameHeaderName)) > 0 || - len(r.Header.Values(oidcapi.AuthorizePasswordHeaderName)) > 0 { + if requestedBrowserlessFlow { // The client set a username header, so they are trying to log in with a username/password. return handleAuthRequestForLDAPUpstreamCLIFlow(r, w, oauthHelperWithStorage, @@ -102,13 +132,9 @@ func NewHandler( idpNameQueryParamValue, ) } - return handleAuthRequestForLDAPUpstreamBrowserFlow( - r, - w, + return handleAuthRequestForLDAPUpstreamBrowserFlow(r, w, oauthHelperWithoutStorage, - generateCSRF, - generateNonce, - generatePKCE, + generateCSRF, generateNonce, generatePKCE, ldapUpstream, ldapUpstream.SessionProviderType, downstreamIssuer, diff --git a/internal/oidc/auth/auth_handler_test.go b/internal/oidc/auth/auth_handler_test.go index f7ff3a88b..5a6a1087a 100644 --- a/internal/oidc/auth/auth_handler_test.go +++ b/internal/oidc/auth/auth_handler_test.go @@ -71,6 +71,7 @@ func TestAuthorizationEndpoint(t *testing.T) { downstreamPKCEChallengeMethod = "S256" happyState = "8b-state" upstreamLDAPURL = "ldaps://some-ldap-host:123?base=ou%3Dusers%2Cdc%3Dpinniped%2Cdc%3Ddev" + plainContentType = "text/plain; charset=utf-8" htmlContentType = "text/html; charset=utf-8" jsonContentType = "application/json; charset=utf-8" formContentType = "application/x-www-form-urlencoded" @@ -406,26 +407,67 @@ func TestAuthorizationEndpoint(t *testing.T) { happyGetRequestPath := pathWithQuery("/some/path", happyGetRequestQueryMap) - modifiedHappyGetRequestQueryMap := func(queryOverrides map[string]string) map[string]string { - copyOfHappyGetRequestQueryMap := map[string]string{} - for k, v := range happyGetRequestQueryMap { - copyOfHappyGetRequestQueryMap[k] = v + modifiedQueryMap := func(modifyThisMap map[string]string, queryOverrides map[string]string) map[string]string { + copyModifyThisMap := map[string]string{} + for k, v := range modifyThisMap { + copyModifyThisMap[k] = v } for k, v := range queryOverrides { - _, hasKey := copyOfHappyGetRequestQueryMap[k] + _, hasKey := copyModifyThisMap[k] if v == "" && hasKey { - delete(copyOfHappyGetRequestQueryMap, k) + delete(copyModifyThisMap, k) } else { - copyOfHappyGetRequestQueryMap[k] = v + copyModifyThisMap[k] = v } } - return copyOfHappyGetRequestQueryMap + return copyModifyThisMap + } + + modifiedHappyGetRequestQueryMap := func(queryOverrides map[string]string) map[string]string { + return modifiedQueryMap(happyGetRequestQueryMap, queryOverrides) } modifiedHappyGetRequestPath := func(queryOverrides map[string]string) string { return pathWithQuery("/some/path", modifiedHappyGetRequestQueryMap(queryOverrides)) } + happyGetRequestPathForOIDCUpstream := modifiedHappyGetRequestPath(map[string]string{"pinniped_idp_name": oidcUpstreamName}) + 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}) + + modifiedHappyGetRequestPathForOIDCUpstream := func(queryOverrides map[string]string) string { + queryOverrides["pinniped_idp_name"] = oidcUpstreamName + return modifiedHappyGetRequestPath(queryOverrides) + } + modifiedHappyGetRequestPathForOIDCPasswordGrantUpstream := func(queryOverrides map[string]string) string { + queryOverrides["pinniped_idp_name"] = oidcPasswordGrantUpstreamName + return modifiedHappyGetRequestPath(queryOverrides) + } + modifiedHappyGetRequestPathForLDAPUpstream := func(queryOverrides map[string]string) string { + queryOverrides["pinniped_idp_name"] = ldapUpstreamName + return modifiedHappyGetRequestPath(queryOverrides) + } + modifiedHappyGetRequestPathForADUpstream := func(queryOverrides map[string]string) string { + queryOverrides["pinniped_idp_name"] = activeDirectoryUpstreamName + return modifiedHappyGetRequestPath(queryOverrides) + } + + happyGetRequestQueryMapForOIDCUpstream := modifiedQueryMap(happyGetRequestQueryMap, map[string]string{"pinniped_idp_name": oidcUpstreamName}) + happyGetRequestQueryMapForOIDCPasswordGrantUpstream := modifiedQueryMap(happyGetRequestQueryMap, map[string]string{"pinniped_idp_name": oidcPasswordGrantUpstreamName}) + happyGetRequestQueryMapForLDAPUpstream := modifiedQueryMap(happyGetRequestQueryMap, map[string]string{"pinniped_idp_name": ldapUpstreamName}) + happyGetRequestQueryMapForADUpstream := modifiedQueryMap(happyGetRequestQueryMap, map[string]string{"pinniped_idp_name": activeDirectoryUpstreamName}) + + modifiedHappyGetRequestQueryMapForOIDCUpstream := func(queryOverrides map[string]string) map[string]string { + return modifiedQueryMap(happyGetRequestQueryMapForOIDCUpstream, queryOverrides) + } + modifiedHappyGetRequestQueryMapForLDAPUpstream := func(queryOverrides map[string]string) map[string]string { + return modifiedQueryMap(happyGetRequestQueryMapForLDAPUpstream, queryOverrides) + } + modifiedHappyGetRequestQueryMapForADUpstream := func(queryOverrides map[string]string) map[string]string { + return modifiedQueryMap(happyGetRequestQueryMapForADUpstream, queryOverrides) + } + expectedUpstreamStateParam := func(queryOverrides map[string]string, csrfValueOverride, upstreamName, upstreamType string) string { csrf := happyCSRF if csrfValueOverride != "" { @@ -464,12 +506,14 @@ func TestAuthorizationEndpoint(t *testing.T) { } expectedHappyActiveDirectoryUpstreamCustomSession := &psession.CustomSessionData{ - Username: happyLDAPUsernameFromAuthenticator, - ProviderUID: activeDirectoryUpstreamResourceUID, - ProviderName: activeDirectoryUpstreamName, - ProviderType: psession.ProviderTypeActiveDirectory, - OIDC: nil, - LDAP: nil, + Username: happyLDAPUsernameFromAuthenticator, + UpstreamUsername: happyLDAPUsernameFromAuthenticator, + UpstreamGroups: happyLDAPGroups, + ProviderUID: activeDirectoryUpstreamResourceUID, + ProviderName: activeDirectoryUpstreamName, + ProviderType: psession.ProviderTypeActiveDirectory, + OIDC: nil, + LDAP: nil, ActiveDirectory: &psession.ActiveDirectorySessionData{ UserDN: happyLDAPUserDN, ExtraRefreshAttributes: map[string]string{happyLDAPExtraRefreshAttribute: happyLDAPExtraRefreshValue}, @@ -477,11 +521,13 @@ func TestAuthorizationEndpoint(t *testing.T) { } expectedHappyLDAPUpstreamCustomSession := &psession.CustomSessionData{ - Username: happyLDAPUsernameFromAuthenticator, - ProviderUID: ldapUpstreamResourceUID, - ProviderName: ldapUpstreamName, - ProviderType: psession.ProviderTypeLDAP, - OIDC: nil, + Username: happyLDAPUsernameFromAuthenticator, + UpstreamUsername: happyLDAPUsernameFromAuthenticator, + UpstreamGroups: happyLDAPGroups, + ProviderUID: ldapUpstreamResourceUID, + ProviderName: ldapUpstreamName, + ProviderType: psession.ProviderTypeLDAP, + OIDC: nil, LDAP: &psession.LDAPSessionData{ UserDN: happyLDAPUserDN, ExtraRefreshAttributes: map[string]string{happyLDAPExtraRefreshAttribute: happyLDAPExtraRefreshValue}, @@ -490,10 +536,12 @@ func TestAuthorizationEndpoint(t *testing.T) { } expectedHappyOIDCPasswordGrantCustomSession := &psession.CustomSessionData{ - Username: oidcUpstreamUsername, - ProviderUID: oidcPasswordGrantUpstreamResourceUID, - ProviderName: oidcPasswordGrantUpstreamName, - ProviderType: psession.ProviderTypeOIDC, + Username: oidcUpstreamUsername, + UpstreamUsername: oidcUpstreamUsername, + UpstreamGroups: oidcUpstreamGroupMembership, + ProviderUID: oidcPasswordGrantUpstreamResourceUID, + ProviderName: oidcPasswordGrantUpstreamName, + ProviderType: psession.ProviderTypeOIDC, OIDC: &psession.OIDCSessionData{ UpstreamRefreshToken: oidcPasswordGrantUpstreamRefreshToken, UpstreamSubject: oidcUpstreamSubject, @@ -501,19 +549,23 @@ func TestAuthorizationEndpoint(t *testing.T) { }, } - expectedHappyOIDCPasswordGrantCustomSessionWithUsername := func(wantUsername string) *psession.CustomSessionData { + expectedHappyOIDCPasswordGrantCustomSessionWithUsernameAndGroups := func(wantUsername string, wantGroups []string) *psession.CustomSessionData { copyOfCustomSession := *expectedHappyOIDCPasswordGrantCustomSession copyOfOIDC := *(expectedHappyOIDCPasswordGrantCustomSession.OIDC) copyOfCustomSession.OIDC = ©OfOIDC copyOfCustomSession.Username = wantUsername + copyOfCustomSession.UpstreamUsername = wantUsername + copyOfCustomSession.UpstreamGroups = wantGroups return ©OfCustomSession } expectedHappyOIDCPasswordGrantCustomSessionWithAccessToken := &psession.CustomSessionData{ - Username: oidcUpstreamUsername, - ProviderUID: oidcPasswordGrantUpstreamResourceUID, - ProviderName: oidcPasswordGrantUpstreamName, - ProviderType: psession.ProviderTypeOIDC, + Username: oidcUpstreamUsername, + UpstreamUsername: oidcUpstreamUsername, + UpstreamGroups: oidcUpstreamGroupMembership, + ProviderUID: oidcPasswordGrantUpstreamResourceUID, + ProviderName: oidcPasswordGrantUpstreamName, + ProviderType: psession.ProviderTypeOIDC, OIDC: &psession.OIDCSessionData{ UpstreamAccessToken: oidcUpstreamAccessToken, UpstreamSubject: oidcUpstreamSubject, @@ -592,7 +644,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCUpstream, wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantCSRFValueInCookieHeader: happyCSRF, @@ -610,7 +662,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantCSRFValueInCookieHeader: happyCSRF, @@ -627,7 +679,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantCSRFValueInCookieHeader: happyCSRF, @@ -645,7 +697,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantCSRFValueInCookieHeader: happyCSRF, @@ -662,7 +714,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForADUpstream, wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantCSRFValueInCookieHeader: happyCSRF, @@ -680,7 +732,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), + path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantCSRFValueInCookieHeader: happyCSRF, @@ -692,7 +744,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "OIDC upstream password grant happy path using GET", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -722,7 +774,7 @@ func TestAuthorizationEndpoint(t *testing.T) { WithIDTokenClaim("upstreamOtherClaim", []interface{}{"hello", true}). Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -753,7 +805,7 @@ func TestAuthorizationEndpoint(t *testing.T) { WithIDTokenClaim("not-upstream", "value"). Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -776,7 +828,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "LDAP cli upstream happy path using GET", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -797,7 +849,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "ActiveDirectory cli upstream happy path using GET", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForADUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -823,7 +875,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCUpstream, csrfCookie: "__Host-pinniped-csrf=" + encodedIncomingCookieCSRFValue + " ", wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, @@ -840,7 +892,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, csrfCookie: "__Host-pinniped-csrf=" + encodedIncomingCookieCSRFValue + " ", wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, @@ -857,7 +909,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForADUpstream, csrfCookie: "__Host-pinniped-csrf=" + encodedIncomingCookieCSRFValue + " ", wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, @@ -876,7 +928,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(happyGetRequestQueryMap), + body: encodeQuery(happyGetRequestQueryMapForOIDCUpstream), wantStatus: http.StatusSeeOther, wantContentType: "", wantBodyString: "", @@ -896,7 +948,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(modifiedHappyGetRequestQueryMap(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep})), + body: encodeQuery(modifiedHappyGetRequestQueryMapForOIDCUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep})), wantStatus: http.StatusSeeOther, wantContentType: "", wantBodyString: "", @@ -915,7 +967,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(happyGetRequestQueryMap), + body: encodeQuery(happyGetRequestQueryMapForLDAPUpstream), wantStatus: http.StatusSeeOther, wantContentType: "", wantBodyString: "", @@ -935,7 +987,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(modifiedHappyGetRequestQueryMap(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep})), + body: encodeQuery(modifiedHappyGetRequestQueryMapForLDAPUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep})), wantStatus: http.StatusSeeOther, wantContentType: "", wantBodyString: "", @@ -954,7 +1006,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(happyGetRequestQueryMap), + body: encodeQuery(happyGetRequestQueryMapForADUpstream), wantStatus: http.StatusSeeOther, wantContentType: "", wantBodyString: "", @@ -974,7 +1026,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(modifiedHappyGetRequestQueryMap(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep})), + body: encodeQuery(modifiedHappyGetRequestQueryMapForADUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep})), wantStatus: http.StatusSeeOther, wantContentType: "", wantBodyString: "", @@ -988,7 +1040,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(happyGetRequestQueryMap), + body: encodeQuery(happyGetRequestQueryMapForOIDCPasswordGrantUpstream), customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1012,7 +1064,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(happyGetRequestQueryMap), + body: encodeQuery(happyGetRequestQueryMapForLDAPUpstream), customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1035,7 +1087,7 @@ func TestAuthorizationEndpoint(t *testing.T) { method: http.MethodPost, path: "/some/path", contentType: formContentType, - body: encodeQuery(happyGetRequestQueryMap), + body: encodeQuery(happyGetRequestQueryMapForADUpstream), customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1061,7 +1113,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"prompt": "login"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"prompt": "login"}), wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantBodyStringWithLocationInHref: true, @@ -1078,7 +1130,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"pinniped_idp_name": "currently-ignored", "pinniped_idp_type": "oidc"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"pinniped_idp_type": "oidc"}), contentType: formContentType, wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, @@ -1096,7 +1148,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"prompt": "login"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"prompt": "login"}), wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantBodyStringWithLocationInHref: true, @@ -1113,7 +1165,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"prompt": "none"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"prompt": "none"}), wantStatus: http.StatusSeeOther, wantContentType: jsonContentType, wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeLoginRequiredErrorQuery), @@ -1128,7 +1180,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCUpstream, csrfCookie: "__Host-pinniped-csrf=this-value-was-not-signed-by-pinniped", wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, @@ -1147,7 +1199,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{ "redirect_uri": downstreamRedirectURIWithDifferentPort, // not the same port number that is registered for the client }), wantStatus: http.StatusSeeOther, @@ -1169,7 +1221,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{ "redirect_uri": downstreamRedirectURIWithDifferentPort, // not the same port number that is registered for the client "client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, @@ -1189,7 +1241,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "OIDC upstream password grant happy path when downstream redirect uri matches what is configured for client except for the port number", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForOIDCPasswordGrantUpstream(map[string]string{ "redirect_uri": downstreamRedirectURIWithDifferentPort, // not the same port number that is registered for the client }), customUsernameHeader: ptr.To(oidcUpstreamUsername), @@ -1213,7 +1265,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "LDAP upstream happy path when downstream redirect uri matches what is configured for client except for the port number", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{ "redirect_uri": downstreamRedirectURIWithDifferentPort, // not the same port number that is registered for the client }), customUsernameHeader: ptr.To(happyLDAPUsername), @@ -1241,7 +1293,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"scope": "openid offline_access"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"scope": "openid offline_access"}), wantStatus: http.StatusSeeOther, wantContentType: htmlContentType, wantCSRFValueInCookieHeader: happyCSRF, @@ -1255,7 +1307,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "OIDC password grant happy path when upstream IDP returned empty refresh token but it did return an access token and has a userinfo endpoint", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithEmptyRefreshToken().WithAccessToken(oidcUpstreamAccessToken, metav1.NewTime(time.Now().Add(9*time.Hour))).WithUserInfoURL().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1277,7 +1329,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "OIDC password grant happy path when upstream IDP returned empty refresh token and an access token that has a short lifetime", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithEmptyRefreshToken().WithAccessToken(oidcUpstreamAccessToken, metav1.NewTime(time.Now().Add(1*time.Hour))).WithUserInfoURL().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1294,11 +1346,13 @@ func TestAuthorizationEndpoint(t *testing.T) { wantDownstreamPKCEChallenge: downstreamPKCEChallenge, wantDownstreamPKCEChallengeMethod: downstreamPKCEChallengeMethod, wantDownstreamCustomSessionData: &psession.CustomSessionData{ - Username: oidcUpstreamUsername, - ProviderUID: oidcPasswordGrantUpstreamResourceUID, - ProviderName: oidcPasswordGrantUpstreamName, - ProviderType: psession.ProviderTypeOIDC, - Warnings: []string{"Access token from identity provider has lifetime of less than 3 hours. Expect frequent prompts to log in."}, + Username: oidcUpstreamUsername, + UpstreamUsername: oidcUpstreamUsername, + UpstreamGroups: oidcUpstreamGroupMembership, + ProviderUID: oidcPasswordGrantUpstreamResourceUID, + ProviderName: oidcPasswordGrantUpstreamName, + ProviderType: psession.ProviderTypeOIDC, + Warnings: []string{"Access token from identity provider has lifetime of less than 3 hours. Expect frequent prompts to log in."}, OIDC: &psession.OIDCSessionData{ UpstreamAccessToken: oidcUpstreamAccessToken, UpstreamSubject: oidcUpstreamSubject, @@ -1310,7 +1364,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "OIDC password grant happy path when upstream IDP did not return a refresh token but it did return an access token and has a userinfo endpoint", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithoutRefreshToken().WithAccessToken(oidcUpstreamAccessToken, metav1.NewTime(time.Now().Add(9*time.Hour))).WithUserInfoURL().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1332,7 +1386,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "error during upstream LDAP authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(erroringUpstreamLDAPIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusBadGateway, @@ -1343,7 +1397,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "error during upstream Active Directory authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(erroringUpstreamLDAPIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusBadGateway, @@ -1359,7 +1413,7 @@ func TestAuthorizationEndpoint(t *testing.T) { Build(), ), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To("wrong-password"), wantPasswordGrantCall: &expectedPasswordGrant{ @@ -1377,7 +1431,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "wrong upstream password for LDAP authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To("wrong-password"), wantStatus: http.StatusFound, @@ -1389,7 +1443,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "wrong upstream password for Active Directory authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForADUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To("wrong-password"), wantStatus: http.StatusFound, @@ -1401,7 +1455,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "wrong upstream username for LDAP authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, customUsernameHeader: ptr.To("wrong-username"), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1413,7 +1467,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "wrong upstream username for Active Directory authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForADUpstream, customUsernameHeader: ptr.To("wrong-username"), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1425,7 +1479,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "missing upstream username but has password on request for OIDC password grant", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: nil, // do not send header customPasswordHeader: ptr.To(oidcUpstreamPassword), wantStatus: http.StatusFound, @@ -1437,7 +1491,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "missing upstream username but has password on request for LDAP authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, customUsernameHeader: nil, // do not send header customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1449,7 +1503,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "missing upstream username on request for Active Directory authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForADUpstream, customUsernameHeader: nil, // do not send header customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1461,7 +1515,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "missing upstream password on request for LDAP authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForLDAPUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: nil, // do not send header wantStatus: http.StatusFound, @@ -1473,7 +1527,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "missing upstream password on request for Active Directory authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForADUpstream, customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: nil, // do not send header wantStatus: http.StatusFound, @@ -1485,7 +1539,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "password grant returns an error when upstream IDP returns no refresh token with an access token but has no userinfo endpoint", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithoutRefreshToken().WithAccessToken(oidcUpstreamAccessToken, metav1.NewTime(time.Now().Add(9*time.Hour))).WithoutUserInfoURL().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1498,7 +1552,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "password grant returns an error when upstream IDP returns empty refresh token with an access token but has no userinfo endpoint", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithEmptyRefreshToken().WithAccessToken(oidcUpstreamAccessToken, metav1.NewTime(time.Now().Add(9*time.Hour))).WithoutUserInfoURL().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1511,7 +1565,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "password grant returns an error when upstream IDP returns empty refresh token and empty access token", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithEmptyRefreshToken().WithEmptyAccessToken().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1524,7 +1578,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "password grant returns an error when upstream IDP returns no refresh and no access token", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithoutRefreshToken().WithoutAccessToken().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1537,7 +1591,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "password grant returns an error when upstream IDP returns no refresh token and empty access token", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithoutRefreshToken().WithEmptyAccessToken().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1550,7 +1604,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "password grant returns an error when upstream IDP returns empty refresh token and no access token", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().WithEmptyRefreshToken().WithoutAccessToken().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantPasswordGrantCall: happyUpstreamPasswordGrantMockExpectation, @@ -1563,7 +1617,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "missing upstream password on request for OIDC password grant authentication", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCPasswordGrantUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: nil, // do not send header wantStatus: http.StatusFound, @@ -1575,7 +1629,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "using the custom username header on request for OIDC password grant authentication when OIDCIdentityProvider does not allow password grants", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(upstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: happyGetRequestPath, + path: happyGetRequestPathForOIDCUpstream, customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantStatus: http.StatusFound, @@ -1588,7 +1642,7 @@ func TestAuthorizationEndpoint(t *testing.T) { idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), + path: modifiedHappyGetRequestPathForOIDCPasswordGrantUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantStatus: http.StatusFound, @@ -1601,7 +1655,7 @@ func TestAuthorizationEndpoint(t *testing.T) { idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1614,7 +1668,7 @@ func TestAuthorizationEndpoint(t *testing.T) { idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), + path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep}), customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1631,7 +1685,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{ "redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client", }), wantStatus: http.StatusBadRequest, @@ -1648,7 +1702,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{ "redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-dynamic-client", "client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, @@ -1661,7 +1715,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "downstream redirect uri does not match what is configured for client when using OIDC upstream password grant", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForOIDCPasswordGrantUpstream(map[string]string{ "redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client", }), customUsernameHeader: ptr.To(oidcUpstreamUsername), @@ -1674,7 +1728,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "downstream redirect uri does not match what is configured for client when using LDAP upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{ "redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client", }), customUsernameHeader: ptr.To(happyLDAPUsername), @@ -1687,7 +1741,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "downstream redirect uri does not match what is configured for client when using active directory upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForADUpstream(map[string]string{ "redirect_uri": "http://127.0.0.1/does-not-match-what-is-configured-for-pinniped-cli-client", }), customUsernameHeader: ptr.To(happyLDAPUsername), @@ -1705,7 +1759,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": "invalid-client"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"client_id": "invalid-client"}), wantStatus: http.StatusUnauthorized, wantContentType: jsonContentType, wantBodyJSON: fositeInvalidClientErrorBody, @@ -1714,7 +1768,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "downstream client does not exist when using OIDC upstream password grant", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": "invalid-client"}), + path: modifiedHappyGetRequestPathForOIDCPasswordGrantUpstream(map[string]string{"client_id": "invalid-client"}), customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantStatus: http.StatusUnauthorized, @@ -1725,7 +1779,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "downstream client does not exist when using LDAP upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": "invalid-client"}), + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"client_id": "invalid-client"}), wantStatus: http.StatusUnauthorized, wantContentType: jsonContentType, wantBodyJSON: fositeInvalidClientErrorBody, @@ -1734,7 +1788,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "downstream client does not exist when using active directory upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": "invalid-client"}), + path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"client_id": "invalid-client"}), wantStatus: http.StatusUnauthorized, wantContentType: jsonContentType, wantBodyJSON: fositeInvalidClientErrorBody, @@ -1748,7 +1802,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"response_type": "unsupported"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"response_type": "unsupported"}), wantStatus: http.StatusSeeOther, wantContentType: jsonContentType, wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeUnsupportedResponseTypeErrorQuery), @@ -1764,7 +1818,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{ "response_type": "unsupported", "client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, @@ -1778,7 +1832,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "response type is unsupported when using OIDC upstream password grant", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"response_type": "unsupported"}), + path: modifiedHappyGetRequestPathForOIDCPasswordGrantUpstream(map[string]string{"response_type": "unsupported"}), customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantStatus: http.StatusFound, @@ -1790,7 +1844,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "response type is unsupported when using LDAP cli upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"response_type": "unsupported"}), + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": "unsupported"}), customUsernameHeader: ptr.To(happyLDAPUsername), customPasswordHeader: ptr.To(happyLDAPPassword), wantStatus: http.StatusFound, @@ -1802,7 +1856,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "response type is unsupported when using LDAP browser upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"response_type": "unsupported"}), + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{"response_type": "unsupported"}), wantStatus: http.StatusSeeOther, wantContentType: jsonContentType, wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeUnsupportedResponseTypeErrorQuery), @@ -1813,7 +1867,7 @@ func TestAuthorizationEndpoint(t *testing.T) { idps: oidctestutil.NewUpstreamIDPListerBuilder().WithLDAP(upstreamLDAPIdentityProvider), kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForLDAPUpstream(map[string]string{ "response_type": "unsupported", "client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, @@ -1827,7 +1881,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "response type is unsupported when using active directory cli upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"response_type": "unsupported"}), + path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": "unsupported"}), customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantStatus: http.StatusFound, @@ -1839,7 +1893,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "response type is unsupported when using active directory browser upstream", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"response_type": "unsupported"}), + path: modifiedHappyGetRequestPathForADUpstream(map[string]string{"response_type": "unsupported"}), wantStatus: http.StatusSeeOther, wantContentType: jsonContentType, wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeUnsupportedResponseTypeErrorQuery), @@ -1850,7 +1904,7 @@ func TestAuthorizationEndpoint(t *testing.T) { idps: oidctestutil.NewUpstreamIDPListerBuilder().WithActiveDirectory(upstreamActiveDirectoryIdentityProvider), kubeResources: addFullyCapableDynamicClientAndSecretToKubeResources, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{ + path: modifiedHappyGetRequestPathForADUpstream(map[string]string{ "response_type": "unsupported", "client_id": dynamicClientID, "scope": testutil.AllDynamicClientScopesSpaceSep, @@ -1869,7 +1923,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"scope": "openid profile email tuna"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"scope": "openid profile email tuna"}), wantStatus: http.StatusSeeOther, wantContentType: jsonContentType, wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeInvalidScopeErrorQuery), @@ -1885,7 +1939,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"client_id": dynamicClientID, "scope": "openid tuna"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"client_id": dynamicClientID, "scope": "openid tuna"}), wantStatus: http.StatusSeeOther, wantContentType: jsonContentType, wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeInvalidScopeErrorQuery), @@ -1895,7 +1949,7 @@ func TestAuthorizationEndpoint(t *testing.T) { name: "downstream scopes do not match what is configured for client using OIDC upstream password grant", idps: oidctestutil.NewUpstreamIDPListerBuilder().WithOIDC(passwordGrantUpstreamOIDCIdentityProviderBuilder().Build()), method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"scope": "openid profile email tuna"}), + path: modifiedHappyGetRequestPathForOIDCPasswordGrantUpstream(map[string]string{"scope": "openid profile email tuna"}), customUsernameHeader: ptr.To(oidcUpstreamUsername), customPasswordHeader: ptr.To(oidcUpstreamPassword), wantStatus: http.StatusFound, @@ -1912,7 +1966,7 @@ func TestAuthorizationEndpoint(t *testing.T) { stateEncoder: happyStateEncoder, cookieEncoder: happyCookieEncoder, method: http.MethodGet, - path: modifiedHappyGetRequestPath(map[string]string{"response_mode": "form_post", "scope": "openid profile email tuna"}), + path: modifiedHappyGetRequestPathForOIDCUpstream(map[string]string{"response_mode": "form_post", "scope": "openid profile email tuna"}), wantStatus: http.StatusOK, wantContentType: htmlContentType, wantBodyRegex: `