org.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package db
  5. import (
  6. "context"
  7. "fmt"
  8. "os"
  9. "strings"
  10. "xorm.io/builder"
  11. "xorm.io/xorm"
  12. "gogs.io/gogs/internal/errutil"
  13. "gogs.io/gogs/internal/repoutil"
  14. "gogs.io/gogs/internal/userutil"
  15. )
  16. // CreateOrganization creates record of a new organization.
  17. func CreateOrganization(org, owner *User) (err error) {
  18. if err = isUsernameAllowed(org.Name); err != nil {
  19. return err
  20. }
  21. if Users.IsUsernameUsed(context.TODO(), org.Name, 0) {
  22. return ErrUserAlreadyExist{
  23. args: errutil.Args{
  24. "name": org.Name,
  25. },
  26. }
  27. }
  28. org.LowerName = strings.ToLower(org.Name)
  29. if org.Rands, err = userutil.RandomSalt(); err != nil {
  30. return err
  31. }
  32. if org.Salt, err = userutil.RandomSalt(); err != nil {
  33. return err
  34. }
  35. org.UseCustomAvatar = true
  36. org.MaxRepoCreation = -1
  37. org.NumTeams = 1
  38. org.NumMembers = 1
  39. sess := x.NewSession()
  40. defer sess.Close()
  41. if err = sess.Begin(); err != nil {
  42. return err
  43. }
  44. if _, err = sess.Insert(org); err != nil {
  45. return fmt.Errorf("insert organization: %v", err)
  46. }
  47. _ = userutil.GenerateRandomAvatar(org.ID, org.Name, org.Email)
  48. // Add initial creator to organization and owner team.
  49. if _, err = sess.Insert(&OrgUser{
  50. UserID: owner.ID,
  51. OrgID: org.ID,
  52. IsOwner: true,
  53. NumTeams: 1,
  54. }); err != nil {
  55. return fmt.Errorf("insert org-user relation: %v", err)
  56. }
  57. // Create default owner team.
  58. t := &Team{
  59. OrgID: org.ID,
  60. LowerName: strings.ToLower(TeamNameOwners),
  61. Name: TeamNameOwners,
  62. Authorize: AccessModeOwner,
  63. NumMembers: 1,
  64. }
  65. if _, err = sess.Insert(t); err != nil {
  66. return fmt.Errorf("insert owner team: %v", err)
  67. }
  68. if _, err = sess.Insert(&TeamUser{
  69. UID: owner.ID,
  70. OrgID: org.ID,
  71. TeamID: t.ID,
  72. }); err != nil {
  73. return fmt.Errorf("insert team-user relation: %v", err)
  74. }
  75. if err = os.MkdirAll(repoutil.UserPath(org.Name), os.ModePerm); err != nil {
  76. return fmt.Errorf("create directory: %v", err)
  77. }
  78. return sess.Commit()
  79. }
  80. // Organizations returns number of organizations in given page.
  81. func Organizations(page, pageSize int) ([]*User, error) {
  82. orgs := make([]*User, 0, pageSize)
  83. return orgs, x.Limit(pageSize, (page-1)*pageSize).Where("type=1").Asc("id").Find(&orgs)
  84. }
  85. // deleteBeans deletes all given beans, beans should contain delete conditions.
  86. func deleteBeans(e Engine, beans ...any) (err error) {
  87. for i := range beans {
  88. if _, err = e.Delete(beans[i]); err != nil {
  89. return err
  90. }
  91. }
  92. return nil
  93. }
  94. // DeleteOrganization completely and permanently deletes everything of organization.
  95. func DeleteOrganization(org *User) error {
  96. err := Users.DeleteByID(context.TODO(), org.ID, false)
  97. if err != nil {
  98. return err
  99. }
  100. sess := x.NewSession()
  101. defer sess.Close()
  102. if err = sess.Begin(); err != nil {
  103. return err
  104. }
  105. if err = deleteBeans(sess,
  106. &Team{OrgID: org.ID},
  107. &OrgUser{OrgID: org.ID},
  108. &TeamUser{OrgID: org.ID},
  109. ); err != nil {
  110. return fmt.Errorf("deleteBeans: %v", err)
  111. }
  112. return sess.Commit()
  113. }
  114. func getOrgsByUserID(sess *xorm.Session, userID int64, showAll bool) ([]*User, error) {
  115. orgs := make([]*User, 0, 10)
  116. if !showAll {
  117. sess.And("`org_user`.is_public=?", true)
  118. }
  119. return orgs, sess.And("`org_user`.uid=?", userID).
  120. Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").Find(&orgs)
  121. }
  122. // GetOrgsByUserID returns a list of organizations that the given user ID
  123. // has joined.
  124. func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) {
  125. return getOrgsByUserID(x.NewSession(), userID, showAll)
  126. }
  127. // getOwnedOrgsByUserID returns a list of organizations are owned by given user ID.
  128. func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
  129. orgs := make([]*User, 0, 10)
  130. return orgs, sess.Where("`org_user`.uid=?", userID).And("`org_user`.is_owner=?", true).
  131. Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").Find(&orgs)
  132. }
  133. // GetOwnedOrganizationsByUserIDDesc returns a list of organizations are owned by
  134. // given user ID, ordered descending by the given condition.
  135. func GetOwnedOrgsByUserIDDesc(userID int64, desc string) ([]*User, error) {
  136. sess := x.NewSession()
  137. return getOwnedOrgsByUserID(sess.Desc(desc), userID)
  138. }
  139. // getOrgUsersByOrgID returns all organization-user relations by organization ID.
  140. func getOrgUsersByOrgID(e Engine, orgID int64, limit int) ([]*OrgUser, error) {
  141. orgUsers := make([]*OrgUser, 0, 10)
  142. sess := e.Where("org_id=?", orgID)
  143. if limit > 0 {
  144. sess = sess.Limit(limit)
  145. }
  146. return orgUsers, sess.Find(&orgUsers)
  147. }
  148. // GetUserMirrorRepositories returns mirror repositories of the organization which the user has access to.
  149. func (u *User) GetUserMirrorRepositories(userID int64) ([]*Repository, error) {
  150. teamIDs, err := u.GetUserTeamIDs(userID)
  151. if err != nil {
  152. return nil, fmt.Errorf("GetUserTeamIDs: %v", err)
  153. }
  154. if len(teamIDs) == 0 {
  155. teamIDs = []int64{-1}
  156. }
  157. var teamRepoIDs []int64
  158. err = x.Table("team_repo").In("team_id", teamIDs).Distinct("repo_id").Find(&teamRepoIDs)
  159. if err != nil {
  160. return nil, fmt.Errorf("get team repository ids: %v", err)
  161. }
  162. if len(teamRepoIDs) == 0 {
  163. // team has no repo but "IN ()" is invalid SQL
  164. teamRepoIDs = []int64{-1} // there is no repo with id=-1
  165. }
  166. repos := make([]*Repository, 0, 10)
  167. if err = x.Where("owner_id = ?", u.ID).
  168. And("is_private = ?", false).
  169. Or(builder.In("id", teamRepoIDs)).
  170. And("is_mirror = ?", true). // Don't move up because it's an independent condition
  171. Desc("updated_unix").
  172. Find(&repos); err != nil {
  173. return nil, fmt.Errorf("get user repositories: %v", err)
  174. }
  175. return repos, nil
  176. }