diff --git a/models/user.go b/models/user.go index 2a7699557..e2b259300 100644 --- a/models/user.go +++ b/models/user.go @@ -538,6 +538,7 @@ func (u *User) GetOwnedOrganizations() (err error) { } // GetOrganizations returns paginated organizations that user belongs to. +// TODO: does not respect All and show orgs you privately participate func (u *User) GetOrganizations(opts *SearchOrganizationsOptions) error { sess := x.NewSession() defer sess.Close() diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 987f14107..ca3e10173 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -17,19 +17,28 @@ import ( "code.gitea.io/gitea/routers/api/v1/utils" ) -func listUserOrgs(ctx *context.APIContext, u *models.User, all bool) { - if err := u.GetOrganizations(&models.SearchOrganizationsOptions{ - ListOptions: utils.GetListOptions(ctx), - All: all, - }); err != nil { - ctx.Error(http.StatusInternalServerError, "GetOrganizations", err) +func listUserOrgs(ctx *context.APIContext, u *models.User) { + + listOptions := utils.GetListOptions(ctx) + showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == u.ID) + + orgs, err := models.GetOrgsByUserID(u.ID, showPrivate) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetOrgsByUserID", err) return } + maxResults := len(orgs) + + orgs = utils.PaginateUserSlice(orgs, listOptions.Page, listOptions.PageSize) - apiOrgs := make([]*api.Organization, len(u.Orgs)) - for i := range u.Orgs { - apiOrgs[i] = convert.ToOrganization(u.Orgs[i]) + apiOrgs := make([]*api.Organization, len(orgs)) + for i := range orgs { + apiOrgs[i] = convert.ToOrganization(orgs[i]) } + + ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) + ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", maxResults)) + ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, Link") ctx.JSON(http.StatusOK, &apiOrgs) } @@ -53,7 +62,7 @@ func ListMyOrgs(ctx *context.APIContext) { // "200": // "$ref": "#/responses/OrganizationList" - listUserOrgs(ctx, ctx.User, true) + listUserOrgs(ctx, ctx.User) } // ListUserOrgs list user's orgs @@ -85,7 +94,7 @@ func ListUserOrgs(ctx *context.APIContext) { if ctx.Written() { return } - listUserOrgs(ctx, u, ctx.User != nil && (ctx.User.IsAdmin || ctx.User.ID == u.ID)) + listUserOrgs(ctx, u) } // GetAll return list of all public organizations diff --git a/routers/api/v1/utils/utils.go b/routers/api/v1/utils/utils.go index ad1a136db..5732ea7f7 100644 --- a/routers/api/v1/utils/utils.go +++ b/routers/api/v1/utils/utils.go @@ -66,3 +66,22 @@ func GetListOptions(ctx *context.APIContext) models.ListOptions { PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")), } } + +// PaginateUserSlice cut a slice of Users as per pagination options +// TODO: make it generic +func PaginateUserSlice(items []*models.User, page, pageSize int) []*models.User { + if page != 0 { + page-- + } + + if page*pageSize >= len(items) { + return items[len(items):] + } + + items = items[page*pageSize:] + + if len(items) > pageSize { + return items[:pageSize] + } + return items +}