Browse Source

Fix repo API bug (#2133)

Don't require token when not necessary
Ethan Koenig 1 year ago
parent
commit
93a1de4842

+ 18 - 0
integrations/api_fork_test.go

@@ -0,0 +1,18 @@
1
+// Copyright 2017 The Gogs Authors. All rights reserved.
2
+// Use of this source code is governed by a MIT-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package integrations
6
+
7
+import (
8
+	"net/http"
9
+	"testing"
10
+
11
+	api "code.gitea.io/sdk/gitea"
12
+)
13
+
14
+func TestCreateForkNoLogin(t *testing.T) {
15
+	prepareTestEnv(t)
16
+	req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/forks", &api.CreateForkOption{})
17
+	MakeRequest(t, req, http.StatusUnauthorized)
18
+}

+ 39 - 0
integrations/api_keys_test.go

@@ -0,0 +1,39 @@
1
+// Copyright 2017 The Gogs Authors. All rights reserved.
2
+// Use of this source code is governed by a MIT-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package integrations
6
+
7
+import (
8
+	"net/http"
9
+	"testing"
10
+
11
+	api "code.gitea.io/sdk/gitea"
12
+)
13
+
14
+func TestViewDeployKeysNoLogin(t *testing.T) {
15
+	prepareTestEnv(t)
16
+	req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/keys")
17
+	MakeRequest(t, req, http.StatusUnauthorized)
18
+}
19
+
20
+func TestCreateDeployKeyNoLogin(t *testing.T) {
21
+	prepareTestEnv(t)
22
+	req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/keys", api.CreateKeyOption{
23
+		Title: "title",
24
+		Key:   "key",
25
+	})
26
+	MakeRequest(t, req, http.StatusUnauthorized)
27
+}
28
+
29
+func TestGetDeployKeyNoLogin(t *testing.T) {
30
+	prepareTestEnv(t)
31
+	req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/keys/1")
32
+	MakeRequest(t, req, http.StatusUnauthorized)
33
+}
34
+
35
+func TestDeleteDeployKeyNoLogin(t *testing.T) {
36
+	prepareTestEnv(t)
37
+	req := NewRequest(t, "DELETE", "/api/v1/repos/user2/repo1/keys/1")
38
+	MakeRequest(t, req, http.StatusUnauthorized)
39
+}

+ 12 - 0
integrations/api_repo_test.go

@@ -51,3 +51,15 @@ func TestAPISearchRepoNotLogin(t *testing.T) {
51 51
 		assert.True(t, strings.Contains(repo.Name, keyword))
52 52
 	}
53 53
 }
54
+
55
+func TestAPIViewRepo(t *testing.T) {
56
+	prepareTestEnv(t)
57
+
58
+	req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1")
59
+	resp := MakeRequest(t, req, http.StatusOK)
60
+
61
+	var repo api.Repository
62
+	DecodeJSON(t, resp, &repo)
63
+	assert.EqualValues(t, 1, repo.ID)
64
+	assert.EqualValues(t, "repo1", repo.Name)
65
+}

+ 43 - 33
routers/api/v1/api.go

@@ -42,6 +42,7 @@ import (
42 42
 	"code.gitea.io/gitea/routers/api/v1/org"
43 43
 	"code.gitea.io/gitea/routers/api/v1/repo"
44 44
 	"code.gitea.io/gitea/routers/api/v1/user"
45
+	"code.gitea.io/gitea/routers/api/v1/utils"
45 46
 )
46 47
 
47 48
 func repoAssignment() macaron.Handler {
@@ -92,7 +93,7 @@ func repoAssignment() macaron.Handler {
92 93
 		if ctx.IsSigned && ctx.User.IsAdmin {
93 94
 			ctx.Repo.AccessMode = models.AccessModeOwner
94 95
 		} else {
95
-			mode, err := models.AccessLevel(ctx.User.ID, repo)
96
+			mode, err := models.AccessLevel(utils.UserID(ctx), repo)
96 97
 			if err != nil {
97 98
 				ctx.Error(500, "AccessLevel", err)
98 99
 				return
@@ -341,27 +342,27 @@ func RegisterRoutes(m *macaron.Macaron) {
341 342
 		m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID)
342 343
 
343 344
 		m.Group("/repos", func() {
344
-			m.Post("/migrate", bind(auth.MigrateRepoForm{}), repo.Migrate)
345
+			m.Post("/migrate", reqToken(), bind(auth.MigrateRepoForm{}), repo.Migrate)
345 346
 
346 347
 			m.Group("/:username/:reponame", func() {
347
-				m.Combo("").Get(repo.Get).Delete(repo.Delete)
348
+				m.Combo("").Get(repo.Get).Delete(reqToken(), repo.Delete)
348 349
 				m.Group("/hooks", func() {
349 350
 					m.Combo("").Get(repo.ListHooks).
350 351
 						Post(bind(api.CreateHookOption{}), repo.CreateHook)
351 352
 					m.Combo("/:id").Get(repo.GetHook).
352 353
 						Patch(bind(api.EditHookOption{}), repo.EditHook).
353 354
 						Delete(repo.DeleteHook)
354
-				}, reqRepoWriter())
355
+				}, reqToken(), reqRepoWriter())
355 356
 				m.Group("/collaborators", func() {
356 357
 					m.Get("", repo.ListCollaborators)
357 358
 					m.Combo("/:collaborator").Get(repo.IsCollaborator).
358 359
 						Put(bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
359 360
 						Delete(repo.DeleteCollaborator)
360
-				})
361
+				}, reqToken())
361 362
 				m.Get("/raw/*", context.RepoRef(), repo.GetRawFile)
362 363
 				m.Get("/archive/*", repo.GetArchive)
363 364
 				m.Combo("/forks").Get(repo.ListForks).
364
-					Post(bind(api.CreateForkOption{}), repo.CreateFork)
365
+					Post(reqToken(), bind(api.CreateForkOption{}), repo.CreateFork)
365 366
 				m.Group("/branches", func() {
366 367
 					m.Get("", repo.ListBranches)
367 368
 					m.Get("/*", context.RepoRef(), repo.GetBranch)
@@ -371,78 +372,87 @@ func RegisterRoutes(m *macaron.Macaron) {
371 372
 						Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
372 373
 					m.Combo("/:id").Get(repo.GetDeployKey).
373 374
 						Delete(repo.DeleteDeploykey)
374
-				})
375
+				}, reqToken())
375 376
 				m.Group("/issues", func() {
376
-					m.Combo("").Get(repo.ListIssues).Post(bind(api.CreateIssueOption{}), repo.CreateIssue)
377
+					m.Combo("").Get(repo.ListIssues).
378
+						Post(reqToken(), bind(api.CreateIssueOption{}), repo.CreateIssue)
377 379
 					m.Group("/comments", func() {
378 380
 						m.Get("", repo.ListRepoIssueComments)
379
-						m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
381
+						m.Combo("/:id", reqToken()).
382
+							Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
380 383
 					})
381 384
 					m.Group("/:index", func() {
382
-						m.Combo("").Get(repo.GetIssue).Patch(bind(api.EditIssueOption{}), repo.EditIssue)
385
+						m.Combo("").Get(repo.GetIssue).
386
+							Patch(reqToken(), bind(api.EditIssueOption{}), repo.EditIssue)
383 387
 
384 388
 						m.Group("/comments", func() {
385
-							m.Combo("").Get(repo.ListIssueComments).Post(bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
386
-							m.Combo("/:id").Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
389
+							m.Combo("").Get(repo.ListIssueComments).
390
+								Post(reqToken(), bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
391
+							m.Combo("/:id", reqToken()).Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
387 392
 								Delete(repo.DeleteIssueComment)
388 393
 						})
389 394
 
390 395
 						m.Group("/labels", func() {
391 396
 							m.Combo("").Get(repo.ListIssueLabels).
392
-								Post(bind(api.IssueLabelsOption{}), repo.AddIssueLabels).
393
-								Put(bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels).
394
-								Delete(repo.ClearIssueLabels)
395
-							m.Delete("/:id", repo.DeleteIssueLabel)
397
+								Post(reqToken(), bind(api.IssueLabelsOption{}), repo.AddIssueLabels).
398
+								Put(reqToken(), bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels).
399
+								Delete(reqToken(), repo.ClearIssueLabels)
400
+							m.Delete("/:id", reqToken(), repo.DeleteIssueLabel)
396 401
 						})
397 402
 
398 403
 					})
399 404
 				}, mustEnableIssues)
400 405
 				m.Group("/labels", func() {
401 406
 					m.Combo("").Get(repo.ListLabels).
402
-						Post(bind(api.CreateLabelOption{}), repo.CreateLabel)
403
-					m.Combo("/:id").Get(repo.GetLabel).Patch(bind(api.EditLabelOption{}), repo.EditLabel).
404
-						Delete(repo.DeleteLabel)
407
+						Post(reqToken(), bind(api.CreateLabelOption{}), repo.CreateLabel)
408
+					m.Combo("/:id").Get(repo.GetLabel).
409
+						Patch(reqToken(), bind(api.EditLabelOption{}), repo.EditLabel).
410
+						Delete(reqToken(), repo.DeleteLabel)
405 411
 				})
406 412
 				m.Group("/milestones", func() {
407 413
 					m.Combo("").Get(repo.ListMilestones).
408
-						Post(reqRepoWriter(), bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
414
+						Post(reqToken(), reqRepoWriter(), bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
409 415
 					m.Combo("/:id").Get(repo.GetMilestone).
410
-						Patch(reqRepoWriter(), bind(api.EditMilestoneOption{}), repo.EditMilestone).
411
-						Delete(reqRepoWriter(), repo.DeleteMilestone)
416
+						Patch(reqToken(), reqRepoWriter(), bind(api.EditMilestoneOption{}), repo.EditMilestone).
417
+						Delete(reqToken(), reqRepoWriter(), repo.DeleteMilestone)
412 418
 				})
413 419
 				m.Get("/stargazers", repo.ListStargazers)
414 420
 				m.Get("/subscribers", repo.ListSubscribers)
415 421
 				m.Group("/subscription", func() {
416 422
 					m.Get("", user.IsWatching)
417
-					m.Put("", user.Watch)
418
-					m.Delete("", user.Unwatch)
423
+					m.Put("", reqToken(), user.Watch)
424
+					m.Delete("", reqToken(), user.Unwatch)
419 425
 				})
420 426
 				m.Group("/releases", func() {
421 427
 					m.Combo("").Get(repo.ListReleases).
422
-						Post(bind(api.CreateReleaseOption{}), repo.CreateRelease)
428
+						Post(reqToken(), bind(api.CreateReleaseOption{}), repo.CreateRelease)
423 429
 					m.Combo("/:id").Get(repo.GetRelease).
424
-						Patch(bind(api.EditReleaseOption{}), repo.EditRelease).
425
-						Delete(repo.DeleteRelease)
430
+						Patch(reqToken(), bind(api.EditReleaseOption{}), repo.EditRelease).
431
+						Delete(reqToken(), repo.DeleteRelease)
426 432
 				})
427
-				m.Post("/mirror-sync", repo.MirrorSync)
433
+				m.Post("/mirror-sync", reqToken(), repo.MirrorSync)
428 434
 				m.Get("/editorconfig/:filename", context.RepoRef(), repo.GetEditorconfig)
429 435
 				m.Group("/pulls", func() {
430
-					m.Combo("").Get(bind(api.ListPullRequestsOptions{}), repo.ListPullRequests).Post(reqRepoWriter(), bind(api.CreatePullRequestOption{}), repo.CreatePullRequest)
436
+					m.Combo("").Get(bind(api.ListPullRequestsOptions{}), repo.ListPullRequests).
437
+						Post(reqToken(), reqRepoWriter(), bind(api.CreatePullRequestOption{}), repo.CreatePullRequest)
431 438
 					m.Group("/:index", func() {
432
-						m.Combo("").Get(repo.GetPullRequest).Patch(reqRepoWriter(), bind(api.EditPullRequestOption{}), repo.EditPullRequest)
433
-						m.Combo("/merge").Get(repo.IsPullRequestMerged).Post(reqRepoWriter(), repo.MergePullRequest)
439
+						m.Combo("").Get(repo.GetPullRequest).
440
+							Patch(reqToken(), reqRepoWriter(), bind(api.EditPullRequestOption{}), repo.EditPullRequest)
441
+						m.Combo("/merge").Get(repo.IsPullRequestMerged).
442
+							Post(reqToken(), reqRepoWriter(), repo.MergePullRequest)
434 443
 					})
435 444
 
436 445
 				}, mustAllowPulls, context.ReferencesGitRepo())
437 446
 				m.Group("/statuses", func() {
438
-					m.Combo("/:sha").Get(repo.GetCommitStatuses).Post(reqRepoWriter(), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
447
+					m.Combo("/:sha").Get(repo.GetCommitStatuses).
448
+						Post(reqToken(), reqRepoWriter(), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
439 449
 				})
440 450
 				m.Group("/commits/:ref", func() {
441 451
 					m.Get("/status", repo.GetCombinedCommitStatus)
442 452
 					m.Get("/statuses", repo.GetCommitStatuses)
443 453
 				})
444 454
 			}, repoAssignment())
445
-		}, reqToken())
455
+		})
446 456
 
447 457
 		// Organizations
448 458
 		m.Get("/user/orgs", reqToken(), org.ListMyOrgs)

+ 2 - 1
routers/api/v1/repo/fork.go

@@ -9,6 +9,7 @@ import (
9 9
 
10 10
 	"code.gitea.io/gitea/models"
11 11
 	"code.gitea.io/gitea/modules/context"
12
+	"code.gitea.io/gitea/routers/api/v1/utils"
12 13
 )
13 14
 
14 15
 // ListForks list a repository's forks
@@ -29,7 +30,7 @@ func ListForks(ctx *context.APIContext) {
29 30
 	}
30 31
 	apiForks := make([]*api.Repository, len(forks))
31 32
 	for i, fork := range forks {
32
-		access, err := models.AccessLevel(ctx.User.ID, fork)
33
+		access, err := models.AccessLevel(utils.UserID(ctx), fork)
33 34
 		if err != nil {
34 35
 			ctx.Error(500, "AccessLevel", err)
35 36
 			return

+ 1 - 7
routers/api/v1/repo/release.go

@@ -34,14 +34,8 @@ func GetRelease(ctx *context.APIContext) {
34 34
 
35 35
 // ListReleases list a repository's releases
36 36
 func ListReleases(ctx *context.APIContext) {
37
-	access, err := models.AccessLevel(ctx.User.ID, ctx.Repo.Repository)
38
-	if err != nil {
39
-		ctx.Error(500, "AccessLevel", err)
40
-		return
41
-	}
42
-
43 37
 	releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{
44
-		IncludeDrafts: access >= models.AccessModeWrite,
38
+		IncludeDrafts: ctx.Repo.AccessMode >= models.AccessModeWrite,
45 39
 	}, 1, 2147483647)
46 40
 	if err != nil {
47 41
 		ctx.Error(500, "GetReleasesByRepoID", err)

+ 1 - 7
routers/api/v1/repo/repo.go

@@ -267,13 +267,7 @@ func Get(ctx *context.APIContext) {
267 267
 	//       200: Repository
268 268
 	//       500: error
269 269
 
270
-	repo := ctx.Repo.Repository
271
-	access, err := models.AccessLevel(ctx.User.ID, repo)
272
-	if err != nil {
273
-		ctx.Error(500, "GetRepository", err)
274
-		return
275
-	}
276
-	ctx.JSON(200, repo.APIFormat(access))
270
+	ctx.JSON(200, ctx.Repo.Repository.APIFormat(ctx.Repo.AccessMode))
277 271
 }
278 272
 
279 273
 // GetByID returns a single Repository

+ 1 - 6
routers/api/v1/repo/status.go

@@ -103,15 +103,10 @@ func GetCombinedCommitStatus(ctx *context.APIContext) {
103 103
 		return
104 104
 	}
105 105
 
106
-	acl, err := models.AccessLevel(ctx.User.ID, repo)
107
-	if err != nil {
108
-		ctx.Error(500, "AccessLevel", fmt.Errorf("AccessLevel[%d, %s]: %v", ctx.User.ID, repo.FullName(), err))
109
-		return
110
-	}
111 106
 	retStatus := &combinedCommitStatus{
112 107
 		SHA:        sha,
113 108
 		TotalCount: len(statuses),
114
-		Repo:       repo.APIFormat(acl),
109
+		Repo:       repo.APIFormat(ctx.Repo.AccessMode),
115 110
 		URL:        "",
116 111
 	}
117 112
 

+ 15 - 0
routers/api/v1/utils/utils.go

@@ -0,0 +1,15 @@
1
+// Copyright 2017 The Gitea Authors. All rights reserved.
2
+// Use of this source code is governed by a MIT-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package utils
6
+
7
+import "code.gitea.io/gitea/modules/context"
8
+
9
+// UserID user ID of authenticated user, or 0 if not authenticated
10
+func UserID(ctx *context.APIContext) int64 {
11
+	if ctx.User == nil {
12
+		return 0
13
+	}
14
+	return ctx.User.ID
15
+}