diff --git a/CHANGELOG.md b/CHANGELOG.md index 57561ebe..ed10aab8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ ## Changes since v7.0.1 +- [#1116](https://github.com/oauth2-proxy/oauth2-proxy/pull/1116) Reinstate preferEmailToUser behaviour for basic auth sessions (@JoelSpeed) - [#1115](https://github.com/oauth2-proxy/oauth2-proxy/pull/1115) Fix upstream proxy appending ? to requests (@JoelSpeed) - [#1117](https://github.com/oauth2-proxy/oauth2-proxy/pull/1117) Deprecate GCP HealthCheck option (@JoelSpeed) - [#1104](https://github.com/oauth2-proxy/oauth2-proxy/pull/1104) Allow custom robots text pages (@JoelSpeed) diff --git a/oauthproxy.go b/oauthproxy.go index e3ea21f2..6415ef6a 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -343,7 +343,7 @@ func buildSessionChain(opts *options.Options, sessionStore sessionsapi.SessionSt } if validator != nil { - chain = chain.Append(middleware.NewBasicAuthSessionLoader(validator, opts.HtpasswdUserGroups)) + chain = chain.Append(middleware.NewBasicAuthSessionLoader(validator, opts.HtpasswdUserGroups, opts.LegacyPreferEmailToUser)) } chain = chain.Append(middleware.NewStoredSessionLoader(&middleware.StoredSessionLoaderOptions{ diff --git a/pkg/apis/options/legacy_options.go b/pkg/apis/options/legacy_options.go index 66205de0..612db9e1 100644 --- a/pkg/apis/options/legacy_options.go +++ b/pkg/apis/options/legacy_options.go @@ -67,6 +67,8 @@ func (l *LegacyOptions) ToOptions() (*Options, error) { l.Options.InjectRequestHeaders, l.Options.InjectResponseHeaders = l.LegacyHeaders.convert() l.Options.Server, l.Options.MetricsServer = l.LegacyServer.convert() + l.Options.LegacyPreferEmailToUser = l.LegacyHeaders.PreferEmailToUser + return &l.Options, nil } diff --git a/pkg/apis/options/options.go b/pkg/apis/options/options.go index 34cb75d5..58ddd2e8 100644 --- a/pkg/apis/options/options.go +++ b/pkg/apis/options/options.go @@ -104,6 +104,9 @@ type Options struct { PubJWKURL string `flag:"pubjwk-url" cfg:"pubjwk_url"` GCPHealthChecks bool `flag:"gcp-healthchecks" cfg:"gcp_healthchecks"` + // This is used for backwards compatibility for basic auth users + LegacyPreferEmailToUser bool `cfg:",internal"` + // internal values that are set after config validation redirectURL *url.URL provider providers.Provider diff --git a/pkg/middleware/basic_session.go b/pkg/middleware/basic_session.go index 54fc559c..a6e92faa 100644 --- a/pkg/middleware/basic_session.go +++ b/pkg/middleware/basic_session.go @@ -11,9 +11,9 @@ import ( "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" ) -func NewBasicAuthSessionLoader(validator basic.Validator, sessionGroups []string) alice.Constructor { +func NewBasicAuthSessionLoader(validator basic.Validator, sessionGroups []string, preferEmail bool) alice.Constructor { return func(next http.Handler) http.Handler { - return loadBasicAuthSession(validator, sessionGroups, next) + return loadBasicAuthSession(validator, sessionGroups, preferEmail, next) } } @@ -22,7 +22,20 @@ func NewBasicAuthSessionLoader(validator basic.Validator, sessionGroups []string // If no authorization header is found, or the header is invalid, no session // will be loaded and the request will be passed to the next handler. // If a session was loaded by a previous handler, it will not be replaced. -func loadBasicAuthSession(validator basic.Validator, sessionGroups []string, next http.Handler) http.Handler { +func loadBasicAuthSession(validator basic.Validator, sessionGroups []string, preferEmail bool, next http.Handler) http.Handler { + // This is a hack to be backwards compatible with the old PreferEmailToUser option. + // Long term we will have a rich static user configuration option and this will + // be removed. + // TODO(JoelSpeed): Remove this hack once rich static user config is implemented. + getSession := getBasicSession + if preferEmail { + getSession = func(validator basic.Validator, sessionGroups []string, req *http.Request) (*sessionsapi.SessionState, error) { + session, err := getBasicSession(validator, sessionGroups, req) + session.Email = session.User + return session, err + } + } + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { scope := middlewareapi.GetRequestScope(req) // If scope is nil, this will panic. @@ -33,7 +46,7 @@ func loadBasicAuthSession(validator basic.Validator, sessionGroups []string, nex return } - session, err := getBasicSession(validator, sessionGroups, req) + session, err := getSession(validator, sessionGroups, req) if err != nil { logger.Errorf("Error retrieving session from token in Authorization header: %v", err) } diff --git a/pkg/middleware/basic_session_test.go b/pkg/middleware/basic_session_test.go index 94cc4248..24f0812d 100644 --- a/pkg/middleware/basic_session_test.go +++ b/pkg/middleware/basic_session_test.go @@ -26,6 +26,7 @@ var _ = Describe("Basic Auth Session Suite", func() { type basicAuthSessionLoaderTableInput struct { authorizationHeader string + preferEmail bool sessionGroups []string existingSession *sessionsapi.SessionState expectedSession *sessionsapi.SessionState @@ -55,7 +56,7 @@ var _ = Describe("Basic Auth Session Suite", func() { // Create the handler with a next handler that will capture the session // from the scope var gotSession *sessionsapi.SessionState - handler := NewBasicAuthSessionLoader(validator, in.sessionGroups)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler := NewBasicAuthSessionLoader(validator, in.sessionGroups, in.preferEmail)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { gotSession = middlewareapi.GetRequestScope(r).Session })) handler.ServeHTTP(rw, req) @@ -118,6 +119,12 @@ var _ = Describe("Basic Auth Session Suite", func() { existingSession: nil, expectedSession: &sessionsapi.SessionState{User: "admin", Groups: []string{"a", "b"}}, }), + Entry("Basic Base64(user1:) (with PreferEmailToUser)", basicAuthSessionLoaderTableInput{ + authorizationHeader: "Basic dXNlcjE6VXNFck9uM1A0NTU=", + preferEmail: true, + existingSession: nil, + expectedSession: &sessionsapi.SessionState{User: "user1", Email: "user1"}, + }), ) }) })