mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-08 15:21:55 +00:00
Update all deps to latest where possible, bump Kube deps to v0.23.1
Highlights from this dep bump: 1. Made a copy of the v0.4.0 github.com/go-logr/stdr implementation for use in tests. We must bump this dep as Kube code uses a newer version now. We would have to rewrite hundreds of test log assertions without this copy. 2. Use github.com/felixge/httpsnoop to undo the changes made by ory/fosite#636 for CLI based login flows. This is required for backwards compatibility with older versions of our CLI. A separate change after this will update the CLI to be more flexible (it is purposefully not part of this change to confirm that we did not break anything). For all browser login flows, we now redirect using http.StatusSeeOther instead of http.StatusFound. 3. Drop plog.RemoveKlogGlobalFlags as klog no longer mutates global process flags 4. Only bump github.com/ory/x to v0.0.297 instead of the latest v0.0.321 because v0.0.298+ pulls in a newer version of go.opentelemetry.io/otel/semconv which breaks k8s.io/apiserver. We should update k8s.io/apiserver to use the newer code. 5. Migrate all code from k8s.io/apimachinery/pkg/util/clock to k8s.io/utils/clock and k8s.io/utils/clock/testing 6. Delete testutil.NewDeleteOptionsRecorder and migrate to the new kubetesting.NewDeleteActionWithOptions 7. Updated ExpectedAuthorizeCodeSessionJSONFromFuzzing caused by fosite's new rotated_secrets OAuth client field. This new field is currently not relevant to us as we have no private clients. Signed-off-by: Monis Khan <mok@vmware.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
coreosoidc "github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/felixge/httpsnoop"
|
||||
"github.com/ory/fosite"
|
||||
"github.com/ory/fosite/handler/openid"
|
||||
"github.com/ory/fosite/token/jwt"
|
||||
@@ -89,7 +90,7 @@ func handleAuthRequestForLDAPUpstream(
|
||||
ldapUpstream provider.UpstreamLDAPIdentityProviderI,
|
||||
idpType psession.ProviderType,
|
||||
) error {
|
||||
authorizeRequester, created := newAuthorizeRequest(r, w, oauthHelper)
|
||||
authorizeRequester, created := newAuthorizeRequest(r, w, oauthHelper, true)
|
||||
if !created {
|
||||
return nil
|
||||
}
|
||||
@@ -106,7 +107,7 @@ func handleAuthRequestForLDAPUpstream(
|
||||
}
|
||||
if !authenticated {
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester,
|
||||
fosite.ErrAccessDenied.WithHintf("Username/password not accepted by LDAP provider."))
|
||||
fosite.ErrAccessDenied.WithHintf("Username/password not accepted by LDAP provider."), true)
|
||||
}
|
||||
|
||||
subject := downstreamSubjectFromUpstreamLDAP(ldapUpstream, authenticateResponse)
|
||||
@@ -143,7 +144,7 @@ func handleAuthRequestForOIDCUpstreamPasswordGrant(
|
||||
oauthHelper fosite.OAuth2Provider,
|
||||
oidcUpstream provider.UpstreamOIDCIdentityProviderI,
|
||||
) error {
|
||||
authorizeRequester, created := newAuthorizeRequest(r, w, oauthHelper)
|
||||
authorizeRequester, created := newAuthorizeRequest(r, w, oauthHelper, true)
|
||||
if !created {
|
||||
return nil
|
||||
}
|
||||
@@ -157,7 +158,7 @@ func handleAuthRequestForOIDCUpstreamPasswordGrant(
|
||||
// Return a user-friendly error for this case which is entirely within our control.
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester,
|
||||
fosite.ErrAccessDenied.WithHint(
|
||||
"Resource owner password credentials grant is not allowed for this upstream provider according to its configuration."))
|
||||
"Resource owner password credentials grant is not allowed for this upstream provider according to its configuration."), true)
|
||||
}
|
||||
|
||||
token, err := oidcUpstream.PasswordCredentialsGrantAndValidateTokens(r.Context(), username, password)
|
||||
@@ -170,7 +171,7 @@ func handleAuthRequestForOIDCUpstreamPasswordGrant(
|
||||
// the OIDC spec, so we don't try too hard to read the upstream errors in this case. (E.g. Dex departs from the
|
||||
// spec and returns something other than an "invalid_grant" error for bad resource owner credentials.)
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester,
|
||||
fosite.ErrAccessDenied.WithDebug(err.Error())) // WithDebug hides the error from the client
|
||||
fosite.ErrAccessDenied.WithDebug(err.Error()), true) // WithDebug hides the error from the client
|
||||
}
|
||||
|
||||
if token.RefreshToken == nil || token.RefreshToken.Token == "" {
|
||||
@@ -180,14 +181,14 @@ func handleAuthRequestForOIDCUpstreamPasswordGrant(
|
||||
"scopes", oidcUpstream.GetScopes())
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester,
|
||||
fosite.ErrAccessDenied.WithHint(
|
||||
"Refresh token not returned by upstream provider during password grant."))
|
||||
"Refresh token not returned by upstream provider during password grant."), true)
|
||||
}
|
||||
|
||||
subject, username, groups, err := downstreamsession.GetDownstreamIdentityFromUpstreamIDToken(oidcUpstream, token.IDToken.Claims)
|
||||
if err != nil {
|
||||
// Return a user-friendly error for this case which is entirely within our control.
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester,
|
||||
fosite.ErrAccessDenied.WithHintf("Reason: %s.", err.Error()),
|
||||
fosite.ErrAccessDenied.WithHintf("Reason: %s.", err.Error()), true,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -214,7 +215,7 @@ func handleAuthRequestForOIDCUpstreamAuthcodeGrant(
|
||||
upstreamStateEncoder oidc.Encoder,
|
||||
cookieCodec oidc.Codec,
|
||||
) error {
|
||||
authorizeRequester, created := newAuthorizeRequest(r, w, oauthHelper)
|
||||
authorizeRequester, created := newAuthorizeRequest(r, w, oauthHelper, false)
|
||||
if !created {
|
||||
return nil
|
||||
}
|
||||
@@ -231,7 +232,7 @@ func handleAuthRequestForOIDCUpstreamAuthcodeGrant(
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester, err)
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester, err, false)
|
||||
}
|
||||
|
||||
csrfValue, nonceValue, pkceValue, err := generateValues(generateCSRF, generateNonce, generatePKCE)
|
||||
@@ -274,7 +275,7 @@ func handleAuthRequestForOIDCUpstreamAuthcodeGrant(
|
||||
|
||||
promptParam := r.Form.Get(promptParamName)
|
||||
if promptParam == promptParamNone && oidc.ScopeWasRequested(authorizeRequester, coreosoidc.ScopeOpenID) {
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester, fosite.ErrLoginRequired)
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester, fosite.ErrLoginRequired, false)
|
||||
}
|
||||
|
||||
for key, val := range oidcUpstream.GetAdditionalAuthcodeParams() {
|
||||
@@ -295,13 +296,13 @@ func handleAuthRequestForOIDCUpstreamAuthcodeGrant(
|
||||
encodedStateParamValue,
|
||||
authCodeOptions...,
|
||||
),
|
||||
302,
|
||||
http.StatusSeeOther, // match fosite and https://tools.ietf.org/id/draft-ietf-oauth-security-topics-18.html#section-4.11
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeAuthorizeError(w http.ResponseWriter, oauthHelper fosite.OAuth2Provider, authorizeRequester fosite.AuthorizeRequester, err error) error {
|
||||
func writeAuthorizeError(w http.ResponseWriter, oauthHelper fosite.OAuth2Provider, authorizeRequester fosite.AuthorizeRequester, err error, isBrowserless bool) error {
|
||||
if plog.Enabled(plog.LevelTrace) {
|
||||
// When trace level logging is enabled, include the stack trace in the log message.
|
||||
keysAndValues := oidc.FositeErrorForLog(err)
|
||||
@@ -314,6 +315,9 @@ func writeAuthorizeError(w http.ResponseWriter, oauthHelper fosite.OAuth2Provide
|
||||
} else {
|
||||
plog.Info("authorize response error", oidc.FositeErrorForLog(err)...)
|
||||
}
|
||||
if isBrowserless {
|
||||
w = rewriteStatusSeeOtherToStatusFoundForBrowserless(w)
|
||||
}
|
||||
// Return an error according to OIDC spec 3.1.2.6 (second paragraph).
|
||||
oauthHelper.WriteAuthorizeError(w, authorizeRequester, err)
|
||||
return nil
|
||||
@@ -333,29 +337,53 @@ func makeDownstreamSessionAndReturnAuthcodeRedirect(
|
||||
|
||||
authorizeResponder, err := oauthHelper.NewAuthorizeResponse(r.Context(), authorizeRequester, openIDSession)
|
||||
if err != nil {
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester, err)
|
||||
return writeAuthorizeError(w, oauthHelper, authorizeRequester, err, true)
|
||||
}
|
||||
|
||||
w = rewriteStatusSeeOtherToStatusFoundForBrowserless(w)
|
||||
oauthHelper.WriteAuthorizeResponse(w, authorizeRequester, authorizeResponder)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func rewriteStatusSeeOtherToStatusFoundForBrowserless(w http.ResponseWriter) http.ResponseWriter {
|
||||
// rewrite http.StatusSeeOther to http.StatusFound for backwards compatibility with old pinniped CLIs.
|
||||
// we can drop this in a few releases once we feel enough time has passed for users to update.
|
||||
//
|
||||
// WriteAuthorizeResponse/WriteAuthorizeError calls used to result in http.StatusFound until
|
||||
// https://github.com/ory/fosite/pull/636 changed it to http.StatusSeeOther to address
|
||||
// https://tools.ietf.org/id/draft-ietf-oauth-security-topics-18.html#section-4.11
|
||||
// Safari has the bad behavior in the case of http.StatusFound and not just http.StatusTemporaryRedirect.
|
||||
//
|
||||
// in the browserless flows, the OAuth client is the pinniped CLI and it already has access to the user's
|
||||
// password. Thus there is no security issue with using http.StatusFound vs. http.StatusSeeOther.
|
||||
return httpsnoop.Wrap(w, httpsnoop.Hooks{
|
||||
WriteHeader: func(delegate httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {
|
||||
return func(code int) {
|
||||
if code == http.StatusSeeOther {
|
||||
code = http.StatusFound
|
||||
}
|
||||
delegate(code)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func requireNonEmptyUsernameAndPasswordHeaders(r *http.Request, w http.ResponseWriter, oauthHelper fosite.OAuth2Provider, authorizeRequester fosite.AuthorizeRequester) (string, string, bool) {
|
||||
username := r.Header.Get(supervisoroidc.AuthorizeUsernameHeaderName)
|
||||
password := r.Header.Get(supervisoroidc.AuthorizePasswordHeaderName)
|
||||
if username == "" || password == "" {
|
||||
_ = writeAuthorizeError(w, oauthHelper, authorizeRequester,
|
||||
fosite.ErrAccessDenied.WithHintf("Missing or blank username or password."))
|
||||
fosite.ErrAccessDenied.WithHintf("Missing or blank username or password."), true)
|
||||
return "", "", false
|
||||
}
|
||||
return username, password, true
|
||||
}
|
||||
|
||||
func newAuthorizeRequest(r *http.Request, w http.ResponseWriter, oauthHelper fosite.OAuth2Provider) (fosite.AuthorizeRequester, bool) {
|
||||
func newAuthorizeRequest(r *http.Request, w http.ResponseWriter, oauthHelper fosite.OAuth2Provider, isBrowserless bool) (fosite.AuthorizeRequester, bool) {
|
||||
authorizeRequester, err := oauthHelper.NewAuthorizeRequest(r.Context(), r)
|
||||
if err != nil {
|
||||
_ = writeAuthorizeError(w, oauthHelper, authorizeRequester, err)
|
||||
_ = writeAuthorizeError(w, oauthHelper, authorizeRequester, err, isBrowserless)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
|
||||
@@ -533,7 +533,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: happyGetRequestPath,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
wantLocationHeader: expectedRedirectLocationForUpstreamOIDC(expectedUpstreamStateParam(nil, "", ""), nil),
|
||||
@@ -615,7 +615,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: happyGetRequestPath,
|
||||
csrfCookie: "__Host-pinniped-csrf=" + encodedIncomingCookieCSRFValue + " ",
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
wantLocationHeader: expectedRedirectLocationForUpstreamOIDC(expectedUpstreamStateParam(nil, incomingCookieCSRFValue, ""), nil),
|
||||
wantUpstreamStateParamInLocationHeader: true,
|
||||
@@ -633,7 +633,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
path: "/some/path",
|
||||
contentType: "application/x-www-form-urlencoded",
|
||||
body: encodeQuery(happyGetRequestQueryMap),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "",
|
||||
wantBodyString: "",
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
@@ -722,7 +722,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"prompt": "login"}),
|
||||
contentType: "application/x-www-form-urlencoded",
|
||||
body: encodeQuery(happyGetRequestQueryMap),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
wantBodyStringWithLocationInHref: true,
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
@@ -741,7 +741,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"prompt": "login"}),
|
||||
contentType: "application/x-www-form-urlencoded",
|
||||
body: encodeQuery(happyGetRequestQueryMap),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
wantBodyStringWithLocationInHref: true,
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
@@ -760,7 +760,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"prompt": "none"}),
|
||||
contentType: "application/x-www-form-urlencoded",
|
||||
body: encodeQuery(happyGetRequestQueryMap),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeLoginRequiredErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -776,7 +776,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: happyGetRequestPath,
|
||||
csrfCookie: "__Host-pinniped-csrf=this-value-was-not-signed-by-pinniped",
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
// Generated a new CSRF cookie and set it in the response.
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
@@ -796,7 +796,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
path: modifiedHappyGetRequestPath(map[string]string{
|
||||
"redirect_uri": downstreamRedirectURIWithDifferentPort, // not the same port number that is registered for the client
|
||||
}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
wantLocationHeader: expectedRedirectLocationForUpstreamOIDC(expectedUpstreamStateParam(map[string]string{
|
||||
@@ -862,7 +862,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"scope": "openid offline_access"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
wantLocationHeader: expectedRedirectLocationForUpstreamOIDC(expectedUpstreamStateParam(map[string]string{
|
||||
@@ -1170,7 +1170,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"response_type": "unsupported"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeUnsupportedResponseTypeErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1217,7 +1217,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"scope": "openid profile email tuna"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeInvalidScopeErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1268,7 +1268,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"response_type": ""}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeMissingResponseTypeErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1349,7 +1349,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"code_challenge": ""}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeMissingCodeChallengeErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1391,7 +1391,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"code_challenge_method": "this-is-not-a-valid-pkce-alg"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeInvalidCodeChallengeErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1433,7 +1433,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"code_challenge_method": "plain"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeMissingCodeChallengeMethodErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1475,7 +1475,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"code_challenge_method": ""}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeMissingCodeChallengeMethodErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1519,7 +1519,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"prompt": "none login"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositePromptHasNoneAndOtherValueErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -1566,7 +1566,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
// The following prompt value is illegal when openid is requested, but note that openid is not requested.
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"prompt": "none login", "scope": "email"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: htmlContentType,
|
||||
wantCSRFValueInCookieHeader: happyCSRF,
|
||||
wantLocationHeader: expectedRedirectLocationForUpstreamOIDC(expectedUpstreamStateParam(
|
||||
@@ -2049,7 +2049,7 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
cookieEncoder: happyCookieEncoder,
|
||||
method: http.MethodGet,
|
||||
path: modifiedHappyGetRequestPath(map[string]string{"state": "short"}),
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantContentType: "application/json; charset=utf-8",
|
||||
wantLocationHeader: urlWithQuery(downstreamRedirectURI, fositeInvalidStateErrorQuery),
|
||||
wantBodyString: "",
|
||||
@@ -2308,8 +2308,16 @@ func TestAuthorizationEndpoint(t *testing.T) {
|
||||
case test.wantBodyJSON != "":
|
||||
require.JSONEq(t, test.wantBodyJSON, rsp.Body.String())
|
||||
case test.wantBodyStringWithLocationInHref:
|
||||
anchorTagWithLocationHref := fmt.Sprintf("<a href=\"%s\">Found</a>.\n\n", html.EscapeString(actualLocation))
|
||||
require.Equal(t, anchorTagWithLocationHref, rsp.Body.String())
|
||||
switch code := rsp.Code; code {
|
||||
case http.StatusFound:
|
||||
anchorTagWithLocationHref := fmt.Sprintf("<a href=\"%s\">Found</a>.\n\n", html.EscapeString(actualLocation))
|
||||
require.Equal(t, anchorTagWithLocationHref, rsp.Body.String())
|
||||
case http.StatusSeeOther:
|
||||
anchorTagWithLocationHref := fmt.Sprintf("<a href=\"%s\">See Other</a>.\n\n", html.EscapeString(actualLocation))
|
||||
require.Equal(t, anchorTagWithLocationHref, rsp.Body.String())
|
||||
default:
|
||||
t.Errorf("unexpected response code: %v", code)
|
||||
}
|
||||
default:
|
||||
require.Equal(t, test.wantBodyString, rsp.Body.String())
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -204,7 +204,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -229,7 +229,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -256,7 +256,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -284,7 +284,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound, // succeed despite `email_verified=false` because we're not using the email claim for anything
|
||||
wantStatus: http.StatusSeeOther, // succeed despite `email_verified=false` because we're not using the email claim for anything
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -372,7 +372,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -397,7 +397,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -422,7 +422,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -575,7 +575,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
Build(t, happyStateCodec),
|
||||
).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: downstreamRedirectURI + `\?code=([^&]+)&scope=&state=` + happyDownstreamState,
|
||||
wantDownstreamIDTokenUsername: oidcUpstreamUsername,
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -601,7 +601,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
Build(t, happyStateCodec),
|
||||
).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: downstreamRedirectURI + `\?code=([^&]+)&scope=openid\+offline_access&state=` + happyDownstreamState,
|
||||
wantDownstreamIDTokenUsername: oidcUpstreamUsername,
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
@@ -698,7 +698,7 @@ func TestCallbackEndpoint(t *testing.T) {
|
||||
method: http.MethodGet,
|
||||
path: newRequestPath().WithState(happyState).String(),
|
||||
csrfCookie: happyCSRFCookie,
|
||||
wantStatus: http.StatusFound,
|
||||
wantStatus: http.StatusSeeOther,
|
||||
wantRedirectLocationRegexp: happyDownstreamRedirectLocationRegexp,
|
||||
wantBody: "",
|
||||
wantDownstreamIDTokenSubject: oidcUpstreamIssuer + "?sub=" + oidcUpstreamSubjectQueryEscaped,
|
||||
|
||||
@@ -114,7 +114,7 @@ func (k KubeStorage) GetOpenIDConnectSession(ctx context.Context, fullAuthcode s
|
||||
}
|
||||
|
||||
func (k KubeStorage) DeleteOpenIDConnectSession(ctx context.Context, fullAuthcode string) error {
|
||||
return k.oidcStorage.DeleteOpenIDConnectSession(ctx, fullAuthcode)
|
||||
return k.oidcStorage.DeleteOpenIDConnectSession(ctx, fullAuthcode) //nolint: staticcheck // we know this is deprecated and never called. our GC controller cleans these up.
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -121,7 +121,7 @@ func TestManager(t *testing.T) {
|
||||
r.False(fallbackHandlerWasCalled)
|
||||
|
||||
// Minimal check to ensure that the right endpoint was called
|
||||
r.Equal(http.StatusFound, recorder.Code)
|
||||
r.Equal(http.StatusSeeOther, recorder.Code)
|
||||
actualLocation := recorder.Header().Get("Location")
|
||||
r.True(
|
||||
strings.HasPrefix(actualLocation, expectedRedirectLocationPrefix),
|
||||
@@ -160,7 +160,7 @@ func TestManager(t *testing.T) {
|
||||
|
||||
// Check just enough of the response to ensure that we wired up the callback endpoint correctly.
|
||||
// The endpoint's own unit tests cover everything else.
|
||||
r.Equal(http.StatusFound, recorder.Code)
|
||||
r.Equal(http.StatusSeeOther, recorder.Code)
|
||||
actualLocation := recorder.Header().Get("Location")
|
||||
r.True(
|
||||
strings.HasPrefix(actualLocation, downstreamRedirectURL),
|
||||
|
||||
@@ -2971,7 +2971,7 @@ func requireValidStoredRequest(
|
||||
|
||||
// At this time, we don't use any of these optional (per the OIDC spec) fields.
|
||||
require.Empty(t, claims.AuthenticationContextClassReference)
|
||||
require.Empty(t, claims.AuthenticationMethodsReference)
|
||||
require.Empty(t, claims.AuthenticationMethodsReferences)
|
||||
require.Empty(t, claims.CodeHash)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user