Skip to content

Commit 4a8ee0b

Browse files
authored
Check that repositories can only be migrated to own user or organizations (#4366)
* Repositories can only migrated to own user or organizations * Add check for organization that user does not belong to * Allow admin to migrate repositories for other users
1 parent b46066f commit 4a8ee0b

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

integrations/api_repo_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,30 @@ func TestAPIGetRepoByIDUnauthorized(t *testing.T) {
235235
req := NewRequestf(t, "GET", "/api/v1/repositories/2")
236236
sess.MakeRequest(t, req, http.StatusNotFound)
237237
}
238+
239+
func TestAPIRepoMigrate(t *testing.T) {
240+
testCases := []struct {
241+
ctxUserID, userID int64
242+
cloneURL, repoName string
243+
expectedStatus int
244+
}{
245+
{ctxUserID: 1, userID: 2, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-admin", expectedStatus: http.StatusCreated},
246+
{ctxUserID: 2, userID: 2, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-own", expectedStatus: http.StatusCreated},
247+
{ctxUserID: 2, userID: 1, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-bad", expectedStatus: http.StatusForbidden},
248+
{ctxUserID: 2, userID: 3, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-org", expectedStatus: http.StatusCreated},
249+
{ctxUserID: 2, userID: 6, cloneURL: "https://github.com/go-gitea/git.git", repoName: "git-bad-org", expectedStatus: http.StatusForbidden},
250+
}
251+
252+
prepareTestEnv(t)
253+
for _, testCase := range testCases {
254+
user := models.AssertExistsAndLoadBean(t, &models.User{ID: testCase.ctxUserID}).(*models.User)
255+
session := loginUser(t, user.Name)
256+
257+
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate", &api.MigrateRepoOption{
258+
CloneAddr: testCase.cloneURL,
259+
UID: int(testCase.userID),
260+
RepoName: testCase.repoName,
261+
})
262+
session.MakeRequest(t, req, testCase.expectedStatus)
263+
}
264+
}

routers/api/v1/repo/repo.go

+15-8
Original file line numberDiff line numberDiff line change
@@ -306,16 +306,23 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
306306
return
307307
}
308308

309-
if ctxUser.IsOrganization() && !ctx.User.IsAdmin {
310-
// Check ownership of organization.
311-
isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID)
312-
if err != nil {
313-
ctx.Error(500, "IsOwnedBy", err)
314-
return
315-
} else if !isOwner {
316-
ctx.Error(403, "", "Given user is not owner of organization.")
309+
if !ctx.User.IsAdmin {
310+
if !ctxUser.IsOrganization() && ctx.User.ID != ctxUser.ID {
311+
ctx.Error(403, "", "Given user is not an organization.")
317312
return
318313
}
314+
315+
if ctxUser.IsOrganization() {
316+
// Check ownership of organization.
317+
isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID)
318+
if err != nil {
319+
ctx.Error(500, "IsOwnedBy", err)
320+
return
321+
} else if !isOwner {
322+
ctx.Error(403, "", "Given user is not owner of organization.")
323+
return
324+
}
325+
}
319326
}
320327

321328
remoteAddr, err := form.ParseRemoteAddr(ctx.User)

0 commit comments

Comments
 (0)