diff --git a/core/app.go b/core/app.go index 256c307..f8f7386 100644 --- a/core/app.go +++ b/core/app.go @@ -82,8 +82,7 @@ func New(documentRoot, userRoot string) *Blog { // Initialize the router. r := mux.NewRouter() r.HandleFunc("/initial-setup", blog.SetupHandler) - r.HandleFunc("/login", blog.LoginHandler) - r.HandleFunc("/logout", blog.LogoutHandler) + blog.AuthRoutes(r) blog.AdminRoutes(r) blog.ContactRoutes(r) blog.BlogRoutes(r) diff --git a/core/auth.go b/core/auth.go index 30a6394..4ac67e1 100644 --- a/core/auth.go +++ b/core/auth.go @@ -4,10 +4,18 @@ import ( "errors" "net/http" + "github.com/gorilla/mux" "github.com/kirsle/blog/core/forms" "github.com/kirsle/blog/core/models/users" ) +// AuthRoutes attaches the auth routes to the app. +func (b *Blog) AuthRoutes(r *mux.Router) { + r.HandleFunc("/login", b.LoginHandler) + r.HandleFunc("/logout", b.LogoutHandler) + r.HandleFunc("/account", b.AccountHandler) +} + // Login logs the browser in as the given user. func (b *Blog) Login(w http.ResponseWriter, r *http.Request, u *users.User) error { session, err := b.store.Get(r, "session") // TODO session name @@ -75,3 +83,84 @@ func (b *Blog) LogoutHandler(w http.ResponseWriter, r *http.Request) { session.Save(r, w) b.Redirect(w, "/") } + +// AccountHandler shows the account settings page. +func (b *Blog) AccountHandler(w http.ResponseWriter, r *http.Request) { + if !b.LoggedIn(r) { + b.FlashAndRedirect(w, r, "/login?next=/account", "You must be logged in to do that!") + return + } + currentUser, err := b.CurrentUser(r) + if err != nil { + b.FlashAndRedirect(w, r, "/login?next=/account", "You must be logged in to do that!!") + return + } + + // Load an editable copy of the user. + user, err := users.Load(currentUser.ID) + if err != nil { + b.FlashAndRedirect(w, r, "/login?next=/account", "User ID %d not loadable?", currentUser.ID) + return + } + + v := NewVars() + form := &forms.Account{ + Username: user.Username, + Email: user.Email, + Name: user.Name, + } + v.Form = form + + if r.Method == http.MethodPost { + form.Username = users.Normalize(r.FormValue("username")) + form.Email = r.FormValue("email") + form.Name = r.FormValue("name") + form.OldPassword = r.FormValue("oldpassword") + form.NewPassword = r.FormValue("newpassword") + form.NewPassword2 = r.FormValue("newpassword2") + if err = form.Validate(); err != nil { + b.Flash(w, r, err.Error()) + } else { + var ok = true + + // Validate the username is available. + if form.Username != user.Username { + if _, err = users.LoadUsername(form.Username); err == nil { + b.Flash(w, r, "That username already exists.") + ok = false + } + } + + // Changing their password? + if len(form.OldPassword) > 0 { + // Validate their old password. + if _, err = users.CheckAuth(form.Username, form.OldPassword); err != nil { + b.Flash(w, r, "Your old password is incorrect.") + ok = false + } else { + err = user.SetPassword(form.NewPassword) + if err != nil { + b.Flash(w, r, "Change password error: %s", err) + ok = false + } + } + } + + // Still good? + if ok { + user.Username = form.Username + user.Name = form.Name + user.Email = form.Email + err = user.Save() + if err != nil { + b.Flash(w, r, "Error saving user: %s", err) + } else { + b.FlashAndRedirect(w, r, "/account", "Settings saved!") + return + } + } + } + } + + b.RenderTemplate(w, r, "account", v) +} diff --git a/core/forms/auth.go b/core/forms/auth.go index 007b3f0..320ba8d 100644 --- a/core/forms/auth.go +++ b/core/forms/auth.go @@ -19,3 +19,29 @@ func (f Login) Validate() error { } return nil } + +// Account is for updating account settings. +type Account struct { + Username string + OldPassword string + NewPassword string + NewPassword2 string + Email string + Name string +} + +// Validate the account form. +func (f Account) Validate() error { + if len(f.Username) == 0 { + return errors.New("username is required") + } + if len(f.OldPassword) > 0 && len(f.NewPassword) > 0 { + if f.NewPassword != f.NewPassword2 { + return errors.New("your passwords don't match") + } + } + if len(f.Name) == 0 { + f.Name = f.Username + } + return nil +} diff --git a/root/.layout.gohtml b/root/.layout.gohtml index 3a68721..fa8d95c 100644 --- a/root/.layout.gohtml +++ b/root/.layout.gohtml @@ -101,7 +101,7 @@
- Logged in as: {{ .CurrentUser.Username }} + Logged in as: {{ .CurrentUser.Username }}