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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // SPDX-License-Identifier: MIT
  4. package models
  5. import (
  6. "context"
  7. "fmt"
  8. "code.gitea.io/gitea/models/db"
  9. "code.gitea.io/gitea/models/organization"
  10. access_model "code.gitea.io/gitea/models/perm/access"
  11. repo_model "code.gitea.io/gitea/models/repo"
  12. user_model "code.gitea.io/gitea/models/user"
  13. )
  14. // RemoveOrgUser removes user from given organization.
  15. func RemoveOrgUser(ctx context.Context, org *organization.Organization, user *user_model.User) error {
  16. ou := new(organization.OrgUser)
  17. has, err := db.GetEngine(ctx).
  18. Where("uid=?", user.ID).
  19. And("org_id=?", org.ID).
  20. Get(ou)
  21. if err != nil {
  22. return fmt.Errorf("get org-user: %w", err)
  23. } else if !has {
  24. return nil
  25. }
  26. // Check if the user to delete is the last member in owner team.
  27. if isOwner, err := organization.IsOrganizationOwner(ctx, org.ID, user.ID); err != nil {
  28. return err
  29. } else if isOwner {
  30. t, err := organization.GetOwnerTeam(ctx, org.ID)
  31. if err != nil {
  32. return err
  33. }
  34. if t.NumMembers == 1 {
  35. if err := t.LoadMembers(ctx); err != nil {
  36. return err
  37. }
  38. if t.Members[0].ID == user.ID {
  39. return organization.ErrLastOrgOwner{UID: user.ID}
  40. }
  41. }
  42. }
  43. ctx, committer, err := db.TxContext(ctx)
  44. if err != nil {
  45. return err
  46. }
  47. defer committer.Close()
  48. if _, err := db.DeleteByID[organization.OrgUser](ctx, ou.ID); err != nil {
  49. return err
  50. } else if _, err = db.Exec(ctx, "UPDATE `user` SET num_members=num_members-1 WHERE id=?", org.ID); err != nil {
  51. return err
  52. }
  53. // Delete all repository accesses and unwatch them.
  54. env, err := organization.AccessibleReposEnv(ctx, org, user.ID)
  55. if err != nil {
  56. return fmt.Errorf("AccessibleReposEnv: %w", err)
  57. }
  58. repoIDs, err := env.RepoIDs(1, org.NumRepos)
  59. if err != nil {
  60. return fmt.Errorf("GetUserRepositories [%d]: %w", user.ID, err)
  61. }
  62. for _, repoID := range repoIDs {
  63. repo, err := repo_model.GetRepositoryByID(ctx, repoID)
  64. if err != nil {
  65. return err
  66. }
  67. if err = repo_model.WatchRepo(ctx, user, repo, false); err != nil {
  68. return err
  69. }
  70. }
  71. if len(repoIDs) > 0 {
  72. if _, err = db.GetEngine(ctx).
  73. Where("user_id = ?", user.ID).
  74. In("repo_id", repoIDs).
  75. Delete(new(access_model.Access)); err != nil {
  76. return err
  77. }
  78. }
  79. // Delete member in their teams.
  80. teams, err := organization.GetUserOrgTeams(ctx, org.ID, user.ID)
  81. if err != nil {
  82. return err
  83. }
  84. for _, t := range teams {
  85. if err = removeTeamMember(ctx, t, user); err != nil {
  86. return err
  87. }
  88. }
  89. return committer.Commit()
  90. }