mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	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:
		
				
					committed by
					
						 techknowlogick
						techknowlogick
					
				
			
			
				
	
			
			
			
						parent
						
							734834a676
						
					
				
				
					commit
					5ac6da3c41
				
			
							
								
								
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							| @@ -11,11 +11,11 @@ | |||||||
|  |  | ||||||
| [[projects]] | [[projects]] | ||||||
|   branch = "master" |   branch = "master" | ||||||
|   digest = "1:aed2bc1c4026233af8ad43cab9d9464a0e3b906d3d058d2d6e814f3e1ddfa528" |   digest = "1:8a559f110defa54f847a3efa2734297571d960b476699579f2008e4a37b62a1a" | ||||||
|   name = "code.gitea.io/sdk" |   name = "code.gitea.io/sdk" | ||||||
|   packages = ["gitea"] |   packages = ["gitea"] | ||||||
|   pruneopts = "NUT" |   pruneopts = "NUT" | ||||||
|   revision = "d95a6e0392218961d1bdd18020290a20bd61b063" |   revision = "140e9fcba7583e1c6f22eb57676bb00794ef14a8" | ||||||
|  |  | ||||||
| [[projects]] | [[projects]] | ||||||
|   digest = "1:3fcef06a1a6561955c94af6c7757a6fa37605eb653f0d06ab960e5bb80092195" |   digest = "1:3fcef06a1a6561955c94af6c7757a6fa37605eb653f0d06ab960e5bb80092195" | ||||||
|   | |||||||
| @@ -522,7 +522,7 @@ func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Delete member in his/her teams. | 	// Delete member in his/her teams. | ||||||
| 	teams, err := getUserTeams(sess, org.ID, userID) | 	teams, err := getUserOrgTeams(sess, org.ID, userID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -543,7 +543,14 @@ func GetTeamMembers(teamID int64) ([]*User, error) { | |||||||
| 	return getTeamMembers(x, teamID) | 	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. | 	return teams, e. | ||||||
| 		Join("INNER", "team_user", "team_user.team_id = team.id"). | 		Join("INNER", "team_user", "team_user.team_id = team.id"). | ||||||
| 		Where("team.org_id = ?", orgID). | 		Where("team.org_id = ?", orgID). | ||||||
| @@ -561,9 +568,14 @@ func getUserRepoTeams(e Engine, orgID, userID, repoID int64) (teams []*Team, err | |||||||
| 		Find(&teams) | 		Find(&teams) | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetUserTeams returns all teams that user belongs to in given organization. | // GetUserOrgTeams returns all teams that user belongs to in given organization. | ||||||
| func GetUserTeams(orgID, userID int64) ([]*Team, error) { | func GetUserOrgTeams(orgID, userID int64) ([]*Team, error) { | ||||||
| 	return getUserTeams(x, orgID, userID) | 	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, | // AddTeamMember adds new membership of given team to given organization, | ||||||
|   | |||||||
| @@ -284,9 +284,23 @@ func TestGetTeamMembers(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestGetUserTeams(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()) | 	assert.NoError(t, PrepareTestDatabase()) | ||||||
| 	test := func(orgID, userID int64) { | 	test := func(orgID, userID int64) { | ||||||
| 		teams, err := GetUserTeams(orgID, userID) | 		teams, err := GetUserOrgTeams(orgID, userID) | ||||||
| 		assert.NoError(t, err) | 		assert.NoError(t, err) | ||||||
| 		for _, team := range teams { | 		for _, team := range teams { | ||||||
| 			assert.EqualValues(t, orgID, team.OrgID) | 			assert.EqualValues(t, orgID, team.OrgID) | ||||||
|   | |||||||
| @@ -463,6 +463,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||||
| 			m.Get("/times", repo.ListMyTrackedTimes) | 			m.Get("/times", repo.ListMyTrackedTimes) | ||||||
|  |  | ||||||
| 			m.Get("/subscriptions", user.GetMyWatchedRepos) | 			m.Get("/subscriptions", user.GetMyWatchedRepos) | ||||||
|  |  | ||||||
|  | 			m.Get("/teams", org.ListUserTeams) | ||||||
| 		}, reqToken()) | 		}, reqToken()) | ||||||
|  |  | ||||||
| 		// Repositories | 		// Repositories | ||||||
| @@ -652,6 +654,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||||
| 			m.Group("/members", func() { | 			m.Group("/members", func() { | ||||||
| 				m.Get("", org.GetTeamMembers) | 				m.Get("", org.GetTeamMembers) | ||||||
| 				m.Combo("/:username"). | 				m.Combo("/:username"). | ||||||
|  | 					Get(org.GetTeamMember). | ||||||
| 					Put(reqOrgOwnership(), org.AddTeamMember). | 					Put(reqOrgOwnership(), org.AddTeamMember). | ||||||
| 					Delete(reqOrgOwnership(), org.RemoveTeamMember) | 					Delete(reqOrgOwnership(), org.RemoveTeamMember) | ||||||
| 			}) | 			}) | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| // Copyright 2016 The Gogs Authors. All rights reserved. | // 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 | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
| @@ -42,6 +43,41 @@ func ListTeams(ctx *context.APIContext) { | |||||||
| 	ctx.JSON(200, apiTeams) | 	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 | // GetTeam api for get a team | ||||||
| func GetTeam(ctx *context.APIContext) { | func GetTeam(ctx *context.APIContext) { | ||||||
| 	// swagger:operation GET /teams/{id} organization orgGetTeam | 	// swagger:operation GET /teams/{id} organization orgGetTeam | ||||||
| @@ -221,6 +257,35 @@ func GetTeamMembers(ctx *context.APIContext) { | |||||||
| 	ctx.JSON(200, members) | 	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 | // AddTeamMember api for add a member to a team | ||||||
| func AddTeamMember(ctx *context.APIContext) { | func AddTeamMember(ctx *context.APIContext) { | ||||||
| 	// swagger:operation PUT /teams/{id}/members/{username} organization orgAddTeamMember | 	// swagger:operation PUT /teams/{id}/members/{username} organization orgAddTeamMember | ||||||
|   | |||||||
| @@ -4629,6 +4629,38 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "/teams/{id}/members/{username}": { |     "/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": { |       "put": { | ||||||
|         "produces": [ |         "produces": [ | ||||||
|           "application/json" |           "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": { |     "/user/times": { | ||||||
|       "get": { |       "get": { | ||||||
|         "produces": [ |         "produces": [ | ||||||
| @@ -7942,6 +7991,9 @@ | |||||||
|           "type": "string", |           "type": "string", | ||||||
|           "x-go-name": "Name" |           "x-go-name": "Name" | ||||||
|         }, |         }, | ||||||
|  |         "organization": { | ||||||
|  |           "$ref": "#/definitions/Organization" | ||||||
|  |         }, | ||||||
|         "permission": { |         "permission": { | ||||||
|           "type": "string", |           "type": "string", | ||||||
|           "enum": [ |           "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"` | 	After      string           `json:"after"` | ||||||
| 	CompareURL string           `json:"compare_url"` | 	CompareURL string           `json:"compare_url"` | ||||||
| 	Commits    []*PayloadCommit `json:"commits"` | 	Commits    []*PayloadCommit `json:"commits"` | ||||||
|  | 	HeadCommit *PayloadCommit   `json:"head_commit"` | ||||||
| 	Repo       *Repository      `json:"repository"` | 	Repo       *Repository      `json:"repository"` | ||||||
| 	Pusher     *User            `json:"pusher"` | 	Pusher     *User            `json:"pusher"` | ||||||
| 	Sender     *User            `json:"sender"` | 	Sender     *User            `json:"sender"` | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								vendor/code.gitea.io/sdk/gitea/org_team.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/code.gitea.io/sdk/gitea/org_team.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,9 +7,10 @@ package gitea | |||||||
|  |  | ||||||
| // Team represents a team in an organization | // Team represents a team in an organization | ||||||
| type Team struct { | type Team struct { | ||||||
| 	ID          int64  `json:"id"` | 	ID           int64         `json:"id"` | ||||||
| 	Name        string `json:"name"` | 	Name         string        `json:"name"` | ||||||
| 	Description string `json:"description"` | 	Description  string        `json:"description"` | ||||||
|  | 	Organization *Organization `json:"organization"` | ||||||
| 	// enum: none,read,write,admin,owner | 	// enum: none,read,write,admin,owner | ||||||
| 	Permission string `json:"permission"` | 	Permission string `json:"permission"` | ||||||
| 	// enum: repo.code,repo.issues,repo.ext_issues,repo.wiki,repo.pulls,repo.releases,repo.ext_wiki | 	// 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 { | type CreateReleaseOption struct { | ||||||
| 	// required: true | 	// required: true | ||||||
| 	TagName      string `json:"tag_name" binding:"Required"` | 	TagName      string `json:"tag_name" binding:"Required"` | ||||||
| 	Target       string `json:"target_commitish"` | 	Target       string `json:"target_commitish" binding:"Required"` | ||||||
| 	Title        string `json:"name"` | 	Title        string `json:"name"` | ||||||
| 	Note         string `json:"body"` | 	Note         string `json:"body"` | ||||||
| 	IsDraft      bool   `json:"draft"` | 	IsDraft      bool   `json:"draft"` | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user