You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

team.go 10 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. // Copyright 2016 The Gogs 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. package org
  5. import (
  6. api "code.gitea.io/sdk/gitea"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/routers/api/v1/convert"
  10. "code.gitea.io/gitea/routers/api/v1/user"
  11. )
  12. // ListTeams list all the teams of an organization
  13. func ListTeams(ctx *context.APIContext) {
  14. // swagger:operation GET /orgs/{org}/teams organization orgListTeams
  15. // ---
  16. // summary: List an organization's teams
  17. // produces:
  18. // - application/json
  19. // parameters:
  20. // - name: org
  21. // in: path
  22. // description: name of the organization
  23. // type: string
  24. // required: true
  25. // responses:
  26. // "200":
  27. // "$ref": "#/responses/TeamList"
  28. org := ctx.Org.Organization
  29. if err := org.GetTeams(); err != nil {
  30. ctx.Error(500, "GetTeams", err)
  31. return
  32. }
  33. apiTeams := make([]*api.Team, len(org.Teams))
  34. for i := range org.Teams {
  35. apiTeams[i] = convert.ToTeam(org.Teams[i])
  36. }
  37. ctx.JSON(200, apiTeams)
  38. }
  39. // GetTeam api for get a team
  40. func GetTeam(ctx *context.APIContext) {
  41. // swagger:operation GET /teams/{id} organization orgGetTeam
  42. // ---
  43. // summary: Get a team
  44. // produces:
  45. // - application/json
  46. // parameters:
  47. // - name: id
  48. // in: path
  49. // description: id of the team to get
  50. // type: integer
  51. // required: true
  52. // responses:
  53. // "200":
  54. // "$ref": "#/responses/Team"
  55. ctx.JSON(200, convert.ToTeam(ctx.Org.Team))
  56. }
  57. // CreateTeam api for create a team
  58. func CreateTeam(ctx *context.APIContext, form api.CreateTeamOption) {
  59. // swagger:operation POST /orgs/{org}/teams organization orgCreateTeam
  60. // ---
  61. // summary: Create a team
  62. // consumes:
  63. // - application/json
  64. // produces:
  65. // - application/json
  66. // parameters:
  67. // - name: org
  68. // in: path
  69. // description: name of the organization
  70. // type: string
  71. // required: true
  72. // - name: body
  73. // in: body
  74. // schema:
  75. // "$ref": "#/definitions/CreateTeamOption"
  76. // responses:
  77. // "201":
  78. // "$ref": "#/responses/Team"
  79. team := &models.Team{
  80. OrgID: ctx.Org.Organization.ID,
  81. Name: form.Name,
  82. Description: form.Description,
  83. Authorize: models.ParseAccessMode(form.Permission),
  84. }
  85. if err := models.NewTeam(team); err != nil {
  86. if models.IsErrTeamAlreadyExist(err) {
  87. ctx.Error(422, "", err)
  88. } else {
  89. ctx.Error(500, "NewTeam", err)
  90. }
  91. return
  92. }
  93. ctx.JSON(201, convert.ToTeam(team))
  94. }
  95. // EditTeam api for edit a team
  96. func EditTeam(ctx *context.APIContext, form api.EditTeamOption) {
  97. // swagger:operation PATCH /teams/{id} organization orgEditTeam
  98. // ---
  99. // summary: Edit a team
  100. // consumes:
  101. // - application/json
  102. // produces:
  103. // - application/json
  104. // parameters:
  105. // - name: id
  106. // in: path
  107. // description: id of the team to edit
  108. // type: integer
  109. // required: true
  110. // - name: body
  111. // in: body
  112. // schema:
  113. // "$ref": "#/definitions/EditTeamOption"
  114. // responses:
  115. // "200":
  116. // "$ref": "#/responses/Team"
  117. team := &models.Team{
  118. ID: ctx.Org.Team.ID,
  119. OrgID: ctx.Org.Team.OrgID,
  120. Name: form.Name,
  121. Description: form.Description,
  122. Authorize: models.ParseAccessMode(form.Permission),
  123. }
  124. if err := models.UpdateTeam(team, true); err != nil {
  125. ctx.Error(500, "EditTeam", err)
  126. return
  127. }
  128. ctx.JSON(200, convert.ToTeam(team))
  129. }
  130. // DeleteTeam api for delete a team
  131. func DeleteTeam(ctx *context.APIContext) {
  132. // swagger:operation DELETE /teams/{id} organization orgDeleteTeam
  133. // ---
  134. // summary: Delete a team
  135. // parameters:
  136. // - name: id
  137. // in: path
  138. // description: id of the team to delete
  139. // type: integer
  140. // required: true
  141. // responses:
  142. // "204":
  143. // description: team deleted
  144. // schema:
  145. // "$ref": "#/responses/empty"
  146. if err := models.DeleteTeam(ctx.Org.Team); err != nil {
  147. ctx.Error(500, "DeleteTeam", err)
  148. return
  149. }
  150. ctx.Status(204)
  151. }
  152. // GetTeamMembers api for get a team's members
  153. func GetTeamMembers(ctx *context.APIContext) {
  154. // swagger:operation GET /teams/{id}/members organization orgListTeamMembers
  155. // ---
  156. // summary: List a team's members
  157. // produces:
  158. // - application/json
  159. // parameters:
  160. // - name: id
  161. // in: path
  162. // description: id of the team
  163. // type: integer
  164. // required: true
  165. // responses:
  166. // "200":
  167. // "$ref": "#/responses/UserList"
  168. if !models.IsOrganizationMember(ctx.Org.Team.OrgID, ctx.User.ID) {
  169. ctx.Status(404)
  170. return
  171. }
  172. team := ctx.Org.Team
  173. if err := team.GetMembers(); err != nil {
  174. ctx.Error(500, "GetTeamMembers", err)
  175. return
  176. }
  177. members := make([]*api.User, len(team.Members))
  178. for i, member := range team.Members {
  179. members[i] = member.APIFormat()
  180. }
  181. ctx.JSON(200, members)
  182. }
  183. // AddTeamMember api for add a member to a team
  184. func AddTeamMember(ctx *context.APIContext) {
  185. // swagger:operation PUT /teams/{id}/members/{username} organization orgAddTeamMember
  186. // ---
  187. // summary: Add a team member
  188. // produces:
  189. // - application/json
  190. // parameters:
  191. // - name: id
  192. // in: path
  193. // description: id of the team
  194. // type: integer
  195. // required: true
  196. // - name: username
  197. // in: path
  198. // description: username of the user to add
  199. // type: string
  200. // required: true
  201. // responses:
  202. // "204":
  203. // "$ref": "#/responses/empty"
  204. u := user.GetUserByParams(ctx)
  205. if ctx.Written() {
  206. return
  207. }
  208. if err := ctx.Org.Team.AddMember(u.ID); err != nil {
  209. ctx.Error(500, "AddMember", err)
  210. return
  211. }
  212. ctx.Status(204)
  213. }
  214. // RemoveTeamMember api for remove one member from a team
  215. func RemoveTeamMember(ctx *context.APIContext) {
  216. // swagger:operation DELETE /teams/{id}/members/{username} organization orgAddTeamMember
  217. // ---
  218. // summary: Remove a team member
  219. // produces:
  220. // - application/json
  221. // parameters:
  222. // - name: id
  223. // in: path
  224. // description: id of the team
  225. // type: integer
  226. // required: true
  227. // - name: username
  228. // in: path
  229. // description: username of the user to remove
  230. // type: string
  231. // required: true
  232. // responses:
  233. // "204":
  234. // "$ref": "#/responses/empty"
  235. u := user.GetUserByParams(ctx)
  236. if ctx.Written() {
  237. return
  238. }
  239. if err := ctx.Org.Team.RemoveMember(u.ID); err != nil {
  240. ctx.Error(500, "RemoveMember", err)
  241. return
  242. }
  243. ctx.Status(204)
  244. }
  245. // GetTeamRepos api for get a team's repos
  246. func GetTeamRepos(ctx *context.APIContext) {
  247. // swagger:operation GET /teams/{id}/repos organization orgListTeamRepos
  248. // ---
  249. // summary: List a team's repos
  250. // produces:
  251. // - application/json
  252. // parameters:
  253. // - name: id
  254. // in: path
  255. // description: id of the team
  256. // type: integer
  257. // required: true
  258. // responses:
  259. // "200":
  260. // "$ref": "#/responses/RepositoryList"
  261. team := ctx.Org.Team
  262. if err := team.GetRepositories(); err != nil {
  263. ctx.Error(500, "GetTeamRepos", err)
  264. }
  265. repos := make([]*api.Repository, len(team.Repos))
  266. for i, repo := range team.Repos {
  267. access, err := models.AccessLevel(ctx.User.ID, repo)
  268. if err != nil {
  269. ctx.Error(500, "GetTeamRepos", err)
  270. return
  271. }
  272. repos[i] = repo.APIFormat(access)
  273. }
  274. ctx.JSON(200, repos)
  275. }
  276. // getRepositoryByParams get repository by a team's organization ID and repo name
  277. func getRepositoryByParams(ctx *context.APIContext) *models.Repository {
  278. repo, err := models.GetRepositoryByName(ctx.Org.Team.OrgID, ctx.Params(":reponame"))
  279. if err != nil {
  280. if models.IsErrRepoNotExist(err) {
  281. ctx.Status(404)
  282. } else {
  283. ctx.Error(500, "GetRepositoryByName", err)
  284. }
  285. return nil
  286. }
  287. return repo
  288. }
  289. // AddTeamRepository api for adding a repository to a team
  290. func AddTeamRepository(ctx *context.APIContext) {
  291. // swagger:operation PUT /teams/{id}/repos/{org}/{repo} organization orgAddTeamMember
  292. // ---
  293. // summary: Add a repository to a team
  294. // produces:
  295. // - application/json
  296. // parameters:
  297. // - name: id
  298. // in: path
  299. // description: id of the team
  300. // type: integer
  301. // required: true
  302. // - name: org
  303. // in: path
  304. // description: organization that owns the repo to add
  305. // type: string
  306. // required: true
  307. // - name: repo
  308. // in: path
  309. // description: name of the repo to add
  310. // type: string
  311. // required: true
  312. // responses:
  313. // "204":
  314. // "$ref": "#/responses/empty"
  315. repo := getRepositoryByParams(ctx)
  316. if ctx.Written() {
  317. return
  318. }
  319. if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
  320. ctx.Error(500, "AccessLevel", err)
  321. return
  322. } else if access < models.AccessModeAdmin {
  323. ctx.Error(403, "", "Must have admin-level access to the repository")
  324. return
  325. }
  326. if err := ctx.Org.Team.AddRepository(repo); err != nil {
  327. ctx.Error(500, "AddRepository", err)
  328. return
  329. }
  330. ctx.Status(204)
  331. }
  332. // RemoveTeamRepository api for removing a repository from a team
  333. func RemoveTeamRepository(ctx *context.APIContext) {
  334. // swagger:operation DELETE /teams/{id}/repos/{org}/{repo} organization orgAddTeamMember
  335. // ---
  336. // summary: Remove a repository from a team
  337. // description: This does not delete the repository, it only removes the
  338. // repository from the team.
  339. // produces:
  340. // - application/json
  341. // parameters:
  342. // - name: id
  343. // in: path
  344. // description: id of the team
  345. // type: integer
  346. // required: true
  347. // - name: org
  348. // in: path
  349. // description: organization that owns the repo to remove
  350. // type: string
  351. // required: true
  352. // - name: repo
  353. // in: path
  354. // description: name of the repo to remove
  355. // type: string
  356. // required: true
  357. // responses:
  358. // "204":
  359. // "$ref": "#/responses/empty"
  360. repo := getRepositoryByParams(ctx)
  361. if ctx.Written() {
  362. return
  363. }
  364. if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
  365. ctx.Error(500, "AccessLevel", err)
  366. return
  367. } else if access < models.AccessModeAdmin {
  368. ctx.Error(403, "", "Must have admin-level access to the repository")
  369. return
  370. }
  371. if err := ctx.Org.Team.RemoveRepository(repo.ID); err != nil {
  372. ctx.Error(500, "RemoveRepository", err)
  373. return
  374. }
  375. ctx.Status(204)
  376. }