gitea源码

collaboration.go 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package setting
  4. import (
  5. "errors"
  6. "net/http"
  7. "strings"
  8. "code.gitea.io/gitea/models/organization"
  9. "code.gitea.io/gitea/models/perm"
  10. repo_model "code.gitea.io/gitea/models/repo"
  11. unit_model "code.gitea.io/gitea/models/unit"
  12. user_model "code.gitea.io/gitea/models/user"
  13. "code.gitea.io/gitea/modules/log"
  14. "code.gitea.io/gitea/modules/setting"
  15. "code.gitea.io/gitea/services/context"
  16. "code.gitea.io/gitea/services/mailer"
  17. repo_service "code.gitea.io/gitea/services/repository"
  18. )
  19. // Collaboration render a repository's collaboration page
  20. func Collaboration(ctx *context.Context) {
  21. ctx.Data["Title"] = ctx.Tr("repo.settings.collaboration")
  22. ctx.Data["PageIsSettingsCollaboration"] = true
  23. users, _, err := repo_model.GetCollaborators(ctx, &repo_model.FindCollaborationOptions{RepoID: ctx.Repo.Repository.ID})
  24. if err != nil {
  25. ctx.ServerError("GetCollaborators", err)
  26. return
  27. }
  28. ctx.Data["Collaborators"] = users
  29. teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID)
  30. if err != nil {
  31. ctx.ServerError("GetRepoTeams", err)
  32. return
  33. }
  34. ctx.Data["Teams"] = teams
  35. ctx.Data["Repo"] = ctx.Repo.Repository
  36. ctx.Data["OrgID"] = ctx.Repo.Repository.OwnerID
  37. ctx.Data["OrgName"] = ctx.Repo.Repository.OwnerName
  38. ctx.Data["Org"] = ctx.Repo.Repository.Owner
  39. ctx.Data["Units"] = unit_model.Units
  40. ctx.HTML(http.StatusOK, tplCollaboration)
  41. }
  42. // CollaborationPost response for actions for a collaboration of a repository
  43. func CollaborationPost(ctx *context.Context) {
  44. name := strings.ToLower(ctx.FormString("collaborator"))
  45. if len(name) == 0 || ctx.Repo.Owner.LowerName == name {
  46. ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
  47. return
  48. }
  49. u, err := user_model.GetUserByName(ctx, name)
  50. if err != nil {
  51. if user_model.IsErrUserNotExist(err) {
  52. ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
  53. ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
  54. } else {
  55. ctx.ServerError("GetUserByName", err)
  56. }
  57. return
  58. }
  59. if !u.IsActive {
  60. ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_inactive_user"))
  61. ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
  62. return
  63. }
  64. // Organization is not allowed to be added as a collaborator.
  65. if u.IsOrganization() {
  66. ctx.Flash.Error(ctx.Tr("repo.settings.org_not_allowed_to_be_collaborator"))
  67. ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
  68. return
  69. }
  70. if got, err := repo_model.IsCollaborator(ctx, ctx.Repo.Repository.ID, u.ID); err == nil && got {
  71. ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_duplicate"))
  72. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  73. return
  74. }
  75. // find the owner team of the organization the repo belongs too and
  76. // check if the user we're trying to add is an owner.
  77. if ctx.Repo.Repository.Owner.IsOrganization() {
  78. if isOwner, err := organization.IsOrganizationOwner(ctx, ctx.Repo.Repository.Owner.ID, u.ID); err != nil {
  79. ctx.ServerError("IsOrganizationOwner", err)
  80. return
  81. } else if isOwner {
  82. ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_owner"))
  83. ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
  84. return
  85. }
  86. }
  87. if err = repo_service.AddOrUpdateCollaborator(ctx, ctx.Repo.Repository, u, perm.AccessModeWrite); err != nil {
  88. if errors.Is(err, user_model.ErrBlockedUser) {
  89. ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator.blocked_user"))
  90. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  91. } else {
  92. ctx.ServerError("AddOrUpdateCollaborator", err)
  93. }
  94. return
  95. }
  96. if setting.Service.EnableNotifyMail {
  97. mailer.SendCollaboratorMail(u, ctx.Doer, ctx.Repo.Repository)
  98. }
  99. ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
  100. ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath())
  101. }
  102. // ChangeCollaborationAccessMode response for changing access of a collaboration
  103. func ChangeCollaborationAccessMode(ctx *context.Context) {
  104. if err := repo_model.ChangeCollaborationAccessMode(
  105. ctx,
  106. ctx.Repo.Repository,
  107. ctx.FormInt64("uid"),
  108. perm.AccessMode(ctx.FormInt("mode"))); err != nil {
  109. log.Error("ChangeCollaborationAccessMode: %v", err)
  110. }
  111. }
  112. // DeleteCollaboration delete a collaboration for a repository
  113. func DeleteCollaboration(ctx *context.Context) {
  114. if collaborator, err := user_model.GetUserByID(ctx, ctx.FormInt64("id")); err != nil {
  115. if user_model.IsErrUserNotExist(err) {
  116. ctx.Flash.Error(ctx.Tr("form.user_not_exist"))
  117. } else {
  118. ctx.ServerError("GetUserByName", err)
  119. return
  120. }
  121. } else {
  122. if err := repo_service.DeleteCollaboration(ctx, ctx.Repo.Repository, collaborator); err != nil {
  123. ctx.Flash.Error("DeleteCollaboration: " + err.Error())
  124. } else {
  125. ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success"))
  126. }
  127. }
  128. ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/collaboration")
  129. }
  130. // AddTeamPost response for adding a team to a repository
  131. func AddTeamPost(ctx *context.Context) {
  132. if !ctx.Repo.Owner.RepoAdminChangeTeamAccess && !ctx.Repo.IsOwner() {
  133. ctx.Flash.Error(ctx.Tr("repo.settings.change_team_access_not_allowed"))
  134. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  135. return
  136. }
  137. name := strings.ToLower(ctx.FormString("team"))
  138. if len(name) == 0 {
  139. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  140. return
  141. }
  142. team, err := organization.OrgFromUser(ctx.Repo.Owner).GetTeam(ctx, name)
  143. if err != nil {
  144. if organization.IsErrTeamNotExist(err) {
  145. ctx.Flash.Error(ctx.Tr("form.team_not_exist"))
  146. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  147. } else {
  148. ctx.ServerError("GetTeam", err)
  149. }
  150. return
  151. }
  152. if team.OrgID != ctx.Repo.Repository.OwnerID {
  153. ctx.Flash.Error(ctx.Tr("repo.settings.team_not_in_organization"))
  154. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  155. return
  156. }
  157. if organization.HasTeamRepo(ctx, ctx.Repo.Repository.OwnerID, team.ID, ctx.Repo.Repository.ID) {
  158. ctx.Flash.Error(ctx.Tr("repo.settings.add_team_duplicate"))
  159. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  160. return
  161. }
  162. if err = repo_service.TeamAddRepository(ctx, team, ctx.Repo.Repository); err != nil {
  163. ctx.ServerError("TeamAddRepository", err)
  164. return
  165. }
  166. ctx.Flash.Success(ctx.Tr("repo.settings.add_team_success"))
  167. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  168. }
  169. // DeleteTeam response for deleting a team from a repository
  170. func DeleteTeam(ctx *context.Context) {
  171. if !ctx.Repo.Owner.RepoAdminChangeTeamAccess && !ctx.Repo.IsOwner() {
  172. ctx.Flash.Error(ctx.Tr("repo.settings.change_team_access_not_allowed"))
  173. ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration")
  174. return
  175. }
  176. team, err := organization.GetTeamByID(ctx, ctx.FormInt64("id"))
  177. if err != nil {
  178. ctx.ServerError("GetTeamByID", err)
  179. return
  180. }
  181. if err = repo_service.RemoveRepositoryFromTeam(ctx, team, ctx.Repo.Repository.ID); err != nil {
  182. ctx.ServerError("team.RemoveRepositorys", err)
  183. return
  184. }
  185. ctx.Flash.Success(ctx.Tr("repo.settings.remove_team_success"))
  186. ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/collaboration")
  187. }