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 7.3KB

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