gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package org
  4. import (
  5. "context"
  6. "fmt"
  7. actions_model "code.gitea.io/gitea/models/actions"
  8. activities_model "code.gitea.io/gitea/models/activities"
  9. "code.gitea.io/gitea/models/db"
  10. org_model "code.gitea.io/gitea/models/organization"
  11. packages_model "code.gitea.io/gitea/models/packages"
  12. access_model "code.gitea.io/gitea/models/perm/access"
  13. repo_model "code.gitea.io/gitea/models/repo"
  14. secret_model "code.gitea.io/gitea/models/secret"
  15. user_model "code.gitea.io/gitea/models/user"
  16. issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
  17. "code.gitea.io/gitea/modules/storage"
  18. "code.gitea.io/gitea/modules/structs"
  19. "code.gitea.io/gitea/modules/util"
  20. repo_service "code.gitea.io/gitea/services/repository"
  21. )
  22. // deleteOrganization deletes models associated to an organization.
  23. func deleteOrganization(ctx context.Context, org *org_model.Organization) error {
  24. if org.Type != user_model.UserTypeOrganization {
  25. return fmt.Errorf("%s is a user not an organization", org.Name)
  26. }
  27. if err := db.DeleteBeans(ctx,
  28. &org_model.Team{OrgID: org.ID},
  29. &org_model.OrgUser{OrgID: org.ID},
  30. &org_model.TeamUser{OrgID: org.ID},
  31. &org_model.TeamUnit{OrgID: org.ID},
  32. &org_model.TeamInvite{OrgID: org.ID},
  33. &secret_model.Secret{OwnerID: org.ID},
  34. &user_model.Blocking{BlockerID: org.ID},
  35. &actions_model.ActionRunner{OwnerID: org.ID},
  36. &actions_model.ActionRunnerToken{OwnerID: org.ID},
  37. ); err != nil {
  38. return fmt.Errorf("DeleteBeans: %w", err)
  39. }
  40. if _, err := db.GetEngine(ctx).ID(org.ID).Delete(new(user_model.User)); err != nil {
  41. return fmt.Errorf("Delete: %w", err)
  42. }
  43. return nil
  44. }
  45. // DeleteOrganization completely and permanently deletes everything of organization.
  46. func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge bool) error {
  47. if err := db.WithTx(ctx, func(ctx context.Context) error {
  48. if purge {
  49. err := repo_service.DeleteOwnerRepositoriesDirectly(ctx, org.AsUser())
  50. if err != nil {
  51. return err
  52. }
  53. }
  54. // Check ownership of repository.
  55. count, err := repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{OwnerID: org.ID})
  56. if err != nil {
  57. return fmt.Errorf("GetRepositoryCount: %w", err)
  58. } else if count > 0 {
  59. return repo_model.ErrUserOwnRepos{UID: org.ID}
  60. }
  61. // Check ownership of packages.
  62. if ownsPackages, err := packages_model.HasOwnerPackages(ctx, org.ID); err != nil {
  63. return fmt.Errorf("HasOwnerPackages: %w", err)
  64. } else if ownsPackages {
  65. return packages_model.ErrUserOwnPackages{UID: org.ID}
  66. }
  67. if err := deleteOrganization(ctx, org); err != nil {
  68. return fmt.Errorf("DeleteOrganization: %w", err)
  69. }
  70. return nil
  71. }); err != nil {
  72. return err
  73. }
  74. // FIXME: system notice
  75. // Note: There are something just cannot be roll back,
  76. // so just keep error logs of those operations.
  77. path := user_model.UserPath(org.Name)
  78. if err := util.RemoveAll(path); err != nil {
  79. return fmt.Errorf("failed to RemoveAll %s: %w", path, err)
  80. }
  81. if len(org.Avatar) > 0 {
  82. avatarPath := org.CustomAvatarRelativePath()
  83. if err := storage.Avatars.Delete(avatarPath); err != nil {
  84. return fmt.Errorf("failed to remove %s: %w", avatarPath, err)
  85. }
  86. }
  87. return nil
  88. }
  89. func updateOrgRepoForVisibilityChanged(ctx context.Context, repo *repo_model.Repository, makePrivate bool) error {
  90. // Organization repository need to recalculate access table when visibility is changed.
  91. if err := access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil {
  92. return fmt.Errorf("recalculateTeamAccesses: %w", err)
  93. }
  94. if makePrivate {
  95. if _, err := db.GetEngine(ctx).Where("repo_id = ?", repo.ID).Cols("is_private").Update(&activities_model.Action{
  96. IsPrivate: true,
  97. }); err != nil {
  98. return err
  99. }
  100. if err := repo_model.ClearRepoStars(ctx, repo.ID); err != nil {
  101. return err
  102. }
  103. }
  104. // Create/Remove git-daemon-export-ok for git-daemon...
  105. if err := repo_service.CheckDaemonExportOK(ctx, repo); err != nil {
  106. return err
  107. }
  108. // If visibility is changed, we need to update the issue indexer.
  109. // Since the data in the issue indexer have field to indicate if the repo is public or not.
  110. // FIXME: it should check organization visibility instead of repository visibility only.
  111. issue_indexer.UpdateRepoIndexer(ctx, repo.ID)
  112. forkRepos, err := repo_model.GetRepositoriesByForkID(ctx, repo.ID)
  113. if err != nil {
  114. return fmt.Errorf("getRepositoriesByForkID: %w", err)
  115. }
  116. for i := range forkRepos {
  117. if err := updateOrgRepoForVisibilityChanged(ctx, forkRepos[i], makePrivate); err != nil {
  118. return fmt.Errorf("updateRepoForVisibilityChanged[%s]: %w", forkRepos[i].FullName(), err)
  119. }
  120. }
  121. return nil
  122. }
  123. func ChangeOrganizationVisibility(ctx context.Context, org *org_model.Organization, visibility structs.VisibleType) error {
  124. if org.Visibility == visibility {
  125. return nil
  126. }
  127. org.Visibility = visibility
  128. // FIXME: If it's a big forks network(forks and sub forks), the database transaction will be too long to fail.
  129. return db.WithTx(ctx, func(ctx context.Context) error {
  130. if err := user_model.UpdateUserColsNoAutoTime(ctx, org.AsUser(), "visibility"); err != nil {
  131. return err
  132. }
  133. repos, _, err := repo_model.GetUserRepositories(ctx, repo_model.SearchRepoOptions{
  134. Actor: org.AsUser(), Private: true, ListOptions: db.ListOptionsAll,
  135. })
  136. if err != nil {
  137. return err
  138. }
  139. for _, repo := range repos {
  140. if err := updateOrgRepoForVisibilityChanged(ctx, repo, visibility == structs.VisibleTypePrivate); err != nil {
  141. return fmt.Errorf("updateOrgRepoForVisibilityChanged: %w", err)
  142. }
  143. }
  144. return nil
  145. })
  146. }