Add GetUserTeams (#18499)
		
	* COrrect use `UserID` in `SearchTeams` - Use `UserID` in the `SearchTeams` function, currently it was useless to pass such information. Now it does a INNER statement to `team_user` which obtains UserID -> TeamID data. - Make OrgID optional. - Resolves #18484 * Seperate searching specific user * Add condition back * Use correct struct type Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		
					parent
					
						
							
								f6f4e1ddb9
							
						
					
				
			
			
				commit
				
					
						d3b31cc1ee
					
				
			
		
					 5 changed files with 62 additions and 18 deletions
				
			
		| 
						 | 
					@ -49,22 +49,67 @@ func init() {
 | 
				
			||||||
	db.RegisterModel(new(TeamUnit))
 | 
						db.RegisterModel(new(TeamUnit))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SearchTeamOptions holds the search options
 | 
					// SearchOrgTeamOptions holds the search options
 | 
				
			||||||
type SearchTeamOptions struct {
 | 
					type SearchOrgTeamOptions struct {
 | 
				
			||||||
	db.ListOptions
 | 
						db.ListOptions
 | 
				
			||||||
	UserID      int64
 | 
					 | 
				
			||||||
	Keyword     string
 | 
						Keyword     string
 | 
				
			||||||
	OrgID       int64
 | 
						OrgID       int64
 | 
				
			||||||
	IncludeDesc bool
 | 
						IncludeDesc bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetUserTeamOptions holds the search options.
 | 
				
			||||||
 | 
					type GetUserTeamOptions struct {
 | 
				
			||||||
 | 
						db.ListOptions
 | 
				
			||||||
 | 
						UserID int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SearchMembersOptions holds the search options
 | 
					// SearchMembersOptions holds the search options
 | 
				
			||||||
type SearchMembersOptions struct {
 | 
					type SearchMembersOptions struct {
 | 
				
			||||||
	db.ListOptions
 | 
						db.ListOptions
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SearchTeam search for teams. Caller is responsible to check permissions.
 | 
					// GetUserTeams search for org teams. Caller is responsible to check permissions.
 | 
				
			||||||
func SearchTeam(opts *SearchTeamOptions) ([]*Team, int64, error) {
 | 
					func GetUserTeams(opts *GetUserTeamOptions) ([]*Team, int64, error) {
 | 
				
			||||||
 | 
						if opts.Page <= 0 {
 | 
				
			||||||
 | 
							opts.Page = 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if opts.PageSize == 0 {
 | 
				
			||||||
 | 
							// Default limit
 | 
				
			||||||
 | 
							opts.PageSize = 10
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sess := db.GetEngine(db.DefaultContext)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id").
 | 
				
			||||||
 | 
							And("team_user.uid=?", opts.UserID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						count, err := sess.
 | 
				
			||||||
 | 
							Count(new(Team))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if opts.PageSize == -1 {
 | 
				
			||||||
 | 
							opts.PageSize = int(count)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sess = sess.Join("INNER", "team_user", "team_user.team_id = team.id").
 | 
				
			||||||
 | 
							And("team_user.uid=?", opts.UserID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						teams := make([]*Team, 0, opts.PageSize)
 | 
				
			||||||
 | 
						if err = sess.
 | 
				
			||||||
 | 
							OrderBy("lower_name").
 | 
				
			||||||
 | 
							Find(&teams); err != nil {
 | 
				
			||||||
 | 
							return nil, 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return teams, count, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SearchOrgTeams search for org teams. Caller is responsible to check permissions.
 | 
				
			||||||
 | 
					func SearchOrgTeams(opts *SearchOrgTeamOptions) ([]*Team, int64, error) {
 | 
				
			||||||
	if opts.Page <= 0 {
 | 
						if opts.Page <= 0 {
 | 
				
			||||||
		opts.Page = 1
 | 
							opts.Page = 1
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -196,7 +241,7 @@ func (t *Team) getRepositories(e db.Engine) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetRepositories returns paginated repositories in team of organization.
 | 
					// GetRepositories returns paginated repositories in team of organization.
 | 
				
			||||||
func (t *Team) GetRepositories(opts *SearchTeamOptions) error {
 | 
					func (t *Team) GetRepositories(opts *SearchOrgTeamOptions) error {
 | 
				
			||||||
	if opts.Page == 0 {
 | 
						if opts.Page == 0 {
 | 
				
			||||||
		return t.getRepositories(db.GetEngine(db.DefaultContext))
 | 
							return t.getRepositories(db.GetEngine(db.DefaultContext))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -716,7 +761,7 @@ func UpdateTeam(t *Team, authChanged, includeAllChanged bool) (err error) {
 | 
				
			||||||
// DeleteTeam deletes given team.
 | 
					// DeleteTeam deletes given team.
 | 
				
			||||||
// It's caller's responsibility to assign organization ID.
 | 
					// It's caller's responsibility to assign organization ID.
 | 
				
			||||||
func DeleteTeam(t *Team) error {
 | 
					func DeleteTeam(t *Team) error {
 | 
				
			||||||
	if err := t.GetRepositories(&SearchTeamOptions{}); err != nil {
 | 
						if err := t.GetRepositories(&SearchOrgTeamOptions{}); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -858,7 +903,7 @@ func AddTeamMember(team *Team, userID int64) error {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get team and its repositories.
 | 
						// Get team and its repositories.
 | 
				
			||||||
	if err := team.GetRepositories(&SearchTeamOptions{}); err != nil {
 | 
						if err := team.GetRepositories(&SearchOrgTeamOptions{}); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ func TestTeam_GetRepositories(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	test := func(teamID int64) {
 | 
						test := func(teamID int64) {
 | 
				
			||||||
		team := unittest.AssertExistsAndLoadBean(t, &Team{ID: teamID}).(*Team)
 | 
							team := unittest.AssertExistsAndLoadBean(t, &Team{ID: teamID}).(*Team)
 | 
				
			||||||
		assert.NoError(t, team.GetRepositories(&SearchTeamOptions{}))
 | 
							assert.NoError(t, team.GetRepositories(&SearchOrgTeamOptions{}))
 | 
				
			||||||
		assert.Len(t, team.Repos, team.NumRepos)
 | 
							assert.Len(t, team.Repos, team.NumRepos)
 | 
				
			||||||
		for _, repo := range team.Repos {
 | 
							for _, repo := range team.Repos {
 | 
				
			||||||
			unittest.AssertExistsAndLoadBean(t, &TeamRepo{TeamID: teamID, RepoID: repo.ID})
 | 
								unittest.AssertExistsAndLoadBean(t, &TeamRepo{TeamID: teamID, RepoID: repo.ID})
 | 
				
			||||||
| 
						 | 
					@ -292,7 +292,7 @@ func TestGetTeamMembers(t *testing.T) {
 | 
				
			||||||
func TestGetUserTeams(t *testing.T) {
 | 
					func TestGetUserTeams(t *testing.T) {
 | 
				
			||||||
	assert.NoError(t, unittest.PrepareTestDatabase())
 | 
						assert.NoError(t, unittest.PrepareTestDatabase())
 | 
				
			||||||
	test := func(userID int64) {
 | 
						test := func(userID int64) {
 | 
				
			||||||
		teams, _, err := SearchTeam(&SearchTeamOptions{UserID: userID})
 | 
							teams, _, err := GetUserTeams(&GetUserTeamOptions{UserID: userID})
 | 
				
			||||||
		assert.NoError(t, err)
 | 
							assert.NoError(t, err)
 | 
				
			||||||
		for _, team := range teams {
 | 
							for _, team := range teams {
 | 
				
			||||||
			unittest.AssertExistsAndLoadBean(t, &TeamUser{TeamID: team.ID, UID: userID})
 | 
								unittest.AssertExistsAndLoadBean(t, &TeamUser{TeamID: team.ID, UID: userID})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testTeamRepositories := func(teamID int64, repoIds []int64) {
 | 
						testTeamRepositories := func(teamID int64, repoIds []int64) {
 | 
				
			||||||
		team := unittest.AssertExistsAndLoadBean(t, &models.Team{ID: teamID}).(*models.Team)
 | 
							team := unittest.AssertExistsAndLoadBean(t, &models.Team{ID: teamID}).(*models.Team)
 | 
				
			||||||
		assert.NoError(t, team.GetRepositories(&models.SearchTeamOptions{}), "%s: GetRepositories", team.Name)
 | 
							assert.NoError(t, team.GetRepositories(&models.SearchOrgTeamOptions{}), "%s: GetRepositories", team.Name)
 | 
				
			||||||
		assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name)
 | 
							assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name)
 | 
				
			||||||
		assert.Len(t, team.Repos, len(repoIds), "%s: repo count", team.Name)
 | 
							assert.Len(t, team.Repos, len(repoIds), "%s: repo count", team.Name)
 | 
				
			||||||
		for i, rid := range repoIds {
 | 
							for i, rid := range repoIds {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ func ListTeams(ctx *context.APIContext) {
 | 
				
			||||||
	//   "200":
 | 
						//   "200":
 | 
				
			||||||
	//     "$ref": "#/responses/TeamList"
 | 
						//     "$ref": "#/responses/TeamList"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	teams, count, err := models.SearchTeam(&models.SearchTeamOptions{
 | 
						teams, count, err := models.SearchOrgTeams(&models.SearchOrgTeamOptions{
 | 
				
			||||||
		ListOptions: utils.GetListOptions(ctx),
 | 
							ListOptions: utils.GetListOptions(ctx),
 | 
				
			||||||
		OrgID:       ctx.Org.Organization.ID,
 | 
							OrgID:       ctx.Org.Organization.ID,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
| 
						 | 
					@ -90,7 +90,7 @@ func ListUserTeams(ctx *context.APIContext) {
 | 
				
			||||||
	//   "200":
 | 
						//   "200":
 | 
				
			||||||
	//     "$ref": "#/responses/TeamList"
 | 
						//     "$ref": "#/responses/TeamList"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	teams, count, err := models.SearchTeam(&models.SearchTeamOptions{
 | 
						teams, count, err := models.GetUserTeams(&models.GetUserTeamOptions{
 | 
				
			||||||
		ListOptions: utils.GetListOptions(ctx),
 | 
							ListOptions: utils.GetListOptions(ctx),
 | 
				
			||||||
		UserID:      ctx.User.ID,
 | 
							UserID:      ctx.User.ID,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
| 
						 | 
					@ -533,7 +533,7 @@ func GetTeamRepos(ctx *context.APIContext) {
 | 
				
			||||||
	//     "$ref": "#/responses/RepositoryList"
 | 
						//     "$ref": "#/responses/RepositoryList"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	team := ctx.Org.Team
 | 
						team := ctx.Org.Team
 | 
				
			||||||
	if err := team.GetRepositories(&models.SearchTeamOptions{
 | 
						if err := team.GetRepositories(&models.SearchOrgTeamOptions{
 | 
				
			||||||
		ListOptions: utils.GetListOptions(ctx),
 | 
							ListOptions: utils.GetListOptions(ctx),
 | 
				
			||||||
	}); err != nil {
 | 
						}); err != nil {
 | 
				
			||||||
		ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
 | 
							ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
 | 
				
			||||||
| 
						 | 
					@ -707,15 +707,14 @@ func SearchTeam(ctx *context.APIContext) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	listOptions := utils.GetListOptions(ctx)
 | 
						listOptions := utils.GetListOptions(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts := &models.SearchTeamOptions{
 | 
						opts := &models.SearchOrgTeamOptions{
 | 
				
			||||||
		UserID:      ctx.User.ID,
 | 
					 | 
				
			||||||
		Keyword:     ctx.FormTrim("q"),
 | 
							Keyword:     ctx.FormTrim("q"),
 | 
				
			||||||
		OrgID:       ctx.Org.Organization.ID,
 | 
							OrgID:       ctx.Org.Organization.ID,
 | 
				
			||||||
		IncludeDesc: ctx.FormString("include_desc") == "" || ctx.FormBool("include_desc"),
 | 
							IncludeDesc: ctx.FormString("include_desc") == "" || ctx.FormBool("include_desc"),
 | 
				
			||||||
		ListOptions: listOptions,
 | 
							ListOptions: listOptions,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	teams, maxResults, err := models.SearchTeam(opts)
 | 
						teams, maxResults, err := models.SearchOrgTeams(opts)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error("SearchTeam failed: %v", err)
 | 
							log.Error("SearchTeam failed: %v", err)
 | 
				
			||||||
		ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
 | 
							ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -319,7 +319,7 @@ func TeamRepositories(ctx *context.Context) {
 | 
				
			||||||
	ctx.Data["Title"] = ctx.Org.Team.Name
 | 
						ctx.Data["Title"] = ctx.Org.Team.Name
 | 
				
			||||||
	ctx.Data["PageIsOrgTeams"] = true
 | 
						ctx.Data["PageIsOrgTeams"] = true
 | 
				
			||||||
	ctx.Data["PageIsOrgTeamRepos"] = true
 | 
						ctx.Data["PageIsOrgTeamRepos"] = true
 | 
				
			||||||
	if err := ctx.Org.Team.GetRepositories(&models.SearchTeamOptions{}); err != nil {
 | 
						if err := ctx.Org.Team.GetRepositories(&models.SearchOrgTeamOptions{}); err != nil {
 | 
				
			||||||
		ctx.ServerError("GetRepositories", err)
 | 
							ctx.ServerError("GetRepositories", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue