git.iko.soy/typeable/oauth2-proxy
on master help sign in
Add EnrichSessionState as main post-Redeem session updater
2b9e1bbNick Meves
CHANGELOG.md+2
@@ -26,9 +26,11 @@
26## Changes since v6.1.1
26## Changes since v6.1.1
27
27
28- [#825](https://github.com/oauth2-proxy/oauth2-proxy/pull/825) Fix code coverage reporting on GitHub actions(@JoelSpeed)
28- [#825](https://github.com/oauth2-proxy/oauth2-proxy/pull/825) Fix code coverage reporting on GitHub actions(@JoelSpeed)
29+- [#767](https://github.com/oauth2-proxy/oauth2-proxy/pull/796) Deprecate GetUserName & GetEmailAdress for EnrichSessionState (@NickMeves)
29- [#705](https://github.com/oauth2-proxy/oauth2-proxy/pull/705) Add generic Header injectors for upstream request and response headers (@JoelSpeed)
30- [#705](https://github.com/oauth2-proxy/oauth2-proxy/pull/705) Add generic Header injectors for upstream request and response headers (@JoelSpeed)
30- [#753](https://github.com/oauth2-proxy/oauth2-proxy/pull/753) Pass resource parameter in login url (@codablock)
31- [#753](https://github.com/oauth2-proxy/oauth2-proxy/pull/753) Pass resource parameter in login url (@codablock)
31- [#789](https://github.com/oauth2-proxy/oauth2-proxy/pull/789) Add `--skip-auth-route` configuration option for `METHOD=pathRegex` based allowlists (@NickMeves)
32- [#789](https://github.com/oauth2-proxy/oauth2-proxy/pull/789) Add `--skip-auth-route` configuration option for `METHOD=pathRegex` based allowlists (@NickMeves)
33+- [#767](https://github.com/oauth2-proxy/oauth2-proxy/pull/796) Deprecate GetUserName & GetEmailAdress for EnrichSessionState (@NickMeves)
32- [#575](https://github.com/oauth2-proxy/oauth2-proxy/pull/575) Stop accepting legacy SHA1 signed cookies (@NickMeves)
34- [#575](https://github.com/oauth2-proxy/oauth2-proxy/pull/575) Stop accepting legacy SHA1 signed cookies (@NickMeves)
33- [#722](https://github.com/oauth2-proxy/oauth2-proxy/pull/722) Validate Redis configuration options at startup (@NickMeves)
35- [#722](https://github.com/oauth2-proxy/oauth2-proxy/pull/722) Validate Redis configuration options at startup (@NickMeves)
34- [#791](https://github.com/oauth2-proxy/oauth2-proxy/pull/791) Remove GetPreferredUsername method from provider interface (@NickMeves)
36- [#791](https://github.com/oauth2-proxy/oauth2-proxy/pull/791) Remove GetPreferredUsername method from provider interface (@NickMeves)
oauthproxy.go+4−3
@@ -360,7 +360,7 @@ func (p *OAuthProxy) redeemCode(ctx context.Context, host, code string) (*sessio
360 return s, nil
360 return s, nil
361}
361}
362
362
363−func (p *OAuthProxy) enrichSession(ctx context.Context, s *sessionsapi.SessionState) error {
363+func (p *OAuthProxy) enrichSessionState(ctx context.Context, s *sessionsapi.SessionState) error {
364 var err error
364 var err error
365 if s.Email == "" {
365 if s.Email == "" {
366 s.Email, err = p.provider.GetEmailAddress(ctx, s)
366 s.Email, err = p.provider.GetEmailAddress(ctx, s)
@@ -374,7 +374,8 @@ func (p *OAuthProxy) enrichSession(ctx context.Context, s *sessionsapi.SessionSt
374 return err
374 return err
375 }
375 }
376 }
376 }
377− return nil
377+
378+ return p.provider.EnrichSessionState(ctx, s)
378}
379}
379
380
380// MakeCSRFCookie creates a cookie for CSRF
381// MakeCSRFCookie creates a cookie for CSRF
@@ -831,7 +832,7 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
831 return
832 return
832 }
833 }
833
834
834− err = p.enrichSession(req.Context(), session)
835+ err = p.enrichSessionState(req.Context(), session)
835 if err != nil {
836 if err != nil {
836 logger.Errorf("Error creating session during OAuth2 callback: %v", err)
837 logger.Errorf("Error creating session during OAuth2 callback: %v", err)
837 p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Internal Error")
838 p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Internal Error")
oauthproxy_test.go+4−4
@@ -396,11 +396,11 @@ func NewTestProvider(providerURL *url.URL, emailAddress string) *TestProvider {
396 }
396 }
397}
397}
398
398
399−func (tp *TestProvider) GetEmailAddress(ctx context.Context, session *sessions.SessionState) (string, error) {
399+func (tp *TestProvider) GetEmailAddress(_ context.Context, _ *sessions.SessionState) (string, error) {
400 return tp.EmailAddress, nil
400 return tp.EmailAddress, nil
401}
401}
402
402
403−func (tp *TestProvider) ValidateSessionState(ctx context.Context, session *sessions.SessionState) bool {
403+func (tp *TestProvider) ValidateSessionState(_ context.Context, _ *sessions.SessionState) bool {
404 return tp.ValidToken
404 return tp.ValidToken
405}
405}
406
406
@@ -468,7 +468,7 @@ func Test_enrichSession(t *testing.T) {
468 t.Fatal(err)
468 t.Fatal(err)
469 }
469 }
470
470
471− err = proxy.enrichSession(context.Background(), tc.session)
471+ err = proxy.enrichSessionState(context.Background(), tc.session)
472 assert.NoError(t, err)
472 assert.NoError(t, err)
473 assert.Equal(t, tc.expectedUser, tc.session.User)
473 assert.Equal(t, tc.expectedUser, tc.session.User)
474 assert.Equal(t, tc.expectedEmail, tc.session.Email)
474 assert.Equal(t, tc.expectedEmail, tc.session.Email)
@@ -1955,7 +1955,7 @@ func TestClearSingleCookie(t *testing.T) {
1955type NoOpKeySet struct {
1955type NoOpKeySet struct {
1956}
1956}
1957
1957
1958−func (NoOpKeySet) VerifySignature(ctx context.Context, jwt string) (payload []byte, err error) {
1958+func (NoOpKeySet) VerifySignature(_ context.Context, jwt string) (payload []byte, err error) {
1959 splitStrings := strings.Split(jwt, ".")
1959 splitStrings := strings.Split(jwt, ".")
1960 payloadString := splitStrings[1]
1960 payloadString := splitStrings[1]
1961 return base64.RawURLEncoding.DecodeString(payloadString)
1961 return base64.RawURLEncoding.DecodeString(payloadString)
providers/provider_default.go+13−5
@@ -87,21 +87,29 @@ func (p *ProviderData) GetLoginURL(redirectURI, state string) string {
87}
87}
88
88
89// GetEmailAddress returns the Account email address
89// GetEmailAddress returns the Account email address
90+// DEPRECATED: Migrate to EnrichSessionState
90−func (p *ProviderData) GetEmailAddress(ctx context.Context, s *sessions.SessionState) (string, error) {
91+func (p *ProviderData) GetEmailAddress(_ context.Context, _ *sessions.SessionState) (string, error) {
91 return "", ErrNotImplemented
92 return "", ErrNotImplemented
92}
93}
93
94
94// GetUserName returns the Account username
95// GetUserName returns the Account username
96+// DEPRECATED: Migrate to EnrichSessionState
95−func (p *ProviderData) GetUserName(ctx context.Context, s *sessions.SessionState) (string, error) {
97+func (p *ProviderData) GetUserName(_ context.Context, _ *sessions.SessionState) (string, error) {
96 return "", ErrNotImplemented
98 return "", ErrNotImplemented
97}
99}
98
100
99// ValidateGroup validates that the provided email exists in the configured provider
101// ValidateGroup validates that the provided email exists in the configured provider
100// email group(s).
102// email group(s).
101−func (p *ProviderData) ValidateGroup(email string) bool {
103+func (p *ProviderData) ValidateGroup(_ string) bool {
102 return true
104 return true
103}
105}
104
106
107+// EnrichSessionState is called after Redeem to allow providers to enrich session fields
108+// such as User, Email, Groups with provider specific API calls.
109+func (p *ProviderData) EnrichSessionState(_ context.Context, _ *sessions.SessionState) error {
110+ return nil
111+}
112+
105// ValidateSessionState validates the AccessToken
113// ValidateSessionState validates the AccessToken
106func (p *ProviderData) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool {
114func (p *ProviderData) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool {
107 return validateToken(ctx, p, s.AccessToken, nil)
115 return validateToken(ctx, p, s.AccessToken, nil)
@@ -109,12 +117,12 @@ func (p *ProviderData) ValidateSessionState(ctx context.Context, s *sessions.Ses
109
117
110// RefreshSessionIfNeeded should refresh the user's session if required and
118// RefreshSessionIfNeeded should refresh the user's session if required and
111// do nothing if a refresh is not required
119// do nothing if a refresh is not required
112−func (p *ProviderData) RefreshSessionIfNeeded(ctx context.Context, s *sessions.SessionState) (bool, error) {
120+func (p *ProviderData) RefreshSessionIfNeeded(_ context.Context, _ *sessions.SessionState) (bool, error) {
113 return false, nil
121 return false, nil
114}
122}
115
123
116// CreateSessionStateFromBearerToken should be implemented to allow providers
124// CreateSessionStateFromBearerToken should be implemented to allow providers
117// to convert ID tokens into sessions
125// to convert ID tokens into sessions
118−func (p *ProviderData) CreateSessionStateFromBearerToken(ctx context.Context, rawIDToken string, idToken *oidc.IDToken) (*sessions.SessionState, error) {
126+func (p *ProviderData) CreateSessionStateFromBearerToken(_ context.Context, _ string, _ *oidc.IDToken) (*sessions.SessionState, error) {
119 return nil, ErrNotImplemented
127 return nil, ErrNotImplemented
120}
128}
providers/provider_default_test.go+6
@@ -47,3 +47,9 @@ func TestAcrValuesConfigured(t *testing.T) {
47 result := p.GetLoginURL("https://my.test.app/oauth", "")
47 result := p.GetLoginURL("https://my.test.app/oauth", "")
48 assert.Contains(t, result, "acr_values=testValue")
48 assert.Contains(t, result, "acr_values=testValue")
49}
49}
50+
51+func TestEnrichSessionState(t *testing.T) {
52+ p := &ProviderData{}
53+ s := &sessions.SessionState{}
54+ assert.NoError(t, p.EnrichSessionState(context.Background(), s))
55+}
providers/providers.go+3
@@ -10,10 +10,13 @@ import (
10// Provider represents an upstream identity provider implementation
10// Provider represents an upstream identity provider implementation
11type Provider interface {
11type Provider interface {
12 Data() *ProviderData
12 Data() *ProviderData
13+ // DEPRECATED: Migrate to EnrichSessionState
13 GetEmailAddress(ctx context.Context, s *sessions.SessionState) (string, error)
14 GetEmailAddress(ctx context.Context, s *sessions.SessionState) (string, error)
15+ // DEPRECATED: Migrate to EnrichSessionState
14 GetUserName(ctx context.Context, s *sessions.SessionState) (string, error)
16 GetUserName(ctx context.Context, s *sessions.SessionState) (string, error)
15 Redeem(ctx context.Context, redirectURI, code string) (*sessions.SessionState, error)
17 Redeem(ctx context.Context, redirectURI, code string) (*sessions.SessionState, error)
16 ValidateGroup(string) bool
18 ValidateGroup(string) bool
19+ EnrichSessionState(ctx context.Context, s *sessions.SessionState) error
17 ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool
20 ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool
18 GetLoginURL(redirectURI, finalRedirect string) string
21 GetLoginURL(redirectURI, finalRedirect string) string
19 RefreshSessionIfNeeded(ctx context.Context, s *sessions.SessionState) (bool, error)
22 RefreshSessionIfNeeded(ctx context.Context, s *sessions.SessionState) (bool, error)