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

395 lines
9.8 KiB

  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 := ctx.Org.Team
  118. team.Name = form.Name
  119. team.Description = form.Description
  120. team.Authorize = models.ParseAccessMode(form.Permission)
  121. if err := models.UpdateTeam(team, true); err != nil {
  122. ctx.Error(500, "EditTeam", err)
  123. return
  124. }
  125. ctx.JSON(200, convert.ToTeam(team))
  126. }
  127. // DeleteTeam api for delete a team
  128. func DeleteTeam(ctx *context.APIContext) {
  129. // swagger:operation DELETE /teams/{id} organization orgDeleteTeam
  130. // ---
  131. // summary: Delete a team
  132. // parameters:
  133. // - name: id
  134. // in: path
  135. // description: id of the team to delete
  136. // type: integer
  137. // required: true
  138. // responses:
  139. // "204":
  140. // description: team deleted
  141. // schema:
  142. // "$ref": "#/responses/empty"
  143. if err := models.DeleteTeam(ctx.Org.Team); err != nil {
  144. ctx.Error(500, "DeleteTeam", err)
  145. return
  146. }
  147. ctx.Status(204)
  148. }
  149. // GetTeamMembers api for get a team's members
  150. func GetTeamMembers(ctx *context.APIContext) {
  151. // swagger:operation GET /teams/{id}/members organization orgListTeamMembers
  152. // ---
  153. // summary: List a team's members
  154. // produces:
  155. // - application/json
  156. // parameters:
  157. // - name: id
  158. // in: path
  159. // description: id of the team
  160. // type: integer
  161. // required: true
  162. // responses:
  163. // "200":
  164. // "$ref": "#/responses/UserList"
  165. isMember, err := models.IsOrganizationMember(ctx.Org.Team.OrgID, ctx.User.ID)
  166. if err != nil {
  167. ctx.Error(500, "IsOrganizationMember", err)
  168. return
  169. } else if !isMember {
  170. ctx.Status(404)
  171. return
  172. }
  173. team := ctx.Org.Team
  174. if err := team.GetMembers(); err != nil {
  175. ctx.Error(500, "GetTeamMembers", err)
  176. return
  177. }
  178. members := make([]*api.User, len(team.Members))
  179. for i, member := range team.Members {
  180. members[i] = member.APIFormat()
  181. }
  182. ctx.JSON(200, members)
  183. }
  184. // AddTeamMember api for add a member to a team
  185. func AddTeamMember(ctx *context.APIContext) {
  186. // swagger:operation PUT /teams/{id}/members/{username} organization orgAddTeamMember
  187. // ---
  188. // summary: Add a team member
  189. // produces:
  190. // - application/json
  191. // parameters:
  192. // - name: id
  193. // in: path
  194. // description: id of the team
  195. // type: integer
  196. // required: true
  197. // - name: username
  198. // in: path
  199. // description: username of the user to add
  200. // type: string
  201. // required: true
  202. // responses:
  203. // "204":
  204. // "$ref": "#/responses/empty"
  205. u := user.GetUserByParams(ctx)
  206. if ctx.Written() {
  207. return
  208. }
  209. if err := ctx.Org.Team.AddMember(u.ID); err != nil {
  210. ctx.Error(500, "AddMember", err)
  211. return
  212. }
  213. ctx.Status(204)
  214. }
  215. // RemoveTeamMember api for remove one member from a team
  216. func RemoveTeamMember(ctx *context.APIContext) {
  217. // swagger:operation DELETE /teams/{id}/members/{username} organization orgRemoveTeamMember
  218. // ---
  219. // summary: Remove a team member
  220. // produces:
  221. // - application/json
  222. // parameters:
  223. // - name: id
  224. // in: path
  225. // description: id of the team
  226. // type: integer
  227. // required: true
  228. // - name: username
  229. // in: path
  230. // description: username of the user to remove
  231. // type: string
  232. // required: true
  233. // responses:
  234. // "204":
  235. // "$ref": "#/responses/empty"
  236. u := user.GetUserByParams(ctx)
  237. if ctx.Written() {
  238. return
  239. }
  240. if err := ctx.Org.Team.RemoveMember(u.ID); err != nil {
  241. ctx.Error(500, "RemoveMember", err)
  242. return
  243. }
  244. ctx.Status(204)
  245. }
  246. // GetTeamRepos api for get a team's repos
  247. func GetTeamRepos(ctx *context.APIContext) {
  248. // swagger:operation GET /teams/{id}/repos organization orgListTeamRepos
  249. // ---
  250. // summary: List a team's repos
  251. // produces:
  252. // - application/json
  253. // parameters:
  254. // - name: id
  255. // in: path
  256. // description: id of the team
  257. // type: integer
  258. // required: true
  259. // responses:
  260. // "200":
  261. // "$ref": "#/responses/RepositoryList"
  262. team := ctx.Org.Team
  263. if err := team.GetRepositories(); err != nil {
  264. ctx.Error(500, "GetTeamRepos", err)
  265. }
  266. repos := make([]*api.Repository, len(team.Repos))
  267. for i, repo := range team.Repos {
  268. access, err := models.AccessLevel(ctx.User.ID, repo)
  269. if err != nil {
  270. ctx.Error(500, "GetTeamRepos", err)
  271. return
  272. }
  273. repos[i] = repo.APIFormat(access)
  274. }
  275. ctx.JSON(200, repos)
  276. }
  277. // getRepositoryByParams get repository by a team's organization ID and repo name
  278. func getRepositoryByParams(ctx *context.APIContext) *models.Repository {
  279. repo, err := models.GetRepositoryByName(ctx.Org.Team.OrgID, ctx.Params(":reponame"))
  280. if err != nil {
  281. if models.IsErrRepoNotExist(err) {
  282. ctx.Status(404)
  283. } else {
  284. ctx.Error(500, "GetRepositoryByName", err)
  285. }
  286. return nil
  287. }
  288. return repo
  289. }
  290. // AddTeamRepository api for adding a repository to a team
  291. func AddTeamRepository(ctx *context.APIContext) {
  292. // swagger:operation PUT /teams/{id}/repos/{org}/{repo} organization orgAddTeamRepository
  293. // ---
  294. // summary: Add a repository to a team
  295. // produces:
  296. // - application/json
  297. // parameters:
  298. // - name: id
  299. // in: path
  300. // description: id of the team
  301. // type: integer
  302. // required: true
  303. // - name: org
  304. // in: path
  305. // description: organization that owns the repo to add
  306. // type: string
  307. // required: true
  308. // - name: repo
  309. // in: path
  310. // description: name of the repo to add
  311. // type: string
  312. // required: true
  313. // responses:
  314. // "204":
  315. // "$ref": "#/responses/empty"
  316. repo := getRepositoryByParams(ctx)
  317. if ctx.Written() {
  318. return
  319. }
  320. if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
  321. ctx.Error(500, "AccessLevel", err)
  322. return
  323. } else if access < models.AccessModeAdmin {
  324. ctx.Error(403, "", "Must have admin-level access to the repository")
  325. return
  326. }
  327. if err := ctx.Org.Team.AddRepository(repo); err != nil {
  328. ctx.Error(500, "AddRepository", err)
  329. return
  330. }
  331. ctx.Status(204)
  332. }
  333. // RemoveTeamRepository api for removing a repository from a team
  334. func RemoveTeamRepository(ctx *context.APIContext) {
  335. // swagger:operation DELETE /teams/{id}/repos/{org}/{repo} organization orgRemoveTeamRepository
  336. // ---
  337. // summary: Remove a repository from a team
  338. // description: This does not delete the repository, it only removes the
  339. // repository from the team.
  340. // produces:
  341. // - application/json
  342. // parameters:
  343. // - name: id
  344. // in: path
  345. // description: id of the team
  346. // type: integer
  347. // required: true
  348. // - name: org
  349. // in: path
  350. // description: organization that owns the repo to remove
  351. // type: string
  352. // required: true
  353. // - name: repo
  354. // in: path
  355. // description: name of the repo to remove
  356. // type: string
  357. // required: true
  358. // responses:
  359. // "204":
  360. // "$ref": "#/responses/empty"
  361. repo := getRepositoryByParams(ctx)
  362. if ctx.Written() {
  363. return
  364. }
  365. if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
  366. ctx.Error(500, "AccessLevel", err)
  367. return
  368. } else if access < models.AccessModeAdmin {
  369. ctx.Error(403, "", "Must have admin-level access to the repository")
  370. return
  371. }
  372. if err := ctx.Org.Team.RemoveRepository(repo.ID); err != nil {
  373. ctx.Error(500, "RemoveRepository", err)
  374. return
  375. }
  376. ctx.Status(204)
  377. }