implement an error alert message for invalid basic auth credentials
This commit is contained in:
		
							parent
							
								
									db74661e10
								
							
						
					
					
						commit
						cbda3cf618
					
				|  | @ -568,26 +568,26 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code | ||||||
| 		redirectURL = "/" | 		redirectURL = "/" | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	p.pageWriter.WriteSignInPage(rw, req, redirectURL) | 	p.pageWriter.WriteSignInPage(rw, req, redirectURL, code) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ManualSignIn handles basic auth logins to the proxy
 | // ManualSignIn handles basic auth logins to the proxy
 | ||||||
| func (p *OAuthProxy) ManualSignIn(req *http.Request) (string, bool) { | func (p *OAuthProxy) ManualSignIn(req *http.Request) (string, bool, int) { | ||||||
| 	if req.Method != "POST" || p.basicAuthValidator == nil { | 	if req.Method != "POST" || p.basicAuthValidator == nil { | ||||||
| 		return "", false | 		return "", false, http.StatusOK | ||||||
| 	} | 	} | ||||||
| 	user := req.FormValue("username") | 	user := req.FormValue("username") | ||||||
| 	passwd := req.FormValue("password") | 	passwd := req.FormValue("password") | ||||||
| 	if user == "" { | 	if user == "" { | ||||||
| 		return "", false | 		return "", false, http.StatusBadRequest | ||||||
| 	} | 	} | ||||||
| 	// check auth
 | 	// check auth
 | ||||||
| 	if p.basicAuthValidator.Validate(user, passwd) { | 	if p.basicAuthValidator.Validate(user, passwd) { | ||||||
| 		logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile") | 		logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile") | ||||||
| 		return user, true | 		return user, true, http.StatusOK | ||||||
| 	} | 	} | ||||||
| 	logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via HtpasswdFile") | 	logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via HtpasswdFile") | ||||||
| 	return "", false | 	return "", false, http.StatusUnauthorized | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SignIn serves a page prompting users to sign in
 | // SignIn serves a page prompting users to sign in
 | ||||||
|  | @ -599,7 +599,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	user, ok := p.ManualSignIn(req) | 	user, ok, statusCode := p.ManualSignIn(req) | ||||||
| 	if ok { | 	if ok { | ||||||
| 		session := &sessionsapi.SessionState{User: user, Groups: p.basicAuthGroups} | 		session := &sessionsapi.SessionState{User: user, Groups: p.basicAuthGroups} | ||||||
| 		err = p.SaveSession(rw, req, session) | 		err = p.SaveSession(rw, req, session) | ||||||
|  | @ -614,7 +614,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) { | ||||||
| 			p.OAuthStart(rw, req) | 			p.OAuthStart(rw, req) | ||||||
| 		} else { | 		} else { | ||||||
| 			// TODO - should we pass on /oauth2/sign_in query params to /oauth2/start?
 | 			// TODO - should we pass on /oauth2/sign_in query params to /oauth2/start?
 | ||||||
| 			p.SignInPage(rw, req, http.StatusOK) | 			p.SignInPage(rw, req, statusCode) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -10,7 +10,7 @@ import ( | ||||||
| // It can also be used to write errors for the http.ReverseProxy used in the
 | // It can also be used to write errors for the http.ReverseProxy used in the
 | ||||||
| // upstream package.
 | // upstream package.
 | ||||||
| type Writer interface { | type Writer interface { | ||||||
| 	WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) | 	WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) | ||||||
| 	WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts) | 	WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts) | ||||||
| 	ProxyErrorHandler(rw http.ResponseWriter, req *http.Request, proxyErr error) | 	ProxyErrorHandler(rw http.ResponseWriter, req *http.Request, proxyErr error) | ||||||
| 	WriteRobotsTxt(rw http.ResponseWriter, req *http.Request) | 	WriteRobotsTxt(rw http.ResponseWriter, req *http.Request) | ||||||
|  | @ -108,7 +108,7 @@ func NewWriter(opts Opts) (Writer, error) { | ||||||
| // If any of the funcs are not provided, a default implementation will be used.
 | // If any of the funcs are not provided, a default implementation will be used.
 | ||||||
| // This is primarily for us in testing.
 | // This is primarily for us in testing.
 | ||||||
| type WriterFuncs struct { | type WriterFuncs struct { | ||||||
| 	SignInPageFunc func(rw http.ResponseWriter, req *http.Request, redirectURL string) | 	SignInPageFunc func(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) | ||||||
| 	ErrorPageFunc  func(rw http.ResponseWriter, opts ErrorPageOpts) | 	ErrorPageFunc  func(rw http.ResponseWriter, opts ErrorPageOpts) | ||||||
| 	ProxyErrorFunc func(rw http.ResponseWriter, req *http.Request, proxyErr error) | 	ProxyErrorFunc func(rw http.ResponseWriter, req *http.Request, proxyErr error) | ||||||
| 	RobotsTxtfunc  func(rw http.ResponseWriter, req *http.Request) | 	RobotsTxtfunc  func(rw http.ResponseWriter, req *http.Request) | ||||||
|  | @ -117,9 +117,9 @@ type WriterFuncs struct { | ||||||
| // WriteSignInPage implements the Writer interface.
 | // WriteSignInPage implements the Writer interface.
 | ||||||
| // If the SignInPageFunc is provided, this will be used, else a default
 | // If the SignInPageFunc is provided, this will be used, else a default
 | ||||||
| // implementation will be used.
 | // implementation will be used.
 | ||||||
| func (w *WriterFuncs) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) { | func (w *WriterFuncs) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) { | ||||||
| 	if w.SignInPageFunc != nil { | 	if w.SignInPageFunc != nil { | ||||||
| 		w.SignInPageFunc(rw, req, redirectURL) | 		w.SignInPageFunc(rw, req, redirectURL, statusCode) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -18,6 +18,28 @@ | ||||||
|       .logo-box { |       .logo-box { | ||||||
|         margin: 1.5rem 3rem; |         margin: 1.5rem 3rem; | ||||||
|       } |       } | ||||||
|  |       .alert { | ||||||
|  |         padding: 5px; | ||||||
|  |         background-color: #f44336; /* Red */ | ||||||
|  |         color: white; | ||||||
|  |         margin-bottom: 5px; | ||||||
|  |         border-radius: 5px | ||||||
|  |       } | ||||||
|  |       /* The close button */ | ||||||
|  |       .closebtn { | ||||||
|  |         margin-left: 10px; | ||||||
|  |         color: white; | ||||||
|  |         font-weight: bold; | ||||||
|  |         float: right; | ||||||
|  |         font-size: 22px; | ||||||
|  |         line-height: 20px; | ||||||
|  |         cursor: pointer; | ||||||
|  |         transition: 0.3s; | ||||||
|  |       } | ||||||
|  |       /* When moving the mouse over the close button */ | ||||||
|  |       .closebtn:hover { | ||||||
|  |         color: black; | ||||||
|  |       } | ||||||
|       footer a { |       footer a { | ||||||
|         text-decoration: underline; |         text-decoration: underline; | ||||||
|       } |       } | ||||||
|  | @ -62,6 +84,18 @@ | ||||||
|         <button class="button is-primary">Sign in</button> |         <button class="button is-primary">Sign in</button> | ||||||
|       </form> |       </form> | ||||||
|       {{ end }} |       {{ end }} | ||||||
|  | 
 | ||||||
|  |       {{ if eq .StatusCode 400 401 }} | ||||||
|  |       <div class="alert"> | ||||||
|  |         <span class="closebtn" onclick="this.parentElement.style.display='none';">×</span> | ||||||
|  |         {{ if eq .StatusCode 400 }} | ||||||
|  |         {{.StatusCode}}: Username cannot be empty | ||||||
|  |         {{ else }} | ||||||
|  |         {{.StatusCode}}: Invalid Username or Password | ||||||
|  |         {{ end }} | ||||||
|  |       </div>  | ||||||
|  |       {{ end }} | ||||||
|  | 
 | ||||||
|     </div> |     </div> | ||||||
|   </section> |   </section> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -54,12 +54,13 @@ type signInPageWriter struct { | ||||||
| 
 | 
 | ||||||
| // WriteSignInPage writes the sign-in page to the given response writer.
 | // WriteSignInPage writes the sign-in page to the given response writer.
 | ||||||
| // It uses the redirectURL to be able to set the final destination for the user post login.
 | // It uses the redirectURL to be able to set the final destination for the user post login.
 | ||||||
| func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) { | func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) { | ||||||
| 	// We allow unescaped template.HTML since it is user configured options
 | 	// We allow unescaped template.HTML since it is user configured options
 | ||||||
| 	/* #nosec G203 */ | 	/* #nosec G203 */ | ||||||
| 	t := struct { | 	t := struct { | ||||||
| 		ProviderName  string | 		ProviderName  string | ||||||
| 		SignInMessage template.HTML | 		SignInMessage template.HTML | ||||||
|  | 		StatusCode    int | ||||||
| 		CustomLogin   bool | 		CustomLogin   bool | ||||||
| 		Redirect      string | 		Redirect      string | ||||||
| 		Version       string | 		Version       string | ||||||
|  | @ -69,6 +70,7 @@ func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Req | ||||||
| 	}{ | 	}{ | ||||||
| 		ProviderName:  s.providerName, | 		ProviderName:  s.providerName, | ||||||
| 		SignInMessage: template.HTML(s.signInMessage), | 		SignInMessage: template.HTML(s.signInMessage), | ||||||
|  | 		StatusCode:    statusCode, | ||||||
| 		CustomLogin:   s.displayLoginForm, | 		CustomLogin:   s.displayLoginForm, | ||||||
| 		Redirect:      redirectURL, | 		Redirect:      redirectURL, | ||||||
| 		Version:       s.version, | 		Version:       s.version, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue