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.

org.go 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2020 The Gitea Authors.
  3. // SPDX-License-Identifier: MIT
  4. package context
  5. import (
  6. "strings"
  7. "code.gitea.io/gitea/models/organization"
  8. "code.gitea.io/gitea/models/perm"
  9. "code.gitea.io/gitea/models/unit"
  10. user_model "code.gitea.io/gitea/models/user"
  11. "code.gitea.io/gitea/modules/log"
  12. "code.gitea.io/gitea/modules/setting"
  13. "code.gitea.io/gitea/modules/structs"
  14. )
  15. // Organization contains organization context
  16. type Organization struct {
  17. IsOwner bool
  18. IsMember bool
  19. IsTeamMember bool // Is member of team.
  20. IsTeamAdmin bool // In owner team or team that has admin permission level.
  21. Organization *organization.Organization
  22. OrgLink string
  23. CanCreateOrgRepo bool
  24. Team *organization.Team
  25. Teams []*organization.Team
  26. }
  27. func (org *Organization) CanWriteUnit(ctx *Context, unitType unit.Type) bool {
  28. if ctx.Doer == nil {
  29. return false
  30. }
  31. return org.UnitPermission(ctx, ctx.Doer.ID, unitType) >= perm.AccessModeWrite
  32. }
  33. func (org *Organization) UnitPermission(ctx *Context, doerID int64, unitType unit.Type) perm.AccessMode {
  34. if doerID > 0 {
  35. teams, err := organization.GetUserOrgTeams(ctx, org.Organization.ID, doerID)
  36. if err != nil {
  37. log.Error("GetUserOrgTeams: %v", err)
  38. return perm.AccessModeNone
  39. }
  40. if len(teams) > 0 {
  41. return teams.UnitMaxAccess(unitType)
  42. }
  43. }
  44. if org.Organization.Visibility == structs.VisibleTypePublic {
  45. return perm.AccessModeRead
  46. }
  47. return perm.AccessModeNone
  48. }
  49. // HandleOrgAssignment handles organization assignment
  50. func HandleOrgAssignment(ctx *Context, args ...bool) {
  51. var (
  52. requireMember bool
  53. requireOwner bool
  54. requireTeamMember bool
  55. requireTeamAdmin bool
  56. )
  57. if len(args) >= 1 {
  58. requireMember = args[0]
  59. }
  60. if len(args) >= 2 {
  61. requireOwner = args[1]
  62. }
  63. if len(args) >= 3 {
  64. requireTeamMember = args[2]
  65. }
  66. if len(args) >= 4 {
  67. requireTeamAdmin = args[3]
  68. }
  69. orgName := ctx.Params(":org")
  70. var err error
  71. ctx.Org.Organization, err = organization.GetOrgByName(orgName)
  72. if err != nil {
  73. if organization.IsErrOrgNotExist(err) {
  74. redirectUserID, err := user_model.LookupUserRedirect(orgName)
  75. if err == nil {
  76. RedirectToUser(ctx, orgName, redirectUserID)
  77. } else if user_model.IsErrUserRedirectNotExist(err) {
  78. ctx.NotFound("GetUserByName", err)
  79. } else {
  80. ctx.ServerError("LookupUserRedirect", err)
  81. }
  82. } else {
  83. ctx.ServerError("GetUserByName", err)
  84. }
  85. return
  86. }
  87. org := ctx.Org.Organization
  88. // Handle Visibility
  89. if org.Visibility != structs.VisibleTypePublic && !ctx.IsSigned {
  90. // We must be signed in to see limited or private organizations
  91. ctx.NotFound("OrgAssignment", err)
  92. return
  93. }
  94. if org.Visibility == structs.VisibleTypePrivate {
  95. requireMember = true
  96. } else if ctx.IsSigned && ctx.Doer.IsRestricted {
  97. requireMember = true
  98. }
  99. ctx.ContextUser = org.AsUser()
  100. ctx.Data["Org"] = org
  101. // Admin has super access.
  102. if ctx.IsSigned && ctx.Doer.IsAdmin {
  103. ctx.Org.IsOwner = true
  104. ctx.Org.IsMember = true
  105. ctx.Org.IsTeamMember = true
  106. ctx.Org.IsTeamAdmin = true
  107. ctx.Org.CanCreateOrgRepo = true
  108. } else if ctx.IsSigned {
  109. ctx.Org.IsOwner, err = org.IsOwnedBy(ctx.Doer.ID)
  110. if err != nil {
  111. ctx.ServerError("IsOwnedBy", err)
  112. return
  113. }
  114. if ctx.Org.IsOwner {
  115. ctx.Org.IsMember = true
  116. ctx.Org.IsTeamMember = true
  117. ctx.Org.IsTeamAdmin = true
  118. ctx.Org.CanCreateOrgRepo = true
  119. } else {
  120. ctx.Org.IsMember, err = org.IsOrgMember(ctx.Doer.ID)
  121. if err != nil {
  122. ctx.ServerError("IsOrgMember", err)
  123. return
  124. }
  125. ctx.Org.CanCreateOrgRepo, err = org.CanCreateOrgRepo(ctx.Doer.ID)
  126. if err != nil {
  127. ctx.ServerError("CanCreateOrgRepo", err)
  128. return
  129. }
  130. }
  131. } else {
  132. // Fake data.
  133. ctx.Data["SignedUser"] = &user_model.User{}
  134. }
  135. if (requireMember && !ctx.Org.IsMember) ||
  136. (requireOwner && !ctx.Org.IsOwner) {
  137. ctx.NotFound("OrgAssignment", err)
  138. return
  139. }
  140. ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
  141. ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
  142. ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
  143. ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
  144. ctx.Data["IsPublicMember"] = func(uid int64) bool {
  145. is, _ := organization.IsPublicMembership(ctx.Org.Organization.ID, uid)
  146. return is
  147. }
  148. ctx.Data["CanCreateOrgRepo"] = ctx.Org.CanCreateOrgRepo
  149. ctx.Org.OrgLink = org.AsUser().OrganisationLink()
  150. ctx.Data["OrgLink"] = ctx.Org.OrgLink
  151. // Team.
  152. if ctx.Org.IsMember {
  153. shouldSeeAllTeams := false
  154. if ctx.Org.IsOwner {
  155. shouldSeeAllTeams = true
  156. } else {
  157. teams, err := org.GetUserTeams(ctx.Doer.ID)
  158. if err != nil {
  159. ctx.ServerError("GetUserTeams", err)
  160. return
  161. }
  162. for _, team := range teams {
  163. if team.IncludesAllRepositories && team.AccessMode >= perm.AccessModeAdmin {
  164. shouldSeeAllTeams = true
  165. break
  166. }
  167. }
  168. }
  169. if shouldSeeAllTeams {
  170. ctx.Org.Teams, err = org.LoadTeams()
  171. if err != nil {
  172. ctx.ServerError("LoadTeams", err)
  173. return
  174. }
  175. } else {
  176. ctx.Org.Teams, err = org.GetUserTeams(ctx.Doer.ID)
  177. if err != nil {
  178. ctx.ServerError("GetUserTeams", err)
  179. return
  180. }
  181. }
  182. }
  183. teamName := ctx.Params(":team")
  184. if len(teamName) > 0 {
  185. teamExists := false
  186. for _, team := range ctx.Org.Teams {
  187. if team.LowerName == strings.ToLower(teamName) {
  188. teamExists = true
  189. ctx.Org.Team = team
  190. ctx.Org.IsTeamMember = true
  191. ctx.Data["Team"] = ctx.Org.Team
  192. break
  193. }
  194. }
  195. if !teamExists {
  196. ctx.NotFound("OrgAssignment", err)
  197. return
  198. }
  199. ctx.Data["IsTeamMember"] = ctx.Org.IsTeamMember
  200. if requireTeamMember && !ctx.Org.IsTeamMember {
  201. ctx.NotFound("OrgAssignment", err)
  202. return
  203. }
  204. ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.AccessMode >= perm.AccessModeAdmin
  205. ctx.Data["IsTeamAdmin"] = ctx.Org.IsTeamAdmin
  206. if requireTeamAdmin && !ctx.Org.IsTeamAdmin {
  207. ctx.NotFound("OrgAssignment", err)
  208. return
  209. }
  210. }
  211. }
  212. // OrgAssignment returns a middleware to handle organization assignment
  213. func OrgAssignment(args ...bool) func(ctx *Context) {
  214. return func(ctx *Context) {
  215. HandleOrgAssignment(ctx, args...)
  216. }
  217. }