Skip to content

Commit 772a60b

Browse files
committed
Delete repos of org when purge delete user
1 parent d0012c8 commit 772a60b

File tree

5 files changed

+47
-15
lines changed

5 files changed

+47
-15
lines changed

routers/api/v1/org/org.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ func Delete(ctx *context.APIContext) {
385385
// "404":
386386
// "$ref": "#/responses/notFound"
387387

388-
if err := org.DeleteOrganization(ctx.Org.Organization); err != nil {
388+
if err := org.DeleteOrganization(ctx, ctx.Org.Organization, false); err != nil {
389389
ctx.Error(http.StatusInternalServerError, "DeleteOrganization", err)
390390
return
391391
}

routers/web/org/setting.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func SettingsPost(ctx *context.Context) {
7575

7676
// Check if organization name has been changed.
7777
if nameChanged {
78-
err := org_service.RenameOrganization(ctx, org, form.Name)
78+
err := user_service.RenameUser(ctx, org.AsUser(), form.Name)
7979
switch {
8080
case user_model.IsErrUserAlreadyExist(err):
8181
ctx.Data["OrgName"] = true
@@ -180,7 +180,7 @@ func SettingsDelete(ctx *context.Context) {
180180
return
181181
}
182182

183-
if err := org_service.DeleteOrganization(ctx.Org.Organization); err != nil {
183+
if err := org_service.DeleteOrganization(ctx, ctx.Org.Organization, false); err != nil {
184184
if models.IsErrUserOwnRepos(err) {
185185
ctx.Flash.Error(ctx.Tr("form.org_still_own_repo"))
186186
ctx.Redirect(ctx.Org.OrgLink + "/settings/delete")

services/org/org.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,44 @@ import (
1515
user_model "code.gitea.io/gitea/models/user"
1616
"code.gitea.io/gitea/modules/storage"
1717
"code.gitea.io/gitea/modules/util"
18-
user_service "code.gitea.io/gitea/services/user"
18+
repo_service "code.gitea.io/gitea/services/repository"
1919
)
2020

2121
// DeleteOrganization completely and permanently deletes everything of organization.
22-
func DeleteOrganization(org *org_model.Organization) error {
23-
ctx, commiter, err := db.TxContext(db.DefaultContext)
22+
func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge bool) error {
23+
if purge {
24+
// Delete all repos belonging to this organisation
25+
// Now this is not within a transaction because there are internal transactions within the DeleteRepository
26+
// BUT: the db will still be consistent even if a number of repos have already been deleted.
27+
// And in fact we want to capture any repositories that are being created in other transactions in the meantime
28+
//
29+
// An alternative option here would be write a DeleteAllRepositoriesForUserID function which would delete all of the repos
30+
// but such a function would likely get out of date
31+
for {
32+
repos, _, err := repo_model.GetUserRepositories(&repo_model.SearchRepoOptions{
33+
ListOptions: db.ListOptions{
34+
PageSize: repo_model.RepositoryListDefaultPageSize,
35+
Page: 1,
36+
},
37+
Private: true,
38+
OwnerID: org.ID,
39+
Actor: org.AsUser(),
40+
})
41+
if err != nil {
42+
return fmt.Errorf("GetUserRepositories: %w", err)
43+
}
44+
if len(repos) == 0 {
45+
break
46+
}
47+
for _, repo := range repos {
48+
if err := repo_service.DeleteRepositoryDirectly(ctx, org.AsUser(), org.ID, repo.ID); err != nil {
49+
return fmt.Errorf("unable to delete repository %s for %s[%d]. Error: %w", repo.Name, org.Name, org.ID, err)
50+
}
51+
}
52+
}
53+
}
54+
55+
ctx, commiter, err := db.TxContext(ctx)
2456
if err != nil {
2557
return err
2658
}
@@ -67,8 +99,3 @@ func DeleteOrganization(org *org_model.Organization) error {
6799

68100
return nil
69101
}
70-
71-
// RenameOrganization renames an organization.
72-
func RenameOrganization(ctx context.Context, org *org_model.Organization, newName string) error {
73-
return user_service.RenameUser(ctx, org.AsUser(), newName)
74-
}

services/org/org_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99

1010
"code.gitea.io/gitea/models"
11+
"code.gitea.io/gitea/models/db"
1112
"code.gitea.io/gitea/models/organization"
1213
"code.gitea.io/gitea/models/unittest"
1314
user_model "code.gitea.io/gitea/models/user"
@@ -24,17 +25,17 @@ func TestMain(m *testing.M) {
2425
func TestDeleteOrganization(t *testing.T) {
2526
assert.NoError(t, unittest.PrepareTestDatabase())
2627
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 6})
27-
assert.NoError(t, DeleteOrganization(org))
28+
assert.NoError(t, DeleteOrganization(db.DefaultContext, org, false))
2829
unittest.AssertNotExistsBean(t, &organization.Organization{ID: 6})
2930
unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: 6})
3031
unittest.AssertNotExistsBean(t, &organization.Team{OrgID: 6})
3132

3233
org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
33-
err := DeleteOrganization(org)
34+
err := DeleteOrganization(db.DefaultContext, org, false)
3435
assert.Error(t, err)
3536
assert.True(t, models.IsErrUserOwnRepos(err))
3637

3738
user := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 5})
38-
assert.Error(t, DeleteOrganization(user))
39+
assert.Error(t, DeleteOrganization(db.DefaultContext, user, false))
3940
unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{})
4041
}

services/user/user.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"code.gitea.io/gitea/modules/storage"
2525
"code.gitea.io/gitea/modules/util"
2626
"code.gitea.io/gitea/services/agit"
27+
org_service "code.gitea.io/gitea/services/org"
2728
"code.gitea.io/gitea/services/packages"
2829
container_service "code.gitea.io/gitea/services/packages/container"
2930
repo_service "code.gitea.io/gitea/services/repository"
@@ -206,7 +207,10 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error {
206207
for _, org := range orgs {
207208
if err := models.RemoveOrgUser(org.ID, u.ID); err != nil {
208209
if organization.IsErrLastOrgOwner(err) {
209-
err = organization.DeleteOrganization(ctx, org)
210+
err = org_service.DeleteOrganization(ctx, org, true)
211+
if err != nil {
212+
return fmt.Errorf("unable to delete organisation %d: %w", org.ID, err)
213+
}
210214
}
211215
if err != nil {
212216
return fmt.Errorf("unable to remove user %s[%d] from org %s[%d]. Error: %w", u.Name, u.ID, org.Name, org.ID, err)

0 commit comments

Comments
 (0)