Add actually deleting the user

This commit is contained in:
kolaente 2021-08-07 16:09:11 +02:00
parent b2a861078f
commit c2b5afe344
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
3 changed files with 167 additions and 2 deletions

View File

@ -95,7 +95,8 @@ func FullInit() {
models.RegisterReminderCron()
models.RegisterOverdueReminderCron()
user.RegisterTokenCleanupCron()
user.RegisterDeletionCron()
user.RegisterDeletionNotificationCron()
models.RegisterUserDeletionCron()
// Start processing events
go func() {

164
pkg/models/user_delete.go Normal file
View File

@ -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
}

View File

@ -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())