fix: deleting users with no namespaces
continuous-integration/drone/push Build encountered an error Details

resolves #984
This commit is contained in:
kolaente 2021-11-22 22:34:20 +01:00
parent b0622732a1
commit f8a0a7e953
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
2 changed files with 71 additions and 30 deletions

View File

@ -87,17 +87,18 @@ func deleteUsers() {
} }
} }
// DeleteUser completely removes a user and all their associated lists, namespaces and tasks. func getNamespacesToDelete(s *xorm.Session, u *user.User) (namespacesToDelete []*Namespace, err error) {
// This action is irrevocable. namespacesToDelete = []*Namespace{}
// Public to allow deletion from the CLI.
func DeleteUser(s *xorm.Session, u *user.User) (err error) {
namespacesToDelete := []*Namespace{}
// Get all namespaces and lists this u has access to
nm := &Namespace{IsArchived: true} nm := &Namespace{IsArchived: true}
res, _, _, err := nm.ReadAll(s, u, "", 1, -1) res, _, _, err := nm.ReadAll(s, u, "", 1, -1)
if err != nil { if err != nil {
return err return nil, err
} }
if res == nil {
return nil, nil
}
namespaces := res.([]*NamespaceWithLists) namespaces := res.([]*NamespaceWithLists)
for _, n := range namespaces { for _, n := range namespaces {
if n.ID < 0 { if n.ID < 0 {
@ -106,14 +107,14 @@ func DeleteUser(s *xorm.Session, u *user.User) (err error) {
hadUsers, err := ensureNamespaceAdminUser(s, &n.Namespace) hadUsers, err := ensureNamespaceAdminUser(s, &n.Namespace)
if err != nil { if err != nil {
return err return nil, err
} }
if hadUsers { if hadUsers {
continue continue
} }
hadTeams, err := ensureNamespaceAdminTeam(s, &n.Namespace) hadTeams, err := ensureNamespaceAdminTeam(s, &n.Namespace)
if err != nil { if err != nil {
return err return nil, err
} }
if hadTeams { if hadTeams {
continue continue
@ -122,13 +123,21 @@ func DeleteUser(s *xorm.Session, u *user.User) (err error) {
namespacesToDelete = append(namespacesToDelete, &n.Namespace) namespacesToDelete = append(namespacesToDelete, &n.Namespace)
} }
// Get all lists to delete return
listsToDelete := []*List{} }
func getListsToDelete(s *xorm.Session, u *user.User) (listsToDelete []*List, err error) {
listsToDelete = []*List{}
lm := &List{IsArchived: true} lm := &List{IsArchived: true}
res, _, _, err = lm.ReadAll(s, u, "", 0, -1) res, _, _, err := lm.ReadAll(s, u, "", 0, -1)
if err != nil { if err != nil {
return err return nil, err
} }
if res == nil {
return nil, nil
}
lists := res.([]*List) lists := res.([]*List)
for _, l := range lists { for _, l := range lists {
if l.ID < 0 { if l.ID < 0 {
@ -137,15 +146,16 @@ func DeleteUser(s *xorm.Session, u *user.User) (err error) {
hadUsers, err := ensureListAdminUser(s, l) hadUsers, err := ensureListAdminUser(s, l)
if err != nil { if err != nil {
return err return nil, err
} }
if hadUsers { if hadUsers {
continue continue
} }
hadTeams, err := ensureListAdminTeam(s, l) hadTeams, err := ensureListAdminTeam(s, l)
if err != nil { if err != nil {
return err return nil, err
} }
if hadTeams { if hadTeams {
continue continue
} }
@ -153,6 +163,23 @@ func DeleteUser(s *xorm.Session, u *user.User) (err error) {
listsToDelete = append(listsToDelete, l) listsToDelete = append(listsToDelete, l)
} }
return
}
// DeleteUser completely removes a user and all their associated lists, namespaces and tasks.
// This action is irrevocable.
// Public to allow deletion from the CLI.
func DeleteUser(s *xorm.Session, u *user.User) (err error) {
namespacesToDelete, err := getNamespacesToDelete(s, u)
if err != nil {
return err
}
listsToDelete, err := getListsToDelete(s, u)
if err != nil {
return err
}
// Delete everything not shared with anybody else // Delete everything not shared with anybody else
for _, n := range namespacesToDelete { for _, n := range namespacesToDelete {
err = deleteNamespace(s, n, u, false) err = deleteNamespace(s, n, u, false)

View File

@ -27,21 +27,35 @@ import (
) )
func TestDeleteUser(t *testing.T) { func TestDeleteUser(t *testing.T) {
db.LoadAndAssertFixtures(t) t.Run("normal", func(t *testing.T) {
s := db.NewSession() db.LoadAndAssertFixtures(t)
defer s.Close() s := db.NewSession()
notifications.Fake() defer s.Close()
notifications.Fake()
u := &user.User{ID: 6} u := &user.User{ID: 6}
err := DeleteUser(s, u) err := DeleteUser(s, u)
assert.NoError(t, err) assert.NoError(t, err)
db.AssertMissing(t, "users", map[string]interface{}{"id": u.ID}) db.AssertMissing(t, "users", map[string]interface{}{"id": u.ID})
db.AssertMissing(t, "lists", map[string]interface{}{"id": 24}) // only user6 had access to this list db.AssertMissing(t, "lists", map[string]interface{}{"id": 24}) // only user6 had access to this list
db.AssertExists(t, "lists", map[string]interface{}{"id": 6}, false) db.AssertExists(t, "lists", map[string]interface{}{"id": 6}, false)
db.AssertExists(t, "lists", map[string]interface{}{"id": 7}, false) db.AssertExists(t, "lists", map[string]interface{}{"id": 7}, false)
db.AssertExists(t, "lists", map[string]interface{}{"id": 8}, false) db.AssertExists(t, "lists", map[string]interface{}{"id": 8}, false)
db.AssertExists(t, "lists", map[string]interface{}{"id": 9}, false) db.AssertExists(t, "lists", map[string]interface{}{"id": 9}, false)
db.AssertExists(t, "lists", map[string]interface{}{"id": 10}, false) db.AssertExists(t, "lists", map[string]interface{}{"id": 10}, false)
db.AssertExists(t, "lists", map[string]interface{}{"id": 11}, false) db.AssertExists(t, "lists", map[string]interface{}{"id": 11}, false)
})
t.Run("user with no namespaces", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
s := db.NewSession()
defer s.Close()
notifications.Fake()
u := &user.User{ID: 4}
err := DeleteUser(s, u)
assert.NoError(t, err)
// No assertions for deleted lists and namespaces since that user doesn't have any
})
} }