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.4 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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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. var units = make([]*models.TeamUnit, 0, len(form.Units))
  166. for _, tp := range form.Units {
  167. units = append(units, &models.TeamUnit{
  168. OrgID: ctx.Org.Organization.ID,
  169. Type: tp,
  170. })
  171. }
  172. t.Units = units
  173. }
  174. ctx.Data["Team"] = t
  175. if ctx.HasError() {
  176. ctx.HTML(200, tplTeamNew)
  177. return
  178. }
  179. if t.Authorize < models.AccessModeAdmin && len(form.Units) == 0 {
  180. ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
  181. return
  182. }
  183. if err := models.NewTeam(t); err != nil {
  184. ctx.Data["Err_TeamName"] = true
  185. switch {
  186. case models.IsErrTeamAlreadyExist(err):
  187. ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), tplTeamNew, &form)
  188. default:
  189. ctx.ServerError("NewTeam", err)
  190. }
  191. return
  192. }
  193. log.Trace("Team created: %s/%s", ctx.Org.Organization.Name, t.Name)
  194. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
  195. }
  196. // TeamMembers render team members page
  197. func TeamMembers(ctx *context.Context) {
  198. ctx.Data["Title"] = ctx.Org.Team.Name
  199. ctx.Data["PageIsOrgTeams"] = true
  200. if err := ctx.Org.Team.GetMembers(); err != nil {
  201. ctx.ServerError("GetMembers", err)
  202. return
  203. }
  204. ctx.HTML(200, tplTeamMembers)
  205. }
  206. // TeamRepositories show the repositories of team
  207. func TeamRepositories(ctx *context.Context) {
  208. ctx.Data["Title"] = ctx.Org.Team.Name
  209. ctx.Data["PageIsOrgTeams"] = true
  210. if err := ctx.Org.Team.GetRepositories(); err != nil {
  211. ctx.ServerError("GetRepositories", err)
  212. return
  213. }
  214. ctx.HTML(200, tplTeamRepositories)
  215. }
  216. // EditTeam render team edit page
  217. func EditTeam(ctx *context.Context) {
  218. ctx.Data["Title"] = ctx.Org.Organization.FullName
  219. ctx.Data["PageIsOrgTeams"] = true
  220. ctx.Data["team_name"] = ctx.Org.Team.Name
  221. ctx.Data["desc"] = ctx.Org.Team.Description
  222. ctx.Data["Units"] = models.Units
  223. ctx.HTML(200, tplTeamNew)
  224. }
  225. // EditTeamPost response for modify team information
  226. func EditTeamPost(ctx *context.Context, form auth.CreateTeamForm) {
  227. t := ctx.Org.Team
  228. ctx.Data["Title"] = ctx.Org.Organization.FullName
  229. ctx.Data["PageIsOrgTeams"] = true
  230. ctx.Data["Team"] = t
  231. ctx.Data["Units"] = models.Units
  232. isAuthChanged := false
  233. if !t.IsOwnerTeam() {
  234. // Validate permission level.
  235. auth := models.ParseAccessMode(form.Permission)
  236. t.Name = form.TeamName
  237. if t.Authorize != auth {
  238. isAuthChanged = true
  239. t.Authorize = auth
  240. }
  241. }
  242. t.Description = form.Description
  243. if t.Authorize < models.AccessModeAdmin {
  244. var units = make([]models.TeamUnit, 0, len(form.Units))
  245. for _, tp := range form.Units {
  246. units = append(units, models.TeamUnit{
  247. OrgID: t.OrgID,
  248. TeamID: t.ID,
  249. Type: tp,
  250. })
  251. }
  252. models.UpdateTeamUnits(t, units)
  253. } else {
  254. models.UpdateTeamUnits(t, nil)
  255. }
  256. if ctx.HasError() {
  257. ctx.HTML(200, tplTeamNew)
  258. return
  259. }
  260. if t.Authorize < models.AccessModeAdmin && len(form.Units) == 0 {
  261. ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
  262. return
  263. }
  264. if err := models.UpdateTeam(t, isAuthChanged); err != nil {
  265. ctx.Data["Err_TeamName"] = true
  266. switch {
  267. case models.IsErrTeamAlreadyExist(err):
  268. ctx.RenderWithErr(ctx.Tr("form.team_name_been_taken"), tplTeamNew, &form)
  269. default:
  270. ctx.ServerError("UpdateTeam", err)
  271. }
  272. return
  273. }
  274. ctx.Redirect(ctx.Org.OrgLink + "/teams/" + t.LowerName)
  275. }
  276. // DeleteTeam response for the delete team request
  277. func DeleteTeam(ctx *context.Context) {
  278. if err := models.DeleteTeam(ctx.Org.Team); err != nil {
  279. ctx.Flash.Error("DeleteTeam: " + err.Error())
  280. } else {
  281. ctx.Flash.Success(ctx.Tr("org.teams.delete_team_success"))
  282. }
  283. ctx.JSON(200, map[string]interface{}{
  284. "redirect": ctx.Org.OrgLink + "/teams",
  285. })
  286. }