diff --git a/admin.go b/admin.go index fdbb82f..5b3acab 100644 --- a/admin.go +++ b/admin.go @@ -16,12 +16,14 @@ import ( "net/http" "runtime" "strconv" + "strings" "time" "github.com/gorilla/mux" "github.com/writeas/impart" "github.com/writeas/web-core/auth" "github.com/writeas/web-core/log" + "github.com/writeas/web-core/passgen" "github.com/writeas/writefreely/appstats" "github.com/writeas/writefreely/config" ) @@ -167,25 +169,34 @@ func handleViewAdminUser(app *App, u *User, w http.ResponseWriter, r *http.Reque p := struct { *UserPage - Config config.AppCfg - Message string + Config config.AppCfg + Message string + OwnUserPage bool - User *User - Colls []inspectedCollection - LastPost string - - TotalPosts int64 + User *User + Colls []inspectedCollection + LastPost string + NewPassword string + TotalPosts int64 }{ Config: app.cfg.App, Message: r.FormValue("m"), Colls: []inspectedCollection{}, } + flashes, _ := getSessionFlashes(app, w, r, nil) + for _, flash := range flashes { + if strings.HasPrefix(flash, "SUCCESS: ") { + p.NewPassword = strings.TrimPrefix(flash, "SUCCESS: ") + } + } + var err error p.User, err = app.db.GetUserForAuth(username) if err != nil { return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get user: %v", err)} } + p.OwnUserPage = u.ID == p.User.ID p.UserPage = NewUserPage(app, r, u, p.User.Username, nil) p.TotalPosts = app.db.GetUserPostsCount(p.User.ID) lp, err := app.db.GetUserLastPostTime(p.User.ID) @@ -230,6 +241,37 @@ func handleViewAdminUser(app *App, u *User, w http.ResponseWriter, r *http.Reque return nil } +func handleAdminResetUserPass(app *App, u *User, w http.ResponseWriter, r *http.Request) error { + vars := mux.Vars(r) + username := vars["username"] + if username == "" { + return impart.HTTPError{http.StatusFound, "/admin/users"} + } + // Generate new random password since none supplied + pass := passgen.New() + hashedPass, err := auth.HashPass([]byte(pass)) + if err != nil { + return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not create password hash: %v", err)} + } + + userIDVal := r.FormValue("user") + log.Info("ADMIN: Changing user %s password", userIDVal) + id, err := strconv.Atoi(userIDVal) + if err != nil { + return impart.HTTPError{http.StatusBadRequest, fmt.Sprintf("Invalid user ID: %v", err)} + } + + err = app.db.ChangePassphrase(int64(id), true, "", hashedPass) + if err != nil { + return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not update passphrase: %v", err)} + } + log.Info("ADMIN: Successfully changed.") + + addSessionFlash(app, w, r, fmt.Sprintf("SUCCESS: %s", pass), nil) + + return impart.HTTPError{http.StatusFound, fmt.Sprintf("/admin/user/%s", username)} +} + func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Request) error { p := struct { *UserPage diff --git a/routes.go b/routes.go index 0113e93..003b7d1 100644 --- a/routes.go +++ b/routes.go @@ -144,6 +144,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router { write.HandleFunc("/admin", handler.Admin(handleViewAdminDash)).Methods("GET") write.HandleFunc("/admin/users", handler.Admin(handleViewAdminUsers)).Methods("GET") write.HandleFunc("/admin/user/{username}", handler.Admin(handleViewAdminUser)).Methods("GET") + write.HandleFunc("/admin/user/{username}", handler.Admin(handleAdminResetUserPass)).Methods("POST") write.HandleFunc("/admin/pages", handler.Admin(handleViewAdminPages)).Methods("GET") write.HandleFunc("/admin/page/{slug}", handler.Admin(handleViewAdminPage)).Methods("GET") write.HandleFunc("/admin/update/config", handler.AdminApper(handleAdminUpdateConfig)).Methods("POST") diff --git a/templates/user/admin/view-user.tmpl b/templates/user/admin/view-user.tmpl index 2a74e5b..211297d 100644 --- a/templates/user/admin/view-user.tmpl +++ b/templates/user/admin/view-user.tmpl @@ -7,12 +7,32 @@ table.classy th { h3 { font-weight: normal; } +input.copy-text { + text-align: center; + font-size: 1.2em; + color: #555; + margin-left: 1rem; +} +button[type="submit"].danger { + padding-left: 2rem; + padding-right: 2rem; +}
New password for user {{.User.Username}} is
+
+
+ You must share this new password with the user, this is the only time it will be displayed.
+
No. | @@ -38,6 +58,21 @@ h3 {Last Post | {{if .LastPost}}{{.LastPost}}{{else}}Never{{end}} |
---|---|---|
Password | ++ {{if not .OwnUserPage}} + + {{else}} + Change your password + {{end}} + | +