Release attachments must belong to the intended repo (#36347) (#36375)

Backport #36347 by @lunny

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
Giteabot
2026-01-15 09:30:18 +08:00
committed by GitHub
parent 5fe9703586
commit dfe4055b92
9 changed files with 122 additions and 32 deletions
+18
View File
@@ -241,6 +241,11 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error {
if err := deleteUser(ctx, u, purge); err != nil {
return fmt.Errorf("DeleteUser: %w", err)
}
// Finally delete any unlinked attachments, this will also delete the attached files
if err := deleteUserUnlinkedAttachments(ctx, u); err != nil {
return fmt.Errorf("deleteUserUnlinkedAttachments: %w", err)
}
return nil
}); err != nil {
return err
@@ -271,6 +276,19 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) error {
return nil
}
func deleteUserUnlinkedAttachments(ctx context.Context, u *user_model.User) error {
attachments, err := repo_model.GetUnlinkedAttachmentsByUserID(ctx, u.ID)
if err != nil {
return fmt.Errorf("GetUnlinkedAttachmentsByUserID: %w", err)
}
for _, attach := range attachments {
if err := repo_model.DeleteAttachment(ctx, attach, true); err != nil {
return fmt.Errorf("DeleteAttachment ID[%d]: %w", attach.ID, err)
}
}
return nil
}
// DeleteInactiveUsers deletes all inactive users and their email addresses.
func DeleteInactiveUsers(ctx context.Context, olderThan time.Duration) error {
inactiveUsers, err := user_model.GetInactiveUsers(ctx, olderThan)
+18
View File
@@ -62,6 +62,24 @@ func TestDeleteUser(t *testing.T) {
assert.Error(t, DeleteUser(t.Context(), org, false))
}
func TestDeleteUserUnlinkedAttachments(t *testing.T) {
t.Run("DeleteExisting", func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 8})
unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: 10})
assert.NoError(t, deleteUserUnlinkedAttachments(t.Context(), user))
unittest.AssertNotExistsBean(t, &repo_model.Attachment{ID: 10})
})
t.Run("NoUnlinkedAttachments", func(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, deleteUserUnlinkedAttachments(t.Context(), user))
})
}
func TestPurgeUser(t *testing.T) {
test := func(userID int64) {
assert.NoError(t, unittest.PrepareTestDatabase())