mirror of
https://github.com/writefreely/writefreely
synced 2024-11-10 11:24:13 +00:00
CLI delete account by username and delete posts
this changed the CLI flag to use the username instead of the userID leaving the underlying database function as is. also now posts are all deleted with no option to skip as this is likely never needed.
This commit is contained in:
parent
c87ca11a52
commit
41166e5c35
4 changed files with 39 additions and 44 deletions
|
@ -1069,6 +1069,6 @@ func getTempInfo(app *App, key string, r *http.Request, w http.ResponseWriter) s
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteAccount(app *App, userID int64, posts bool) error {
|
func deleteAccount(app *App, userID int64) error {
|
||||||
return app.db.DeleteAccount(userID, posts)
|
return app.db.DeleteAccount(userID)
|
||||||
}
|
}
|
||||||
|
|
25
app.go
25
app.go
|
@ -682,21 +682,24 @@ func ResetPassword(apper Apper, username string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoDeleteAccount runs the confirmation and account delete process.
|
// 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
|
// Connect to the database
|
||||||
apper.LoadConfig()
|
apper.LoadConfig()
|
||||||
connectToDatabase(apper.App())
|
connectToDatabase(apper.App())
|
||||||
defer shutdown(apper.App())
|
defer shutdown(apper.App())
|
||||||
|
|
||||||
// do not delete the root admin account
|
// check user exists
|
||||||
// TODO: check for other admins and skip?
|
u, err := apper.App().db.GetUserForAuth(username)
|
||||||
if userID == 1 {
|
if err != nil {
|
||||||
log.Error("Can not delete admin account")
|
log.Error("%s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
// check user exists
|
userID := u.ID
|
||||||
if _, err := apper.App().db.GetUserByID(userID); err != nil {
|
|
||||||
log.Error("%s", err)
|
// 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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,17 +708,17 @@ func DoDeleteAccount(apper Apper, userID int64, posts bool) error {
|
||||||
Templates: &promptui.PromptTemplates{
|
Templates: &promptui.PromptTemplates{
|
||||||
Success: "{{ . | bold | faint }}: ",
|
Success: "{{ . | bold | faint }}: ",
|
||||||
},
|
},
|
||||||
Label: fmt.Sprintf("Delete user with ID: %d", userID),
|
Label: fmt.Sprintf("Really delete user : %s", username),
|
||||||
IsConfirm: true,
|
IsConfirm: true,
|
||||||
}
|
}
|
||||||
_, err := prompt.Run()
|
_, err = prompt.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Aborted...")
|
log.Info("Aborted...")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Deleting...")
|
log.Info("Deleting...")
|
||||||
err = deleteAccount(apper.App(), userID, posts)
|
err = deleteAccount(apper.App(), userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("%s", err)
|
log.Error("%s", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
@ -39,8 +39,7 @@ func main() {
|
||||||
// Admin actions
|
// Admin actions
|
||||||
createAdmin := flag.String("create-admin", "", "Create an admin with the given username:password")
|
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")
|
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`")
|
deleteUsername := flag.String("delete-user", "", "Delete a user with the given username")
|
||||||
deletePosts := flag.Bool("posts", false, "Optionally delete the user's posts during account deletion")
|
|
||||||
resetPassUser := flag.String("reset-pass", "", "Reset the given user's password")
|
resetPassUser := flag.String("reset-pass", "", "Reset the given user's password")
|
||||||
outputVersion := flag.Bool("v", false, "Output the current version")
|
outputVersion := flag.Bool("v", false, "Output the current version")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
@ -105,8 +104,8 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
} else if *deleteUserID != 0 {
|
} else if *deleteUsername != "" {
|
||||||
err := writefreely.DoDeleteAccount(app, *deleteUserID, *deletePosts)
|
err := writefreely.DoDeleteAccount(app, *deleteUsername)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
47
database.go
47
database.go
|
@ -61,7 +61,7 @@ type writestore interface {
|
||||||
GetAccessToken(userID int64) (string, error)
|
GetAccessToken(userID int64) (string, error)
|
||||||
GetTemporaryAccessToken(userID int64, validSecs int) (string, error)
|
GetTemporaryAccessToken(userID int64, validSecs int) (string, error)
|
||||||
GetTemporaryOneTimeAccessToken(userID int64, validSecs int, oneTime bool) (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
|
ChangeSettings(app *App, u *User, s *userSettings) error
|
||||||
ChangePassphrase(userID int64, sudo bool, curPass string, hashedPass []byte) 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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteAccount will delete the entire account for userID, and if posts
|
// DeleteAccount will delete the entire account for userID
|
||||||
// is true, also all posts associated with the userID
|
func (db *datastore) DeleteAccount(userID int64) error {
|
||||||
func (db *datastore) DeleteAccount(userID int64, posts bool) error {
|
|
||||||
// Get all collections
|
// Get all collections
|
||||||
rows, err := db.Query("SELECT id, alias FROM collections WHERE owner_id = ?", userID)
|
rows, err := db.Query("SELECT id, alias FROM collections WHERE owner_id = ?", userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2110,7 +2109,6 @@ func (db *datastore) DeleteAccount(userID int64, posts bool) error {
|
||||||
// Clean up all collection related information
|
// Clean up all collection related information
|
||||||
var res sql.Result
|
var res sql.Result
|
||||||
for _, c := range colls {
|
for _, c := range colls {
|
||||||
// TODO: user deleteCollection() func
|
|
||||||
// Delete tokens
|
// Delete tokens
|
||||||
res, err = t.Exec("DELETE FROM collectionattributes WHERE collection_id = ?", c.ID)
|
res, err = t.Exec("DELETE FROM collectionattributes WHERE collection_id = ?", c.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2151,18 +2149,15 @@ func (db *datastore) DeleteAccount(userID int64, posts bool) error {
|
||||||
rs, _ = res.RowsAffected()
|
rs, _ = res.RowsAffected()
|
||||||
log.Info("Deleted %d for %s from collectionkeys", rs, c.Alias)
|
log.Info("Deleted %d for %s from collectionkeys", rs, c.Alias)
|
||||||
|
|
||||||
// only remove collection in posts if not deleting the user posts
|
// Float all collection's posts
|
||||||
if !posts {
|
res, err = t.Exec("UPDATE posts SET collection_id = NULL WHERE collection_id = ? AND owner_id = ?", c.ID, userID)
|
||||||
// Float all collection's posts
|
if err != nil {
|
||||||
res, err = t.Exec("UPDATE posts SET collection_id = NULL WHERE collection_id = ? AND owner_id = ?", c.ID, userID)
|
t.Rollback()
|
||||||
if err != nil {
|
log.Error("Unable to update collection %s for posts: %v", c.Alias, err)
|
||||||
t.Rollback()
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
rs, _ = res.RowsAffected()
|
||||||
|
log.Info("Removed %d posts from collection %s", rs, c.Alias)
|
||||||
|
|
||||||
// TODO: federate delete collection
|
// TODO: federate delete collection
|
||||||
|
|
||||||
|
@ -2198,18 +2193,16 @@ func (db *datastore) DeleteAccount(userID int64, posts bool) error {
|
||||||
log.Info("Deleted %d from accesstokens", rs)
|
log.Info("Deleted %d from accesstokens", rs)
|
||||||
|
|
||||||
// Delete posts
|
// Delete posts
|
||||||
if posts {
|
// TODO: should maybe get each row so we can federate a delete
|
||||||
// TODO: should maybe get each row so we can federate a delete
|
// if so needs to be outside of transaction like collections
|
||||||
// if so needs to be outside of transaction like collections
|
res, err = t.Exec("DELETE FROM posts WHERE owner_id = ?", userID)
|
||||||
res, err = t.Exec("DELETE FROM posts WHERE owner_id = ?", userID)
|
if err != nil {
|
||||||
if err != nil {
|
t.Rollback()
|
||||||
t.Rollback()
|
log.Error("Unable to delete posts: %v", err)
|
||||||
log.Error("Unable to delete posts: %v", err)
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
rs, _ = res.RowsAffected()
|
|
||||||
log.Info("Deleted %d from posts", rs)
|
|
||||||
}
|
}
|
||||||
|
rs, _ = res.RowsAffected()
|
||||||
|
log.Info("Deleted %d from posts", rs)
|
||||||
|
|
||||||
// Delete user attributes
|
// Delete user attributes
|
||||||
res, err = t.Exec("DELETE FROM userattributes WHERE user_id = ?", userID)
|
res, err = t.Exec("DELETE FROM userattributes WHERE user_id = ?", userID)
|
||||||
|
|
Loading…
Reference in a new issue