api: Add missing GET teams endpoints (#5382)
* api: Add an endpoint to list a particular member of team. * models: Rename `GetUserTeams()` to `GetUserOrgTeams()` in `org_team` model. `GetUserTeams()` sounds a bit misnomer since it actually returns the teams that user belongs to in a given organization rather than all the teams across all the organization that the user has joined. * models: Add `GetUserTeams()`. Returns all the teams that a user belongs to. * api: Add an endpoint for GET '/user/teams'. A GET request to this endpoint lists all the teams that a user belongs to.
This commit is contained in:
		
							parent
							
								
									734834a676
								
							
						
					
					
						commit
						5ac6da3c41
					
				
					 10 changed files with 160 additions and 12 deletions
				
			
		
							
								
								
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							|  | @ -11,11 +11,11 @@ | |||
| 
 | ||||
| [[projects]] | ||||
|   branch = "master" | ||||
|   digest = "1:aed2bc1c4026233af8ad43cab9d9464a0e3b906d3d058d2d6e814f3e1ddfa528" | ||||
|   digest = "1:8a559f110defa54f847a3efa2734297571d960b476699579f2008e4a37b62a1a" | ||||
|   name = "code.gitea.io/sdk" | ||||
|   packages = ["gitea"] | ||||
|   pruneopts = "NUT" | ||||
|   revision = "d95a6e0392218961d1bdd18020290a20bd61b063" | ||||
|   revision = "140e9fcba7583e1c6f22eb57676bb00794ef14a8" | ||||
| 
 | ||||
| [[projects]] | ||||
|   digest = "1:3fcef06a1a6561955c94af6c7757a6fa37605eb653f0d06ab960e5bb80092195" | ||||
|  |  | |||
|  | @ -522,7 +522,7 @@ func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { | |||
| 	} | ||||
| 
 | ||||
| 	// Delete member in his/her teams.
 | ||||
| 	teams, err := getUserTeams(sess, org.ID, userID) | ||||
| 	teams, err := getUserOrgTeams(sess, org.ID, userID) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -543,7 +543,14 @@ func GetTeamMembers(teamID int64) ([]*User, error) { | |||
| 	return getTeamMembers(x, teamID) | ||||
| } | ||||
| 
 | ||||
| func getUserTeams(e Engine, orgID, userID int64) (teams []*Team, err error) { | ||||
| func getUserTeams(e Engine, userID int64) (teams []*Team, err error) { | ||||
| 	return teams, e. | ||||
| 		Join("INNER", "team_user", "team_user.team_id = team.id"). | ||||
| 		Where("team_user.uid=?", userID). | ||||
| 		Find(&teams) | ||||
| } | ||||
| 
 | ||||
| func getUserOrgTeams(e Engine, orgID, userID int64) (teams []*Team, err error) { | ||||
| 	return teams, e. | ||||
| 		Join("INNER", "team_user", "team_user.team_id = team.id"). | ||||
| 		Where("team.org_id = ?", orgID). | ||||
|  | @ -561,9 +568,14 @@ func getUserRepoTeams(e Engine, orgID, userID, repoID int64) (teams []*Team, err | |||
| 		Find(&teams) | ||||
| } | ||||
| 
 | ||||
| // GetUserTeams returns all teams that user belongs to in given organization.
 | ||||
| func GetUserTeams(orgID, userID int64) ([]*Team, error) { | ||||
| 	return getUserTeams(x, orgID, userID) | ||||
| // GetUserOrgTeams returns all teams that user belongs to in given organization.
 | ||||
| func GetUserOrgTeams(orgID, userID int64) ([]*Team, error) { | ||||
| 	return getUserOrgTeams(x, orgID, userID) | ||||
| } | ||||
| 
 | ||||
| // GetUserTeams returns all teams that user belongs across all organizations.
 | ||||
| func GetUserTeams(userID int64) ([]*Team, error) { | ||||
| 	return getUserTeams(x, userID) | ||||
| } | ||||
| 
 | ||||
| // AddTeamMember adds new membership of given team to given organization,
 | ||||
|  |  | |||
|  | @ -284,9 +284,23 @@ func TestGetTeamMembers(t *testing.T) { | |||
| } | ||||
| 
 | ||||
| func TestGetUserTeams(t *testing.T) { | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 	test := func(userID int64) { | ||||
| 		teams, err := GetUserTeams(userID) | ||||
| 		assert.NoError(t, err) | ||||
| 		for _, team := range teams { | ||||
| 			AssertExistsAndLoadBean(t, &TeamUser{TeamID: team.ID, UID: userID}) | ||||
| 		} | ||||
| 	} | ||||
| 	test(2) | ||||
| 	test(5) | ||||
| 	test(NonexistentID) | ||||
| } | ||||
| 
 | ||||
| func TestGetUserOrgTeams(t *testing.T) { | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 	test := func(orgID, userID int64) { | ||||
| 		teams, err := GetUserTeams(orgID, userID) | ||||
| 		teams, err := GetUserOrgTeams(orgID, userID) | ||||
| 		assert.NoError(t, err) | ||||
| 		for _, team := range teams { | ||||
| 			assert.EqualValues(t, orgID, team.OrgID) | ||||
|  |  | |||
|  | @ -463,6 +463,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| 			m.Get("/times", repo.ListMyTrackedTimes) | ||||
| 
 | ||||
| 			m.Get("/subscriptions", user.GetMyWatchedRepos) | ||||
| 
 | ||||
| 			m.Get("/teams", org.ListUserTeams) | ||||
| 		}, reqToken()) | ||||
| 
 | ||||
| 		// Repositories
 | ||||
|  | @ -652,6 +654,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| 			m.Group("/members", func() { | ||||
| 				m.Get("", org.GetTeamMembers) | ||||
| 				m.Combo("/:username"). | ||||
| 					Get(org.GetTeamMember). | ||||
| 					Put(reqOrgOwnership(), org.AddTeamMember). | ||||
| 					Delete(reqOrgOwnership(), org.RemoveTeamMember) | ||||
| 			}) | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| // Copyright 2016 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2019 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
|  | @ -42,6 +43,41 @@ func ListTeams(ctx *context.APIContext) { | |||
| 	ctx.JSON(200, apiTeams) | ||||
| } | ||||
| 
 | ||||
| // ListUserTeams list all the teams a user belongs to
 | ||||
| func ListUserTeams(ctx *context.APIContext) { | ||||
| 	// swagger:operation GET /user/teams user userListTeams
 | ||||
| 	// ---
 | ||||
| 	// summary: List all the teams a user belongs to
 | ||||
| 	// produces:
 | ||||
| 	// - application/json
 | ||||
| 	// responses:
 | ||||
| 	//   "200":
 | ||||
| 	//     "$ref": "#/responses/TeamList"
 | ||||
| 	teams, err := models.GetUserTeams(ctx.User.ID) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(500, "GetUserTeams", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	cache := make(map[int64]*api.Organization) | ||||
| 	apiTeams := make([]*api.Team, len(teams)) | ||||
| 	for i := range teams { | ||||
| 		apiOrg, ok := cache[teams[i].OrgID] | ||||
| 		if !ok { | ||||
| 			org, err := models.GetUserByID(teams[i].OrgID) | ||||
| 			if err != nil { | ||||
| 				ctx.Error(500, "GetUserByID", err) | ||||
| 				return | ||||
| 			} | ||||
| 			apiOrg = convert.ToOrganization(org) | ||||
| 			cache[teams[i].OrgID] = apiOrg | ||||
| 		} | ||||
| 		apiTeams[i] = convert.ToTeam(teams[i]) | ||||
| 		apiTeams[i].Organization = apiOrg | ||||
| 	} | ||||
| 	ctx.JSON(200, apiTeams) | ||||
| } | ||||
| 
 | ||||
| // GetTeam api for get a team
 | ||||
| func GetTeam(ctx *context.APIContext) { | ||||
| 	// swagger:operation GET /teams/{id} organization orgGetTeam
 | ||||
|  | @ -221,6 +257,35 @@ func GetTeamMembers(ctx *context.APIContext) { | |||
| 	ctx.JSON(200, members) | ||||
| } | ||||
| 
 | ||||
| // GetTeamMember api for get a particular member of team
 | ||||
| func GetTeamMember(ctx *context.APIContext) { | ||||
| 	// swagger:operation GET /teams/{id}/members/{username} organization orgListTeamMember
 | ||||
| 	// ---
 | ||||
| 	// summary: List a particular member of team
 | ||||
| 	// produces:
 | ||||
| 	// - application/json
 | ||||
| 	// parameters:
 | ||||
| 	// - name: id
 | ||||
| 	//   in: path
 | ||||
| 	//   description: id of the team
 | ||||
| 	//   type: integer
 | ||||
| 	//   format: int64
 | ||||
| 	//   required: true
 | ||||
| 	// - name: username
 | ||||
| 	//   in: path
 | ||||
| 	//   description: username of the member to list
 | ||||
| 	//   type: string
 | ||||
| 	//   required: true
 | ||||
| 	// responses:
 | ||||
| 	//   "200":
 | ||||
| 	//     "$ref": "#/responses/User"
 | ||||
| 	u := user.GetUserByParams(ctx) | ||||
| 	if ctx.Written() { | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.JSON(200, u.APIFormat()) | ||||
| } | ||||
| 
 | ||||
| // AddTeamMember api for add a member to a team
 | ||||
| func AddTeamMember(ctx *context.APIContext) { | ||||
| 	// swagger:operation PUT /teams/{id}/members/{username} organization orgAddTeamMember
 | ||||
|  |  | |||
|  | @ -4629,6 +4629,38 @@ | |||
|       } | ||||
|     }, | ||||
|     "/teams/{id}/members/{username}": { | ||||
|       "get": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "organization" | ||||
|         ], | ||||
|         "summary": "List a particular member of team", | ||||
|         "operationId": "orgListTeamMember", | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "type": "integer", | ||||
|             "format": "int64", | ||||
|             "description": "id of the team", | ||||
|             "name": "id", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           }, | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "username of the member to list", | ||||
|             "name": "username", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "200": { | ||||
|             "$ref": "#/responses/User" | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       "put": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|  | @ -5418,6 +5450,23 @@ | |||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/user/teams": { | ||||
|       "get": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "user" | ||||
|         ], | ||||
|         "summary": "List all the teams a user belongs to", | ||||
|         "operationId": "userListTeams", | ||||
|         "responses": { | ||||
|           "200": { | ||||
|             "$ref": "#/responses/TeamList" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/user/times": { | ||||
|       "get": { | ||||
|         "produces": [ | ||||
|  | @ -7942,6 +7991,9 @@ | |||
|           "type": "string", | ||||
|           "x-go-name": "Name" | ||||
|         }, | ||||
|         "organization": { | ||||
|           "$ref": "#/definitions/Organization" | ||||
|         }, | ||||
|         "permission": { | ||||
|           "type": "string", | ||||
|           "enum": [ | ||||
|  |  | |||
							
								
								
									
										1
									
								
								vendor/code.gitea.io/sdk/gitea/hook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/code.gitea.io/sdk/gitea/hook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -371,6 +371,7 @@ type PushPayload struct { | |||
| 	After      string           `json:"after"` | ||||
| 	CompareURL string           `json:"compare_url"` | ||||
| 	Commits    []*PayloadCommit `json:"commits"` | ||||
| 	HeadCommit *PayloadCommit   `json:"head_commit"` | ||||
| 	Repo       *Repository      `json:"repository"` | ||||
| 	Pusher     *User            `json:"pusher"` | ||||
| 	Sender     *User            `json:"sender"` | ||||
|  |  | |||
							
								
								
									
										1
									
								
								vendor/code.gitea.io/sdk/gitea/org_team.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/code.gitea.io/sdk/gitea/org_team.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -10,6 +10,7 @@ type Team struct { | |||
| 	ID           int64         `json:"id"` | ||||
| 	Name         string        `json:"name"` | ||||
| 	Description  string        `json:"description"` | ||||
| 	Organization *Organization `json:"organization"` | ||||
| 	// enum: none,read,write,admin,owner
 | ||||
| 	Permission string `json:"permission"` | ||||
| 	// enum: repo.code,repo.issues,repo.ext_issues,repo.wiki,repo.pulls,repo.releases,repo.ext_wiki
 | ||||
|  |  | |||
							
								
								
									
										2
									
								
								vendor/code.gitea.io/sdk/gitea/release.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/code.gitea.io/sdk/gitea/release.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -53,7 +53,7 @@ func (c *Client) GetRelease(user, repo string, id int64) (*Release, error) { | |||
| type CreateReleaseOption struct { | ||||
| 	// required: true
 | ||||
| 	TagName      string `json:"tag_name" binding:"Required"` | ||||
| 	Target       string `json:"target_commitish"` | ||||
| 	Target       string `json:"target_commitish" binding:"Required"` | ||||
| 	Title        string `json:"name"` | ||||
| 	Note         string `json:"body"` | ||||
| 	IsDraft      bool   `json:"draft"` | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue