Add actually deleting the user
This commit is contained in:
parent
b2a861078f
commit
c2b5afe344
|
@ -95,7 +95,8 @@ func FullInit() {
|
|||
models.RegisterReminderCron()
|
||||
models.RegisterOverdueReminderCron()
|
||||
user.RegisterTokenCleanupCron()
|
||||
user.RegisterDeletionCron()
|
||||
user.RegisterDeletionNotificationCron()
|
||||
models.RegisterUserDeletionCron()
|
||||
|
||||
// Start processing events
|
||||
go func() {
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
// Copyright 2021 Vikunja and contriubtors. All rights reserved.
|
||||
//
|
||||
// This file is part of Vikunja.
|
||||
//
|
||||
// Vikunja is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Vikunja is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Vikunja. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"code.vikunja.io/api/pkg/cron"
|
||||
"code.vikunja.io/api/pkg/db"
|
||||
"code.vikunja.io/api/pkg/log"
|
||||
"code.vikunja.io/api/pkg/user"
|
||||
"time"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
// User deletion must happen here in this packaage because we want to delete everything associated to this user.
|
||||
// Because most of these things are managed in the models package, using them has to happen here.
|
||||
|
||||
// RegisterUserDeletionCron registers the cron job that actually removes users who are scheduled to delete.
|
||||
func RegisterUserDeletionCron() {
|
||||
err := cron.Schedule("0 * * * *", deleteUsers)
|
||||
if err != nil {
|
||||
log.Errorf("Could not register deletion cron: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func deleteUsers() {
|
||||
s := db.NewSession()
|
||||
users := []*user.User{}
|
||||
err := s.Where(builder.Lt{"deletion_scheduled_at": time.Now()}).
|
||||
Find(&users)
|
||||
if err != nil {
|
||||
log.Errorf("Could not get users scheduled for deletion: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
err = s.Begin()
|
||||
if err != nil {
|
||||
log.Errorf("Could not start transaction: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = deleteUser(s, user)
|
||||
if err != nil {
|
||||
_ = s.Rollback()
|
||||
log.Errorf("Could not delete user %d: %s", user.ID, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = s.Commit()
|
||||
if err != nil {
|
||||
log.Errorf("Could not commit transaction: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func deleteUser(s *xorm.Session, u *user.User) (err error) {
|
||||
if u.DeletionScheduledAt.Before(time.Now()) {
|
||||
// TODO: Proper error
|
||||
log.Debugf("User %d is not yet scheduled for deletion.", u.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
namespacesToDelete := []*NamespaceWithLists{}
|
||||
// Get all namespaces and lists this u has access to
|
||||
nm := &Namespace{}
|
||||
res, _, _, err := nm.ReadAll(s, u, "", 1, -1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
namespaces := res.([]*NamespaceWithLists)
|
||||
for _, n := range namespaces {
|
||||
if n.ID < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if this namespace is shared
|
||||
sharedUser, err := s.Where("namespace_id = ?", n.ID).Exist(&NamespaceUser{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sharedUser {
|
||||
continue
|
||||
}
|
||||
sharedTeam, err := s.Where("namespace_id = ?", n.ID).Exist(&TeamNamespace{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sharedTeam {
|
||||
continue
|
||||
}
|
||||
|
||||
namespacesToDelete = append(namespacesToDelete, n)
|
||||
}
|
||||
|
||||
// Get all lists to delete
|
||||
listsToDelete := []*List{}
|
||||
lm := &List{}
|
||||
res, _, _, err = lm.ReadAll(s, u, "", 0, -1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lists := res.([]*List)
|
||||
for _, l := range lists {
|
||||
if l.ID < 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
sharedUser, err := s.Where("list_id = ?", l.ID).Exist(&ListUser{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sharedUser {
|
||||
continue
|
||||
}
|
||||
sharedTeam, err := s.Where("list_id = ?", l.ID).Exist(&TeamList{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sharedTeam {
|
||||
continue
|
||||
}
|
||||
|
||||
listsToDelete = append(listsToDelete, l)
|
||||
}
|
||||
|
||||
// Delete everything not shared with anybody else
|
||||
for _, n := range namespacesToDelete {
|
||||
err = n.Delete(s, u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, l := range listsToDelete {
|
||||
err = l.Delete(s, u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = s.Where("id = ?", u.ID).Delete(u)
|
||||
return
|
||||
}
|
|
@ -28,7 +28,7 @@ import (
|
|||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func RegisterDeletionCron() {
|
||||
func RegisterDeletionNotificationCron() {
|
||||
err := cron.Schedule("0 * * * *", notifyUsersScheduledForDeletion)
|
||||
if err != nil {
|
||||
log.Errorf("Could not register deletion cron: %s", err.Error())
|
||||
|
|
Loading…
Reference in New Issue