1// Copyright 2017 The Gitea Authors. All rights reserved.
2// Use of this source code is governed by a MIT-style
3// license that can be found in the LICENSE file.
4
5package user
6
7import (
8	"net/http"
9
10	"code.gitea.io/gitea/models"
11	"code.gitea.io/gitea/models/db"
12	"code.gitea.io/gitea/models/perm"
13	user_model "code.gitea.io/gitea/models/user"
14	"code.gitea.io/gitea/modules/context"
15	"code.gitea.io/gitea/modules/convert"
16	api "code.gitea.io/gitea/modules/structs"
17	"code.gitea.io/gitea/routers/api/v1/utils"
18)
19
20// listUserRepos - List the repositories owned by the given user.
21func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
22	opts := utils.GetListOptions(ctx)
23
24	repos, count, err := models.GetUserRepositories(&models.SearchRepoOptions{
25		Actor:       u,
26		Private:     private,
27		ListOptions: opts,
28		OrderBy:     "id ASC",
29	})
30	if err != nil {
31		ctx.Error(http.StatusInternalServerError, "GetUserRepositories", err)
32		return
33	}
34
35	apiRepos := make([]*api.Repository, 0, len(repos))
36	for i := range repos {
37		access, err := models.AccessLevel(ctx.User, repos[i])
38		if err != nil {
39			ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
40			return
41		}
42		if ctx.IsSigned && ctx.User.IsAdmin || access >= perm.AccessModeRead {
43			apiRepos = append(apiRepos, convert.ToRepo(repos[i], access))
44		}
45	}
46
47	ctx.SetLinkHeader(int(count), opts.PageSize)
48	ctx.SetTotalCountHeader(count)
49	ctx.JSON(http.StatusOK, &apiRepos)
50}
51
52// ListUserRepos - list the repos owned by the given user.
53func ListUserRepos(ctx *context.APIContext) {
54	// swagger:operation GET /users/{username}/repos user userListRepos
55	// ---
56	// summary: List the repos owned by the given user
57	// produces:
58	// - application/json
59	// parameters:
60	// - name: username
61	//   in: path
62	//   description: username of user
63	//   type: string
64	//   required: true
65	// - name: page
66	//   in: query
67	//   description: page number of results to return (1-based)
68	//   type: integer
69	// - name: limit
70	//   in: query
71	//   description: page size of results
72	//   type: integer
73	// responses:
74	//   "200":
75	//     "$ref": "#/responses/RepositoryList"
76
77	user := GetUserByParams(ctx)
78	if ctx.Written() {
79		return
80	}
81	private := ctx.IsSigned
82	listUserRepos(ctx, user, private)
83}
84
85// ListMyRepos - list the repositories you own or have access to.
86func ListMyRepos(ctx *context.APIContext) {
87	// swagger:operation GET /user/repos user userCurrentListRepos
88	// ---
89	// summary: List the repos that the authenticated user owns
90	// produces:
91	// - application/json
92	// parameters:
93	// - name: page
94	//   in: query
95	//   description: page number of results to return (1-based)
96	//   type: integer
97	// - name: limit
98	//   in: query
99	//   description: page size of results
100	//   type: integer
101	// responses:
102	//   "200":
103	//     "$ref": "#/responses/RepositoryList"
104
105	opts := &models.SearchRepoOptions{
106		ListOptions:        utils.GetListOptions(ctx),
107		Actor:              ctx.User,
108		OwnerID:            ctx.User.ID,
109		Private:            ctx.IsSigned,
110		IncludeDescription: true,
111	}
112
113	var err error
114	repos, count, err := models.SearchRepository(opts)
115	if err != nil {
116		ctx.Error(http.StatusInternalServerError, "SearchRepository", err)
117		return
118	}
119
120	results := make([]*api.Repository, len(repos))
121	for i, repo := range repos {
122		if err = repo.GetOwner(db.DefaultContext); err != nil {
123			ctx.Error(http.StatusInternalServerError, "GetOwner", err)
124			return
125		}
126		accessMode, err := models.AccessLevel(ctx.User, repo)
127		if err != nil {
128			ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
129		}
130		results[i] = convert.ToRepo(repo, accessMode)
131	}
132
133	ctx.SetLinkHeader(int(count), opts.ListOptions.PageSize)
134	ctx.SetTotalCountHeader(count)
135	ctx.JSON(http.StatusOK, &results)
136}
137
138// ListOrgRepos - list the repositories of an organization.
139func ListOrgRepos(ctx *context.APIContext) {
140	// swagger:operation GET /orgs/{org}/repos organization orgListRepos
141	// ---
142	// summary: List an organization's repos
143	// produces:
144	// - application/json
145	// parameters:
146	// - name: org
147	//   in: path
148	//   description: name of the organization
149	//   type: string
150	//   required: true
151	// - name: page
152	//   in: query
153	//   description: page number of results to return (1-based)
154	//   type: integer
155	// - name: limit
156	//   in: query
157	//   description: page size of results
158	//   type: integer
159	// responses:
160	//   "200":
161	//     "$ref": "#/responses/RepositoryList"
162
163	listUserRepos(ctx, ctx.Org.Organization.AsUser(), ctx.IsSigned)
164}
165