git.iko.soy/typeable/oauth2-proxy
on master help sign in
implement an error alert message for invalid basic auth credentials
cbda3cfAlexandru Ciobanu
oauthproxy.go+8−8
@@ -568,26 +568,26 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
568 redirectURL = "/"
568 redirectURL = "/"
569 }
569 }
570
570
571− p.pageWriter.WriteSignInPage(rw, req, redirectURL)
571+ p.pageWriter.WriteSignInPage(rw, req, redirectURL, code)
572}
572}
573
573
574// ManualSignIn handles basic auth logins to the proxy
574// ManualSignIn handles basic auth logins to the proxy
575−func (p *OAuthProxy) ManualSignIn(req *http.Request) (string, bool) {
575+func (p *OAuthProxy) ManualSignIn(req *http.Request) (string, bool, int) {
576 if req.Method != "POST" || p.basicAuthValidator == nil {
576 if req.Method != "POST" || p.basicAuthValidator == nil {
577− return "", false
577+ return "", false, http.StatusOK
578 }
578 }
579 user := req.FormValue("username")
579 user := req.FormValue("username")
580 passwd := req.FormValue("password")
580 passwd := req.FormValue("password")
581 if user == "" {
581 if user == "" {
582− return "", false
582+ return "", false, http.StatusBadRequest
583 }
583 }
584 // check auth
584 // check auth
585 if p.basicAuthValidator.Validate(user, passwd) {
585 if p.basicAuthValidator.Validate(user, passwd) {
586 logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile")
586 logger.PrintAuthf(user, req, logger.AuthSuccess, "Authenticated via HtpasswdFile")
587− return user, true
587+ return user, true, http.StatusOK
588 }
588 }
589 logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via HtpasswdFile")
589 logger.PrintAuthf(user, req, logger.AuthFailure, "Invalid authentication via HtpasswdFile")
590− return "", false
590+ return "", false, http.StatusUnauthorized
591}
591}
592
592
593// SignIn serves a page prompting users to sign in
593// SignIn serves a page prompting users to sign in
@@ -599,7 +599,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
599 return
599 return
600 }
600 }
601
601
602− user, ok := p.ManualSignIn(req)
602+ user, ok, statusCode := p.ManualSignIn(req)
603 if ok {
603 if ok {
604 session := &sessionsapi.SessionState{User: user, Groups: p.basicAuthGroups}
604 session := &sessionsapi.SessionState{User: user, Groups: p.basicAuthGroups}
605 err = p.SaveSession(rw, req, session)
605 err = p.SaveSession(rw, req, session)
@@ -614,7 +614,7 @@ func (p *OAuthProxy) SignIn(rw http.ResponseWriter, req *http.Request) {
614 p.OAuthStart(rw, req)
614 p.OAuthStart(rw, req)
615 } else {
615 } else {
616 // TODO - should we pass on /oauth2/sign_in query params to /oauth2/start?
616 // TODO - should we pass on /oauth2/sign_in query params to /oauth2/start?
617− p.SignInPage(rw, req, http.StatusOK)
617+ p.SignInPage(rw, req, statusCode)
618 }
618 }
619 }
619 }
620}
620}
pkg/app/pagewriter/pagewriter.go+4−4
@@ -10,7 +10,7 @@ import (
10// It can also be used to write errors for the http.ReverseProxy used in the
10// It can also be used to write errors for the http.ReverseProxy used in the
11// upstream package.
11// upstream package.
12type Writer interface {
12type Writer interface {
13− WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string)
13+ WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int)
14 WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts)
14 WriteErrorPage(rw http.ResponseWriter, opts ErrorPageOpts)
15 ProxyErrorHandler(rw http.ResponseWriter, req *http.Request, proxyErr error)
15 ProxyErrorHandler(rw http.ResponseWriter, req *http.Request, proxyErr error)
16 WriteRobotsTxt(rw http.ResponseWriter, req *http.Request)
16 WriteRobotsTxt(rw http.ResponseWriter, req *http.Request)
@@ -108,7 +108,7 @@ func NewWriter(opts Opts) (Writer, error) {
108// If any of the funcs are not provided, a default implementation will be used.
108// If any of the funcs are not provided, a default implementation will be used.
109// This is primarily for us in testing.
109// This is primarily for us in testing.
110type WriterFuncs struct {
110type WriterFuncs struct {
111− SignInPageFunc func(rw http.ResponseWriter, req *http.Request, redirectURL string)
111+ SignInPageFunc func(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int)
112 ErrorPageFunc func(rw http.ResponseWriter, opts ErrorPageOpts)
112 ErrorPageFunc func(rw http.ResponseWriter, opts ErrorPageOpts)
113 ProxyErrorFunc func(rw http.ResponseWriter, req *http.Request, proxyErr error)
113 ProxyErrorFunc func(rw http.ResponseWriter, req *http.Request, proxyErr error)
114 RobotsTxtfunc func(rw http.ResponseWriter, req *http.Request)
114 RobotsTxtfunc func(rw http.ResponseWriter, req *http.Request)
@@ -117,9 +117,9 @@ type WriterFuncs struct {
117// WriteSignInPage implements the Writer interface.
117// WriteSignInPage implements the Writer interface.
118// If the SignInPageFunc is provided, this will be used, else a default
118// If the SignInPageFunc is provided, this will be used, else a default
119// implementation will be used.
119// implementation will be used.
120−func (w *WriterFuncs) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) {
120+func (w *WriterFuncs) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) {
121 if w.SignInPageFunc != nil {
121 if w.SignInPageFunc != nil {
122− w.SignInPageFunc(rw, req, redirectURL)
122+ w.SignInPageFunc(rw, req, redirectURL, statusCode)
123 return
123 return
124 }
124 }
125
125
pkg/app/pagewriter/sign_in.html+34
@@ -18,6 +18,28 @@
18 .logo-box {
18 .logo-box {
19 margin: 1.5rem 3rem;
19 margin: 1.5rem 3rem;
20 }
20 }
21+ .alert {
22+ padding: 5px;
23+ background-color: #f44336; /* Red */
24+ color: white;
25+ margin-bottom: 5px;
26+ border-radius: 5px
27+ }
28+ /* The close button */
29+ .closebtn {
30+ margin-left: 10px;
31+ color: white;
32+ font-weight: bold;
33+ float: right;
34+ font-size: 22px;
35+ line-height: 20px;
36+ cursor: pointer;
37+ transition: 0.3s;
38+ }
39+ /* When moving the mouse over the close button */
40+ .closebtn:hover {
41+ color: black;
42+ }
21 footer a {
43 footer a {
22 text-decoration: underline;
44 text-decoration: underline;
23 }
45 }
@@ -62,6 +84,18 @@
62 <button class="button is-primary">Sign in</button>
84 <button class="button is-primary">Sign in</button>
63 </form>
85 </form>
64 {{ end }}
86 {{ end }}
87+
88+ {{ if eq .StatusCode 400 401 }}
89+ <div class="alert">
90+ <span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
91+ {{ if eq .StatusCode 400 }}
92+ {{.StatusCode}}: Username cannot be empty
93+ {{ else }}
94+ {{.StatusCode}}: Invalid Username or Password
95+ {{ end }}
96+ </div>
97+ {{ end }}
98+
65 </div>
99 </div>
66 </section>
100 </section>
67
101
pkg/app/pagewriter/sign_in_page.go+3−1
@@ -54,12 +54,13 @@ type signInPageWriter struct {
54
54
55// WriteSignInPage writes the sign-in page to the given response writer.
55// WriteSignInPage writes the sign-in page to the given response writer.
56// It uses the redirectURL to be able to set the final destination for the user post login.
56// It uses the redirectURL to be able to set the final destination for the user post login.
57−func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string) {
57+func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Request, redirectURL string, statusCode int) {
58 // We allow unescaped template.HTML since it is user configured options
58 // We allow unescaped template.HTML since it is user configured options
59 /* #nosec G203 */
59 /* #nosec G203 */
60 t := struct {
60 t := struct {
61 ProviderName string
61 ProviderName string
62 SignInMessage template.HTML
62 SignInMessage template.HTML
63+ StatusCode int
63 CustomLogin bool
64 CustomLogin bool
64 Redirect string
65 Redirect string
65 Version string
66 Version string
@@ -69,6 +70,7 @@ func (s *signInPageWriter) WriteSignInPage(rw http.ResponseWriter, req *http.Req
69 }{
70 }{
70 ProviderName: s.providerName,
71 ProviderName: s.providerName,
71 SignInMessage: template.HTML(s.signInMessage),
72 SignInMessage: template.HTML(s.signInMessage),
73+ StatusCode: statusCode,
72 CustomLogin: s.displayLoginForm,
74 CustomLogin: s.displayLoginForm,
73 Redirect: redirectURL,
75 Redirect: redirectURL,
74 Version: s.version,
76 Version: s.version,