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 11 kB

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