From 3c19c364bde3120b8da88a2e36b9ccdc3641eb4e Mon Sep 17 00:00:00 2001 From: Akshay Pratinav Date: Tue, 12 Mar 2019 21:24:47 -0700 Subject: [PATCH 01/16] add pagination support for /user/teams --- providers/github.go | 72 +++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/providers/github.go b/providers/github.go index d39ee2b6..fc3740c4 100644 --- a/providers/github.go +++ b/providers/github.go @@ -137,36 +137,56 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { } `json:"organization"` } - params := url.Values{ - "limit": {"200"}, + type teamsPage []struct { + Name string `json:"name"` + Slug string `json:"slug"` + Org struct { + Login string `json:"login"` + } `json:"organization"` } - endpoint := &url.URL{ - Scheme: p.ValidateURL.Scheme, - Host: p.ValidateURL.Host, - Path: path.Join(p.ValidateURL.Path, "/user/teams"), - RawQuery: params.Encode(), - } - req, _ := http.NewRequest("GET", endpoint.String(), nil) - req.Header.Set("Accept", "application/vnd.github.v3+json") - req.Header.Set("Authorization", fmt.Sprintf("token %s", accessToken)) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return false, err - } + pn := 1 + for { + params := url.Values{ + "limit": {"200"}, + "page": {strconv.Itoa(pn)}, + } - body, err := ioutil.ReadAll(resp.Body) - resp.Body.Close() - if err != nil { - return false, err - } - if resp.StatusCode != 200 { - return false, fmt.Errorf( - "got %d from %q %s", resp.StatusCode, endpoint.String(), body) - } + endpoint := &url.URL{ + Scheme: p.ValidateURL.Scheme, + Host: p.ValidateURL.Host, + Path: path.Join(p.ValidateURL.Path, "/user/teams"), + RawQuery: params.Encode(), + } - if err := json.Unmarshal(body, &teams); err != nil { - return false, fmt.Errorf("%s unmarshaling %s", err, body) + req, _ := http.NewRequest("GET", endpoint.String(), nil) + req.Header.Set("Accept", "application/vnd.github.v3+json") + req.Header.Set("Authorization", fmt.Sprintf("token %s", accessToken)) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return false, err + } + + body, err := ioutil.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + return false, err + } + if resp.StatusCode != 200 { + return false, fmt.Errorf( + "got %d from %q %s", resp.StatusCode, endpoint.String(), body) + } + + var tp teamsPage + if err := json.Unmarshal(body, &tp); err != nil { + return false, fmt.Errorf("%s unmarshaling %s", err, body) + } + if len(tp) == 0 { + break + } + + teams = append(teams, tp...) + pn++ } var hasOrg bool From e73f6501f0171e63f804c45469e58ac219a83b03 Mon Sep 17 00:00:00 2001 From: Akshay Pratinav Date: Thu, 14 Mar 2019 20:04:45 -0700 Subject: [PATCH 02/16] limit => per_page --- providers/github.go | 8 ++++---- providers/github_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/providers/github.go b/providers/github.go index fc3740c4..eecf5dfc 100644 --- a/providers/github.go +++ b/providers/github.go @@ -73,8 +73,8 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) { pn := 1 for { params := url.Values{ - "limit": {"200"}, - "page": {strconv.Itoa(pn)}, + "per_page": {"200"}, + "page": {strconv.Itoa(pn)}, } endpoint := &url.URL{ @@ -148,8 +148,8 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { pn := 1 for { params := url.Values{ - "limit": {"200"}, - "page": {strconv.Itoa(pn)}, + "per_page": {"200"}, + "page": {strconv.Itoa(pn)}, } endpoint := &url.URL{ diff --git a/providers/github_test.go b/providers/github_test.go index c96877cb..1a66a59c 100644 --- a/providers/github_test.go +++ b/providers/github_test.go @@ -31,7 +31,7 @@ func testGitHubBackend(payload []string) *httptest.Server { pathToQueryMap := map[string][]string{ "/user": {""}, "/user/emails": {""}, - "/user/orgs": {"limit=200&page=1", "limit=200&page=2", "limit=200&page=3"}, + "/user/orgs": {"page=1&per_page=200", "page=2&per_page=200", "page=3&per_page=200"}, } return httptest.NewServer(http.HandlerFunc( From 6d15fe004eabcad382737976d3b686db7132becf Mon Sep 17 00:00:00 2001 From: Akshay Pratinav Date: Fri, 15 Mar 2019 08:00:20 -0700 Subject: [PATCH 03/16] change per_page value from 200 to 100 --- providers/github.go | 4 ++-- providers/github_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/providers/github.go b/providers/github.go index eecf5dfc..7bbc8b95 100644 --- a/providers/github.go +++ b/providers/github.go @@ -73,7 +73,7 @@ func (p *GitHubProvider) hasOrg(accessToken string) (bool, error) { pn := 1 for { params := url.Values{ - "per_page": {"200"}, + "per_page": {"100"}, "page": {strconv.Itoa(pn)}, } @@ -148,7 +148,7 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { pn := 1 for { params := url.Values{ - "per_page": {"200"}, + "per_page": {"100"}, "page": {strconv.Itoa(pn)}, } diff --git a/providers/github_test.go b/providers/github_test.go index 1a66a59c..3d63551e 100644 --- a/providers/github_test.go +++ b/providers/github_test.go @@ -31,7 +31,7 @@ func testGitHubBackend(payload []string) *httptest.Server { pathToQueryMap := map[string][]string{ "/user": {""}, "/user/emails": {""}, - "/user/orgs": {"page=1&per_page=200", "page=2&per_page=200", "page=3&per_page=200"}, + "/user/orgs": {"page=1&per_page=100", "page=2&per_page=100", "page=3&per_page=100"}, } return httptest.NewServer(http.HandlerFunc( From 31d7b61cc4816a20e372064d95df44cee0a38193 Mon Sep 17 00:00:00 2001 From: toshi-miura Date: Mon, 7 Oct 2019 22:38:57 +0900 Subject: [PATCH 04/16] Added handling of link header in githubAPI paging process ====================================================== changelog note [#274](https://github.com/pusher/oauth2_proxy/pull/274) Add github api pagination support (@toshi-miura ,@apratina) ====================================================== I didn't edit CHANGELOG.md. Since # 102 was taken over and the change difference of CHANGELOG.md was large --- providers/github.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/providers/github.go b/providers/github.go index 3dd677e9..dde166e9 100644 --- a/providers/github.go +++ b/providers/github.go @@ -7,6 +7,7 @@ import ( "net/http" "net/url" "path" + "regexp" "strconv" "strings" @@ -148,6 +149,7 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { } pn := 1 + last := 0 for { params := url.Values{ "per_page": {"100"}, @@ -170,6 +172,30 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { } body, err := ioutil.ReadAll(resp.Body) + + if last == 0 { + // link header may not be obtained + // When paging is not required and all data can be retrieved with a single call + + // Conditions for obtaining the link header. + // 1. When paging is required (Example: When the data size is 100 and the page size is 99 or less) + // 2. When it exceeds the paging frame (Example: When there is only 10 records but the second page is called with a page size of 100) + + // link header at not last page + // ; rel="prev", ; rel="last", ; rel="first" + // link header at last page (doesn't exist last info) + // ; rel="prev", ; rel="first" + + link := resp.Header.Get("Link") + rep1 := regexp.MustCompile(`(?s).*\; rel="last".*`) + i, converr := strconv.Atoi(rep1.ReplaceAllString(link, "$1")) + + // If the last page cannot be taken from the link in the http header, the last variable remains zero + if converr == nil { + last = i + } + } + resp.Body.Close() if err != nil { return false, err @@ -188,6 +214,14 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { } teams = append(teams, tp...) + + if pn == last { + break + } + if last == 0 { + break + } + pn++ } From e71797b40911b87c308214219201343fdb3c2c61 Mon Sep 17 00:00:00 2001 From: toshi-miura Date: Fri, 11 Oct 2019 16:02:04 +0900 Subject: [PATCH 05/16] =?UTF-8?q?ReadAll()=20&=20Close()=20=E3=80=80close?= =?UTF-8?q?=20together.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- providers/github.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/providers/github.go b/providers/github.go index dde166e9..f9821cb2 100644 --- a/providers/github.go +++ b/providers/github.go @@ -171,8 +171,6 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { return false, err } - body, err := ioutil.ReadAll(resp.Body) - if last == 0 { // link header may not be obtained // When paging is not required and all data can be retrieved with a single call @@ -196,10 +194,13 @@ func (p *GitHubProvider) hasOrgAndTeam(accessToken string) (bool, error) { } } - resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) if err != nil { + resp.Body.Close() return false, err } + resp.Body.Close() + if resp.StatusCode != 200 { return false, fmt.Errorf( "got %d from %q %s", resp.StatusCode, endpoint.String(), body) From 0d256a329fb712da126319a250f236a45081147c Mon Sep 17 00:00:00 2001 From: toshi-miura Date: Fri, 11 Oct 2019 19:49:08 +0900 Subject: [PATCH 06/16] add change log. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44cd0cf6..ec03406e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Changes since v4.0.0 +- [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura ,@apratina) + # v4.0.0 ## Release Highlights From 610ee6d0ec5c03adef744a6c8a5a723842ca3893 Mon Sep 17 00:00:00 2001 From: toshi-miura Date: Sat, 12 Oct 2019 02:30:58 +0900 Subject: [PATCH 07/16] Fix typo. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc24e136..10aba308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - [#227](https://github.com/pusher/oauth2_proxy/pull/227) Add Keycloak provider (@Ofinka) - [#273](https://github.com/pusher/oauth2_proxy/pull/273) Support Go 1.13 (@dio) - [#275](https://github.com/pusher/oauth2_proxy/pull/275) docker: build from debian buster (@syscll) -- [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura ,@apratina) +- [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura,@apratina) # v4.0.0 From e34f18ef2cf864c952e35977d9ee7e8d4ff19f8e Mon Sep 17 00:00:00 2001 From: toshi-miura Date: Mon, 21 Oct 2019 18:14:01 +0900 Subject: [PATCH 08/16] Update CHANGELOG.md Co-Authored-By: Joel Speed --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10aba308..201fb912 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - [#227](https://github.com/pusher/oauth2_proxy/pull/227) Add Keycloak provider (@Ofinka) - [#273](https://github.com/pusher/oauth2_proxy/pull/273) Support Go 1.13 (@dio) - [#275](https://github.com/pusher/oauth2_proxy/pull/275) docker: build from debian buster (@syscll) -- [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura,@apratina) +- [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura, @apratina) # v4.0.0 From 2a07983a36d3eef9d1ddd80a54440fc01d4e084c Mon Sep 17 00:00:00 2001 From: Kimball Leavitt Date: Tue, 5 Nov 2019 19:39:10 -0700 Subject: [PATCH 09/16] Add bash completion script (#307) * added bash completion script * added install instructions for bash completion --- contrib/oauth2_proxy_autocomplete.sh | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 contrib/oauth2_proxy_autocomplete.sh diff --git a/contrib/oauth2_proxy_autocomplete.sh b/contrib/oauth2_proxy_autocomplete.sh new file mode 100644 index 00000000..fd9d87a4 --- /dev/null +++ b/contrib/oauth2_proxy_autocomplete.sh @@ -0,0 +1,30 @@ +# +# Autocompletion for oauth2_proxy +# +# To install this, copy/move this file to /etc/bash.completion.d/ +# or add a line to your ~/.bashrc | ~/.bash_profile that says ". /path/to/oauth2_proxy/contrib/oauth2_proxy_autocomplete.sh" +# + +_oauth2_proxy() { + _oauth2_proxy_commands=$(oauth2_proxy -h 2>&1 | sed -n '/^\s*-/s/ \+/ /gp' | awk '{print $1}' | tr '\n' ' ') + local cur prev + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + case "$prev" in + -@(config|tls-cert-file|tls-key-file|authenticated-emails-file|htpasswd-file|custom-templates-dir|logging-filename|jwt-key-file)) + _filedir + return 0 + ;; + -provider) + COMPREPLY=( $(compgen -W "google azure facebook github keycloak gitlab linkedin login.gov" -- ${cur}) ) + return 0 + ;; + -@(http-address|https-address|redirect-url|upstream|basic-auth-password|skip-auth-regex|flush-interval|extra-jwt-issuers|email-domain|whitelist-domain|keycloak-group|azure-tenant|bitbucket-team|bitbucket-repository|github-org|github-team|gitlab-group|google-group|google-admin-email|google-service-account-json|client-id|client_secret|banner|footer|proxy-prefix|ping-path|cookie-name|cookie-secret|cookie-domain|cookie-path|cookie-expire|cookie-refresh|redist-sentinel-master-name|redist-sentinel-connection-urls|logging-max-size|logging-max-age|logging-max-backups|standard-logging-format|request-logging-format|exclude-logging-paths|auth-logging-format|oidc-issuer-url|oidc-jwks-url|login-url|redeem-url|profile-url|resource|validate-url|scope|approval-prompt|signature-key|acr-values|jwt-key|pubjwk-url)) + return 0 + ;; + esac + COMPREPLY=( $(compgen -W "${_oauth2_proxy_commands}" -- ${cur}) ) + return 0; +} +complete -F _oauth2_proxy oauth2_proxy From fef940da9a9034ff296d999c3e377a33c20359fa Mon Sep 17 00:00:00 2001 From: Konstantine Date: Fri, 8 Nov 2019 00:38:36 +0200 Subject: [PATCH 10/16] Added userinfo endpoint (#300) * Added userinfo endpoint * Added documentation for the userinfo endpoint * Update oauthproxy.go Co-Authored-By: Dan Bond * Suggested fixes : Streaming json to rw , header set after error check * Update oauthproxy.go Co-Authored-By: Dan Bond * fix session.Email * Ported tests and updated changelog --- CHANGELOG.md | 1 + docs/5_endpoints.md | 1 + oauthproxy.go | 21 +++++++++++++++++++++ oauthproxy_test.go | 26 ++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d72f4565..556beca4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - [#286](https://github.com/pusher/oauth2_proxy/pull/286) Requests.go updated with useful error messages (@biotom) - [#302](https://github.com/pusher/oauth2_proxy/pull/302) Rewrite dist script (@syscll) - [#304](https://github.com/pusher/oauth2_proxy/pull/304) Add new Logo! :tada: (@JoelSpeed) +- [#300](https://github.com/pusher/oauth2_proxy/pull/300) Added userinfo endpoint (@kbabuadze) # v4.0.0 diff --git a/docs/5_endpoints.md b/docs/5_endpoints.md index 6733cb14..75b8f16f 100644 --- a/docs/5_endpoints.md +++ b/docs/5_endpoints.md @@ -14,4 +14,5 @@ OAuth2 Proxy responds directly to the following endpoints. All other endpoints w - /oauth2/sign_in - the login page, which also doubles as a sign out page (it clears cookies) - /oauth2/start - a URL that will redirect to start the OAuth cycle - /oauth2/callback - the URL used at the end of the OAuth cycle. The oauth app will be configured with this as the callback url. +- /oauth2/userinfo - the URL is used to return user's email from the session in JSON format. - /oauth2/auth - only returns a 202 Accepted response or a 401 Unauthorized response; for use with the [Nginx `auth_request` directive](#nginx-auth-request) diff --git a/oauthproxy.go b/oauthproxy.go index 01c18c39..3c665db7 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" b64 "encoding/base64" + "encoding/json" "errors" "fmt" "html/template" @@ -75,6 +76,7 @@ type OAuthProxy struct { OAuthStartPath string OAuthCallbackPath string AuthOnlyPath string + UserInfoPath string redirectURL *url.URL // the url to receive requests at whitelistDomains []string @@ -266,6 +268,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { OAuthStartPath: fmt.Sprintf("%s/start", opts.ProxyPrefix), OAuthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix), AuthOnlyPath: fmt.Sprintf("%s/auth", opts.ProxyPrefix), + UserInfoPath: fmt.Sprintf("%s/userinfo", opts.ProxyPrefix), ProxyPrefix: opts.ProxyPrefix, provider: opts.provider, @@ -557,6 +560,8 @@ func (p *OAuthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { p.OAuthCallback(rw, req) case path == p.AuthOnlyPath: p.AuthenticateOnly(rw, req) + case path == p.UserInfoPath: + p.UserInfo(rw, req) default: p.Proxy(rw, req) } @@ -585,6 +590,22 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) { } } +//UserInfo endpoint outputs session email in JSON format +func (p *OAuthProxy) UserInfo(rw http.ResponseWriter, req *http.Request) { + + session, err := p.getAuthenticatedSession(rw, req) + if err != nil { + http.Error(rw, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + return + } + userInfo := struct { + Email string `json:"email"` + }{session.Email} + rw.Header().Set("Content-Type", "application/json") + rw.WriteHeader(http.StatusOK) + json.NewEncoder(rw).Encode(userInfo) +} + // SignOut sends a response to clear the authentication cookie func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) { p.ClearSessionCookie(rw, req) diff --git a/oauthproxy_test.go b/oauthproxy_test.go index 8dd3adfb..ce56e8a3 100644 --- a/oauthproxy_test.go +++ b/oauthproxy_test.go @@ -746,6 +746,32 @@ func TestProcessCookieFailIfRefreshSetAndCookieExpired(t *testing.T) { } } +func NewUserInfoEndpointTest() *ProcessCookieTest { + pcTest := NewProcessCookieTestWithDefaults() + pcTest.req, _ = http.NewRequest("GET", + pcTest.opts.ProxyPrefix+"/userinfo", nil) + return pcTest +} + +func TestUserInfoEndpointAccepted(t *testing.T) { + test := NewUserInfoEndpointTest() + startSession := &sessions.SessionState{ + Email: "john.doe@example.com", AccessToken: "my_access_token"} + test.SaveSession(startSession) + + test.proxy.ServeHTTP(test.rw, test.req) + assert.Equal(t, http.StatusOK, test.rw.Code) + bodyBytes, _ := ioutil.ReadAll(test.rw.Body) + assert.Equal(t, "{\"email\":\"john.doe@example.com\"}\n", string(bodyBytes)) +} + +func TestUserInfoEndpointUnauthorizedOnNoCookieSetError(t *testing.T) { + test := NewUserInfoEndpointTest() + + test.proxy.ServeHTTP(test.rw, test.req) + assert.Equal(t, http.StatusUnauthorized, test.rw.Code) +} + func NewAuthOnlyEndpointTest(modifiers ...OptionsModifier) *ProcessCookieTest { pcTest := NewProcessCookieTestWithOptionsModifiers(modifiers...) pcTest.req, _ = http.NewRequest("GET", From 3f7ed36e4643c4ca78121c8292d1fdbfac040825 Mon Sep 17 00:00:00 2001 From: Lukasz Leszczuk Date: Thu, 7 Nov 2019 11:04:40 +0100 Subject: [PATCH 11/16] Add support for Redis with custom CA. --- main.go | 2 ++ pkg/apis/options/sessions.go | 2 ++ pkg/sessions/redis/redis_store.go | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/main.go b/main.go index e84a796e..6943f508 100644 --- a/main.go +++ b/main.go @@ -91,6 +91,8 @@ func main() { flagSet.String("redis-connection-url", "", "URL of redis server for redis session storage (eg: redis://HOST[:PORT])") flagSet.Bool("redis-use-sentinel", false, "Connect to redis via sentinels. Must set --redis-sentinel-master-name and --redis-sentinel-connection-urls to use this feature") flagSet.String("redis-sentinel-master-name", "", "Redis sentinel master name. Used in conjunction with --redis-use-sentinel") + flagSet.String("redis-ca-path", "", "Redis custom CA path") + flagSet.Bool("redis-insecure-tls", false, "Use insecure TLS connection to redis") flagSet.Var(&redisSentinelConnectionURLs, "redis-sentinel-connection-urls", "List of Redis sentinel connection URLs (eg redis://HOST[:PORT]). Used in conjunction with --redis-use-sentinel") flagSet.String("logging-filename", "", "File to log requests to, empty for stdout") diff --git a/pkg/apis/options/sessions.go b/pkg/apis/options/sessions.go index c96d490c..d4bb585f 100644 --- a/pkg/apis/options/sessions.go +++ b/pkg/apis/options/sessions.go @@ -27,4 +27,6 @@ type RedisStoreOptions struct { UseSentinel bool `flag:"redis-use-sentinel" cfg:"redis_use_sentinel" env:"OAUTH2_PROXY_REDIS_USE_SENTINEL"` SentinelMasterName string `flag:"redis-sentinel-master-name" cfg:"redis_sentinel_master_name" env:"OAUTH2_PROXY_REDIS_SENTINEL_MASTER_NAME"` SentinelConnectionURLs []string `flag:"redis-sentinel-connection-urls" cfg:"redis_sentinel_connection_urls" env:"OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS"` + RedisCAPath string `flag:"redis-ca-path" cfg:"redis_ca_path" env:"OAUTH2_PROXY_REDIS_CA_PATH"` + RedisInsecureTLS bool `flag:"redis-insecure-tls" cfg:"redis_insecure_tls" env:"OAUTH2_PROXY_REDIS_INSECURE_TLS"` } diff --git a/pkg/sessions/redis/redis_store.go b/pkg/sessions/redis/redis_store.go index ed33d72d..0efa47d0 100644 --- a/pkg/sessions/redis/redis_store.go +++ b/pkg/sessions/redis/redis_store.go @@ -4,10 +4,13 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" + "crypto/x509" "encoding/base64" "encoding/hex" "fmt" + "github.com/pusher/oauth2_proxy/pkg/logger" "io" + "io/ioutil" "net/http" "strings" "time" @@ -64,6 +67,28 @@ func newRedisClient(opts options.RedisStoreOptions) (*redis.Client, error) { return nil, fmt.Errorf("unable to parse redis url: %s", err) } + if opts.RedisInsecureTLS != false { + opt.TLSConfig.InsecureSkipVerify = true + } + + if opts.RedisCAPath != "" { + rootCAs, _ := x509.SystemCertPool() + if rootCAs == nil { + rootCAs = x509.NewCertPool() + } + certs, err := ioutil.ReadFile(opts.RedisCAPath) + if err != nil { + return nil, fmt.Errorf("failed to load %q, %v", opts.RedisCAPath, err) + } + + // Append our cert to the system pool + if ok := rootCAs.AppendCertsFromPEM(certs); !ok { + logger.Printf("no certs appended, using system certs only") + } + + opt.TLSConfig.RootCAs = rootCAs + } + client := redis.NewClient(opt) return client, nil } From 3c10aee62c8fde64cf19a747e6495fe57b1b8744 Mon Sep 17 00:00:00 2001 From: Lukasz Leszczuk Date: Sat, 9 Nov 2019 13:57:40 +0100 Subject: [PATCH 12/16] Code formatting. Add missing CHANGELOG entry. --- CHANGELOG.md | 2 +- pkg/sessions/redis/redis_store.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 556beca4..7b4dc975 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ - [#302](https://github.com/pusher/oauth2_proxy/pull/302) Rewrite dist script (@syscll) - [#304](https://github.com/pusher/oauth2_proxy/pull/304) Add new Logo! :tada: (@JoelSpeed) - [#300](https://github.com/pusher/oauth2_proxy/pull/300) Added userinfo endpoint (@kbabuadze) - +- [#309](https://github.com/pusher/oauth2_proxy/pull/309) Added support for custom CA when connecting to Redis cache # v4.0.0 - [#248](https://github.com/pusher/oauth2_proxy/pull/248) Fix issue with X-Auth-Request-Redirect header being ignored diff --git a/pkg/sessions/redis/redis_store.go b/pkg/sessions/redis/redis_store.go index 0efa47d0..a0f331b7 100644 --- a/pkg/sessions/redis/redis_store.go +++ b/pkg/sessions/redis/redis_store.go @@ -8,7 +8,6 @@ import ( "encoding/base64" "encoding/hex" "fmt" - "github.com/pusher/oauth2_proxy/pkg/logger" "io" "io/ioutil" "net/http" @@ -20,6 +19,7 @@ import ( "github.com/pusher/oauth2_proxy/pkg/apis/sessions" "github.com/pusher/oauth2_proxy/pkg/cookies" "github.com/pusher/oauth2_proxy/pkg/encryption" + "github.com/pusher/oauth2_proxy/pkg/logger" ) // TicketData is a structure representing the ticket used in server session storage From d7a51e4aabf649f2f96df0a1cf8a56743bd02123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Leszczuk?= Date: Tue, 12 Nov 2019 11:34:14 +0100 Subject: [PATCH 13/16] Update main.go Co-Authored-By: Joel Speed --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 6943f508..7cf562bd 100644 --- a/main.go +++ b/main.go @@ -92,7 +92,7 @@ func main() { flagSet.Bool("redis-use-sentinel", false, "Connect to redis via sentinels. Must set --redis-sentinel-master-name and --redis-sentinel-connection-urls to use this feature") flagSet.String("redis-sentinel-master-name", "", "Redis sentinel master name. Used in conjunction with --redis-use-sentinel") flagSet.String("redis-ca-path", "", "Redis custom CA path") - flagSet.Bool("redis-insecure-tls", false, "Use insecure TLS connection to redis") + flagSet.Bool("redis-insecure-skip-tls-verify", false, "Use insecure TLS connection to redis") flagSet.Var(&redisSentinelConnectionURLs, "redis-sentinel-connection-urls", "List of Redis sentinel connection URLs (eg redis://HOST[:PORT]). Used in conjunction with --redis-use-sentinel") flagSet.String("logging-filename", "", "File to log requests to, empty for stdout") From befab0521ad53e9a7211065cd6f382d635701144 Mon Sep 17 00:00:00 2001 From: Lukasz Leszczuk Date: Tue, 12 Nov 2019 11:42:03 +0100 Subject: [PATCH 14/16] log message in case of failure during loading system cert pool --- pkg/sessions/redis/redis_store.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/sessions/redis/redis_store.go b/pkg/sessions/redis/redis_store.go index a0f331b7..fdeebf6b 100644 --- a/pkg/sessions/redis/redis_store.go +++ b/pkg/sessions/redis/redis_store.go @@ -72,7 +72,10 @@ func newRedisClient(opts options.RedisStoreOptions) (*redis.Client, error) { } if opts.RedisCAPath != "" { - rootCAs, _ := x509.SystemCertPool() + rootCAs, err := x509.SystemCertPool() + if err != nil { + logger.Printf("failed to load system cert pool for redis connection, falling back to empty cert pool") + } if rootCAs == nil { rootCAs = x509.NewCertPool() } From 06a283e581039f20a1be5ce7663a9281682899bb Mon Sep 17 00:00:00 2001 From: Lukasz Leszczuk Date: Tue, 12 Nov 2019 16:11:27 +0100 Subject: [PATCH 15/16] Fix settings naming --- pkg/apis/options/sessions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/apis/options/sessions.go b/pkg/apis/options/sessions.go index d4bb585f..dbbb1cba 100644 --- a/pkg/apis/options/sessions.go +++ b/pkg/apis/options/sessions.go @@ -28,5 +28,5 @@ type RedisStoreOptions struct { SentinelMasterName string `flag:"redis-sentinel-master-name" cfg:"redis_sentinel_master_name" env:"OAUTH2_PROXY_REDIS_SENTINEL_MASTER_NAME"` SentinelConnectionURLs []string `flag:"redis-sentinel-connection-urls" cfg:"redis_sentinel_connection_urls" env:"OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS"` RedisCAPath string `flag:"redis-ca-path" cfg:"redis_ca_path" env:"OAUTH2_PROXY_REDIS_CA_PATH"` - RedisInsecureTLS bool `flag:"redis-insecure-tls" cfg:"redis_insecure_tls" env:"OAUTH2_PROXY_REDIS_INSECURE_TLS"` + RedisInsecureTLS bool `flag:"redis-insecure-skip-tls-verify" cfg:"redis_insecure_skip_tls_verify" env:"OAUTH2_PROXY_REDIS_INSECURE_SKIP_TLS_VERIFY"` } From 5c9a0f8308d2e06f9bbb2444213595aef290ae74 Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Fri, 15 Nov 2019 12:02:09 +0000 Subject: [PATCH 16/16] Fixup Changelog entries (#312) --- CHANGELOG.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f78b24f7..1c0b1f04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,19 +6,18 @@ - [#259](https://github.com/pusher/oauth2_proxy/pull/259) Redirect to HTTPS (@jmickey) - [#273](https://github.com/pusher/oauth2_proxy/pull/273) Support Go 1.13 (@dio) - [#275](https://github.com/pusher/oauth2_proxy/pull/275) docker: build from debian buster (@syscll) -- [#258](https://github.com/pusher/oauth2_proxy/pull/258) Add IDToken for Azure provider +- [#258](https://github.com/pusher/oauth2_proxy/pull/258) Add IDToken for Azure provider (@leyshon) - This PR adds the IDToken into the session for the Azure provider allowing requests to a backend to be identified as a specific user. As a consequence, if you are using a cookie to store the session the cookie will now exceed the 4kb size limit and be split into multiple cookies. This can cause problems when using nginx as a proxy, resulting in no cookie being passed at all. Either increase the proxy_buffer_size in nginx or implement the redis session storage (see https://pusher.github.io/oauth2_proxy/configuration#redis-storage) - [#286](https://github.com/pusher/oauth2_proxy/pull/286) Requests.go updated with useful error messages (@biotom) - [#274](https://github.com/pusher/oauth2_proxy/pull/274) Supports many github teams with api pagination support (@toshi-miura, @apratina) - [#302](https://github.com/pusher/oauth2_proxy/pull/302) Rewrite dist script (@syscll) - [#304](https://github.com/pusher/oauth2_proxy/pull/304) Add new Logo! :tada: (@JoelSpeed) - [#300](https://github.com/pusher/oauth2_proxy/pull/300) Added userinfo endpoint (@kbabuadze) -- [#309](https://github.com/pusher/oauth2_proxy/pull/309) Added support for custom CA when connecting to Redis cache +- [#309](https://github.com/pusher/oauth2_proxy/pull/309) Added support for custom CA when connecting to Redis cache (@lleszczu) +- [#248](https://github.com/pusher/oauth2_proxy/pull/248) Fix issue with X-Auth-Request-Redirect header being ignored (@webnard) # v4.0.0 -- [#248](https://github.com/pusher/oauth2_proxy/pull/248) Fix issue with X-Auth-Request-Redirect header being ignored - ## Release Highlights - Documentation is now on a [microsite](https://pusher.github.io/oauth2_proxy/) - Health check logging can now be disabled for quieter logs