From acb03c430ec49867b99249c5d432c4fa482abf35 Mon Sep 17 00:00:00 2001 From: kolaente Date: Wed, 23 Aug 2023 16:10:51 +0200 Subject: [PATCH] fix(user): allow deleting a user if they have a default project Resolves https://github.com/go-vikunja/api/issues/78 --- pkg/db/fixtures/projects.yml | 9 +++++++++ pkg/db/fixtures/users.yml | 8 ++++++++ pkg/models/project.go | 13 ++++++++++++- pkg/models/user_delete_test.go | 13 +++++++++++++ pkg/user/user_test.go | 4 ++-- 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/pkg/db/fixtures/projects.yml b/pkg/db/fixtures/projects.yml index d9cbdd175..6603554e1 100644 --- a/pkg/db/fixtures/projects.yml +++ b/pkg/db/fixtures/projects.yml @@ -315,3 +315,12 @@ position: 1 updated: 2018-12-02 15:13:12 created: 2018-12-01 15:13:12 +- + id: 37 + title: Project 37 + description: Lorem Ipsum + identifier: test37 + owner_id: 16 + position: 1 + updated: 2018-12-02 15:13:12 + created: 2018-12-01 15:13:12 diff --git a/pkg/db/fixtures/users.yml b/pkg/db/fixtures/users.yml index e02b19b44..f430c700f 100644 --- a/pkg/db/fixtures/users.yml +++ b/pkg/db/fixtures/users.yml @@ -118,3 +118,11 @@ issuer: local updated: 2018-12-02 15:13:12 created: 2018-12-01 15:13:12 +- id: 16 + username: 'user16' + password: '$2a$14$dcadBoMBL9jQoOcZK8Fju.cy0Ptx2oZECkKLnaa8ekRoTFe1w7To.' # 1234 + email: 'user16@example.com' + issuer: local + default_project_id: 37 + updated: 2018-12-02 15:13:12 + created: 2018-12-01 15:13:12 diff --git a/pkg/models/project.go b/pkg/models/project.go index 97e418398..12e95f655 100644 --- a/pkg/models/project.go +++ b/pkg/models/project.go @@ -960,7 +960,8 @@ func (p *Project) Delete(s *xorm.Session, a web.Auth) (err error) { if err != nil { return err } - if isDefaultProject { + // Owners should be allowed to delete the default project + if isDefaultProject && p.OwnerID != a.GetID() { return &ErrCannotDeleteDefaultProject{ProjectID: p.ID} } @@ -988,6 +989,16 @@ func (p *Project) Delete(s *xorm.Session, a web.Auth) (err error) { return } + // If we're deleting a default project, remove it as default + if isDefaultProject { + _, err = s.Where("default_project_id = ?", p.ID). + Cols("default_project_id"). + Update(&user.User{DefaultProjectID: 0}) + if err != nil { + return + } + } + // Delete the project _, err = s.ID(p.ID).Delete(&Project{}) if err != nil { diff --git a/pkg/models/user_delete_test.go b/pkg/models/user_delete_test.go index e589d10e7..7c9af9dc4 100644 --- a/pkg/models/user_delete_test.go +++ b/pkg/models/user_delete_test.go @@ -58,4 +58,17 @@ func TestDeleteUser(t *testing.T) { assert.NoError(t, err) // No assertions for deleted projects since that user doesn't have any }) + t.Run("user with a default project", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + notifications.Fake() + + u := &user.User{ID: 16} + err := DeleteUser(s, u) + + assert.NoError(t, err) + db.AssertMissing(t, "users", map[string]interface{}{"id": u.ID}) + db.AssertMissing(t, "projects", map[string]interface{}{"id": 37}) // only user16 had access to this project, and it was their default + }) } diff --git a/pkg/user/user_test.go b/pkg/user/user_test.go index bfe7d5d06..8b498e409 100644 --- a/pkg/user/user_test.go +++ b/pkg/user/user_test.go @@ -399,7 +399,7 @@ func TestListUsers(t *testing.T) { all, err := ListAllUsers(s) assert.NoError(t, err) - assert.Len(t, all, 15) + assert.Len(t, all, 16) }) t.Run("no search term", func(t *testing.T) { db.LoadAndAssertFixtures(t) @@ -512,7 +512,7 @@ func TestListUsers(t *testing.T) { MatchFuzzily: true, }) assert.NoError(t, err) - assert.Len(t, all, 15) + assert.Len(t, all, 16) }) }