|
5 | 5 | "encoding/hex"
|
6 | 6 | "encoding/json"
|
7 | 7 | "fmt"
|
| 8 | + "html/template" |
8 | 9 | "net/http"
|
9 |
| - "text/template" |
10 | 10 | "time"
|
11 | 11 |
|
12 | 12 | "golang.org/x/crypto/bcrypt"
|
@@ -39,13 +39,13 @@ func (s *Server) GetSession(w http.ResponseWriter, r *http.Request, req *saml.Id
|
39 | 39 | user := User{}
|
40 | 40 | if err := s.Store.Get(fmt.Sprintf("/users/%s", r.PostForm.Get("user")), &user); err != nil {
|
41 | 41 | s.logger.Printf("ERROR: User '%s' doesn't exists", r.PostForm.Get("user"))
|
42 |
| - s.sendLoginForm(w, r, req, "Invalid username or password") |
| 42 | + s.sendLoginForm(w, req, "Invalid username or password") |
43 | 43 | return nil
|
44 | 44 | }
|
45 | 45 |
|
46 | 46 | if err := bcrypt.CompareHashAndPassword(user.HashedPassword, []byte(r.PostForm.Get("password"))); err != nil {
|
47 | 47 | s.logger.Printf("ERROR: Invalid password for user '%s'", r.PostForm.Get("user"))
|
48 |
| - s.sendLoginForm(w, r, req, "Invalid username or password") |
| 48 | + s.sendLoginForm(w, req, "Invalid username or password") |
49 | 49 | return nil
|
50 | 50 | }
|
51 | 51 |
|
@@ -86,39 +86,44 @@ func (s *Server) GetSession(w http.ResponseWriter, r *http.Request, req *saml.Id
|
86 | 86 | session := &saml.Session{}
|
87 | 87 | if err := s.Store.Get(fmt.Sprintf("/sessions/%s", sessionCookie.Value), session); err != nil {
|
88 | 88 | if err == ErrNotFound {
|
89 |
| - s.sendLoginForm(w, r, req, "") |
| 89 | + s.sendLoginForm(w, req, "") |
90 | 90 | return nil
|
91 | 91 | }
|
92 | 92 | http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
93 | 93 | return nil
|
94 | 94 | }
|
95 | 95 |
|
96 | 96 | if saml.TimeNow().After(session.ExpireTime) {
|
97 |
| - s.sendLoginForm(w, r, req, "") |
| 97 | + s.sendLoginForm(w, req, "") |
98 | 98 | return nil
|
99 | 99 | }
|
100 | 100 | return session
|
101 | 101 | }
|
102 | 102 |
|
103 |
| - s.sendLoginForm(w, r, req, "") |
| 103 | + s.sendLoginForm(w, req, "") |
104 | 104 | return nil
|
105 | 105 | }
|
106 | 106 |
|
| 107 | +var defaultLoginFormTemplate = template.Must(template.New("saml-post-form").Parse(`` + |
| 108 | + `<html>` + |
| 109 | + `<p>{{.Toast}}</p>` + |
| 110 | + `<form method="post" action="{{.URL}}">` + |
| 111 | + `<input type="text" name="user" placeholder="user" value="" />` + |
| 112 | + `<input type="password" name="password" placeholder="password" value="" />` + |
| 113 | + `<input type="hidden" name="SAMLRequest" value="{{.SAMLRequest}}" />` + |
| 114 | + `<input type="hidden" name="RelayState" value="{{.RelayState}}" />` + |
| 115 | + `<input type="submit" value="Log In" />` + |
| 116 | + `</form>` + |
| 117 | + `</html>`)) |
| 118 | + |
107 | 119 | // sendLoginForm produces a form which requests a username and password and directs the user
|
108 | 120 | // back to the IDP authorize URL to restart the SAML login flow, this time establishing a
|
109 | 121 | // session based on the credentials that were provided.
|
110 |
| -func (s *Server) sendLoginForm(w http.ResponseWriter, _ *http.Request, req *saml.IdpAuthnRequest, toast string) { |
111 |
| - tmpl := template.Must(template.New("saml-post-form").Parse(`` + |
112 |
| - `<html>` + |
113 |
| - `<p>{{.Toast}}</p>` + |
114 |
| - `<form method="post" action="{{.URL}}">` + |
115 |
| - `<input type="text" name="user" placeholder="user" value="" />` + |
116 |
| - `<input type="password" name="password" placeholder="password" value="" />` + |
117 |
| - `<input type="hidden" name="SAMLRequest" value="{{.SAMLRequest}}" />` + |
118 |
| - `<input type="hidden" name="RelayState" value="{{.RelayState}}" />` + |
119 |
| - `<input type="submit" value="Log In" />` + |
120 |
| - `</form>` + |
121 |
| - `</html>`)) |
| 122 | +func (s *Server) sendLoginForm(w http.ResponseWriter, req *saml.IdpAuthnRequest, toast string) { |
| 123 | + tmpl := s.LoginFormTemplate |
| 124 | + if tmpl == nil { |
| 125 | + tmpl = defaultLoginFormTemplate |
| 126 | + } |
122 | 127 | data := struct {
|
123 | 128 | Toast string
|
124 | 129 | URL string
|
|
0 commit comments