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.

teams.go 8.0 kB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. // Copyright 2014 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. "path"
  7. "strings"
  8. "github.com/Unknwon/com"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/auth"
  11. "code.gitea.io/gitea/modules/base"
  12. "code.gitea.io/gitea/modules/context"
  13. "code.gitea.io/gitea/modules/log"
  14. "code.gitea.io/gitea/routers/utils"
  15. )
  16. const (
  17. // tplTeams template path for teams list page
  18. tplTeams base.TplName = "org/team/teams"
  19. // tplTeamNew template path for create new team page
  20. tplTeamNew base.TplName = "org/team/new"
  21. // tplTeamMembers template path for showing team members page
  22. tplTeamMembers base.TplName = "org/team/members"
  23. // tplTeamRepositories template path for showing team repositories page
  24. tplTeamRepositories base.TplName = "org/team/repositories"
  25. )
  26. // Teams render teams list page
  27. func Teams(ctx *context.Context) {
  28. org := ctx.Org.Organization
  29. ctx.Data["Title"] = org.FullName
  30. ctx.Data["PageIsOrgTeams"] = true
  31. for _, t := range org.Teams {
  32. if err := t.GetMembers(); err != nil {
  33. ctx.ServerError("GetMembers", err)
  34. return
  35. }
  36. }
  37. ctx.Data["Teams"] = org.Teams
  38. ctx.HTML(200, tplTeams)
  39. }
  40. // TeamsAction response for join, leave, remove, add operations to team
  41. func TeamsAction(ctx *context.Context) {
  42. uid := com.StrTo(ctx.Query("uid")).MustInt64()
  43. if uid == 0 {
  44. ctx.Redirect(ctx.Org.OrgLink + "/teams")
  45. return
  46. }
  47. page := ctx.Query("page")
  48. var err error
  49. switch ctx.Params(":action") {
  50. case "join":
  51. if !ctx.Org.IsOwner {
  52. ctx.Error(404)
  53. return
  54. }
  55. err = ctx.Org.Team.AddMember(ctx.User.ID)
  56. case "leave":
  57. err = ctx.Org.Team.RemoveMember(ctx.User.ID)
  58. case "remove":
  59. if !ctx.Org.IsOwner {
  60. ctx.Error(404)
  61. return
  62. }
  63. err = ctx.Org.Team.RemoveMember(uid)
  64. page = "team"
  65. case "add":
  66. if !ctx.Org.IsOwner {
  67. ctx.Error(404)
  68. return
  69. }
  70. uname := utils.RemoveUsernameParameterSuffix(strings.ToLower(ctx.Query("uname")))
  71. var u *models.User
  72. u, err = models.GetUserByName(uname)
  73. if err != nil {
  74. if models.IsErrUserNotExist(err) {
  75. ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
  76. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
  77. } else {
  78. ctx.ServerError(" GetUserByName", err)
  79. }
  80. return
  81. }
  82. if u.IsOrganization() {
  83. ctx.Flash.Error(ctx.Tr("form.cannot_add_org_to_team"))
  84. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
  85. return
  86. }
  87. err = ctx.Org.Team.AddMember(u.ID)
  88. page = "team"
  89. }
  90. if err != nil {
  91. if models.IsErrLastOrgOwner(err) {
  92. ctx.Flash.Error(ctx.Tr("form.last_org_owner"))
  93. } else {
  94. log.Error(3, "Action(%s): %v", ctx.Params(":action"), err)
  95. ctx.JSON(200, map[string]interface{}{
  96. "ok": false,
  97. "err": err.Error(),
  98. })
  99. return
  100. }
  101. }
  102. switch page {
  103. case "team":
  104. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName)
  105. case "home":
  106. ctx.Redirect(ctx.Org.Organization.HomeLink())
  107. default:
  108. ctx.Redirect(ctx.Org.OrgLink + "/teams")
  109. }
  110. }
  111. // TeamsRepoAction operate team's repository
  112. func TeamsRepoAction(ctx *context.Context) {
  113. if !ctx.Org.IsOwner {
  114. ctx.Error(404)
  115. return
  116. }
  117. var err error
  118. switch ctx.Params(":action") {
  119. case "add":
  120. repoName := path.Base(ctx.Query("repo_name"))
  121. var repo *models.Repository
  122. repo, err = models.GetRepositoryByName(ctx.Org.Organization.ID, repoName)
  123. if err != nil {
  124. if models.IsErrRepoNotExist(err) {
  125. ctx.Flash.Error(ctx.Tr("org.teams.add_nonexistent_repo"))
  126. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
  127. return
  128. }
  129. ctx.ServerError("GetRepositoryByName", err)
  130. return
  131. }
  132. err = ctx.Org.Team.AddRepository(repo)
  133. case "remove":
  134. err = ctx.Org.Team.RemoveRepository(com.StrTo(ctx.Query("repoid")).MustInt64())
  135. }
  136. if err != nil {
  137. log.Error(3, "Action(%s): '%s' %v", ctx.Params(":action"), ctx.Org.Team.Name, err)
  138. ctx.ServerError("TeamsRepoAction", err)
  139. return
  140. }
  141. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName + "/repositories")
  142. }
  143. // NewTeam render create new team page
  144. func NewTeam(ctx *context.Context) {
  145. ctx.Data["Title"] = ctx.Org.Organization.FullName
  146. ctx.Data["PageIsOrgTeams"] = true
  147. ctx.Data["PageIsOrgTeamsNew"] = true
  148. ctx.Data["Team"] = &models.Team{}
  149. ctx.Data["Units"] = models.Units
  150. ctx.HTML(200, tplTeamNew)
  151. }
  152. // NewTeamPost response for create new team
  153. func NewTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
  154. ctx.Data["Title"] = ctx.Org.Organization.FullName
  155. ctx.Data["PageIsOrgTeams"] = true
  156. ctx.Data["PageIsOrgTeamsNew"] = true
  157. ctx.Data["Units"] = models.Units
  158. t := &models.Team{
  159. OrgID: ctx.Org.Organization.ID,
  160. Name: form.TeamName,
  161. Description: form.Description,
  162. Authorize: models.ParseAccessMode(form.Permission),
  163. }
  164. if t.Authorize < models.AccessModeAdmin {
  165. t.UnitTypes = form.Units
  166. }
  167. ctx.Data["Team"] = t
  168. if ctx.HasError() {
  169. ctx.HTML(200, tplTeamNew)
  170. return
  171. }
  172. if t.Authorize < models.AccessModeAdmin && len(form.Units) == 0 {
  173. ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
  174. return
  175. }
  176. if err := models.NewTeam(t); err != nil {
  177. ctx.Data["Err_TeamName"] = true
  178. switch {
  179. case models.IsErrTeamAlreadyExist(err):
  180. ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), tplTeamNew, &form)
  181. default:
  182. ctx.ServerError("NewTeam", err)
  183. }
  184. return
  185. }
  186. log.Trace("Team created: %s/%s", ctx.Org.Organization.Name, t.Name)
  187. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
  188. }
  189. // TeamMembers render team members page
  190. func TeamMembers(ctx *context.Context) {
  191. ctx.Data["Title"] = ctx.Org.Team.Name
  192. ctx.Data["PageIsOrgTeams"] = true
  193. if err := ctx.Org.Team.GetMembers(); err != nil {
  194. ctx.ServerError("GetMembers", err)
  195. return
  196. }
  197. ctx.HTML(200, tplTeamMembers)
  198. }
  199. // TeamRepositories show the repositories of team
  200. func TeamRepositories(ctx *context.Context) {
  201. ctx.Data["Title"] = ctx.Org.Team.Name
  202. ctx.Data["PageIsOrgTeams"] = true
  203. if err := ctx.Org.Team.GetRepositories(); err != nil {
  204. ctx.ServerError("GetRepositories", err)
  205. return
  206. }
  207. ctx.HTML(200, tplTeamRepositories)
  208. }
  209. // EditTeam render team edit page
  210. func EditTeam(ctx *context.Context) {
  211. ctx.Data["Title"] = ctx.Org.Organization.FullName
  212. ctx.Data["PageIsOrgTeams"] = true
  213. ctx.Data["team_name"] = ctx.Org.Team.Name
  214. ctx.Data["desc"] = ctx.Org.Team.Description
  215. ctx.Data["Units"] = models.Units
  216. ctx.HTML(200, tplTeamNew)
  217. }
  218. // EditTeamPost response for modify team information
  219. func EditTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
  220. t := ctx.Org.Team
  221. ctx.Data["Title"] = ctx.Org.Organization.FullName
  222. ctx.Data["PageIsOrgTeams"] = true
  223. ctx.Data["Team"] = t
  224. ctx.Data["Units"] = models.Units
  225. isAuthChanged := false
  226. if !t.IsOwnerTeam() {
  227. // Validate permission level.
  228. auth := models.ParseAccessMode(form.Permission)
  229. t.Name = form.TeamName
  230. if t.Authorize != auth {
  231. isAuthChanged = true
  232. t.Authorize = auth
  233. }
  234. }
  235. t.Description = form.Description
  236. if t.Authorize < models.AccessModeAdmin {
  237. t.UnitTypes = form.Units
  238. } else {
  239. t.UnitTypes = nil
  240. }
  241. if ctx.HasError() {
  242. ctx.HTML(200, tplTeamNew)
  243. return
  244. }
  245. if t.Authorize < models.AccessModeAdmin && len(form.Units) == 0 {
  246. ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
  247. return
  248. }
  249. if err := models.UpdateTeam(t, isAuthChanged); err != nil {
  250. ctx.Data["Err_TeamName"] = true
  251. switch {
  252. case models.IsErrTeamAlreadyExist(err):
  253. ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), tplTeamNew, &form)
  254. default:
  255. ctx.ServerError("UpdateTeam", err)
  256. }
  257. return
  258. }
  259. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
  260. }
  261. // DeleteTeam response for the delete team request
  262. func DeleteTeam(ctx *context.Context) {
  263. if err := models.DeleteTeam(ctx.Org.Team); err != nil {
  264. ctx.Flash.Error("DeleteTeam: " + err.Error())
  265. } else {
  266. ctx.Flash.Success(ctx.Tr("org.teams.delete_team_success"))
  267. }
  268. ctx.JSON(200, map[string]interface{}{
  269. "redirect": ctx.Org.OrgLink + "/teams",
  270. })
  271. }