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.8KB

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