From 3b49837d167e8770f1054457e172c36109169e51 Mon Sep 17 00:00:00 2001 From: Thibaut Horel Date: Mon, 31 Dec 2018 09:05:29 -0500 Subject: Add password change feature --- main.go | 38 +++++++++++++++++++++++++++++++++++++- store.go | 7 ++++++- templates/index.tmpl | 2 +- templates/login.tmpl | 5 +++-- templates/password.tmpl | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 templates/password.tmpl diff --git a/main.go b/main.go index 86fd969..10815a5 100644 --- a/main.go +++ b/main.go @@ -59,7 +59,6 @@ func (app *App) rootHandler(w http.ResponseWriter, r *http.Request) { func (app *App) loginHandler(w http.ResponseWriter, r *http.Request) { if _, ok := app.validate(r); ok { http.Redirect(w, r, "/", http.StatusSeeOther) - return } else if r.Method == http.MethodPost { username := r.FormValue("username") hash := md5hex([]byte(r.FormValue("password"))) @@ -95,6 +94,42 @@ func (app *App) loginHandler(w http.ResponseWriter, r *http.Request) { } } +type Flash struct { + Type string + Value string +} + +func (app *App) passwordHandler(w http.ResponseWriter, r *http.Request) { + if s, ok := app.validate(r); !ok { + http.Redirect(w, r, "/login", http.StatusSeeOther) + return + } else if r.Method == http.MethodGet { + app.Template.ExecuteTemplate(w, "password.tmpl", Flash{}) + } else if r.Method == http.MethodPost { + password := r.FormValue("password") + confirm := r.FormValue("confirm") + if password != "" && password == confirm { + hash := md5hex([]byte(password)) + app.ChangePassword(s.UserId, hash) + app.Template.ExecuteTemplate(w, "password.tmpl", Flash{ + "success", + "Mot de passe enregistré", + }) + } else { + var bad string + if password != confirm { + bad = "Les deux mots de passe ne coïncident pas" + } else if password == "" { + bad = "Le mot de passe est vide" + } + app.Template.ExecuteTemplate(w, "password.tmpl", Flash{ + "danger", + bad, + }) + } + } +} + func (app *App) logoutHandler(w http.ResponseWriter, r *http.Request) { if s, ok := app.validate(r); ok { // should we save old sessions in another table? @@ -142,6 +177,7 @@ func main() { http.HandleFunc("/login", app.loginHandler) http.HandleFunc("/logout", app.logoutHandler) http.HandleFunc("/", app.rootHandler) + http.HandleFunc("/password", app.passwordHandler) if err := http.ListenAndServe(*address, logMux(http.DefaultServeMux)); err != nil { panic(err) } diff --git a/store.go b/store.go index 5e76cfc..d830150 100644 --- a/store.go +++ b/store.go @@ -25,6 +25,7 @@ type Store interface { NewSession(userId int64) *Session GetUser(name string) (*User, bool) DeleteSession(id string) + ChangePassword(userId int64, hash []byte) } type PgStore struct { @@ -68,10 +69,14 @@ func (store *PgStore) NewSession(userId int64) *Session { } func (store *PgStore) DeleteSession(id string) { - store.Query("DELETE FROM sessions WHERE id = $1", id) + store.Exec("DELETE FROM sessions WHERE id = $1", id) delete(store.sessionCache, id) } +func (store *PgStore) ChangePassword(userId int64, hash []byte) { + store.Exec("UPDATE users SET password=$1 WHERE id=$2", hash, userId) +} + func (store *PgStore) GetUser(name string) (*User, bool) { u := &User{Name: name} row := store.QueryRow( diff --git a/templates/index.tmpl b/templates/index.tmpl index 8f6a3b9..d72d562 100644 --- a/templates/index.tmpl +++ b/templates/index.tmpl @@ -18,7 +18,7 @@ button:hover {background-color: #1967be; border-color: #1862b5} -

Logout

+

Changer le mot de passe Logout

{{.Id}} {{.Created}}

diff --git a/templates/login.tmpl b/templates/login.tmpl index a78fdc1..8854695 100644 --- a/templates/login.tmpl +++ b/templates/login.tmpl @@ -9,7 +9,8 @@ body{margin: 0 auto; width: 400px; padding-top: 10em; font-family: "Source Sans form > hr{border: none; border-top: 1px solid #e6e6e6; margin: 1.3em 0;} form > h4{font-weight: 300; font-size: 19px; margin-bottom: 0} label {font-weight: bold; text-align: right;} form > div {display: grid; grid-template-columns: 2fr 5fr; grid-gap: 1em 1em; align-items: center;} -form .alert { background-color: #ff0039; grid-column: 1 / 3; color: white; padding: 0.8em 1em} +form .danger { background-color: #f8d7da; grid-column: 1 / 3; color: #721c24; padding: 0.8em 1em} +form .success { background-color: #d4edda; grid-column: 1 / 3; color: #155724; padding: 0.8em 1em} input, button {font-size: inherit; font-family: inherit; line-height: inherit; padding: 0.8em 1em; border-radius: 0} input {border: 1px solid #cccccc; transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s} input:focus {border-color: #66afe9; outline: 0; box-shadow: inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)} @@ -29,7 +30,7 @@ button:hover {background-color: #1967be; border-color: #1862b5} - {{ if .Flash }}
{{.Flash}}
{{end}} + {{ if .Flash }}
{{.Flash}}
{{end}} diff --git a/templates/password.tmpl b/templates/password.tmpl new file mode 100644 index 0000000..8b5e8cf --- /dev/null +++ b/templates/password.tmpl @@ -0,0 +1,40 @@ + + + + + + + + + + +
+

Mot de passe

+
+
+ + + + + + + {{ if .Value }}
{{.Value}}
{{end}} + +
+
+
+ + + -- cgit v1.2.3-70-g09d2