(incomplete) change password feature
This commit is contained in:
parent
5531ef6bab
commit
0052c470f9
8 changed files with 76 additions and 25 deletions
|
@ -3,6 +3,7 @@ package admin
|
|||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -13,13 +14,22 @@ import (
|
|||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type TemplateData struct {
|
||||
type loginRegisterResponse struct {
|
||||
Account *model.Account
|
||||
Message string
|
||||
Token string
|
||||
}
|
||||
|
||||
func AccountHandler(app *model.AppState) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("/password", changePasswordHandler(app))
|
||||
mux.Handle("/", accountIndexHandler(app))
|
||||
|
||||
return mux
|
||||
}
|
||||
|
||||
func accountIndexHandler(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
account := r.Context().Value("account").(*model.Account)
|
||||
|
||||
|
@ -29,14 +39,18 @@ func AccountHandler(app *model.AppState) http.Handler {
|
|||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
type AccountResponse struct {
|
||||
type accountResponse struct {
|
||||
Account *model.Account
|
||||
TOTPs []model.TOTP
|
||||
Message string
|
||||
Error string
|
||||
}
|
||||
|
||||
err = pages["account"].Execute(w, AccountResponse{
|
||||
err = pages["account"].Execute(w, accountResponse{
|
||||
Account: account,
|
||||
TOTPs: totps,
|
||||
Message: r.URL.Query().Get("message"),
|
||||
Error: r.URL.Query().Get("error"),
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Failed to render admin account page: %v\n", err)
|
||||
|
@ -59,7 +73,7 @@ func LoginHandler(app *model.AppState) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
err = pages["login"].Execute(w, TemplateData{})
|
||||
err = pages["login"].Execute(w, loginRegisterResponse{})
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Error rendering admin login page: %s\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
|
@ -213,12 +227,12 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
type CreateAccountResponse struct {
|
||||
type CreateaccountResponse struct {
|
||||
Account *model.Account
|
||||
Message string
|
||||
}
|
||||
|
||||
render := func(data CreateAccountResponse) {
|
||||
render := func(data CreateaccountResponse) {
|
||||
err := pages["create-account"].Execute(w, data)
|
||||
if err != nil {
|
||||
fmt.Printf("WARN: Error rendering create account page: %s\n", err)
|
||||
|
@ -227,7 +241,7 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
}
|
||||
|
||||
if r.Method == http.MethodGet {
|
||||
render(CreateAccountResponse{})
|
||||
render(CreateaccountResponse{})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -238,7 +252,7 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
|
||||
err = r.ParseForm()
|
||||
if err != nil {
|
||||
render(CreateAccountResponse{
|
||||
render(CreateaccountResponse{
|
||||
Message: "Malformed data.",
|
||||
})
|
||||
return
|
||||
|
@ -261,7 +275,7 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
invite, err := controller.GetInvite(app.DB, credentials.Invite)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to retrieve invite: %v\n", err)
|
||||
render(CreateAccountResponse{
|
||||
render(CreateaccountResponse{
|
||||
Message: "Something went wrong. Please try again.",
|
||||
})
|
||||
return
|
||||
|
@ -271,7 +285,7 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
err := controller.DeleteInvite(app.DB, invite.Code)
|
||||
if err != nil { fmt.Fprintf(os.Stderr, "WARN: Failed to delete expired invite: %v\n", err) }
|
||||
}
|
||||
render(CreateAccountResponse{
|
||||
render(CreateaccountResponse{
|
||||
Message: "Invalid invite code.",
|
||||
})
|
||||
return
|
||||
|
@ -280,7 +294,7 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(credentials.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to generate password hash: %v\n", err)
|
||||
render(CreateAccountResponse{
|
||||
render(CreateaccountResponse{
|
||||
Message: "Something went wrong. Please try again.",
|
||||
})
|
||||
return
|
||||
|
@ -295,13 +309,13 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
err = controller.CreateAccount(app.DB, &account)
|
||||
if err != nil {
|
||||
if strings.HasPrefix(err.Error(), "pq: duplicate key") {
|
||||
render(CreateAccountResponse{
|
||||
render(CreateaccountResponse{
|
||||
Message: "An account with that username already exists.",
|
||||
})
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to create account: %v\n", err)
|
||||
render(CreateAccountResponse{
|
||||
render(CreateaccountResponse{
|
||||
Message: "Something went wrong. Please try again.",
|
||||
})
|
||||
return
|
||||
|
@ -330,14 +344,41 @@ func createAccountHandler(app *model.AppState) http.Handler {
|
|||
cookie.Path = "/"
|
||||
http.SetCookie(w, &cookie)
|
||||
|
||||
err = pages["login"].Execute(w, TemplateData{
|
||||
err = pages["login"].Execute(w, loginRegisterResponse{
|
||||
Account: &account,
|
||||
Token: token.Token,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "WARN: Failed to render login page: %v\n", err)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func changePasswordHandler(app *model.AppState) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
account := r.Context().Value("account").(*model.Account)
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
currentPassword := r.Form.Get("current-password")
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(account.Password), []byte(currentPassword)); err != nil {
|
||||
http.Redirect(w, r, "/admin/account?error=" + url.PathEscape("Incorrect password."), http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
newPassword := r.Form.Get("new-password")
|
||||
|
||||
http.Redirect(
|
||||
w, r, "/admin/account?message=" +
|
||||
url.PathEscape(fmt.Sprintf("Updating password to <code>%s</code>", newPassword)),
|
||||
http.StatusFound,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue