gitea源码

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