diff --git a/account.go b/account.go index c8e946a..5e5f03e 100644 --- a/account.go +++ b/account.go @@ -1069,6 +1069,6 @@ func getTempInfo(app *App, key string, r *http.Request, w http.ResponseWriter) s return s } -func deleteAccount(app *App, userID int64, posts bool) error { - return app.db.DeleteAccount(userID, posts) +func deleteAccount(app *App, userID int64) error { + return app.db.DeleteAccount(userID) } diff --git a/app.go b/app.go index 8e8471f..e793902 100644 --- a/app.go +++ b/app.go @@ -682,40 +682,43 @@ func ResetPassword(apper Apper, username string) error { } // DoDeleteAccount runs the confirmation and account delete process. -func DoDeleteAccount(apper Apper, userID int64, posts bool) error { +func DoDeleteAccount(apper Apper, username string) error { // Connect to the database apper.LoadConfig() connectToDatabase(apper.App()) defer shutdown(apper.App()) - // do not delete the root admin account - // TODO: check for other admins and skip? - if userID == 1 { - log.Error("Can not delete admin account") - os.Exit(1) - } // check user exists - if _, err := apper.App().db.GetUserByID(userID); err != nil { + u, err := apper.App().db.GetUserForAuth(username) + if err != nil { log.Error("%s", err) os.Exit(1) } + userID := u.ID + + // do not delete the admin account + // TODO: check for other admins and skip? + if u.IsAdmin() { + log.Error("Can not delete admin account") + os.Exit(1) + } // confirm deletion, w/ w/out posts prompt := promptui.Prompt{ Templates: &promptui.PromptTemplates{ Success: "{{ . | bold | faint }}: ", }, - Label: fmt.Sprintf("Delete user with ID: %d", userID), + Label: fmt.Sprintf("Really delete user : %s", username), IsConfirm: true, } - _, err := prompt.Run() + _, err = prompt.Run() if err != nil { log.Info("Aborted...") os.Exit(0) } log.Info("Deleting...") - err = deleteAccount(apper.App(), userID, posts) + err = deleteAccount(apper.App(), userID) if err != nil { log.Error("%s", err) os.Exit(1) diff --git a/cmd/writefreely/main.go b/cmd/writefreely/main.go index 10d8141..7fc2342 100644 --- a/cmd/writefreely/main.go +++ b/cmd/writefreely/main.go @@ -39,8 +39,7 @@ func main() { // Admin actions createAdmin := flag.String("create-admin", "", "Create an admin with the given username:password") createUser := flag.String("create-user", "", "Create a regular user with the given username:password") - deleteUserID := flag.Int64("delete-user", 0, "Delete a user with the given id, does not delete posts. Use `--delete-user id --posts`") - deletePosts := flag.Bool("posts", false, "Optionally delete the user's posts during account deletion") + deleteUsername := flag.String("delete-user", "", "Delete a user with the given username") resetPassUser := flag.String("reset-pass", "", "Reset the given user's password") outputVersion := flag.Bool("v", false, "Output the current version") flag.Parse() @@ -105,8 +104,8 @@ func main() { os.Exit(1) } os.Exit(0) - } else if *deleteUserID != 0 { - err := writefreely.DoDeleteAccount(app, *deleteUserID, *deletePosts) + } else if *deleteUsername != "" { + err := writefreely.DoDeleteAccount(app, *deleteUsername) if err != nil { log.Error(err.Error()) os.Exit(1) diff --git a/database.go b/database.go index cecd169..f2888ec 100644 --- a/database.go +++ b/database.go @@ -61,7 +61,7 @@ type writestore interface { GetAccessToken(userID int64) (string, error) GetTemporaryAccessToken(userID int64, validSecs int) (string, error) GetTemporaryOneTimeAccessToken(userID int64, validSecs int, oneTime bool) (string, error) - DeleteAccount(userID int64, posts bool) error + DeleteAccount(userID int64) error ChangeSettings(app *App, u *User, s *userSettings) error ChangePassphrase(userID int64, sudo bool, curPass string, hashedPass []byte) error @@ -2079,9 +2079,8 @@ func (db *datastore) CollectionHasAttribute(id int64, attr string) bool { return true } -// DeleteAccount will delete the entire account for userID, and if posts -// is true, also all posts associated with the userID -func (db *datastore) DeleteAccount(userID int64, posts bool) error { +// DeleteAccount will delete the entire account for userID +func (db *datastore) DeleteAccount(userID int64) error { // Get all collections rows, err := db.Query("SELECT id, alias FROM collections WHERE owner_id = ?", userID) if err != nil { @@ -2110,7 +2109,6 @@ func (db *datastore) DeleteAccount(userID int64, posts bool) error { // Clean up all collection related information var res sql.Result for _, c := range colls { - // TODO: user deleteCollection() func // Delete tokens res, err = t.Exec("DELETE FROM collectionattributes WHERE collection_id = ?", c.ID) if err != nil { @@ -2151,18 +2149,15 @@ func (db *datastore) DeleteAccount(userID int64, posts bool) error { rs, _ = res.RowsAffected() log.Info("Deleted %d for %s from collectionkeys", rs, c.Alias) - // only remove collection in posts if not deleting the user posts - if !posts { - // Float all collection's posts - res, err = t.Exec("UPDATE posts SET collection_id = NULL WHERE collection_id = ? AND owner_id = ?", c.ID, userID) - if err != nil { - t.Rollback() - log.Error("Unable to update collection %s for posts: %v", err) - return err - } - rs, _ = res.RowsAffected() - log.Info("Removed %d posts from collection %s", rs, c.Alias) + // Float all collection's posts + res, err = t.Exec("UPDATE posts SET collection_id = NULL WHERE collection_id = ? AND owner_id = ?", c.ID, userID) + if err != nil { + t.Rollback() + log.Error("Unable to update collection %s for posts: %v", c.Alias, err) + return err } + rs, _ = res.RowsAffected() + log.Info("Removed %d posts from collection %s", rs, c.Alias) // TODO: federate delete collection @@ -2198,18 +2193,16 @@ func (db *datastore) DeleteAccount(userID int64, posts bool) error { log.Info("Deleted %d from accesstokens", rs) // Delete posts - if posts { - // TODO: should maybe get each row so we can federate a delete - // if so needs to be outside of transaction like collections - res, err = t.Exec("DELETE FROM posts WHERE owner_id = ?", userID) - if err != nil { - t.Rollback() - log.Error("Unable to delete posts: %v", err) - return err - } - rs, _ = res.RowsAffected() - log.Info("Deleted %d from posts", rs) + // TODO: should maybe get each row so we can federate a delete + // if so needs to be outside of transaction like collections + res, err = t.Exec("DELETE FROM posts WHERE owner_id = ?", userID) + if err != nil { + t.Rollback() + log.Error("Unable to delete posts: %v", err) + return err } + rs, _ = res.RowsAffected() + log.Info("Deleted %d from posts", rs) // Delete user attributes res, err = t.Exec("DELETE FROM userattributes WHERE user_id = ?", userID)