gitea源码

org_repo.go 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package repo
  4. import (
  5. "context"
  6. "fmt"
  7. "strings"
  8. "code.gitea.io/gitea/models/db"
  9. org_model "code.gitea.io/gitea/models/organization"
  10. user_model "code.gitea.io/gitea/models/user"
  11. "xorm.io/builder"
  12. )
  13. // GetOrgRepositories get repos belonging to the given organization
  14. func GetOrgRepositories(ctx context.Context, orgID int64) (RepositoryList, error) {
  15. var orgRepos []*Repository
  16. return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos)
  17. }
  18. type SearchTeamRepoOptions struct {
  19. db.ListOptions
  20. TeamID int64
  21. }
  22. // GetRepositories returns paginated repositories in team of organization.
  23. func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (RepositoryList, error) {
  24. sess := db.GetEngine(ctx)
  25. if opts.TeamID > 0 {
  26. sess = sess.In("id",
  27. builder.Select("repo_id").
  28. From("team_repo").
  29. Where(builder.Eq{"team_id": opts.TeamID}),
  30. )
  31. }
  32. if opts.PageSize > 0 {
  33. sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
  34. }
  35. var repos []*Repository
  36. return repos, sess.OrderBy("repository.name").
  37. Find(&repos)
  38. }
  39. // AccessibleReposEnvironment operations involving the repositories that are
  40. // accessible to a particular user
  41. type AccessibleReposEnvironment interface {
  42. CountRepos(ctx context.Context) (int64, error)
  43. RepoIDs(ctx context.Context) ([]int64, error)
  44. MirrorRepos(ctx context.Context) (RepositoryList, error)
  45. AddKeyword(keyword string)
  46. SetSort(db.SearchOrderBy)
  47. }
  48. type accessibleReposEnv struct {
  49. org *org_model.Organization
  50. user *user_model.User
  51. team *org_model.Team
  52. teamIDs []int64
  53. keyword string
  54. orderBy db.SearchOrderBy
  55. }
  56. // AccessibleReposEnv builds an AccessibleReposEnvironment for the repositories in `org`
  57. // that are accessible to the specified user.
  58. func AccessibleReposEnv(ctx context.Context, org *org_model.Organization, userID int64) (AccessibleReposEnvironment, error) {
  59. var user *user_model.User
  60. if userID > 0 {
  61. u, err := user_model.GetUserByID(ctx, userID)
  62. if err != nil {
  63. return nil, err
  64. }
  65. user = u
  66. }
  67. teamIDs, err := org.GetUserTeamIDs(ctx, userID)
  68. if err != nil {
  69. return nil, err
  70. }
  71. return &accessibleReposEnv{
  72. org: org,
  73. user: user,
  74. teamIDs: teamIDs,
  75. orderBy: db.SearchOrderByRecentUpdated,
  76. }, nil
  77. }
  78. // AccessibleTeamReposEnv an AccessibleReposEnvironment for the repositories in `org`
  79. // that are accessible to the specified team.
  80. func AccessibleTeamReposEnv(org *org_model.Organization, team *org_model.Team) AccessibleReposEnvironment {
  81. return &accessibleReposEnv{
  82. org: org,
  83. team: team,
  84. orderBy: db.SearchOrderByRecentUpdated,
  85. }
  86. }
  87. func (env *accessibleReposEnv) cond() builder.Cond {
  88. cond := builder.NewCond()
  89. if env.team != nil {
  90. cond = cond.And(builder.Eq{"team_repo.team_id": env.team.ID})
  91. } else {
  92. if env.user == nil || !env.user.IsRestricted {
  93. cond = cond.Or(builder.Eq{
  94. "`repository`.owner_id": env.org.ID,
  95. "`repository`.is_private": false,
  96. })
  97. }
  98. if len(env.teamIDs) > 0 {
  99. cond = cond.Or(builder.In("team_repo.team_id", env.teamIDs))
  100. }
  101. }
  102. if env.keyword != "" {
  103. cond = cond.And(builder.Like{"`repository`.lower_name", strings.ToLower(env.keyword)})
  104. }
  105. return cond
  106. }
  107. func (env *accessibleReposEnv) CountRepos(ctx context.Context) (int64, error) {
  108. repoCount, err := db.GetEngine(ctx).
  109. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
  110. Where(env.cond()).
  111. Distinct("`repository`.id").
  112. Count(&Repository{})
  113. if err != nil {
  114. return 0, fmt.Errorf("count user repositories in organization: %w", err)
  115. }
  116. return repoCount, nil
  117. }
  118. func (env *accessibleReposEnv) RepoIDs(ctx context.Context) ([]int64, error) {
  119. var repoIDs []int64
  120. return repoIDs, db.GetEngine(ctx).
  121. Table("repository").
  122. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
  123. Where(env.cond()).
  124. GroupBy("`repository`.id,`repository`." + strings.Fields(string(env.orderBy))[0]).
  125. OrderBy(string(env.orderBy)).
  126. Cols("`repository`.id").
  127. Find(&repoIDs)
  128. }
  129. func (env *accessibleReposEnv) MirrorRepoIDs(ctx context.Context) ([]int64, error) {
  130. repoIDs := make([]int64, 0, 10)
  131. return repoIDs, db.GetEngine(ctx).
  132. Table("repository").
  133. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true).
  134. Where(env.cond()).
  135. GroupBy("`repository`.id, `repository`.updated_unix").
  136. OrderBy(string(env.orderBy)).
  137. Cols("`repository`.id").
  138. Find(&repoIDs)
  139. }
  140. func (env *accessibleReposEnv) MirrorRepos(ctx context.Context) (RepositoryList, error) {
  141. repoIDs, err := env.MirrorRepoIDs(ctx)
  142. if err != nil {
  143. return nil, fmt.Errorf("MirrorRepoIDs: %w", err)
  144. }
  145. repos := make([]*Repository, 0, len(repoIDs))
  146. if len(repoIDs) == 0 {
  147. return repos, nil
  148. }
  149. return repos, db.GetEngine(ctx).
  150. In("`repository`.id", repoIDs).
  151. Find(&repos)
  152. }
  153. func (env *accessibleReposEnv) AddKeyword(keyword string) {
  154. env.keyword = keyword
  155. }
  156. func (env *accessibleReposEnv) SetSort(orderBy db.SearchOrderBy) {
  157. env.orderBy = orderBy
  158. }