package actions import ( "errors" "os" "path" "strconv" "github.com/photoview/photoview/api/graphql/models" "github.com/photoview/photoview/api/utils" "gorm.io/gorm" ) func DeleteUser(db *gorm.DB, userID int) (*models.User, error) { // make sure the last admin user is not deleted var adminUsers []*models.User db.Model(&models.User{}).Where("admin = true").Limit(2).Find(&adminUsers) if len(adminUsers) == 1 && adminUsers[0].ID == userID { return nil, errors.New("deleting sole admin user is not allowed") } var user models.User deletedAlbumIDs := make([]int, 0) err := db.Transaction(func(tx *gorm.DB) error { if err := tx.First(&user, userID).Error; err != nil { return err } userAlbums := user.Albums if err := tx.Model(&user).Association("Albums").Find(&userAlbums); err != nil { return err } if err := tx.Model(&user).Association("Albums").Clear(); err != nil { return err } for _, album := range userAlbums { var associatedUsers = tx.Model(album).Association("Owners").Count() if associatedUsers == 0 { deletedAlbumIDs = append(deletedAlbumIDs, album.ID) if err := tx.Delete(album).Error; err != nil { return err } } } if err := tx.Delete(&user).Error; err != nil { return err } return nil }) if err != nil { return nil, err } // If there is only one associated user, clean up the cache folder and delete the album row for _, deletedAlbumID := range deletedAlbumIDs { cachePath := path.Join(utils.MediaCachePath(), strconv.Itoa(int(deletedAlbumID))) if err := os.RemoveAll(cachePath); err != nil { return &user, err } } return &user, nil }