mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-15 19:21:48 +02:00
added system notice
This commit is contained in:
parent
9f31e6cac1
commit
a5092e5aa7
@ -5,6 +5,7 @@
|
|||||||
package org
|
package org
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
activities_model "code.gitea.io/gitea/models/activities"
|
activities_model "code.gitea.io/gitea/models/activities"
|
||||||
@ -12,6 +13,7 @@ import (
|
|||||||
"code.gitea.io/gitea/models/organization"
|
"code.gitea.io/gitea/models/organization"
|
||||||
"code.gitea.io/gitea/models/perm"
|
"code.gitea.io/gitea/models/perm"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
system_model "code.gitea.io/gitea/models/system"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
@ -513,6 +515,8 @@ func DeleteOrgRepos(ctx *context.APIContext) {
|
|||||||
// responses:
|
// responses:
|
||||||
// "202":
|
// "202":
|
||||||
// description: Deletion started
|
// description: Deletion started
|
||||||
|
// "204":
|
||||||
|
// description: No repositories to delete
|
||||||
// "403":
|
// "403":
|
||||||
// "$ref": "#/responses/forbidden"
|
// "$ref": "#/responses/forbidden"
|
||||||
// "404":
|
// "404":
|
||||||
@ -524,6 +528,11 @@ func DeleteOrgRepos(ctx *context.APIContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(repos) == 0 {
|
||||||
|
ctx.Status(http.StatusNoContent)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
doer := ctx.Doer
|
doer := ctx.Doer
|
||||||
|
|
||||||
// Start deletion in background with detached context
|
// Start deletion in background with detached context
|
||||||
@ -539,7 +548,10 @@ func DeleteOrgRepos(ctx *context.APIContext) {
|
|||||||
|
|
||||||
for _, repo := range repos {
|
for _, repo := range repos {
|
||||||
if err := repo_service.DeleteRepository(bgCtx, doer, repo, true); err != nil {
|
if err := repo_service.DeleteRepository(bgCtx, doer, repo, true); err != nil {
|
||||||
log.Error("Failed to delete repository %s (ID: %d) in org %s: %v", repo.Name, repo.ID, org.Name, err)
|
desc := fmt.Sprintf("Failed to delete repository %s (ID: %d) in org %s: %v", repo.Name, repo.ID, org.Name, err)
|
||||||
|
if noticeErr := system_model.CreateNotice(bgCtx, system_model.NoticeRepository, desc); noticeErr != nil {
|
||||||
|
log.Error("Failed to create notice for repo deletion failure: %v", noticeErr)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Info("Successfully deleted repository %s (ID: %d) in org %s", repo.Name, repo.ID, org.Name)
|
log.Info("Successfully deleted repository %s (ID: %d) in org %s", repo.Name, repo.ID, org.Name)
|
||||||
}
|
}
|
||||||
|
|||||||
3
templates/swagger/v1_json.tmpl
generated
3
templates/swagger/v1_json.tmpl
generated
@ -3551,6 +3551,9 @@
|
|||||||
"202": {
|
"202": {
|
||||||
"description": "Deletion started"
|
"description": "Deletion started"
|
||||||
},
|
},
|
||||||
|
"204": {
|
||||||
|
"description": "No repositories to delete"
|
||||||
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"$ref": "#/responses/forbidden"
|
"$ref": "#/responses/forbidden"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -8,16 +8,20 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
auth_model "code.gitea.io/gitea/models/auth"
|
auth_model "code.gitea.io/gitea/models/auth"
|
||||||
org_model "code.gitea.io/gitea/models/organization"
|
org_model "code.gitea.io/gitea/models/organization"
|
||||||
"code.gitea.io/gitea/models/perm"
|
"code.gitea.io/gitea/models/perm"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
system_model "code.gitea.io/gitea/models/system"
|
||||||
unit_model "code.gitea.io/gitea/models/unit"
|
unit_model "code.gitea.io/gitea/models/unit"
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/test"
|
"code.gitea.io/gitea/modules/test"
|
||||||
|
repo_service "code.gitea.io/gitea/services/repository"
|
||||||
"code.gitea.io/gitea/tests"
|
"code.gitea.io/gitea/tests"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -326,4 +330,86 @@ func TestAPIDeleteOrgRepos(t *testing.T) {
|
|||||||
req = NewRequest(t, "DELETE", "/api/v1/orgs/org3/repos").AddTokenAuth(nonOwnerToken)
|
req = NewRequest(t, "DELETE", "/api/v1/orgs/org3/repos").AddTokenAuth(nonOwnerToken)
|
||||||
MakeRequest(t, req, http.StatusForbidden)
|
MakeRequest(t, req, http.StatusForbidden)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("No system notice created on successful deletion", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
session := loginUser(t, "user1")
|
||||||
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository)
|
||||||
|
|
||||||
|
orgName := "test_notice_org"
|
||||||
|
req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{
|
||||||
|
UserName: orgName,
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
// Create a repo
|
||||||
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos", orgName), &api.CreateRepoOption{
|
||||||
|
Name: "test_repo",
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
// Get initial notice count
|
||||||
|
initialNotices := unittest.GetCount(t, &system_model.Notice{Type: system_model.NoticeRepository})
|
||||||
|
|
||||||
|
// Delete repos
|
||||||
|
req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/orgs/%s/repos", orgName)).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusAccepted)
|
||||||
|
|
||||||
|
// Wait for background deletion to complete
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
|
||||||
|
// Check if notices were created (should be 0 for successful deletions)
|
||||||
|
finalNotices := unittest.GetCount(t, &system_model.Notice{Type: system_model.NoticeRepository})
|
||||||
|
assert.Equal(t, initialNotices, finalNotices, "No notices should be created for successful deletions")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Returns 204 when repos already deleted", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
session := loginUser(t, "user1")
|
||||||
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository)
|
||||||
|
|
||||||
|
orgName := "test_fail_notice"
|
||||||
|
req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{
|
||||||
|
UserName: orgName,
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
// Create a repo
|
||||||
|
repoName := "test_fail_repo"
|
||||||
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos", orgName), &api.CreateRepoOption{
|
||||||
|
Name: repoName,
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
// Delete the repo directly to cause the bulk delete to fail
|
||||||
|
org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: orgName})
|
||||||
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: repoName, OwnerID: org.ID})
|
||||||
|
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
|
||||||
|
|
||||||
|
err := repo_service.DeleteRepository(t.Context(), user, repo, true)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Now try to delete all org repos - should return 204 since no repos exist
|
||||||
|
req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/orgs/%s/repos", orgName)).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Returns 204 when no repos exist", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
session := loginUser(t, "user1")
|
||||||
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository)
|
||||||
|
|
||||||
|
orgName := "test_empty_org"
|
||||||
|
req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{
|
||||||
|
UserName: orgName,
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusCreated)
|
||||||
|
|
||||||
|
// Delete repos when org has no repos - should return 204
|
||||||
|
req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/orgs/%s/repos", orgName)).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusNoContent)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user