commit
						e6e2dbe459
					
				
							
								
								
									
										6
									
								
								main.go
								
								
								
								
							
							
						
						
									
										6
									
								
								main.go
								
								
								
								
							|  | @ -66,8 +66,8 @@ func main() { | |||
| 	flagSet.String("redeem-url", "", "Token redemption endpoint") | ||||
| 	flagSet.String("profile-url", "", "Profile access endpoint") | ||||
| 	flagSet.String("validate-url", "", "Access token validation endpoint") | ||||
| 	flagSet.String("scope", "", "Oauth scope specification") | ||||
| 	flagSet.String("approval-prompt", "force", "Oauth approval_prompt") | ||||
| 	flagSet.String("scope", "", "OAuth scope specification") | ||||
| 	flagSet.String("approval-prompt", "force", "OAuth approval_prompt") | ||||
| 
 | ||||
| 	flagSet.Parse(os.Args[1:]) | ||||
| 
 | ||||
|  | @ -95,7 +95,7 @@ func main() { | |||
| 	} | ||||
| 
 | ||||
| 	validator := NewValidator(opts.EmailDomains, opts.AuthenticatedEmailsFile) | ||||
| 	oauthproxy := NewOauthProxy(opts, validator) | ||||
| 	oauthproxy := NewOAuthProxy(opts, validator) | ||||
| 
 | ||||
| 	if len(opts.EmailDomains) != 0 && opts.AuthenticatedEmailsFile == "" { | ||||
| 		if len(opts.EmailDomains) > 1 { | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ import ( | |||
| 	"github.com/bitly/oauth2_proxy/providers" | ||||
| ) | ||||
| 
 | ||||
| type OauthProxy struct { | ||||
| type OAuthProxy struct { | ||||
| 	CookieSeed     string | ||||
| 	CookieName     string | ||||
| 	CookieDomain   string | ||||
|  | @ -31,10 +31,10 @@ type OauthProxy struct { | |||
| 	RobotsPath        string | ||||
| 	PingPath          string | ||||
| 	SignInPath        string | ||||
| 	OauthStartPath    string | ||||
| 	OauthCallbackPath string | ||||
| 	OAuthStartPath    string | ||||
| 	OAuthCallbackPath string | ||||
| 
 | ||||
| 	redirectUrl         *url.URL // the url to receive requests at
 | ||||
| 	redirectURL         *url.URL // the url to receive requests at
 | ||||
| 	provider            providers.Provider | ||||
| 	ProxyPrefix         string | ||||
| 	SignInMessage       string | ||||
|  | @ -86,9 +86,9 @@ func NewFileServer(path string, filesystemPath string) (proxy http.Handler) { | |||
| 	return http.StripPrefix(path, http.FileServer(http.Dir(filesystemPath))) | ||||
| } | ||||
| 
 | ||||
| func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { | ||||
| func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { | ||||
| 	serveMux := http.NewServeMux() | ||||
| 	for _, u := range opts.proxyUrls { | ||||
| 	for _, u := range opts.proxyURLs { | ||||
| 		path := u.Path | ||||
| 		switch u.Scheme { | ||||
| 		case "http", "https": | ||||
|  | @ -116,10 +116,10 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { | |||
| 		log.Printf("compiled skip-auth-regex => %q", u) | ||||
| 	} | ||||
| 
 | ||||
| 	redirectUrl := opts.redirectUrl | ||||
| 	redirectUrl.Path = fmt.Sprintf("%s/callback", opts.ProxyPrefix) | ||||
| 	redirectURL := opts.redirectURL | ||||
| 	redirectURL.Path = fmt.Sprintf("%s/callback", opts.ProxyPrefix) | ||||
| 
 | ||||
| 	log.Printf("OauthProxy configured for %s Client ID: %s", opts.provider.Data().ProviderName, opts.ClientID) | ||||
| 	log.Printf("OAuthProxy configured for %s Client ID: %s", opts.provider.Data().ProviderName, opts.ClientID) | ||||
| 	domain := opts.CookieDomain | ||||
| 	if domain == "" { | ||||
| 		domain = "<default>" | ||||
|  | @ -141,7 +141,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &OauthProxy{ | ||||
| 	return &OAuthProxy{ | ||||
| 		CookieName:     opts.CookieName, | ||||
| 		CookieSeed:     opts.CookieSecret, | ||||
| 		CookieDomain:   opts.CookieDomain, | ||||
|  | @ -154,13 +154,13 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { | |||
| 		RobotsPath:        "/robots.txt", | ||||
| 		PingPath:          "/ping", | ||||
| 		SignInPath:        fmt.Sprintf("%s/sign_in", opts.ProxyPrefix), | ||||
| 		OauthStartPath:    fmt.Sprintf("%s/start", opts.ProxyPrefix), | ||||
| 		OauthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix), | ||||
| 		OAuthStartPath:    fmt.Sprintf("%s/start", opts.ProxyPrefix), | ||||
| 		OAuthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix), | ||||
| 
 | ||||
| 		ProxyPrefix:       opts.ProxyPrefix, | ||||
| 		provider:          opts.provider, | ||||
| 		serveMux:          serveMux, | ||||
| 		redirectUrl:       redirectUrl, | ||||
| 		redirectURL:       redirectURL, | ||||
| 		skipAuthRegex:     opts.SkipAuthRegex, | ||||
| 		compiledRegex:     opts.CompiledRegex, | ||||
| 		PassBasicAuth:     opts.PassBasicAuth, | ||||
|  | @ -171,13 +171,13 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) GetRedirectURI(host string) string { | ||||
| func (p *OAuthProxy) GetRedirectURI(host string) string { | ||||
| 	// default to the request Host if not set
 | ||||
| 	if p.redirectUrl.Host != "" { | ||||
| 		return p.redirectUrl.String() | ||||
| 	if p.redirectURL.Host != "" { | ||||
| 		return p.redirectURL.String() | ||||
| 	} | ||||
| 	var u url.URL | ||||
| 	u = *p.redirectUrl | ||||
| 	u = *p.redirectURL | ||||
| 	if u.Scheme == "" { | ||||
| 		if p.CookieSecure { | ||||
| 			u.Scheme = "https" | ||||
|  | @ -189,16 +189,16 @@ func (p *OauthProxy) GetRedirectURI(host string) string { | |||
| 	return u.String() | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) displayCustomLoginForm() bool { | ||||
| func (p *OAuthProxy) displayCustomLoginForm() bool { | ||||
| 	return p.HtpasswdFile != nil && p.DisplayHtpasswdForm | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) redeemCode(host, code string) (s *providers.SessionState, err error) { | ||||
| func (p *OAuthProxy) redeemCode(host, code string) (s *providers.SessionState, err error) { | ||||
| 	if code == "" { | ||||
| 		return nil, errors.New("missing code") | ||||
| 	} | ||||
| 	redirectUri := p.GetRedirectURI(host) | ||||
| 	s, err = p.provider.Redeem(redirectUri, code) | ||||
| 	redirectURI := p.GetRedirectURI(host) | ||||
| 	s, err = p.provider.Redeem(redirectURI, code) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | @ -209,7 +209,7 @@ func (p *OauthProxy) redeemCode(host, code string) (s *providers.SessionState, e | |||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) MakeCookie(req *http.Request, value string, expiration time.Duration, now time.Time) *http.Cookie { | ||||
| func (p *OAuthProxy) MakeCookie(req *http.Request, value string, expiration time.Duration, now time.Time) *http.Cookie { | ||||
| 	domain := req.Host | ||||
| 	if h, _, err := net.SplitHostPort(domain); err == nil { | ||||
| 		domain = h | ||||
|  | @ -235,15 +235,15 @@ func (p *OauthProxy) MakeCookie(req *http.Request, value string, expiration time | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) ClearCookie(rw http.ResponseWriter, req *http.Request) { | ||||
| func (p *OAuthProxy) ClearCookie(rw http.ResponseWriter, req *http.Request) { | ||||
| 	http.SetCookie(rw, p.MakeCookie(req, "", time.Hour*-1, time.Now())) | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) SetCookie(rw http.ResponseWriter, req *http.Request, val string) { | ||||
| func (p *OAuthProxy) SetCookie(rw http.ResponseWriter, req *http.Request, val string) { | ||||
| 	http.SetCookie(rw, p.MakeCookie(req, val, p.CookieExpire, time.Now())) | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) LoadCookiedSession(req *http.Request) (*providers.SessionState, time.Duration, error) { | ||||
| func (p *OAuthProxy) LoadCookiedSession(req *http.Request) (*providers.SessionState, time.Duration, error) { | ||||
| 	var age time.Duration | ||||
| 	c, err := req.Cookie(p.CookieName) | ||||
| 	if err != nil { | ||||
|  | @ -264,7 +264,7 @@ func (p *OauthProxy) LoadCookiedSession(req *http.Request) (*providers.SessionSt | |||
| 	return session, age, nil | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) SaveSession(rw http.ResponseWriter, req *http.Request, s *providers.SessionState) error { | ||||
| func (p *OAuthProxy) SaveSession(rw http.ResponseWriter, req *http.Request, s *providers.SessionState) error { | ||||
| 	value, err := p.provider.CookieForSession(s, p.CookieCipher) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|  | @ -273,17 +273,17 @@ func (p *OauthProxy) SaveSession(rw http.ResponseWriter, req *http.Request, s *p | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) RobotsTxt(rw http.ResponseWriter) { | ||||
| func (p *OAuthProxy) RobotsTxt(rw http.ResponseWriter) { | ||||
| 	rw.WriteHeader(http.StatusOK) | ||||
| 	fmt.Fprintf(rw, "User-agent: *\nDisallow: /") | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) PingPage(rw http.ResponseWriter) { | ||||
| func (p *OAuthProxy) PingPage(rw http.ResponseWriter) { | ||||
| 	rw.WriteHeader(http.StatusOK) | ||||
| 	fmt.Fprintf(rw, "OK") | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) ErrorPage(rw http.ResponseWriter, code int, title string, message string) { | ||||
| func (p *OAuthProxy) ErrorPage(rw http.ResponseWriter, code int, title string, message string) { | ||||
| 	log.Printf("ErrorPage %d %s %s", code, title, message) | ||||
| 	rw.WriteHeader(code) | ||||
| 	t := struct { | ||||
|  | @ -298,7 +298,7 @@ func (p *OauthProxy) ErrorPage(rw http.ResponseWriter, code int, title string, m | |||
| 	p.templates.ExecuteTemplate(rw, "error.html", t) | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code int) { | ||||
| func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code int) { | ||||
| 	p.ClearCookie(rw, req) | ||||
| 	rw.WriteHeader(code) | ||||
| 
 | ||||
|  | @ -325,7 +325,7 @@ func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code | |||
| 	p.templates.ExecuteTemplate(rw, "sign_in.html", t) | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) ManualSignIn(rw http.ResponseWriter, req *http.Request) (string, bool) { | ||||
| func (p *OAuthProxy) ManualSignIn(rw http.ResponseWriter, req *http.Request) (string, bool) { | ||||
| 	if req.Method != "POST" || p.HtpasswdFile == nil { | ||||
| 		return "", false | ||||
| 	} | ||||
|  | @ -342,7 +342,7 @@ func (p *OauthProxy) ManualSignIn(rw http.ResponseWriter, req *http.Request) (st | |||
| 	return "", false | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) GetRedirect(req *http.Request) (string, error) { | ||||
| func (p *OAuthProxy) GetRedirect(req *http.Request) (string, error) { | ||||
| 	err := req.ParseForm() | ||||
| 
 | ||||
| 	if err != nil { | ||||
|  | @ -358,7 +358,7 @@ func (p *OauthProxy) GetRedirect(req *http.Request) (string, error) { | |||
| 	return redirect, err | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) IsWhitelistedPath(path string) (ok bool) { | ||||
| func (p *OAuthProxy) IsWhitelistedPath(path string) (ok bool) { | ||||
| 	for _, u := range p.compiledRegex { | ||||
| 		ok = u.MatchString(path) | ||||
| 		if ok { | ||||
|  | @ -376,7 +376,7 @@ func getRemoteAddr(req *http.Request) (s string) { | |||
| 	return | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | ||||
| func (p *OAuthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | ||||
| 	switch path := req.URL.Path; { | ||||
| 	case path == p.RobotsPath: | ||||
| 		p.RobotsTxt(rw) | ||||
|  | @ -386,16 +386,16 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | |||
| 		p.serveMux.ServeHTTP(rw, req) | ||||
| 	case path == p.SignInPath: | ||||
| 		p.SignIn(rw, req) | ||||
| 	case path == p.OauthStartPath: | ||||
| 		p.OauthStart(rw, req) | ||||
| 	case path == p.OauthCallbackPath: | ||||
| 		p.OauthCallback(rw, req) | ||||
| 	case path == p.OAuthStartPath: | ||||
| 		p.OAuthStart(rw, req) | ||||
| 	case path == p.OAuthCallbackPath: | ||||
| 		p.OAuthCallback(rw, req) | ||||
| 	default: | ||||
| 		p.Proxy(rw, req) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) SignIn(rw http.ResponseWriter, req *http.Request) { | ||||
| func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) { | ||||
| 	redirect, err := p.GetRedirect(req) | ||||
| 	if err != nil { | ||||
| 		p.ErrorPage(rw, 500, "Internal Error", err.Error()) | ||||
|  | @ -412,7 +412,7 @@ func (p *OauthProxy) SignIn(rw http.ResponseWriter, req *http.Request) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) OauthStart(rw http.ResponseWriter, req *http.Request) { | ||||
| func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request) { | ||||
| 	redirect, err := p.GetRedirect(req) | ||||
| 	if err != nil { | ||||
| 		p.ErrorPage(rw, 500, "Internal Error", err.Error()) | ||||
|  | @ -422,7 +422,7 @@ func (p *OauthProxy) OauthStart(rw http.ResponseWriter, req *http.Request) { | |||
| 	http.Redirect(rw, req, p.provider.GetLoginURL(redirectURI, redirect), 302) | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) OauthCallback(rw http.ResponseWriter, req *http.Request) { | ||||
| func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) { | ||||
| 	remoteAddr := getRemoteAddr(req) | ||||
| 
 | ||||
| 	// finish the oauth cycle
 | ||||
|  | @ -465,7 +465,7 @@ func (p *OauthProxy) OauthCallback(rw http.ResponseWriter, req *http.Request) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) Proxy(rw http.ResponseWriter, req *http.Request) { | ||||
| func (p *OAuthProxy) Proxy(rw http.ResponseWriter, req *http.Request) { | ||||
| 	var saveSession, clearSession, revalidated bool | ||||
| 	remoteAddr := getRemoteAddr(req) | ||||
| 
 | ||||
|  | @ -555,7 +555,7 @@ func (p *OauthProxy) Proxy(rw http.ResponseWriter, req *http.Request) { | |||
| 	p.serveMux.ServeHTTP(rw, req) | ||||
| } | ||||
| 
 | ||||
| func (p *OauthProxy) CheckBasicAuth(req *http.Request) (*providers.SessionState, error) { | ||||
| func (p *OAuthProxy) CheckBasicAuth(req *http.Request) (*providers.SessionState, error) { | ||||
| 	if p.HtpasswdFile == nil { | ||||
| 		return nil, nil | ||||
| 	} | ||||
|  |  | |||
|  | @ -80,7 +80,7 @@ func TestRobotsTxt(t *testing.T) { | |||
| 	opts.CookieSecret = "xyzzyplugh" | ||||
| 	opts.Validate() | ||||
| 
 | ||||
| 	proxy := NewOauthProxy(opts, func(string) bool { return true }) | ||||
| 	proxy := NewOAuthProxy(opts, func(string) bool { return true }) | ||||
| 	rw := httptest.NewRecorder() | ||||
| 	req, _ := http.NewRequest("GET", "/robots.txt", nil) | ||||
| 	proxy.ServeHTTP(rw, req) | ||||
|  | @ -124,17 +124,17 @@ func TestBasicAuthPassword(t *testing.T) { | |||
| 	opts.provider = &TestProvider{ | ||||
| 		ProviderData: &providers.ProviderData{ | ||||
| 			ProviderName: "Test Provider", | ||||
| 			LoginUrl: &url.URL{ | ||||
| 			LoginURL: &url.URL{ | ||||
| 				Scheme: "http", | ||||
| 				Host:   provider_url.Host, | ||||
| 				Path:   "/oauth/authorize", | ||||
| 			}, | ||||
| 			RedeemUrl: &url.URL{ | ||||
| 			RedeemURL: &url.URL{ | ||||
| 				Scheme: "http", | ||||
| 				Host:   provider_url.Host, | ||||
| 				Path:   "/oauth/token", | ||||
| 			}, | ||||
| 			ProfileUrl: &url.URL{ | ||||
| 			ProfileURL: &url.URL{ | ||||
| 				Scheme: "http", | ||||
| 				Host:   provider_url.Host, | ||||
| 				Path:   "/api/v1/profile", | ||||
|  | @ -144,7 +144,7 @@ func TestBasicAuthPassword(t *testing.T) { | |||
| 		EmailAddress: email_address, | ||||
| 	} | ||||
| 
 | ||||
| 	proxy := NewOauthProxy(opts, func(email string) bool { | ||||
| 	proxy := NewOAuthProxy(opts, func(email string) bool { | ||||
| 		return email == email_address | ||||
| 	}) | ||||
| 
 | ||||
|  | @ -199,7 +199,7 @@ func (tp *TestProvider) ValidateSessionState(session *providers.SessionState) bo | |||
| 
 | ||||
| type PassAccessTokenTest struct { | ||||
| 	provider_server *httptest.Server | ||||
| 	proxy           *OauthProxy | ||||
| 	proxy           *OAuthProxy | ||||
| 	opts            *Options | ||||
| } | ||||
| 
 | ||||
|  | @ -245,17 +245,17 @@ func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) *PassAccessTokenTes | |||
| 	t.opts.provider = &TestProvider{ | ||||
| 		ProviderData: &providers.ProviderData{ | ||||
| 			ProviderName: "Test Provider", | ||||
| 			LoginUrl: &url.URL{ | ||||
| 			LoginURL: &url.URL{ | ||||
| 				Scheme: "http", | ||||
| 				Host:   provider_url.Host, | ||||
| 				Path:   "/oauth/authorize", | ||||
| 			}, | ||||
| 			RedeemUrl: &url.URL{ | ||||
| 			RedeemURL: &url.URL{ | ||||
| 				Scheme: "http", | ||||
| 				Host:   provider_url.Host, | ||||
| 				Path:   "/oauth/token", | ||||
| 			}, | ||||
| 			ProfileUrl: &url.URL{ | ||||
| 			ProfileURL: &url.URL{ | ||||
| 				Scheme: "http", | ||||
| 				Host:   provider_url.Host, | ||||
| 				Path:   "/api/v1/profile", | ||||
|  | @ -265,7 +265,7 @@ func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) *PassAccessTokenTes | |||
| 		EmailAddress: email_address, | ||||
| 	} | ||||
| 
 | ||||
| 	t.proxy = NewOauthProxy(t.opts, func(email string) bool { | ||||
| 	t.proxy = NewOAuthProxy(t.opts, func(email string) bool { | ||||
| 		return email == email_address | ||||
| 	}) | ||||
| 	return t | ||||
|  | @ -360,7 +360,7 @@ func TestDoNotForwardAccessTokenUpstream(t *testing.T) { | |||
| 
 | ||||
| type SignInPageTest struct { | ||||
| 	opts           *Options | ||||
| 	proxy          *OauthProxy | ||||
| 	proxy          *OAuthProxy | ||||
| 	sign_in_regexp *regexp.Regexp | ||||
| } | ||||
| 
 | ||||
|  | @ -375,7 +375,7 @@ func NewSignInPageTest() *SignInPageTest { | |||
| 	sip_test.opts.ClientSecret = "xyzzyplugh" | ||||
| 	sip_test.opts.Validate() | ||||
| 
 | ||||
| 	sip_test.proxy = NewOauthProxy(sip_test.opts, func(email string) bool { | ||||
| 	sip_test.proxy = NewOAuthProxy(sip_test.opts, func(email string) bool { | ||||
| 		return true | ||||
| 	}) | ||||
| 	sip_test.sign_in_regexp = regexp.MustCompile(signInRedirectPattern) | ||||
|  | @ -425,7 +425,7 @@ func TestSignInPageDirectAccessRedirectsToRoot(t *testing.T) { | |||
| 
 | ||||
| type ProcessCookieTest struct { | ||||
| 	opts          *Options | ||||
| 	proxy         *OauthProxy | ||||
| 	proxy         *OAuthProxy | ||||
| 	rw            *httptest.ResponseRecorder | ||||
| 	req           *http.Request | ||||
| 	provider      TestProvider | ||||
|  | @ -449,7 +449,7 @@ func NewProcessCookieTest(opts ProcessCookieTestOpts) *ProcessCookieTest { | |||
| 	pc_test.opts.CookieRefresh = time.Hour | ||||
| 	pc_test.opts.Validate() | ||||
| 
 | ||||
| 	pc_test.proxy = NewOauthProxy(pc_test.opts, func(email string) bool { | ||||
| 	pc_test.proxy = NewOAuthProxy(pc_test.opts, func(email string) bool { | ||||
| 		return pc_test.validate_user | ||||
| 	}) | ||||
| 	pc_test.proxy.provider = &TestProvider{ | ||||
|  |  | |||
							
								
								
									
										36
									
								
								options.go
								
								
								
								
							
							
						
						
									
										36
									
								
								options.go
								
								
								
								
							|  | @ -16,7 +16,7 @@ type Options struct { | |||
| 	ProxyPrefix  string `flag:"proxy-prefix" cfg:"proxy-prefix"` | ||||
| 	HttpAddress  string `flag:"http-address" cfg:"http_address"` | ||||
| 	HttpsAddress string `flag:"https-address" cfg:"https_address"` | ||||
| 	RedirectUrl  string `flag:"redirect-url" cfg:"redirect_url"` | ||||
| 	RedirectURL  string `flag:"redirect-url" cfg:"redirect_url"` | ||||
| 	ClientID     string `flag:"client-id" cfg:"client_id" env:"OAUTH2_PROXY_CLIENT_ID"` | ||||
| 	ClientSecret string `flag:"client-secret" cfg:"client_secret" env:"OAUTH2_PROXY_CLIENT_SECRET"` | ||||
| 	TLSCertFile  string `flag:"tls-cert" cfg:"tls_cert_file"` | ||||
|  | @ -51,18 +51,18 @@ type Options struct { | |||
| 	// These options allow for other providers besides Google, with
 | ||||
| 	// potential overrides.
 | ||||
| 	Provider       string `flag:"provider" cfg:"provider"` | ||||
| 	LoginUrl       string `flag:"login-url" cfg:"login_url"` | ||||
| 	RedeemUrl      string `flag:"redeem-url" cfg:"redeem_url"` | ||||
| 	ProfileUrl     string `flag:"profile-url" cfg:"profile_url"` | ||||
| 	ValidateUrl    string `flag:"validate-url" cfg:"validate_url"` | ||||
| 	LoginURL       string `flag:"login-url" cfg:"login_url"` | ||||
| 	RedeemURL      string `flag:"redeem-url" cfg:"redeem_url"` | ||||
| 	ProfileURL     string `flag:"profile-url" cfg:"profile_url"` | ||||
| 	ValidateURL    string `flag:"validate-url" cfg:"validate_url"` | ||||
| 	Scope          string `flag:"scope" cfg:"scope"` | ||||
| 	ApprovalPrompt string `flag:"approval-prompt" cfg:"approval_prompt"` | ||||
| 
 | ||||
| 	RequestLogging bool `flag:"request-logging" cfg:"request_logging"` | ||||
| 
 | ||||
| 	// internal values that are set after config validation
 | ||||
| 	redirectUrl   *url.URL | ||||
| 	proxyUrls     []*url.URL | ||||
| 	redirectURL   *url.URL | ||||
| 	proxyURLs     []*url.URL | ||||
| 	CompiledRegex []*regexp.Regexp | ||||
| 	provider      providers.Provider | ||||
| } | ||||
|  | @ -86,7 +86,7 @@ func NewOptions() *Options { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func parseUrl(to_parse string, urltype string, msgs []string) (*url.URL, []string) { | ||||
| func parseURL(to_parse string, urltype string, msgs []string) (*url.URL, []string) { | ||||
| 	parsed, err := url.Parse(to_parse) | ||||
| 	if err != nil { | ||||
| 		return nil, append(msgs, fmt.Sprintf( | ||||
|  | @ -113,19 +113,19 @@ func (o *Options) Validate() error { | |||
| 		msgs = append(msgs, "missing setting for email validation: email-domain or authenticated-emails-file required.\n      use email-domain=* to authorize all email addresses") | ||||
| 	} | ||||
| 
 | ||||
| 	o.redirectUrl, msgs = parseUrl(o.RedirectUrl, "redirect", msgs) | ||||
| 	o.redirectURL, msgs = parseURL(o.RedirectURL, "redirect", msgs) | ||||
| 
 | ||||
| 	for _, u := range o.Upstreams { | ||||
| 		upstreamUrl, err := url.Parse(u) | ||||
| 		upstreamURL, err := url.Parse(u) | ||||
| 		if err != nil { | ||||
| 			msgs = append(msgs, fmt.Sprintf( | ||||
| 				"error parsing upstream=%q %s", | ||||
| 				upstreamUrl, err)) | ||||
| 				upstreamURL, err)) | ||||
| 		} | ||||
| 		if upstreamUrl.Path == "" { | ||||
| 			upstreamUrl.Path = "/" | ||||
| 		if upstreamURL.Path == "" { | ||||
| 			upstreamURL.Path = "/" | ||||
| 		} | ||||
| 		o.proxyUrls = append(o.proxyUrls, upstreamUrl) | ||||
| 		o.proxyURLs = append(o.proxyURLs, upstreamURL) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, u := range o.SkipAuthRegex { | ||||
|  | @ -189,10 +189,10 @@ func parseProviderInfo(o *Options, msgs []string) []string { | |||
| 		ClientSecret:   o.ClientSecret, | ||||
| 		ApprovalPrompt: o.ApprovalPrompt, | ||||
| 	} | ||||
| 	p.LoginUrl, msgs = parseUrl(o.LoginUrl, "login", msgs) | ||||
| 	p.RedeemUrl, msgs = parseUrl(o.RedeemUrl, "redeem", msgs) | ||||
| 	p.ProfileUrl, msgs = parseUrl(o.ProfileUrl, "profile", msgs) | ||||
| 	p.ValidateUrl, msgs = parseUrl(o.ValidateUrl, "validate", msgs) | ||||
| 	p.LoginURL, msgs = parseURL(o.LoginURL, "login", msgs) | ||||
| 	p.RedeemURL, msgs = parseURL(o.RedeemURL, "redeem", msgs) | ||||
| 	p.ProfileURL, msgs = parseURL(o.ProfileURL, "profile", msgs) | ||||
| 	p.ValidateURL, msgs = parseURL(o.ValidateURL, "validate", msgs) | ||||
| 
 | ||||
| 	o.provider = providers.New(o.Provider, p) | ||||
| 	switch p := o.provider.(type) { | ||||
|  |  | |||
|  | @ -73,16 +73,16 @@ func TestInitializedOptions(t *testing.T) { | |||
| 
 | ||||
| // Note that it's not worth testing nonparseable URLs, since url.Parse()
 | ||||
| // seems to parse damn near anything.
 | ||||
| func TestRedirectUrl(t *testing.T) { | ||||
| func TestRedirectURL(t *testing.T) { | ||||
| 	o := testOptions() | ||||
| 	o.RedirectUrl = "https://myhost.com/oauth2/callback" | ||||
| 	o.RedirectURL = "https://myhost.com/oauth2/callback" | ||||
| 	assert.Equal(t, nil, o.Validate()) | ||||
| 	expected := &url.URL{ | ||||
| 		Scheme: "https", Host: "myhost.com", Path: "/oauth2/callback"} | ||||
| 	assert.Equal(t, expected, o.redirectUrl) | ||||
| 	assert.Equal(t, expected, o.redirectURL) | ||||
| } | ||||
| 
 | ||||
| func TestProxyUrls(t *testing.T) { | ||||
| func TestProxyURLs(t *testing.T) { | ||||
| 	o := testOptions() | ||||
| 	o.Upstreams = append(o.Upstreams, "http://127.0.0.1:8081") | ||||
| 	assert.Equal(t, nil, o.Validate()) | ||||
|  | @ -91,7 +91,7 @@ func TestProxyUrls(t *testing.T) { | |||
| 		// note the '/' was added
 | ||||
| 		&url.URL{Scheme: "http", Host: "127.0.0.1:8081", Path: "/"}, | ||||
| 	} | ||||
| 	assert.Equal(t, expected, o.proxyUrls) | ||||
| 	assert.Equal(t, expected, o.proxyURLs) | ||||
| } | ||||
| 
 | ||||
| func TestCompiledRegex(t *testing.T) { | ||||
|  | @ -125,10 +125,10 @@ func TestDefaultProviderApiSettings(t *testing.T) { | |||
| 	assert.Equal(t, nil, o.Validate()) | ||||
| 	p := o.provider.Data() | ||||
| 	assert.Equal(t, "https://accounts.google.com/o/oauth2/auth?access_type=offline", | ||||
| 		p.LoginUrl.String()) | ||||
| 		p.LoginURL.String()) | ||||
| 	assert.Equal(t, "https://www.googleapis.com/oauth2/v3/token", | ||||
| 		p.RedeemUrl.String()) | ||||
| 	assert.Equal(t, "", p.ProfileUrl.String()) | ||||
| 		p.RedeemURL.String()) | ||||
| 	assert.Equal(t, "", p.ProfileURL.String()) | ||||
| 	assert.Equal(t, "profile email", p.Scope) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,22 +17,22 @@ type GitHubProvider struct { | |||
| 
 | ||||
| func NewGitHubProvider(p *ProviderData) *GitHubProvider { | ||||
| 	p.ProviderName = "GitHub" | ||||
| 	if p.LoginUrl == nil || p.LoginUrl.String() == "" { | ||||
| 		p.LoginUrl = &url.URL{ | ||||
| 	if p.LoginURL == nil || p.LoginURL.String() == "" { | ||||
| 		p.LoginURL = &url.URL{ | ||||
| 			Scheme: "https", | ||||
| 			Host:   "github.com", | ||||
| 			Path:   "/login/oauth/authorize", | ||||
| 		} | ||||
| 	} | ||||
| 	if p.RedeemUrl == nil || p.RedeemUrl.String() == "" { | ||||
| 		p.RedeemUrl = &url.URL{ | ||||
| 	if p.RedeemURL == nil || p.RedeemURL.String() == "" { | ||||
| 		p.RedeemURL = &url.URL{ | ||||
| 			Scheme: "https", | ||||
| 			Host:   "github.com", | ||||
| 			Path:   "/login/oauth/access_token", | ||||
| 		} | ||||
| 	} | ||||
| 	if p.ValidateUrl == nil || p.ValidateUrl.String() == "" { | ||||
| 		p.ValidateUrl = &url.URL{ | ||||
| 	if p.ValidateURL == nil || p.ValidateURL.String() == "" { | ||||
| 		p.ValidateURL = &url.URL{ | ||||
| 			Scheme: "https", | ||||
| 			Host:   "api.github.com", | ||||
| 			Path:   "/user/emails", | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ import ( | |||
| 
 | ||||
| type GoogleProvider struct { | ||||
| 	*ProviderData | ||||
| 	RedeemRefreshUrl *url.URL | ||||
| 	RedeemRefreshURL *url.URL | ||||
| 	// GroupValidator is a function that determines if the passed email is in
 | ||||
| 	// the configured Google group.
 | ||||
| 	GroupValidator func(string) bool | ||||
|  | @ -29,21 +29,21 @@ type GoogleProvider struct { | |||
| 
 | ||||
| func NewGoogleProvider(p *ProviderData) *GoogleProvider { | ||||
| 	p.ProviderName = "Google" | ||||
| 	if p.LoginUrl.String() == "" { | ||||
| 		p.LoginUrl = &url.URL{Scheme: "https", | ||||
| 	if p.LoginURL.String() == "" { | ||||
| 		p.LoginURL = &url.URL{Scheme: "https", | ||||
| 			Host: "accounts.google.com", | ||||
| 			Path: "/o/oauth2/auth", | ||||
| 			// to get a refresh token. see https://developers.google.com/identity/protocols/OAuth2WebServer#offline
 | ||||
| 			RawQuery: "access_type=offline", | ||||
| 		} | ||||
| 	} | ||||
| 	if p.RedeemUrl.String() == "" { | ||||
| 		p.RedeemUrl = &url.URL{Scheme: "https", | ||||
| 	if p.RedeemURL.String() == "" { | ||||
| 		p.RedeemURL = &url.URL{Scheme: "https", | ||||
| 			Host: "www.googleapis.com", | ||||
| 			Path: "/oauth2/v3/token"} | ||||
| 	} | ||||
| 	if p.ValidateUrl.String() == "" { | ||||
| 		p.ValidateUrl = &url.URL{Scheme: "https", | ||||
| 	if p.ValidateURL.String() == "" { | ||||
| 		p.ValidateURL = &url.URL{Scheme: "https", | ||||
| 			Host: "www.googleapis.com", | ||||
| 			Path: "/oauth2/v1/tokeninfo"} | ||||
| 	} | ||||
|  | @ -96,20 +96,20 @@ func jwtDecodeSegment(seg string) ([]byte, error) { | |||
| 	return base64.URLEncoding.DecodeString(seg) | ||||
| } | ||||
| 
 | ||||
| func (p *GoogleProvider) Redeem(redirectUrl, code string) (s *SessionState, err error) { | ||||
| func (p *GoogleProvider) Redeem(redirectURL, code string) (s *SessionState, err error) { | ||||
| 	if code == "" { | ||||
| 		err = errors.New("missing code") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	params := url.Values{} | ||||
| 	params.Add("redirect_uri", redirectUrl) | ||||
| 	params.Add("redirect_uri", redirectURL) | ||||
| 	params.Add("client_id", p.ClientID) | ||||
| 	params.Add("client_secret", p.ClientSecret) | ||||
| 	params.Add("code", code) | ||||
| 	params.Add("grant_type", "authorization_code") | ||||
| 	var req *http.Request | ||||
| 	req, err = http.NewRequest("POST", p.RedeemUrl.String(), bytes.NewBufferString(params.Encode())) | ||||
| 	req, err = http.NewRequest("POST", p.RedeemURL.String(), bytes.NewBufferString(params.Encode())) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | @ -127,7 +127,7 @@ func (p *GoogleProvider) Redeem(redirectUrl, code string) (s *SessionState, err | |||
| 	} | ||||
| 
 | ||||
| 	if resp.StatusCode != 200 { | ||||
| 		err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemUrl.String(), body) | ||||
| 		err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemURL.String(), body) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | @ -281,7 +281,7 @@ func (p *GoogleProvider) redeemRefreshToken(refreshToken string) (token string, | |||
| 	params.Add("refresh_token", refreshToken) | ||||
| 	params.Add("grant_type", "refresh_token") | ||||
| 	var req *http.Request | ||||
| 	req, err = http.NewRequest("POST", p.RedeemUrl.String(), bytes.NewBufferString(params.Encode())) | ||||
| 	req, err = http.NewRequest("POST", p.RedeemURL.String(), bytes.NewBufferString(params.Encode())) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | @ -299,7 +299,7 @@ func (p *GoogleProvider) redeemRefreshToken(refreshToken string) (token string, | |||
| 	} | ||||
| 
 | ||||
| 	if resp.StatusCode != 200 { | ||||
| 		err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemUrl.String(), body) | ||||
| 		err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemURL.String(), body) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,10 +23,10 @@ func newGoogleProvider() *GoogleProvider { | |||
| 	return NewGoogleProvider( | ||||
| 		&ProviderData{ | ||||
| 			ProviderName: "", | ||||
| 			LoginUrl:     &url.URL{}, | ||||
| 			RedeemUrl:    &url.URL{}, | ||||
| 			ProfileUrl:   &url.URL{}, | ||||
| 			ValidateUrl:  &url.URL{}, | ||||
| 			LoginURL:     &url.URL{}, | ||||
| 			RedeemURL:    &url.URL{}, | ||||
| 			ProfileURL:   &url.URL{}, | ||||
| 			ValidateURL:  &url.URL{}, | ||||
| 			Scope:        ""}) | ||||
| } | ||||
| 
 | ||||
|  | @ -35,31 +35,31 @@ func TestGoogleProviderDefaults(t *testing.T) { | |||
| 	assert.NotEqual(t, nil, p) | ||||
| 	assert.Equal(t, "Google", p.Data().ProviderName) | ||||
| 	assert.Equal(t, "https://accounts.google.com/o/oauth2/auth?access_type=offline", | ||||
| 		p.Data().LoginUrl.String()) | ||||
| 		p.Data().LoginURL.String()) | ||||
| 	assert.Equal(t, "https://www.googleapis.com/oauth2/v3/token", | ||||
| 		p.Data().RedeemUrl.String()) | ||||
| 		p.Data().RedeemURL.String()) | ||||
| 	assert.Equal(t, "https://www.googleapis.com/oauth2/v1/tokeninfo", | ||||
| 		p.Data().ValidateUrl.String()) | ||||
| 	assert.Equal(t, "", p.Data().ProfileUrl.String()) | ||||
| 		p.Data().ValidateURL.String()) | ||||
| 	assert.Equal(t, "", p.Data().ProfileURL.String()) | ||||
| 	assert.Equal(t, "profile email", p.Data().Scope) | ||||
| } | ||||
| 
 | ||||
| func TestGoogleProviderOverrides(t *testing.T) { | ||||
| 	p := NewGoogleProvider( | ||||
| 		&ProviderData{ | ||||
| 			LoginUrl: &url.URL{ | ||||
| 			LoginURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/auth"}, | ||||
| 			RedeemUrl: &url.URL{ | ||||
| 			RedeemURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/token"}, | ||||
| 			ProfileUrl: &url.URL{ | ||||
| 			ProfileURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/profile"}, | ||||
| 			ValidateUrl: &url.URL{ | ||||
| 			ValidateURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/tokeninfo"}, | ||||
|  | @ -67,13 +67,13 @@ func TestGoogleProviderOverrides(t *testing.T) { | |||
| 	assert.NotEqual(t, nil, p) | ||||
| 	assert.Equal(t, "Google", p.Data().ProviderName) | ||||
| 	assert.Equal(t, "https://example.com/oauth/auth", | ||||
| 		p.Data().LoginUrl.String()) | ||||
| 		p.Data().LoginURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/token", | ||||
| 		p.Data().RedeemUrl.String()) | ||||
| 		p.Data().RedeemURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/profile", | ||||
| 		p.Data().ProfileUrl.String()) | ||||
| 		p.Data().ProfileURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/tokeninfo", | ||||
| 		p.Data().ValidateUrl.String()) | ||||
| 		p.Data().ValidateURL.String()) | ||||
| 	assert.Equal(t, "profile", p.Data().Scope) | ||||
| } | ||||
| 
 | ||||
|  | @ -94,7 +94,7 @@ func TestGoogleProviderGetEmailAddress(t *testing.T) { | |||
| 	}) | ||||
| 	assert.Equal(t, nil, err) | ||||
| 	var server *httptest.Server | ||||
| 	p.RedeemUrl, server = newRedeemServer(body) | ||||
| 	p.RedeemURL, server = newRedeemServer(body) | ||||
| 	defer server.Close() | ||||
| 
 | ||||
| 	session, err := p.Redeem("http://redirect/", "code1234") | ||||
|  | @ -131,7 +131,7 @@ func TestGoogleProviderGetEmailAddressInvalidEncoding(t *testing.T) { | |||
| 	}) | ||||
| 	assert.Equal(t, nil, err) | ||||
| 	var server *httptest.Server | ||||
| 	p.RedeemUrl, server = newRedeemServer(body) | ||||
| 	p.RedeemURL, server = newRedeemServer(body) | ||||
| 	defer server.Close() | ||||
| 
 | ||||
| 	session, err := p.Redeem("http://redirect/", "code1234") | ||||
|  | @ -150,7 +150,7 @@ func TestGoogleProviderGetEmailAddressInvalidJson(t *testing.T) { | |||
| 	}) | ||||
| 	assert.Equal(t, nil, err) | ||||
| 	var server *httptest.Server | ||||
| 	p.RedeemUrl, server = newRedeemServer(body) | ||||
| 	p.RedeemURL, server = newRedeemServer(body) | ||||
| 	defer server.Close() | ||||
| 
 | ||||
| 	session, err := p.Redeem("http://redirect/", "code1234") | ||||
|  | @ -169,7 +169,7 @@ func TestGoogleProviderGetEmailAddressEmailMissing(t *testing.T) { | |||
| 	}) | ||||
| 	assert.Equal(t, nil, err) | ||||
| 	var server *httptest.Server | ||||
| 	p.RedeemUrl, server = newRedeemServer(body) | ||||
| 	p.RedeemURL, server = newRedeemServer(body) | ||||
| 	defer server.Close() | ||||
| 
 | ||||
| 	session, err := p.Redeem("http://redirect/", "code1234") | ||||
|  |  | |||
|  | @ -11,10 +11,10 @@ import ( | |||
| 
 | ||||
| // validateToken returns true if token is valid
 | ||||
| func validateToken(p Provider, access_token string, header http.Header) bool { | ||||
| 	if access_token == "" || p.Data().ValidateUrl == nil { | ||||
| 	if access_token == "" || p.Data().ValidateURL == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	endpoint := p.Data().ValidateUrl.String() | ||||
| 	endpoint := p.Data().ValidateURL.String() | ||||
| 	if len(header) == 0 { | ||||
| 		params := url.Values{"access_token": {access_token}} | ||||
| 		endpoint = endpoint + "?" + params.Encode() | ||||
|  |  | |||
|  | @ -63,7 +63,7 @@ func NewValidateSessionStateTest() *ValidateSessionStateTest { | |||
| 	backend_url, _ := url.Parse(vt_test.backend.URL) | ||||
| 	vt_test.provider = &ValidateSessionStateTestProvider{ | ||||
| 		ProviderData: &ProviderData{ | ||||
| 			ValidateUrl: &url.URL{ | ||||
| 			ValidateURL: &url.URL{ | ||||
| 				Scheme: "http", | ||||
| 				Host:   backend_url.Host, | ||||
| 				Path:   "/oauth/tokeninfo", | ||||
|  | @ -99,10 +99,10 @@ func TestValidateSessionStateEmptyToken(t *testing.T) { | |||
| 	assert.Equal(t, false, validateToken(vt_test.provider, "", nil)) | ||||
| } | ||||
| 
 | ||||
| func TestValidateSessionStateEmptyValidateUrl(t *testing.T) { | ||||
| func TestValidateSessionStateEmptyValidateURL(t *testing.T) { | ||||
| 	vt_test := NewValidateSessionStateTest() | ||||
| 	defer vt_test.Close() | ||||
| 	vt_test.provider.Data().ValidateUrl = nil | ||||
| 	vt_test.provider.Data().ValidateURL = nil | ||||
| 	assert.Equal(t, false, validateToken(vt_test.provider, "foobar", nil)) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,23 +15,23 @@ type LinkedInProvider struct { | |||
| 
 | ||||
| func NewLinkedInProvider(p *ProviderData) *LinkedInProvider { | ||||
| 	p.ProviderName = "LinkedIn" | ||||
| 	if p.LoginUrl.String() == "" { | ||||
| 		p.LoginUrl = &url.URL{Scheme: "https", | ||||
| 	if p.LoginURL.String() == "" { | ||||
| 		p.LoginURL = &url.URL{Scheme: "https", | ||||
| 			Host: "www.linkedin.com", | ||||
| 			Path: "/uas/oauth2/authorization"} | ||||
| 	} | ||||
| 	if p.RedeemUrl.String() == "" { | ||||
| 		p.RedeemUrl = &url.URL{Scheme: "https", | ||||
| 	if p.RedeemURL.String() == "" { | ||||
| 		p.RedeemURL = &url.URL{Scheme: "https", | ||||
| 			Host: "www.linkedin.com", | ||||
| 			Path: "/uas/oauth2/accessToken"} | ||||
| 	} | ||||
| 	if p.ProfileUrl.String() == "" { | ||||
| 		p.ProfileUrl = &url.URL{Scheme: "https", | ||||
| 	if p.ProfileURL.String() == "" { | ||||
| 		p.ProfileURL = &url.URL{Scheme: "https", | ||||
| 			Host: "www.linkedin.com", | ||||
| 			Path: "/v1/people/~/email-address"} | ||||
| 	} | ||||
| 	if p.ValidateUrl.String() == "" { | ||||
| 		p.ValidateUrl = p.ProfileUrl | ||||
| 	if p.ValidateURL.String() == "" { | ||||
| 		p.ValidateURL = p.ProfileURL | ||||
| 	} | ||||
| 	if p.Scope == "" { | ||||
| 		p.Scope = "r_emailaddress r_basicprofile" | ||||
|  | @ -51,7 +51,7 @@ func (p *LinkedInProvider) GetEmailAddress(s *SessionState) (string, error) { | |||
| 	if s.AccessToken == "" { | ||||
| 		return "", errors.New("missing access token") | ||||
| 	} | ||||
| 	req, err := http.NewRequest("GET", p.ProfileUrl.String()+"?format=json", nil) | ||||
| 	req, err := http.NewRequest("GET", p.ProfileURL.String()+"?format=json", nil) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  |  | |||
|  | @ -12,15 +12,15 @@ func testLinkedInProvider(hostname string) *LinkedInProvider { | |||
| 	p := NewLinkedInProvider( | ||||
| 		&ProviderData{ | ||||
| 			ProviderName: "", | ||||
| 			LoginUrl:     &url.URL{}, | ||||
| 			RedeemUrl:    &url.URL{}, | ||||
| 			ProfileUrl:   &url.URL{}, | ||||
| 			ValidateUrl:  &url.URL{}, | ||||
| 			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().LoginURL, hostname) | ||||
| 		updateURL(p.Data().RedeemURL, hostname) | ||||
| 		updateURL(p.Data().ProfileURL, hostname) | ||||
| 	} | ||||
| 	return p | ||||
| } | ||||
|  | @ -47,32 +47,32 @@ func TestLinkedInProviderDefaults(t *testing.T) { | |||
| 	assert.NotEqual(t, nil, p) | ||||
| 	assert.Equal(t, "LinkedIn", p.Data().ProviderName) | ||||
| 	assert.Equal(t, "https://www.linkedin.com/uas/oauth2/authorization", | ||||
| 		p.Data().LoginUrl.String()) | ||||
| 		p.Data().LoginURL.String()) | ||||
| 	assert.Equal(t, "https://www.linkedin.com/uas/oauth2/accessToken", | ||||
| 		p.Data().RedeemUrl.String()) | ||||
| 		p.Data().RedeemURL.String()) | ||||
| 	assert.Equal(t, "https://www.linkedin.com/v1/people/~/email-address", | ||||
| 		p.Data().ProfileUrl.String()) | ||||
| 		p.Data().ProfileURL.String()) | ||||
| 	assert.Equal(t, "https://www.linkedin.com/v1/people/~/email-address", | ||||
| 		p.Data().ValidateUrl.String()) | ||||
| 		p.Data().ValidateURL.String()) | ||||
| 	assert.Equal(t, "r_emailaddress r_basicprofile", p.Data().Scope) | ||||
| } | ||||
| 
 | ||||
| func TestLinkedInProviderOverrides(t *testing.T) { | ||||
| 	p := NewLinkedInProvider( | ||||
| 		&ProviderData{ | ||||
| 			LoginUrl: &url.URL{ | ||||
| 			LoginURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/auth"}, | ||||
| 			RedeemUrl: &url.URL{ | ||||
| 			RedeemURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/token"}, | ||||
| 			ProfileUrl: &url.URL{ | ||||
| 			ProfileURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/profile"}, | ||||
| 			ValidateUrl: &url.URL{ | ||||
| 			ValidateURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/tokeninfo"}, | ||||
|  | @ -80,13 +80,13 @@ func TestLinkedInProviderOverrides(t *testing.T) { | |||
| 	assert.NotEqual(t, nil, p) | ||||
| 	assert.Equal(t, "LinkedIn", p.Data().ProviderName) | ||||
| 	assert.Equal(t, "https://example.com/oauth/auth", | ||||
| 		p.Data().LoginUrl.String()) | ||||
| 		p.Data().LoginURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/token", | ||||
| 		p.Data().RedeemUrl.String()) | ||||
| 		p.Data().RedeemURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/profile", | ||||
| 		p.Data().ProfileUrl.String()) | ||||
| 		p.Data().ProfileURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/tokeninfo", | ||||
| 		p.Data().ValidateUrl.String()) | ||||
| 		p.Data().ValidateURL.String()) | ||||
| 	assert.Equal(t, "profile", p.Data().Scope) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,23 +16,23 @@ func NewMyUsaProvider(p *ProviderData) *MyUsaProvider { | |||
| 	const myUsaHost string = "alpha.my.usa.gov" | ||||
| 
 | ||||
| 	p.ProviderName = "MyUSA" | ||||
| 	if p.LoginUrl.String() == "" { | ||||
| 		p.LoginUrl = &url.URL{Scheme: "https", | ||||
| 	if p.LoginURL.String() == "" { | ||||
| 		p.LoginURL = &url.URL{Scheme: "https", | ||||
| 			Host: myUsaHost, | ||||
| 			Path: "/oauth/authorize"} | ||||
| 	} | ||||
| 	if p.RedeemUrl.String() == "" { | ||||
| 		p.RedeemUrl = &url.URL{Scheme: "https", | ||||
| 	if p.RedeemURL.String() == "" { | ||||
| 		p.RedeemURL = &url.URL{Scheme: "https", | ||||
| 			Host: myUsaHost, | ||||
| 			Path: "/oauth/token"} | ||||
| 	} | ||||
| 	if p.ProfileUrl.String() == "" { | ||||
| 		p.ProfileUrl = &url.URL{Scheme: "https", | ||||
| 	if p.ProfileURL.String() == "" { | ||||
| 		p.ProfileURL = &url.URL{Scheme: "https", | ||||
| 			Host: myUsaHost, | ||||
| 			Path: "/api/v1/profile"} | ||||
| 	} | ||||
| 	if p.ValidateUrl.String() == "" { | ||||
| 		p.ValidateUrl = &url.URL{Scheme: "https", | ||||
| 	if p.ValidateURL.String() == "" { | ||||
| 		p.ValidateURL = &url.URL{Scheme: "https", | ||||
| 			Host: myUsaHost, | ||||
| 			Path: "/api/v1/tokeninfo"} | ||||
| 	} | ||||
|  | @ -44,7 +44,7 @@ func NewMyUsaProvider(p *ProviderData) *MyUsaProvider { | |||
| 
 | ||||
| func (p *MyUsaProvider) GetEmailAddress(s *SessionState) (string, error) { | ||||
| 	req, err := http.NewRequest("GET", | ||||
| 		p.ProfileUrl.String()+"?access_token="+s.AccessToken, nil) | ||||
| 		p.ProfileURL.String()+"?access_token="+s.AccessToken, nil) | ||||
| 	if err != nil { | ||||
| 		log.Printf("failed building request %s", err) | ||||
| 		return "", err | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ import ( | |||
| 	"github.com/bmizerany/assert" | ||||
| ) | ||||
| 
 | ||||
| func updateUrl(url *url.URL, hostname string) { | ||||
| func updateURL(url *url.URL, hostname string) { | ||||
| 	url.Scheme = "http" | ||||
| 	url.Host = hostname | ||||
| } | ||||
|  | @ -18,16 +18,16 @@ func testMyUsaProvider(hostname string) *MyUsaProvider { | |||
| 	p := NewMyUsaProvider( | ||||
| 		&ProviderData{ | ||||
| 			ProviderName: "", | ||||
| 			LoginUrl:     &url.URL{}, | ||||
| 			RedeemUrl:    &url.URL{}, | ||||
| 			ProfileUrl:   &url.URL{}, | ||||
| 			ValidateUrl:  &url.URL{}, | ||||
| 			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) | ||||
| 		updateURL(p.Data().LoginURL, hostname) | ||||
| 		updateURL(p.Data().RedeemURL, hostname) | ||||
| 		updateURL(p.Data().ProfileURL, hostname) | ||||
| 		updateURL(p.Data().ValidateURL, hostname) | ||||
| 	} | ||||
| 	return p | ||||
| } | ||||
|  | @ -53,32 +53,32 @@ func TestMyUsaProviderDefaults(t *testing.T) { | |||
| 	assert.NotEqual(t, nil, p) | ||||
| 	assert.Equal(t, "MyUSA", p.Data().ProviderName) | ||||
| 	assert.Equal(t, "https://alpha.my.usa.gov/oauth/authorize", | ||||
| 		p.Data().LoginUrl.String()) | ||||
| 		p.Data().LoginURL.String()) | ||||
| 	assert.Equal(t, "https://alpha.my.usa.gov/oauth/token", | ||||
| 		p.Data().RedeemUrl.String()) | ||||
| 		p.Data().RedeemURL.String()) | ||||
| 	assert.Equal(t, "https://alpha.my.usa.gov/api/v1/profile", | ||||
| 		p.Data().ProfileUrl.String()) | ||||
| 		p.Data().ProfileURL.String()) | ||||
| 	assert.Equal(t, "https://alpha.my.usa.gov/api/v1/tokeninfo", | ||||
| 		p.Data().ValidateUrl.String()) | ||||
| 		p.Data().ValidateURL.String()) | ||||
| 	assert.Equal(t, "profile.email", p.Data().Scope) | ||||
| } | ||||
| 
 | ||||
| func TestMyUsaProviderOverrides(t *testing.T) { | ||||
| 	p := NewMyUsaProvider( | ||||
| 		&ProviderData{ | ||||
| 			LoginUrl: &url.URL{ | ||||
| 			LoginURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/auth"}, | ||||
| 			RedeemUrl: &url.URL{ | ||||
| 			RedeemURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/token"}, | ||||
| 			ProfileUrl: &url.URL{ | ||||
| 			ProfileURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/profile"}, | ||||
| 			ValidateUrl: &url.URL{ | ||||
| 			ValidateURL: &url.URL{ | ||||
| 				Scheme: "https", | ||||
| 				Host:   "example.com", | ||||
| 				Path:   "/oauth/tokeninfo"}, | ||||
|  | @ -86,13 +86,13 @@ func TestMyUsaProviderOverrides(t *testing.T) { | |||
| 	assert.NotEqual(t, nil, p) | ||||
| 	assert.Equal(t, "MyUSA", p.Data().ProviderName) | ||||
| 	assert.Equal(t, "https://example.com/oauth/auth", | ||||
| 		p.Data().LoginUrl.String()) | ||||
| 		p.Data().LoginURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/token", | ||||
| 		p.Data().RedeemUrl.String()) | ||||
| 		p.Data().RedeemURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/profile", | ||||
| 		p.Data().ProfileUrl.String()) | ||||
| 		p.Data().ProfileURL.String()) | ||||
| 	assert.Equal(t, "https://example.com/oauth/tokeninfo", | ||||
| 		p.Data().ValidateUrl.String()) | ||||
| 		p.Data().ValidateURL.String()) | ||||
| 	assert.Equal(t, "profile", p.Data().Scope) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,10 +8,10 @@ type ProviderData struct { | |||
| 	ProviderName   string | ||||
| 	ClientID       string | ||||
| 	ClientSecret   string | ||||
| 	LoginUrl       *url.URL | ||||
| 	RedeemUrl      *url.URL | ||||
| 	ProfileUrl     *url.URL | ||||
| 	ValidateUrl    *url.URL | ||||
| 	LoginURL       *url.URL | ||||
| 	RedeemURL      *url.URL | ||||
| 	ProfileURL     *url.URL | ||||
| 	ValidateURL    *url.URL | ||||
| 	Scope          string | ||||
| 	ApprovalPrompt string | ||||
| } | ||||
|  |  | |||
|  | @ -13,20 +13,20 @@ import ( | |||
| 	"github.com/bitly/oauth2_proxy/cookie" | ||||
| ) | ||||
| 
 | ||||
| func (p *ProviderData) Redeem(redirectUrl, code string) (s *SessionState, err error) { | ||||
| func (p *ProviderData) Redeem(redirectURL, code string) (s *SessionState, err error) { | ||||
| 	if code == "" { | ||||
| 		err = errors.New("missing code") | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	params := url.Values{} | ||||
| 	params.Add("redirect_uri", redirectUrl) | ||||
| 	params.Add("redirect_uri", redirectURL) | ||||
| 	params.Add("client_id", p.ClientID) | ||||
| 	params.Add("client_secret", p.ClientSecret) | ||||
| 	params.Add("code", code) | ||||
| 	params.Add("grant_type", "authorization_code") | ||||
| 	var req *http.Request | ||||
| 	req, err = http.NewRequest("POST", p.RedeemUrl.String(), bytes.NewBufferString(params.Encode())) | ||||
| 	req, err = http.NewRequest("POST", p.RedeemURL.String(), bytes.NewBufferString(params.Encode())) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | @ -45,7 +45,7 @@ func (p *ProviderData) Redeem(redirectUrl, code string) (s *SessionState, err er | |||
| 	} | ||||
| 
 | ||||
| 	if resp.StatusCode != 200 { | ||||
| 		err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemUrl.String(), body) | ||||
| 		err = fmt.Errorf("got %d from %q %s", resp.StatusCode, p.RedeemURL.String(), body) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | @ -77,7 +77,7 @@ func (p *ProviderData) Redeem(redirectUrl, code string) (s *SessionState, err er | |||
| // GetLoginURL with typical oauth parameters
 | ||||
| func (p *ProviderData) GetLoginURL(redirectURI, finalRedirect string) string { | ||||
| 	var a url.URL | ||||
| 	a = *p.LoginUrl | ||||
| 	a = *p.LoginURL | ||||
| 	params, _ := url.ParseQuery(a.RawQuery) | ||||
| 	params.Set("redirect_uri", redirectURI) | ||||
| 	params.Set("approval_prompt", p.ApprovalPrompt) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue