mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Add API to check if team has repo access (#19540)
* Add API to check if team has repo access * Add test case
This commit is contained in:
		@@ -11,6 +11,7 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/organization"
 | 
						"code.gitea.io/gitea/models/organization"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/models/repo"
 | 
				
			||||||
	"code.gitea.io/gitea/models/unit"
 | 
						"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"
 | 
				
			||||||
@@ -239,3 +240,26 @@ func TestAPITeamSearch(t *testing.T) {
 | 
				
			|||||||
	req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5)
 | 
						req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5)
 | 
				
			||||||
	MakeRequest(t, req, http.StatusForbidden)
 | 
						MakeRequest(t, req, http.StatusForbidden)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestAPIGetTeamRepo(t *testing.T) {
 | 
				
			||||||
 | 
						defer prepareTestEnv(t)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User)
 | 
				
			||||||
 | 
						teamRepo := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 24}).(*repo.Repository)
 | 
				
			||||||
 | 
						team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var results api.Repository
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						token := getUserToken(t, user.Name)
 | 
				
			||||||
 | 
						req := NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token)
 | 
				
			||||||
 | 
						resp := MakeRequest(t, req, http.StatusOK)
 | 
				
			||||||
 | 
						DecodeJSON(t, resp, &results)
 | 
				
			||||||
 | 
						assert.Equal(t, "big_test_private_4", teamRepo.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// no access if not organization member
 | 
				
			||||||
 | 
						user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
 | 
				
			||||||
 | 
						token5 := getUserToken(t, user5.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req = NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token5)
 | 
				
			||||||
 | 
						MakeRequest(t, req, http.StatusNotFound)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1121,7 +1121,8 @@ func Routes() *web.Route {
 | 
				
			|||||||
				m.Get("", org.GetTeamRepos)
 | 
									m.Get("", org.GetTeamRepos)
 | 
				
			||||||
				m.Combo("/{org}/{reponame}").
 | 
									m.Combo("/{org}/{reponame}").
 | 
				
			||||||
					Put(org.AddTeamRepository).
 | 
										Put(org.AddTeamRepository).
 | 
				
			||||||
					Delete(org.RemoveTeamRepository)
 | 
										Delete(org.RemoveTeamRepository).
 | 
				
			||||||
 | 
										Get(org.GetTeamRepo)
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}, orgAssignment(false, true), reqToken(), reqTeamMembership())
 | 
							}, orgAssignment(false, true), reqToken(), reqTeamMembership())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -558,6 +558,55 @@ func GetTeamRepos(ctx *context.APIContext) {
 | 
				
			|||||||
	ctx.JSON(http.StatusOK, repos)
 | 
						ctx.JSON(http.StatusOK, repos)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetTeamRepo api for get a particular repo of team
 | 
				
			||||||
 | 
					func GetTeamRepo(ctx *context.APIContext) {
 | 
				
			||||||
 | 
						// swagger:operation GET /teams/{id}/repos/{org}/{repo} organization orgListTeamRepo
 | 
				
			||||||
 | 
						// ---
 | 
				
			||||||
 | 
						// summary: List a particular repo of team
 | 
				
			||||||
 | 
						// produces:
 | 
				
			||||||
 | 
						// - application/json
 | 
				
			||||||
 | 
						// parameters:
 | 
				
			||||||
 | 
						// - name: id
 | 
				
			||||||
 | 
						//   in: path
 | 
				
			||||||
 | 
						//   description: id of the team
 | 
				
			||||||
 | 
						//   type: integer
 | 
				
			||||||
 | 
						//   format: int64
 | 
				
			||||||
 | 
						//   required: true
 | 
				
			||||||
 | 
						// - name: org
 | 
				
			||||||
 | 
						//   in: path
 | 
				
			||||||
 | 
						//   description: organization that owns the repo to list
 | 
				
			||||||
 | 
						//   type: string
 | 
				
			||||||
 | 
						//   required: true
 | 
				
			||||||
 | 
						// - name: repo
 | 
				
			||||||
 | 
						//   in: path
 | 
				
			||||||
 | 
						//   description: name of the repo to list
 | 
				
			||||||
 | 
						//   type: string
 | 
				
			||||||
 | 
						//   required: true
 | 
				
			||||||
 | 
						// responses:
 | 
				
			||||||
 | 
						//   "200":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/Repository"
 | 
				
			||||||
 | 
						//   "404":
 | 
				
			||||||
 | 
						//     "$ref": "#/responses/notFound"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						repo := getRepositoryByParams(ctx)
 | 
				
			||||||
 | 
						if ctx.Written() {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !organization.HasTeamRepo(ctx, ctx.Org.Team.OrgID, ctx.Org.Team.ID, repo.ID) {
 | 
				
			||||||
 | 
							ctx.NotFound()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						access, err := models.AccessLevel(ctx.Doer, repo)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.JSON(http.StatusOK, convert.ToRepo(repo, access))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// getRepositoryByParams get repository by a team's organization ID and repo name
 | 
					// getRepositoryByParams get repository by a team's organization ID and repo name
 | 
				
			||||||
func getRepositoryByParams(ctx *context.APIContext) *repo_model.Repository {
 | 
					func getRepositoryByParams(ctx *context.APIContext) *repo_model.Repository {
 | 
				
			||||||
	repo, err := repo_model.GetRepositoryByName(ctx.Org.Team.OrgID, ctx.Params(":reponame"))
 | 
						repo, err := repo_model.GetRepositoryByName(ctx.Org.Team.OrgID, ctx.Params(":reponame"))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11114,6 +11114,48 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "/teams/{id}/repos/{org}/{repo}": {
 | 
					    "/teams/{id}/repos/{org}/{repo}": {
 | 
				
			||||||
 | 
					      "get": {
 | 
				
			||||||
 | 
					        "produces": [
 | 
				
			||||||
 | 
					          "application/json"
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "tags": [
 | 
				
			||||||
 | 
					          "organization"
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "summary": "List a particular repo of team",
 | 
				
			||||||
 | 
					        "operationId": "orgListTeamRepo",
 | 
				
			||||||
 | 
					        "parameters": [
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            "type": "integer",
 | 
				
			||||||
 | 
					            "format": "int64",
 | 
				
			||||||
 | 
					            "description": "id of the team",
 | 
				
			||||||
 | 
					            "name": "id",
 | 
				
			||||||
 | 
					            "in": "path",
 | 
				
			||||||
 | 
					            "required": true
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            "type": "string",
 | 
				
			||||||
 | 
					            "description": "organization that owns the repo to list",
 | 
				
			||||||
 | 
					            "name": "org",
 | 
				
			||||||
 | 
					            "in": "path",
 | 
				
			||||||
 | 
					            "required": true
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            "type": "string",
 | 
				
			||||||
 | 
					            "description": "name of the repo to list",
 | 
				
			||||||
 | 
					            "name": "repo",
 | 
				
			||||||
 | 
					            "in": "path",
 | 
				
			||||||
 | 
					            "required": true
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        "responses": {
 | 
				
			||||||
 | 
					          "200": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/Repository"
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "404": {
 | 
				
			||||||
 | 
					            "$ref": "#/responses/notFound"
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "put": {
 | 
					      "put": {
 | 
				
			||||||
        "produces": [
 | 
					        "produces": [
 | 
				
			||||||
          "application/json"
 | 
					          "application/json"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user