From 1295f87b33448bafdd67acfef625424d11304a52 Mon Sep 17 00:00:00 2001 From: Christian Groschupp Date: Wed, 18 Sep 2019 22:40:33 +0200 Subject: [PATCH 01/17] Add static upstream --- docs/configuration/configuration.md | 2 +- main.go | 2 +- oauthproxy.go | 11 +++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index c076dc88..ffe1be42 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -105,7 +105,7 @@ An example [oauth2_proxy.cfg]({{ site.gitweb }}/contrib/oauth2_proxy.cfg.example | `-standard-logging-format` | string | Template for standard log lines | see [Logging Configuration](#logging-configuration) | | `-tls-cert-file` | string | path to certificate file | | | `-tls-key-file` | string | path to private key file | | -| `-upstream` | string \| list | the http url(s) of the upstream endpoint or `file://` paths for static files. Routing is based on the path | | +| `-upstream` | string \| list | the http url(s) of the upstream endpoint, file:// paths for static files or `static://` for static response. Routing is based on the path | | | `-validate-url` | string | Access token validation endpoint | | | `-version` | n/a | print version string | | | `-whitelist-domain` | string \| list | allowed domains for redirection after authentication. Prefix domain with a `.` to allow subdomains (eg `.example.com`) | | diff --git a/main.go b/main.go index a4bf378e..d30d6bda 100644 --- a/main.go +++ b/main.go @@ -36,7 +36,7 @@ func main() { flagSet.String("tls-key-file", "", "path to private key file") flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"") flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)") - flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint or file:// paths for static files. Routing is based on the path") + flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint, file:// paths for static files or static:// for static response. Routing is based on the path") flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream") flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream") flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header") diff --git a/oauthproxy.go b/oauthproxy.go index 01c18c39..429775d1 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -12,6 +12,7 @@ import ( "net/http/httputil" "net/url" "regexp" + "strconv" "strings" "time" @@ -207,6 +208,16 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { proxy := NewWebSocketOrRestReverseProxy(u, opts, auth) serveMux.Handle(path, proxy) + case "static": + serveMux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) { + responseCode, err := strconv.Atoi(u.Host) + if err != nil { + logger.Printf("unable to convert %q to int, use default \"200\"", u.Host) + responseCode = 200 + } + rw.WriteHeader(responseCode) + fmt.Fprintf(rw, "Authenticated") + }) case "file": if u.Fragment != "" { path = u.Fragment From dc36836800b0749f78e6ec5854e08926ef8a6830 Mon Sep 17 00:00:00 2001 From: Christian Groschupp Date: Thu, 19 Sep 2019 11:03:38 +0200 Subject: [PATCH 02/17] Add tests for static upstream --- oauthproxy.go | 8 +++---- oauthproxy_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/oauthproxy.go b/oauthproxy.go index 429775d1..66fad491 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -202,17 +202,17 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { } for _, u := range opts.proxyURLs { path := u.Path + host := u.Host switch u.Scheme { case httpScheme, httpsScheme: logger.Printf("mapping path %q => upstream %q", path, u) proxy := NewWebSocketOrRestReverseProxy(u, opts, auth) serveMux.Handle(path, proxy) - case "static": - serveMux.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) { - responseCode, err := strconv.Atoi(u.Host) + serveMux.HandleFunc(path, func(rw http.ResponseWriter, req *http.Request) { + responseCode, err := strconv.Atoi(host) if err != nil { - logger.Printf("unable to convert %q to int, use default \"200\"", u.Host) + logger.Printf("unable to convert %q to int, use default \"200\"", host) responseCode = 200 } rw.WriteHeader(responseCode) diff --git a/oauthproxy_test.go b/oauthproxy_test.go index 8dd3adfb..563e6cef 100644 --- a/oauthproxy_test.go +++ b/oauthproxy_test.go @@ -365,6 +365,7 @@ type PassAccessTokenTest struct { type PassAccessTokenTestOptions struct { PassAccessToken bool + ProxyUpstream string } func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) *PassAccessTokenTest { @@ -372,7 +373,6 @@ func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) *PassAccessTokenTes t.providerServer = httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - logger.Printf("%#v", r) var payload string switch r.URL.Path { case "/oauth/token": @@ -389,6 +389,9 @@ func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) *PassAccessTokenTes t.opts = NewOptions() t.opts.Upstreams = append(t.opts.Upstreams, t.providerServer.URL) + if opts.ProxyUpstream != "" { + t.opts.Upstreams = append(t.opts.Upstreams, opts.ProxyUpstream) + } // The CookieSecret must be 32 bytes in order to create the AES // cipher. t.opts.CookieSecret = "xyzzyplughxyzzyplughxyzzyplughxp" @@ -459,6 +462,39 @@ func (patTest *PassAccessTokenTest) getRootEndpoint(cookie string) (httpCode int return rw.Code, rw.Body.String() } +func (patTest *PassAccessTokenTest) getProxyEndpoint(cookie string) (httpCode int, accessToken string) { + cookieName := patTest.proxy.CookieName + var value string + keyPrefix := cookieName + "=" + + for _, field := range strings.Split(cookie, "; ") { + value = strings.TrimPrefix(field, keyPrefix) + if value != field { + break + } else { + value = "" + } + } + if value == "" { + return 0, "" + } + + req, err := http.NewRequest("GET", "/static-proxy", strings.NewReader("")) + if err != nil { + return 0, "" + } + req.AddCookie(&http.Cookie{ + Name: cookieName, + Value: value, + Path: "/", + Expires: time.Now().Add(time.Duration(24)), + HttpOnly: true, + }) + rw := httptest.NewRecorder() + patTest.proxy.ServeHTTP(rw, req) + return rw.Code, rw.Body.String() +} + func TestForwardAccessTokenUpstream(t *testing.T) { patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{ PassAccessToken: true, @@ -482,6 +518,28 @@ func TestForwardAccessTokenUpstream(t *testing.T) { assert.Equal(t, "my_auth_token", payload) } +func TestStaticProxyUpstream(t *testing.T) { + patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{ + PassAccessToken: true, + ProxyUpstream: "static://200/static-proxy", + }) + + defer patTest.Close() + + // A successful validation will redirect and set the auth cookie. + code, cookie := patTest.getCallbackEndpoint() + if code != 302 { + t.Fatalf("expected 302; got %d", code) + } + assert.NotEqual(t, nil, cookie) + + code, payload := patTest.getProxyEndpoint(cookie) + if code != 200 { + t.Fatalf("expected 200; got %d", code) + } + assert.Equal(t, "Authenticated", payload) +} + func TestDoNotForwardAccessTokenUpstream(t *testing.T) { patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{ PassAccessToken: false, From a46ee952a65e93358fe10731a8ffc89c627dd83d Mon Sep 17 00:00:00 2001 From: Christian Groschupp Date: Fri, 4 Oct 2019 15:07:31 +0200 Subject: [PATCH 03/17] Move responceCode out of HandleFunc. --- oauthproxy.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/oauthproxy.go b/oauthproxy.go index 66fad491..9a45866a 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -209,12 +209,13 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { proxy := NewWebSocketOrRestReverseProxy(u, opts, auth) serveMux.Handle(path, proxy) case "static": + responseCode, err := strconv.Atoi(host) + if err != nil { + logger.Printf("unable to convert %q to int, use default \"200\"", host) + responseCode = 200 + } + serveMux.HandleFunc(path, func(rw http.ResponseWriter, req *http.Request) { - responseCode, err := strconv.Atoi(host) - if err != nil { - logger.Printf("unable to convert %q to int, use default \"200\"", host) - responseCode = 200 - } rw.WriteHeader(responseCode) fmt.Fprintf(rw, "Authenticated") }) From 3d17159c5c641a19f798e8ff9fdfd203dbafcd4c Mon Sep 17 00:00:00 2001 From: Christian Groschupp Date: Fri, 4 Oct 2019 15:39:31 +0200 Subject: [PATCH 04/17] replace getRootEndpoint by getEndpointWithCookie --- oauthproxy_test.go | 47 +++++++++------------------------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/oauthproxy_test.go b/oauthproxy_test.go index 563e6cef..f64c6b18 100644 --- a/oauthproxy_test.go +++ b/oauthproxy_test.go @@ -428,7 +428,9 @@ func (patTest *PassAccessTokenTest) getCallbackEndpoint() (httpCode int, return rw.Code, rw.HeaderMap["Set-Cookie"][1] } -func (patTest *PassAccessTokenTest) getRootEndpoint(cookie string) (httpCode int, accessToken string) { +// getEndpointWithCookie makes a requests againt the oauthproxy with passed requestPath +// and cookie and returns body and status code. +func (patTest *PassAccessTokenTest) getEndpointWithCookie(cookie string, endpoint string) (httpCode int, accessToken string) { cookieName := patTest.proxy.CookieName var value string keyPrefix := cookieName + "=" @@ -445,7 +447,7 @@ func (patTest *PassAccessTokenTest) getRootEndpoint(cookie string) (httpCode int return 0, "" } - req, err := http.NewRequest("GET", "/", strings.NewReader("")) + req, err := http.NewRequest("GET", endpoint, strings.NewReader("")) if err != nil { return 0, "" } @@ -462,39 +464,6 @@ func (patTest *PassAccessTokenTest) getRootEndpoint(cookie string) (httpCode int return rw.Code, rw.Body.String() } -func (patTest *PassAccessTokenTest) getProxyEndpoint(cookie string) (httpCode int, accessToken string) { - cookieName := patTest.proxy.CookieName - var value string - keyPrefix := cookieName + "=" - - for _, field := range strings.Split(cookie, "; ") { - value = strings.TrimPrefix(field, keyPrefix) - if value != field { - break - } else { - value = "" - } - } - if value == "" { - return 0, "" - } - - req, err := http.NewRequest("GET", "/static-proxy", strings.NewReader("")) - if err != nil { - return 0, "" - } - req.AddCookie(&http.Cookie{ - Name: cookieName, - Value: value, - Path: "/", - Expires: time.Now().Add(time.Duration(24)), - HttpOnly: true, - }) - rw := httptest.NewRecorder() - patTest.proxy.ServeHTTP(rw, req) - return rw.Code, rw.Body.String() -} - func TestForwardAccessTokenUpstream(t *testing.T) { patTest := NewPassAccessTokenTest(PassAccessTokenTestOptions{ PassAccessToken: true, @@ -511,7 +480,7 @@ func TestForwardAccessTokenUpstream(t *testing.T) { // Now we make a regular request; the access_token from the cookie is // forwarded as the "X-Forwarded-Access-Token" header. The token is // read by the test provider server and written in the response body. - code, payload := patTest.getRootEndpoint(cookie) + code, payload := patTest.getEndpointWithCookie(cookie, "/") if code != 200 { t.Fatalf("expected 200; got %d", code) } @@ -533,7 +502,9 @@ func TestStaticProxyUpstream(t *testing.T) { } assert.NotEqual(t, nil, cookie) - code, payload := patTest.getProxyEndpoint(cookie) + // Now we make a regular request againts the upstream proxy; And validate + // the returned status code through the static proxy. + code, payload := patTest.getEndpointWithCookie(cookie, "/static-proxy") if code != 200 { t.Fatalf("expected 200; got %d", code) } @@ -555,7 +526,7 @@ func TestDoNotForwardAccessTokenUpstream(t *testing.T) { // Now we make a regular request, but the access token header should // not be present. - code, payload := patTest.getRootEndpoint(cookie) + code, payload := patTest.getEndpointWithCookie(cookie, "/") if code != 200 { t.Fatalf("expected 200; got %d", code) } From f570fb9f58e48e383ff52e1637026183f9674e10 Mon Sep 17 00:00:00 2001 From: Christian Groschupp Date: Thu, 10 Oct 2019 10:15:04 +0200 Subject: [PATCH 05/17] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d76e8958..7687dd3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +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) +- [#265](https://github.com/pusher/oauth2_proxy/pull/265) Add upstream with static response (@cgroschupp) # v4.0.0 From 5c9a0f8308d2e06f9bbb2444213595aef290ae74 Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Fri, 15 Nov 2019 12:02:09 +0000 Subject: [PATCH 06/17] 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 From ca0b8375da57b84e33b3869ae0c0024c35d17177 Mon Sep 17 00:00:00 2001 From: Moraru Costel Date: Tue, 19 Nov 2019 18:17:26 +0100 Subject: [PATCH 07/17] Add redirect capability to sign_out (#314) * addint redirect capability to sign_out * updating changelog --- CHANGELOG.md | 1 + oauthproxy.go | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc67d5fd..a81ed108 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - [#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 (@lleszczu) - [#248](https://github.com/pusher/oauth2_proxy/pull/248) Fix issue with X-Auth-Request-Redirect header being ignored (@webnard) +- [#314](https://github.com/pusher/oauth2_proxy/pull/314) Add redirect capability to sign_out (@costelmoraru) - [#265](https://github.com/pusher/oauth2_proxy/pull/265) Add upstream with static response (@cgroschupp) # v4.0.0 diff --git a/oauthproxy.go b/oauthproxy.go index d206aa64..61a94402 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -620,8 +620,14 @@ func (p *OAuthProxy) UserInfo(rw http.ResponseWriter, req *http.Request) { // SignOut sends a response to clear the authentication cookie func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request) { + redirect, err := p.GetRedirect(req) + if err != nil { + logger.Printf("Error obtaining redirect: %s", err.Error()) + p.ErrorPage(rw, 500, "Internal Error", err.Error()) + return + } p.ClearSessionCookie(rw, req) - http.Redirect(rw, req, "/", 302) + http.Redirect(rw, req, redirect, 302) } // OAuthStart starts the OAuth2 authentication flow From 11205c739992f2a4f5a00a31300ed15513568d5d Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 25 Nov 2019 18:20:37 +0100 Subject: [PATCH 08/17] Allow to change provider's name (#296) * Allow to change provider's name. * Add changelog entry. * Linting. * provider-name -> provider-display-name. * Add flag in main.go. * Update CHANGELOG.md --- CHANGELOG.md | 1 + docs/2_auth.md | 1 + docs/configuration/configuration.md | 1 + main.go | 1 + oauthproxy.go | 99 +++++++++++++++-------------- options.go | 1 + 6 files changed, 57 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a81ed108..80c628cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - [#248](https://github.com/pusher/oauth2_proxy/pull/248) Fix issue with X-Auth-Request-Redirect header being ignored (@webnard) - [#314](https://github.com/pusher/oauth2_proxy/pull/314) Add redirect capability to sign_out (@costelmoraru) - [#265](https://github.com/pusher/oauth2_proxy/pull/265) Add upstream with static response (@cgroschupp) +- [#296](https://github.com/pusher/oauth2_proxy/pull/296) Allow to override provider's name for sign-in page (@ffdybuster) # v4.0.0 diff --git a/docs/2_auth.md b/docs/2_auth.md index 991bbae2..5a7e556e 100644 --- a/docs/2_auth.md +++ b/docs/2_auth.md @@ -156,6 +156,7 @@ OpenID Connect is a spec for OAUTH 2.0 + identity that is implemented by many ma 3. Login with the fixture use in the dex guide and run the oauth2_proxy with the following args: -provider oidc + -provider-display-name "My OIDC Provider" -client-id oauth2_proxy -client-secret proxy -redirect-url http://127.0.0.1:4180/oauth2/callback diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index 158ad3bd..8ff64c18 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -76,6 +76,7 @@ An example [oauth2_proxy.cfg]({{ site.gitweb }}/contrib/oauth2_proxy.cfg.example | `-pass-user-headers` | bool | pass X-Forwarded-User and X-Forwarded-Email information to upstream | true | | `-profile-url` | string | Profile access endpoint | | | `-provider` | string | OAuth provider | google | +| `-provider-display-name` | string | Override the provider's name with the given string; used for the sign-in page | (depends on provider) | | `-ping-path` | string | the ping endpoint that can be used for basic health checks | `"/ping"` | | `-proxy-prefix` | string | the url root path that this proxy should be nested under (e.g. /`/sign_in`) | `"/oauth2"` | | `-proxy-websockets` | bool | enables WebSocket proxying | true | diff --git a/main.go b/main.go index 11a28bd8..16bafbc0 100644 --- a/main.go +++ b/main.go @@ -114,6 +114,7 @@ func main() { flagSet.String("auth-logging-format", logger.DefaultAuthLoggingFormat, "Template for authentication log lines") flagSet.String("provider", "google", "OAuth provider") + flagSet.String("provider-display-name", "", "Provider display name") flagSet.String("oidc-issuer-url", "", "OpenID Connect issuer URL (ie: https://accounts.google.com)") flagSet.Bool("insecure-oidc-allow-unverified-email", false, "Don't fail if an email address in an id_token is not verified") flagSet.Bool("skip-oidc-discovery", false, "Skip OIDC discovery and use manually supplied Endpoints") diff --git a/oauthproxy.go b/oauthproxy.go index 61a94402..72ab580b 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -79,31 +79,32 @@ type OAuthProxy struct { AuthOnlyPath string UserInfoPath string - redirectURL *url.URL // the url to receive requests at - whitelistDomains []string - provider providers.Provider - sessionStore sessionsapi.SessionStore - ProxyPrefix string - SignInMessage string - HtpasswdFile *HtpasswdFile - DisplayHtpasswdForm bool - serveMux http.Handler - SetXAuthRequest bool - PassBasicAuth bool - SkipProviderButton bool - PassUserHeaders bool - BasicAuthPassword string - PassAccessToken bool - SetAuthorization bool - PassAuthorization bool - skipAuthRegex []string - skipAuthPreflight bool - skipJwtBearerTokens bool - jwtBearerVerifiers []*oidc.IDTokenVerifier - compiledRegex []*regexp.Regexp - templates *template.Template - Banner string - Footer string + redirectURL *url.URL // the url to receive requests at + whitelistDomains []string + provider providers.Provider + providerNameOverride string + sessionStore sessionsapi.SessionStore + ProxyPrefix string + SignInMessage string + HtpasswdFile *HtpasswdFile + DisplayHtpasswdForm bool + serveMux http.Handler + SetXAuthRequest bool + PassBasicAuth bool + SkipProviderButton bool + PassUserHeaders bool + BasicAuthPassword string + PassAccessToken bool + SetAuthorization bool + PassAuthorization bool + skipAuthRegex []string + skipAuthPreflight bool + skipJwtBearerTokens bool + jwtBearerVerifiers []*oidc.IDTokenVerifier + compiledRegex []*regexp.Regexp + templates *template.Template + Banner string + Footer string } // UpstreamProxy represents an upstream server to proxy to @@ -282,28 +283,29 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { AuthOnlyPath: fmt.Sprintf("%s/auth", opts.ProxyPrefix), UserInfoPath: fmt.Sprintf("%s/userinfo", opts.ProxyPrefix), - ProxyPrefix: opts.ProxyPrefix, - provider: opts.provider, - sessionStore: opts.sessionStore, - serveMux: serveMux, - redirectURL: redirectURL, - whitelistDomains: opts.WhitelistDomains, - skipAuthRegex: opts.SkipAuthRegex, - skipAuthPreflight: opts.SkipAuthPreflight, - skipJwtBearerTokens: opts.SkipJwtBearerTokens, - jwtBearerVerifiers: opts.jwtBearerVerifiers, - compiledRegex: opts.CompiledRegex, - SetXAuthRequest: opts.SetXAuthRequest, - PassBasicAuth: opts.PassBasicAuth, - PassUserHeaders: opts.PassUserHeaders, - BasicAuthPassword: opts.BasicAuthPassword, - PassAccessToken: opts.PassAccessToken, - SetAuthorization: opts.SetAuthorization, - PassAuthorization: opts.PassAuthorization, - SkipProviderButton: opts.SkipProviderButton, - templates: loadTemplates(opts.CustomTemplatesDir), - Banner: opts.Banner, - Footer: opts.Footer, + ProxyPrefix: opts.ProxyPrefix, + provider: opts.provider, + providerNameOverride: opts.ProviderName, + sessionStore: opts.sessionStore, + serveMux: serveMux, + redirectURL: redirectURL, + whitelistDomains: opts.WhitelistDomains, + skipAuthRegex: opts.SkipAuthRegex, + skipAuthPreflight: opts.SkipAuthPreflight, + skipJwtBearerTokens: opts.SkipJwtBearerTokens, + jwtBearerVerifiers: opts.jwtBearerVerifiers, + compiledRegex: opts.CompiledRegex, + SetXAuthRequest: opts.SetXAuthRequest, + PassBasicAuth: opts.PassBasicAuth, + PassUserHeaders: opts.PassUserHeaders, + BasicAuthPassword: opts.BasicAuthPassword, + PassAccessToken: opts.PassAccessToken, + SetAuthorization: opts.SetAuthorization, + PassAuthorization: opts.PassAuthorization, + SkipProviderButton: opts.SkipProviderButton, + templates: loadTemplates(opts.CustomTemplatesDir), + Banner: opts.Banner, + Footer: opts.Footer, } } @@ -465,6 +467,9 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code ProxyPrefix: p.ProxyPrefix, Footer: template.HTML(p.Footer), } + if p.providerNameOverride != "" { + t.ProviderName = p.providerNameOverride + } p.templates.ExecuteTemplate(rw, "sign_in.html", t) } diff --git a/options.go b/options.go index ddc10cfd..5bb829b0 100644 --- a/options.go +++ b/options.go @@ -87,6 +87,7 @@ type Options struct { // These options allow for other providers besides Google, with // potential overrides. Provider string `flag:"provider" cfg:"provider" env:"OAUTH2_PROXY_PROVIDER"` + ProviderName string `flag:"provider-display-name" cfg:"provider_display_name" env:"OAUTH2_PROXY_PROVIDER_DISPLAY_NAME"` OIDCIssuerURL string `flag:"oidc-issuer-url" cfg:"oidc_issuer_url" env:"OAUTH2_PROXY_OIDC_ISSUER_URL"` InsecureOIDCAllowUnverifiedEmail bool `flag:"insecure-oidc-allow-unverified-email" cfg:"insecure_oidc_allow_unverified_email" env:"OAUTH2_PROXY_INSECURE_OIDC_ALLOW_UNVERIFIED_EMAIL"` SkipOIDCDiscovery bool `flag:"skip-oidc-discovery" cfg:"skip_oidc_discovery" env:"OAUTH2_PROXY_SKIP_OIDC_DISCOVERY"` From 227ea5da44859c00cae1cee38541608e08da51f3 Mon Sep 17 00:00:00 2001 From: Casey Link Date: Wed, 5 Jun 2019 18:59:04 +0200 Subject: [PATCH 09/17] Add Nextcloud provider (#179) --- .github/CODEOWNERS | 4 ++ CHANGELOG.md | 1 + docs/2_auth.md | 27 +++++++ providers/nextcloud.go | 45 ++++++++++++ providers/nextcloud_test.go | 138 ++++++++++++++++++++++++++++++++++++ providers/providers.go | 2 + 6 files changed, 217 insertions(+) create mode 100644 providers/nextcloud.go create mode 100644 providers/nextcloud_test.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c7f2960e..71a79063 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,3 +14,7 @@ providers/logingov_test.go @timothy-spencer # Bitbucket provider providers/bitbucket.go @aledeganopix4d providers/bitbucket_test.go @aledeganopix4d + +# Nextcloud provider +providers/nextcloud.go @Ramblurr +providers/nextcloud_test.go @Ramblurr diff --git a/CHANGELOG.md b/CHANGELOG.md index 80c628cb..65803040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Changes since v4.0.0 - [#292](https://github.com/pusher/oauth2_proxy/pull/292) Added bash >= 4.0 dependency to configure script (@jmfrank63) - [#227](https://github.com/pusher/oauth2_proxy/pull/227) Add Keycloak provider (@Ofinka) +- [#179](https://github.com/pusher/oauth2_proxy/pull/179) Add Nextcloud provider (@Ramblurr) - [#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) diff --git a/docs/2_auth.md b/docs/2_auth.md index 5a7e556e..b3d96559 100644 --- a/docs/2_auth.md +++ b/docs/2_auth.md @@ -19,6 +19,7 @@ Valid providers are : - [GitLab](#gitlab-auth-provider) - [LinkedIn](#linkedin-auth-provider) - [login.gov](#logingov-provider) +- [Nextcloud](#nextcloud-provider) The provider can be selected using the `provider` configuration value. @@ -289,6 +290,32 @@ In this case, you can set the `-skip-oidc-discovery` option, and supply those re -email-domain example.com ``` +### Nextcloud Provider + +The Nextcloud provider allows you to authenticate against users in your +Nextcloud instance. + +When you are using the Nextcloud provider, you must specify the urls via +configuration, environment variable, or command line argument. Depending +on whether your Nextcloud instance is using pretty urls your urls may be of the +form `/index.php/apps/oauth2/*` or `/apps/oauth2/*`. + +Refer to the [OAuth2 +documentation](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/oauth2.html) +to setup the client id and client secret. Your "Redirection URI" will be +`https://internalapp.yourcompany.com/oauth2/callback`. + +``` + -provider nextcloud + -client-id + -client-secret + -login-url="/index.php/apps/oauth2/authorize" + -redeem-url="/index.php/apps/oauth2/api/v1/token" + -validate-url="/ocs/v2.php/cloud/user?format=json" +``` + +Note: in *all* cases the validate-url will *not* have the `index.php`. + ## Email Authentication To authorize by email domain use `--email-domain=yourcompany.com`. To authorize individual email addresses use `--authenticated-emails-file=/path/to/file` with one email per line. To authorize all email addresses use `--email-domain=*`. diff --git a/providers/nextcloud.go b/providers/nextcloud.go new file mode 100644 index 00000000..18855c8c --- /dev/null +++ b/providers/nextcloud.go @@ -0,0 +1,45 @@ +package providers + +import ( + "fmt" + "net/http" + + "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/pusher/oauth2_proxy/pkg/logger" + "github.com/pusher/oauth2_proxy/pkg/requests" +) + +// NextcloudProvider represents an Nextcloud based Identity Provider +type NextcloudProvider struct { + *ProviderData +} + +// NewNextcloudProvider initiates a new NextcloudProvider +func NewNextcloudProvider(p *ProviderData) *NextcloudProvider { + p.ProviderName = "Nextcloud" + return &NextcloudProvider{ProviderData: p} +} + +func getNextcloudHeader(accessToken string) http.Header { + header := make(http.Header) + header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken)) + return header +} + +// GetEmailAddress returns the Account email address +func (p *NextcloudProvider) GetEmailAddress(s *sessions.SessionState) (string, error) { + req, err := http.NewRequest("GET", + p.ValidateURL.String(), nil) + if err != nil { + logger.Printf("failed building request %s", err) + return "", err + } + req.Header = getNextcloudHeader(s.AccessToken) + json, err := requests.Request(req) + if err != nil { + logger.Printf("failed making request %s", err) + return "", err + } + email, err := json.Get("ocs").Get("data").Get("email").String() + return email, err +} diff --git a/providers/nextcloud_test.go b/providers/nextcloud_test.go new file mode 100644 index 00000000..350e5840 --- /dev/null +++ b/providers/nextcloud_test.go @@ -0,0 +1,138 @@ +package providers + +import ( + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "github.com/pusher/oauth2_proxy/pkg/apis/sessions" + "github.com/stretchr/testify/assert" +) + +const formatJSON = "format=json" +const userPath = "/ocs/v2.php/cloud/user" + +func testNextcloudProvider(hostname string) *NextcloudProvider { + p := NewNextcloudProvider( + &ProviderData{ + ProviderName: "", + LoginURL: &url.URL{}, + RedeemURL: &url.URL{}, + ProfileURL: &url.URL{}, + ValidateURL: &url.URL{}, + Scope: ""}) + if hostname != "" { + updateURL(p.Data().LoginURL, hostname) + updateURL(p.Data().RedeemURL, hostname) + updateURL(p.Data().ProfileURL, hostname) + updateURL(p.Data().ValidateURL, hostname) + } + return p +} + +func testNextcloudBackend(payload string) *httptest.Server { + path := userPath + query := formatJSON + + return httptest.NewServer(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != path || r.URL.RawQuery != query { + w.WriteHeader(404) + } else if r.Header.Get("Authorization") != "Bearer imaginary_access_token_nextcloud" { + w.WriteHeader(403) + } else { + w.WriteHeader(200) + w.Write([]byte(payload)) + } + })) +} + +func TestNextcloudProviderDefaults(t *testing.T) { + p := testNextcloudProvider("") + assert.NotEqual(t, nil, p) + assert.Equal(t, "Nextcloud", p.Data().ProviderName) + assert.Equal(t, "", + p.Data().LoginURL.String()) + assert.Equal(t, "", + p.Data().RedeemURL.String()) + assert.Equal(t, "", + p.Data().ValidateURL.String()) +} + +func TestNextcloudProviderOverrides(t *testing.T) { + p := NewNextcloudProvider( + &ProviderData{ + LoginURL: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/index.php/apps/oauth2/authorize"}, + RedeemURL: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/index.php/apps/oauth2/api/v1/token"}, + ValidateURL: &url.URL{ + Scheme: "https", + Host: "example.com", + Path: "/test/ocs/v2.php/cloud/user", + RawQuery: formatJSON}, + Scope: "profile"}) + assert.NotEqual(t, nil, p) + assert.Equal(t, "Nextcloud", p.Data().ProviderName) + assert.Equal(t, "https://example.com/index.php/apps/oauth2/authorize", + p.Data().LoginURL.String()) + assert.Equal(t, "https://example.com/index.php/apps/oauth2/api/v1/token", + p.Data().RedeemURL.String()) + assert.Equal(t, "https://example.com/test/ocs/v2.php/cloud/user?"+formatJSON, + p.Data().ValidateURL.String()) +} + +func TestNextcloudProviderGetEmailAddress(t *testing.T) { + b := testNextcloudBackend("{\"ocs\": {\"data\": { \"email\": \"michael.bland@gsa.gov\"}}}") + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testNextcloudProvider(bURL.Host) + p.ValidateURL.Path = userPath + p.ValidateURL.RawQuery = formatJSON + + session := &sessions.SessionState{AccessToken: "imaginary_access_token_nextcloud"} + email, err := p.GetEmailAddress(session) + assert.Equal(t, nil, err) + assert.Equal(t, "michael.bland@gsa.gov", email) +} + +// Note that trying to trigger the "failed building request" case is not +// practical, since the only way it can fail is if the URL fails to parse. +func TestNextcloudProviderGetEmailAddressFailedRequest(t *testing.T) { + b := testNextcloudBackend("unused payload") + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testNextcloudProvider(bURL.Host) + p.ValidateURL.Path = userPath + p.ValidateURL.RawQuery = formatJSON + + // We'll trigger a request failure by using an unexpected access + // token. Alternatively, we could allow the parsing of the payload as + // JSON to fail. + session := &sessions.SessionState{AccessToken: "unexpected_access_token"} + email, err := p.GetEmailAddress(session) + assert.NotEqual(t, nil, err) + assert.Equal(t, "", email) +} + +func TestNextcloudProviderGetEmailAddressEmailNotPresentInPayload(t *testing.T) { + b := testNextcloudBackend("{\"foo\": \"bar\"}") + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testNextcloudProvider(bURL.Host) + p.ValidateURL.Path = userPath + p.ValidateURL.RawQuery = formatJSON + + session := &sessions.SessionState{AccessToken: "imaginary_access_token_nextcloud"} + email, err := p.GetEmailAddress(session) + assert.NotEqual(t, nil, err) + assert.Equal(t, "", email) +} diff --git a/providers/providers.go b/providers/providers.go index 1df2413a..0e264105 100644 --- a/providers/providers.go +++ b/providers/providers.go @@ -40,6 +40,8 @@ func New(provider string, p *ProviderData) Provider { return NewLoginGovProvider(p) case "bitbucket": return NewBitbucketProvider(p) + case "nextcloud": + return NewNextcloudProvider(p) default: return NewGoogleProvider(p) } From f6790265e10a2e39497ed3ee307dfcb4be528dd1 Mon Sep 17 00:00:00 2001 From: Florian Kaiser Date: Tue, 26 Nov 2019 17:38:22 +0100 Subject: [PATCH 10/17] dist.sh: Add build for FreeBSD (#317) --- CHANGELOG.md | 1 + dist.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80c628cb..9a08ffaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - [#248](https://github.com/pusher/oauth2_proxy/pull/248) Fix issue with X-Auth-Request-Redirect header being ignored (@webnard) - [#314](https://github.com/pusher/oauth2_proxy/pull/314) Add redirect capability to sign_out (@costelmoraru) - [#265](https://github.com/pusher/oauth2_proxy/pull/265) Add upstream with static response (@cgroschupp) +- [#317](https://github.com/pusher/oauth2_proxy/pull/317) Add build for FreeBSD (@fnkr) - [#296](https://github.com/pusher/oauth2_proxy/pull/296) Allow to override provider's name for sign-in page (@ffdybuster) # v4.0.0 diff --git a/dist.sh b/dist.sh index e5be8180..583475c9 100755 --- a/dist.sh +++ b/dist.sh @@ -14,7 +14,7 @@ if [[ ! "${GO_VERSION}" =~ ^go1.13.* ]]; then exit 1 fi -ARCHS=(darwin-amd64 linux-amd64 linux-arm64 linux-armv6 windows-amd64) +ARCHS=(darwin-amd64 linux-amd64 linux-arm64 linux-armv6 freebsd-amd64 windows-amd64) mkdir -p release From 8165f6c4835d5c817ca6cd1853698feb136c77b3 Mon Sep 17 00:00:00 2001 From: Dan Bond Date: Tue, 10 Dec 2019 16:34:33 +0000 Subject: [PATCH 11/17] Update CHANGELOG for v4.1.0 (#323) --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a08ffaf..b1fb216a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Vx.x.x (Pre-release) +## Important Notes + +## Breaking Changes + +## Changes since v4.1.0 + +# v4.1.0 + +## Release Highlights +- Added Keycloak provider +- Build on Go 1.13 +- Upgrade Docker image to use Debian Buster +- Added support for FreeBSD builds +- Added new logo +- Added support for GitHub teams + +## Important Notes +N/A + +## Breaking Changes +N/A + ## Changes since v4.0.0 - [#292](https://github.com/pusher/oauth2_proxy/pull/292) Added bash >= 4.0 dependency to configure script (@jmfrank63) - [#227](https://github.com/pusher/oauth2_proxy/pull/227) Add Keycloak provider (@Ofinka) From ef8b7b5e25d1b38b8ec72d754d6794c9e782579b Mon Sep 17 00:00:00 2001 From: Dan Bond Date: Tue, 10 Dec 2019 17:24:15 +0000 Subject: [PATCH 12/17] dist.sh: use sha256sum (#325) * dist.sh: use sha256sum * update CHANGELOG --- CHANGELOG.md | 1 + dist.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1fb216a..cd2846b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## Breaking Changes ## Changes since v4.1.0 +- [#325](https://github.com/pusher/oauth2_proxy/pull/325) dist.sh: use sha256sum (@syscll) # v4.1.0 diff --git a/dist.sh b/dist.sh index 583475c9..c161ac32 100755 --- a/dist.sh +++ b/dist.sh @@ -37,7 +37,7 @@ for ARCH in "${ARCHS[@]}"; do cd release # Create sha256sum for architecture specific binary - shasum -a 256 ${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}/${BINARY} > ${BINARY}-${VERSION}.${ARCH}-sha256sum.txt + sha256sum ${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}/${BINARY} > ${BINARY}-${VERSION}.${ARCH}-sha256sum.txt # Create tar file for architecture specific binary tar -czvf ${BINARY}-${VERSION}.${ARCH}.${GO_VERSION}.tar.gz ${BINARY}-${VERSION}.${ARCH}.${GO_VERSION} From 28d64c90d9f33ad03e16acc7c7fe66169ea674a5 Mon Sep 17 00:00:00 2001 From: hjenkins Date: Tue, 10 Dec 2019 17:11:33 +0000 Subject: [PATCH 13/17] Add notes on how to create a release --- README.md | 2 +- RELEASE.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 RELEASE.md diff --git a/README.md b/README.md index daae04cc..6ae5cff9 100644 --- a/README.md +++ b/README.md @@ -47,4 +47,4 @@ If you would like to reach out to the maintainers, come talk to us in the `#oaut ## Contributing -Please see our [Contributing](CONTRIBUTING.md) guidelines. +Please see our [Contributing](CONTRIBUTING.md) guidelines. For releasing see our guide to [release creation guide](RELEASE.md). diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..74aaca04 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,46 @@ +# Release + +Here's how OAuth2_Proxy releases are created. + +## Schedule + +Our aim is to release once a quarter, but bug fixes will be prioritised and might be released earlier. + +## The Process + +Note this uses `v4.1.0` as an example release number. + +1. Create a draft Github release + * Use format `v4.1.0` for both the tag and title +2. Update [CHANGELOG.md](CHANGELOG.md) + * Write the release highlights + * Copy in headings ready for the next release +3. Create release commit + ``` + git checkout -b release-v4.1.0 + ``` +4. Create pull request getting other maintainers to review +5. Copy the release notes in to the draft Github release, adding a link to the [changelog](CHANGELOG.md) +6. Update you local master branch + ``` + git checkout master + git pull + ``` +7. Create & push the tag + ``` + git tag v4.1.0 + git push upstream --tags + ``` +8. Make the release artefacts + ``` + make release + ``` +9. Upload all the files (not the folders) from the `/release` folder to Github release as binary artefacts +10. Publish release in Github +11. Make and push docker images to Quay + ``` + make docker-all + make docker-push-all + ``` + Note: Ensure the docker tags are tags aren't `-dirty` +12. Verify everything looks good at [quay](https://quay.io/repository/pusher/oauth2_proxy?tag=latest&tab=tags) and [github](https://github.com/pusher/oauth2_proxy/releases) From 61137f67a9b2360f2acad539ac3578ac440a03d7 Mon Sep 17 00:00:00 2001 From: Henry Jenkins Date: Tue, 10 Dec 2019 17:56:14 +0000 Subject: [PATCH 14/17] Update RELEASE.md --- RELEASE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE.md b/RELEASE.md index 74aaca04..f6516de9 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -43,4 +43,5 @@ Note this uses `v4.1.0` as an example release number. make docker-push-all ``` Note: Ensure the docker tags are tags aren't `-dirty` + 12. Verify everything looks good at [quay](https://quay.io/repository/pusher/oauth2_proxy?tag=latest&tab=tags) and [github](https://github.com/pusher/oauth2_proxy/releases) From b8bfa226dd78766f24c576b57b8af08260906bbe Mon Sep 17 00:00:00 2001 From: Henry Jenkins Date: Mon, 16 Dec 2019 16:08:44 +0000 Subject: [PATCH 15/17] Update README.md Co-Authored-By: Joel Speed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ae5cff9..e12532c0 100644 --- a/README.md +++ b/README.md @@ -47,4 +47,4 @@ If you would like to reach out to the maintainers, come talk to us in the `#oaut ## Contributing -Please see our [Contributing](CONTRIBUTING.md) guidelines. For releasing see our guide to [release creation guide](RELEASE.md). +Please see our [Contributing](CONTRIBUTING.md) guidelines. For releasing see our [release creation guide](RELEASE.md). From 8602aa4f133864e9426fc9ed471d6be6aa4147f0 Mon Sep 17 00:00:00 2001 From: Henry Jenkins Date: Mon, 16 Dec 2019 16:13:51 +0000 Subject: [PATCH 16/17] Update RELEASE.md --- RELEASE.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index f6516de9..1dc9b888 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -20,7 +20,7 @@ Note this uses `v4.1.0` as an example release number. git checkout -b release-v4.1.0 ``` 4. Create pull request getting other maintainers to review -5. Copy the release notes in to the draft Github release, adding a link to the [changelog](CHANGELOG.md) +5. Copy the release notes in to the draft Github release, adding a link to [CHANGELOG.md](CHANGELOG.md) 6. Update you local master branch ``` git checkout master @@ -29,19 +29,19 @@ Note this uses `v4.1.0` as an example release number. 7. Create & push the tag ``` git tag v4.1.0 - git push upstream --tags + git push --tags ``` 8. Make the release artefacts ``` make release ``` -9. Upload all the files (not the folders) from the `/release` folder to Github release as binary artefacts +9. Upload all the files (not the folders) from the `/release` folder to Github release as binary artefacts. There should be both the tarballs (`tar.gz`) and the checksum files (`sha256sum.txt`). 10. Publish release in Github 11. Make and push docker images to Quay ``` make docker-all make docker-push-all ``` - Note: Ensure the docker tags are tags aren't `-dirty` + Note: Ensure the docker tags don't include `-dirty`. This means you have uncommitted changes. 12. Verify everything looks good at [quay](https://quay.io/repository/pusher/oauth2_proxy?tag=latest&tab=tags) and [github](https://github.com/pusher/oauth2_proxy/releases) From effe1e0bdb4307d802a0209d3532b242d114ed0c Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Tue, 17 Dec 2019 12:17:05 +0000 Subject: [PATCH 17/17] Fix changelog entry release --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7531f506..90b7ccf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ## Changes since v4.1.0 - [#325](https://github.com/pusher/oauth2_proxy/pull/325) dist.sh: use sha256sum (@syscll) +- [#179](https://github.com/pusher/oauth2_proxy/pull/179) Add Nextcloud provider (@Ramblurr) # v4.1.0 @@ -26,7 +27,6 @@ N/A ## Changes since v4.0.0 - [#292](https://github.com/pusher/oauth2_proxy/pull/292) Added bash >= 4.0 dependency to configure script (@jmfrank63) - [#227](https://github.com/pusher/oauth2_proxy/pull/227) Add Keycloak provider (@Ofinka) -- [#179](https://github.com/pusher/oauth2_proxy/pull/179) Add Nextcloud provider (@Ramblurr) - [#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)