Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
8 роки тому
10 роки тому
10 роки тому
8 роки тому
10 роки тому
7 роки тому
7 роки тому
10 роки тому
10 роки тому
10 роки тому
8 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
8 роки тому
8 роки тому
8 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
7 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
5 роки тому
8 роки тому
10 роки тому
7 роки тому
9 роки тому
7 роки тому
9 роки тому
10 роки тому
10 роки тому
6 роки тому
8 роки тому
10 роки тому
8 роки тому
10 роки тому
8 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
7 роки тому
10 роки тому
7 роки тому
7 роки тому
8 роки тому
5 роки тому
8 роки тому
10 роки тому
8 роки тому
10 роки тому
7 роки тому
7 роки тому
5 роки тому
5 роки тому
7 роки тому
9 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
7 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package models
  6. import (
  7. "fmt"
  8. "os"
  9. "strings"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/setting"
  12. "code.gitea.io/gitea/modules/structs"
  13. "github.com/unknwon/com"
  14. "xorm.io/builder"
  15. "xorm.io/xorm"
  16. )
  17. // IsOwnedBy returns true if given user is in the owner team.
  18. func (org *User) IsOwnedBy(uid int64) (bool, error) {
  19. return IsOrganizationOwner(org.ID, uid)
  20. }
  21. // IsOrgMember returns true if given user is member of organization.
  22. func (org *User) IsOrgMember(uid int64) (bool, error) {
  23. return IsOrganizationMember(org.ID, uid)
  24. }
  25. // CanCreateOrgRepo returns true if given user can create repo in organization
  26. func (org *User) CanCreateOrgRepo(uid int64) (bool, error) {
  27. return CanCreateOrgRepo(org.ID, uid)
  28. }
  29. func (org *User) getTeam(e Engine, name string) (*Team, error) {
  30. return getTeam(e, org.ID, name)
  31. }
  32. // GetTeam returns named team of organization.
  33. func (org *User) GetTeam(name string) (*Team, error) {
  34. return org.getTeam(x, name)
  35. }
  36. func (org *User) getOwnerTeam(e Engine) (*Team, error) {
  37. return org.getTeam(e, ownerTeamName)
  38. }
  39. // GetOwnerTeam returns owner team of organization.
  40. func (org *User) GetOwnerTeam() (*Team, error) {
  41. return org.getOwnerTeam(x)
  42. }
  43. func (org *User) getTeams(e Engine) error {
  44. if org.Teams != nil {
  45. return nil
  46. }
  47. return e.
  48. Where("org_id=?", org.ID).
  49. OrderBy("CASE WHEN name LIKE '" + ownerTeamName + "' THEN '' ELSE name END").
  50. Find(&org.Teams)
  51. }
  52. // GetTeams returns all teams that belong to organization.
  53. func (org *User) GetTeams() error {
  54. return org.getTeams(x)
  55. }
  56. // GetMembers returns all members of organization.
  57. func (org *User) GetMembers() error {
  58. ous, err := GetOrgUsersByOrgID(org.ID)
  59. if err != nil {
  60. return err
  61. }
  62. var ids = make([]int64, len(ous))
  63. var idsIsPublic = make(map[int64]bool, len(ous))
  64. for i, ou := range ous {
  65. ids[i] = ou.UID
  66. idsIsPublic[ou.UID] = ou.IsPublic
  67. }
  68. org.MembersIsPublic = idsIsPublic
  69. org.Members, err = GetUsersByIDs(ids)
  70. return err
  71. }
  72. // AddMember adds new member to organization.
  73. func (org *User) AddMember(uid int64) error {
  74. return AddOrgUser(org.ID, uid)
  75. }
  76. // RemoveMember removes member from organization.
  77. func (org *User) RemoveMember(uid int64) error {
  78. return RemoveOrgUser(org.ID, uid)
  79. }
  80. func (org *User) removeOrgRepo(e Engine, repoID int64) error {
  81. return removeOrgRepo(e, org.ID, repoID)
  82. }
  83. // RemoveOrgRepo removes all team-repository relations of organization.
  84. func (org *User) RemoveOrgRepo(repoID int64) error {
  85. return org.removeOrgRepo(x, repoID)
  86. }
  87. // CreateOrganization creates record of a new organization.
  88. func CreateOrganization(org, owner *User) (err error) {
  89. if !owner.CanCreateOrganization() {
  90. return ErrUserNotAllowedCreateOrg{}
  91. }
  92. if err = IsUsableUsername(org.Name); err != nil {
  93. return err
  94. }
  95. isExist, err := IsUserExist(0, org.Name)
  96. if err != nil {
  97. return err
  98. } else if isExist {
  99. return ErrUserAlreadyExist{org.Name}
  100. }
  101. org.LowerName = strings.ToLower(org.Name)
  102. if org.Rands, err = GetUserSalt(); err != nil {
  103. return err
  104. }
  105. if org.Salt, err = GetUserSalt(); err != nil {
  106. return err
  107. }
  108. org.UseCustomAvatar = true
  109. org.MaxRepoCreation = -1
  110. org.NumTeams = 1
  111. org.NumMembers = 1
  112. org.Type = UserTypeOrganization
  113. sess := x.NewSession()
  114. defer sess.Close()
  115. if err = sess.Begin(); err != nil {
  116. return err
  117. }
  118. if _, err = sess.Insert(org); err != nil {
  119. return fmt.Errorf("insert organization: %v", err)
  120. }
  121. if err = org.generateRandomAvatar(sess); err != nil {
  122. return fmt.Errorf("generate random avatar: %v", err)
  123. }
  124. // Add initial creator to organization and owner team.
  125. if _, err = sess.Insert(&OrgUser{
  126. UID: owner.ID,
  127. OrgID: org.ID,
  128. }); err != nil {
  129. return fmt.Errorf("insert org-user relation: %v", err)
  130. }
  131. // Create default owner team.
  132. t := &Team{
  133. OrgID: org.ID,
  134. LowerName: strings.ToLower(ownerTeamName),
  135. Name: ownerTeamName,
  136. Authorize: AccessModeOwner,
  137. NumMembers: 1,
  138. IncludesAllRepositories: true,
  139. CanCreateOrgRepo: true,
  140. }
  141. if _, err = sess.Insert(t); err != nil {
  142. return fmt.Errorf("insert owner team: %v", err)
  143. }
  144. // insert units for team
  145. var units = make([]TeamUnit, 0, len(AllRepoUnitTypes))
  146. for _, tp := range AllRepoUnitTypes {
  147. units = append(units, TeamUnit{
  148. OrgID: org.ID,
  149. TeamID: t.ID,
  150. Type: tp,
  151. })
  152. }
  153. if _, err = sess.Insert(&units); err != nil {
  154. if err := sess.Rollback(); err != nil {
  155. log.Error("CreateOrganization: sess.Rollback: %v", err)
  156. }
  157. return err
  158. }
  159. if _, err = sess.Insert(&TeamUser{
  160. UID: owner.ID,
  161. OrgID: org.ID,
  162. TeamID: t.ID,
  163. }); err != nil {
  164. return fmt.Errorf("insert team-user relation: %v", err)
  165. }
  166. return sess.Commit()
  167. }
  168. // GetOrgByName returns organization by given name.
  169. func GetOrgByName(name string) (*User, error) {
  170. if len(name) == 0 {
  171. return nil, ErrOrgNotExist{0, name}
  172. }
  173. u := &User{
  174. LowerName: strings.ToLower(name),
  175. Type: UserTypeOrganization,
  176. }
  177. has, err := x.Get(u)
  178. if err != nil {
  179. return nil, err
  180. } else if !has {
  181. return nil, ErrOrgNotExist{0, name}
  182. }
  183. return u, nil
  184. }
  185. // CountOrganizations returns number of organizations.
  186. func CountOrganizations() int64 {
  187. count, _ := x.
  188. Where("type=1").
  189. Count(new(User))
  190. return count
  191. }
  192. // DeleteOrganization completely and permanently deletes everything of organization.
  193. func DeleteOrganization(org *User) (err error) {
  194. sess := x.NewSession()
  195. defer sess.Close()
  196. if err = sess.Begin(); err != nil {
  197. return err
  198. }
  199. if err = deleteOrg(sess, org); err != nil {
  200. if IsErrUserOwnRepos(err) {
  201. return err
  202. } else if err != nil {
  203. return fmt.Errorf("deleteOrg: %v", err)
  204. }
  205. }
  206. return sess.Commit()
  207. }
  208. func deleteOrg(e *xorm.Session, u *User) error {
  209. if !u.IsOrganization() {
  210. return fmt.Errorf("You can't delete none organization user: %s", u.Name)
  211. }
  212. // Check ownership of repository.
  213. count, err := getRepositoryCount(e, u)
  214. if err != nil {
  215. return fmt.Errorf("GetRepositoryCount: %v", err)
  216. } else if count > 0 {
  217. return ErrUserOwnRepos{UID: u.ID}
  218. }
  219. if err := deleteBeans(e,
  220. &Team{OrgID: u.ID},
  221. &OrgUser{OrgID: u.ID},
  222. &TeamUser{OrgID: u.ID},
  223. &TeamUnit{OrgID: u.ID},
  224. ); err != nil {
  225. return fmt.Errorf("deleteBeans: %v", err)
  226. }
  227. if _, err = e.ID(u.ID).Delete(new(User)); err != nil {
  228. return fmt.Errorf("Delete: %v", err)
  229. }
  230. // FIXME: system notice
  231. // Note: There are something just cannot be roll back,
  232. // so just keep error logs of those operations.
  233. path := UserPath(u.Name)
  234. if err := os.RemoveAll(path); err != nil {
  235. return fmt.Errorf("Failed to RemoveAll %s: %v", path, err)
  236. }
  237. if len(u.Avatar) > 0 {
  238. avatarPath := u.CustomAvatarPath()
  239. if com.IsExist(avatarPath) {
  240. if err := os.Remove(avatarPath); err != nil {
  241. return fmt.Errorf("Failed to remove %s: %v", avatarPath, err)
  242. }
  243. }
  244. }
  245. return nil
  246. }
  247. // ________ ____ ___
  248. // \_____ \_______ ____ | | \______ ___________
  249. // / | \_ __ \/ ___\| | / ___// __ \_ __ \
  250. // / | \ | \/ /_/ > | /\___ \\ ___/| | \/
  251. // \_______ /__| \___ /|______//____ >\___ >__|
  252. // \/ /_____/ \/ \/
  253. // OrgUser represents an organization-user relation.
  254. type OrgUser struct {
  255. ID int64 `xorm:"pk autoincr"`
  256. UID int64 `xorm:"INDEX UNIQUE(s)"`
  257. OrgID int64 `xorm:"INDEX UNIQUE(s)"`
  258. IsPublic bool `xorm:"INDEX"`
  259. }
  260. func isOrganizationOwner(e Engine, orgID, uid int64) (bool, error) {
  261. ownerTeam, err := getOwnerTeam(e, orgID)
  262. if err != nil {
  263. if IsErrTeamNotExist(err) {
  264. log.Error("Organization does not have owner team: %d", orgID)
  265. return false, nil
  266. }
  267. return false, err
  268. }
  269. return isTeamMember(e, orgID, ownerTeam.ID, uid)
  270. }
  271. // IsOrganizationOwner returns true if given user is in the owner team.
  272. func IsOrganizationOwner(orgID, uid int64) (bool, error) {
  273. return isOrganizationOwner(x, orgID, uid)
  274. }
  275. // IsOrganizationMember returns true if given user is member of organization.
  276. func IsOrganizationMember(orgID, uid int64) (bool, error) {
  277. return isOrganizationMember(x, orgID, uid)
  278. }
  279. func isOrganizationMember(e Engine, orgID, uid int64) (bool, error) {
  280. return e.
  281. Where("uid=?", uid).
  282. And("org_id=?", orgID).
  283. Table("org_user").
  284. Exist()
  285. }
  286. // IsPublicMembership returns true if given user public his/her membership.
  287. func IsPublicMembership(orgID, uid int64) (bool, error) {
  288. return x.
  289. Where("uid=?", uid).
  290. And("org_id=?", orgID).
  291. And("is_public=?", true).
  292. Table("org_user").
  293. Exist()
  294. }
  295. // CanCreateOrgRepo returns true if user can create repo in organization
  296. func CanCreateOrgRepo(orgID, uid int64) (bool, error) {
  297. if owner, err := IsOrganizationOwner(orgID, uid); owner || err != nil {
  298. return owner, err
  299. }
  300. return x.
  301. Where(builder.Eq{"team.can_create_org_repo": true}).
  302. Join("INNER", "team_user", "team_user.team_id = team.id").
  303. And("team_user.uid = ?", uid).
  304. And("team_user.org_id = ?", orgID).
  305. Exist(new(Team))
  306. }
  307. func getOrgsByUserID(sess *xorm.Session, userID int64, showAll bool) ([]*User, error) {
  308. orgs := make([]*User, 0, 10)
  309. if !showAll {
  310. sess.And("`org_user`.is_public=?", true)
  311. }
  312. return orgs, sess.
  313. And("`org_user`.uid=?", userID).
  314. Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").
  315. Asc("`user`.name").
  316. Find(&orgs)
  317. }
  318. // GetOrgsByUserID returns a list of organizations that the given user ID
  319. // has joined.
  320. func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) {
  321. sess := x.NewSession()
  322. defer sess.Close()
  323. return getOrgsByUserID(sess, userID, showAll)
  324. }
  325. func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
  326. orgs := make([]*User, 0, 10)
  327. return orgs, sess.
  328. Join("INNER", "`team_user`", "`team_user`.org_id=`user`.id").
  329. Join("INNER", "`team`", "`team`.id=`team_user`.team_id").
  330. Where("`team_user`.uid=?", userID).
  331. And("`team`.authorize=?", AccessModeOwner).
  332. Asc("`user`.name").
  333. Find(&orgs)
  334. }
  335. // HasOrgVisible tells if the given user can see the given org
  336. func HasOrgVisible(org *User, user *User) bool {
  337. return hasOrgVisible(x, org, user)
  338. }
  339. func hasOrgVisible(e Engine, org *User, user *User) bool {
  340. // Not SignedUser
  341. if user == nil {
  342. return org.Visibility == structs.VisibleTypePublic
  343. }
  344. if user.IsAdmin {
  345. return true
  346. }
  347. if org.Visibility == structs.VisibleTypePrivate && !org.isUserPartOfOrg(e, user.ID) {
  348. return false
  349. }
  350. return true
  351. }
  352. // HasOrgsVisible tells if the given user can see at least one of the orgs provided
  353. func HasOrgsVisible(orgs []*User, user *User) bool {
  354. if len(orgs) == 0 {
  355. return false
  356. }
  357. for _, org := range orgs {
  358. if HasOrgVisible(org, user) {
  359. return true
  360. }
  361. }
  362. return false
  363. }
  364. // GetOwnedOrgsByUserID returns a list of organizations are owned by given user ID.
  365. func GetOwnedOrgsByUserID(userID int64) ([]*User, error) {
  366. sess := x.NewSession()
  367. defer sess.Close()
  368. return getOwnedOrgsByUserID(sess, userID)
  369. }
  370. // GetOwnedOrgsByUserIDDesc returns a list of organizations are owned by
  371. // given user ID, ordered descending by the given condition.
  372. func GetOwnedOrgsByUserIDDesc(userID int64, desc string) ([]*User, error) {
  373. return getOwnedOrgsByUserID(x.Desc(desc), userID)
  374. }
  375. // GetOrgsCanCreateRepoByUserID returns a list of organizations where given user ID
  376. // are allowed to create repos.
  377. func GetOrgsCanCreateRepoByUserID(userID int64) ([]*User, error) {
  378. orgs := make([]*User, 0, 10)
  379. return orgs, x.Join("INNER", "`team_user`", "`team_user`.org_id=`user`.id").
  380. Join("INNER", "`team`", "`team`.id=`team_user`.team_id").
  381. Where("`team_user`.uid=?", userID).
  382. And(builder.Eq{"`team`.authorize": AccessModeOwner}.Or(builder.Eq{"`team`.can_create_org_repo": true})).
  383. Desc("`user`.updated_unix").
  384. Find(&orgs)
  385. }
  386. // GetOrgUsersByUserID returns all organization-user relations by user ID.
  387. func GetOrgUsersByUserID(uid int64, all bool) ([]*OrgUser, error) {
  388. ous := make([]*OrgUser, 0, 10)
  389. sess := x.
  390. Join("LEFT", "`user`", "`org_user`.org_id=`user`.id").
  391. Where("`org_user`.uid=?", uid)
  392. if !all {
  393. // Only show public organizations
  394. sess.And("is_public=?", true)
  395. }
  396. err := sess.
  397. Asc("`user`.name").
  398. Find(&ous)
  399. return ous, err
  400. }
  401. // GetOrgUsersByOrgID returns all organization-user relations by organization ID.
  402. func GetOrgUsersByOrgID(orgID int64) ([]*OrgUser, error) {
  403. return getOrgUsersByOrgID(x, orgID)
  404. }
  405. func getOrgUsersByOrgID(e Engine, orgID int64) ([]*OrgUser, error) {
  406. ous := make([]*OrgUser, 0, 10)
  407. err := e.
  408. Where("org_id=?", orgID).
  409. Find(&ous)
  410. return ous, err
  411. }
  412. // ChangeOrgUserStatus changes public or private membership status.
  413. func ChangeOrgUserStatus(orgID, uid int64, public bool) error {
  414. ou := new(OrgUser)
  415. has, err := x.
  416. Where("uid=?", uid).
  417. And("org_id=?", orgID).
  418. Get(ou)
  419. if err != nil {
  420. return err
  421. } else if !has {
  422. return nil
  423. }
  424. ou.IsPublic = public
  425. _, err = x.ID(ou.ID).Cols("is_public").Update(ou)
  426. return err
  427. }
  428. // AddOrgUser adds new user to given organization.
  429. func AddOrgUser(orgID, uid int64) error {
  430. isAlreadyMember, err := IsOrganizationMember(orgID, uid)
  431. if err != nil || isAlreadyMember {
  432. return err
  433. }
  434. sess := x.NewSession()
  435. defer sess.Close()
  436. if err := sess.Begin(); err != nil {
  437. return err
  438. }
  439. ou := &OrgUser{
  440. UID: uid,
  441. OrgID: orgID,
  442. IsPublic: setting.Service.DefaultOrgMemberVisible,
  443. }
  444. if _, err := sess.Insert(ou); err != nil {
  445. if err := sess.Rollback(); err != nil {
  446. log.Error("AddOrgUser: sess.Rollback: %v", err)
  447. }
  448. return err
  449. } else if _, err = sess.Exec("UPDATE `user` SET num_members = num_members + 1 WHERE id = ?", orgID); err != nil {
  450. if err := sess.Rollback(); err != nil {
  451. log.Error("AddOrgUser: sess.Rollback: %v", err)
  452. }
  453. return err
  454. }
  455. return sess.Commit()
  456. }
  457. func removeOrgUser(sess *xorm.Session, orgID, userID int64) error {
  458. ou := new(OrgUser)
  459. has, err := sess.
  460. Where("uid=?", userID).
  461. And("org_id=?", orgID).
  462. Get(ou)
  463. if err != nil {
  464. return fmt.Errorf("get org-user: %v", err)
  465. } else if !has {
  466. return nil
  467. }
  468. org, err := getUserByID(sess, orgID)
  469. if err != nil {
  470. return fmt.Errorf("GetUserByID [%d]: %v", orgID, err)
  471. }
  472. // Check if the user to delete is the last member in owner team.
  473. if isOwner, err := isOrganizationOwner(sess, orgID, userID); err != nil {
  474. return err
  475. } else if isOwner {
  476. t, err := org.getOwnerTeam(sess)
  477. if err != nil {
  478. return err
  479. }
  480. if t.NumMembers == 1 {
  481. if err := t.getMembers(sess); err != nil {
  482. return err
  483. }
  484. if t.Members[0].ID == userID {
  485. return ErrLastOrgOwner{UID: userID}
  486. }
  487. }
  488. }
  489. if _, err := sess.ID(ou.ID).Delete(ou); err != nil {
  490. return err
  491. } else if _, err = sess.Exec("UPDATE `user` SET num_members=num_members-1 WHERE id=?", orgID); err != nil {
  492. return err
  493. }
  494. // Delete all repository accesses and unwatch them.
  495. env, err := org.accessibleReposEnv(sess, userID)
  496. if err != nil {
  497. return fmt.Errorf("AccessibleReposEnv: %v", err)
  498. }
  499. repoIDs, err := env.RepoIDs(1, org.NumRepos)
  500. if err != nil {
  501. return fmt.Errorf("GetUserRepositories [%d]: %v", userID, err)
  502. }
  503. for _, repoID := range repoIDs {
  504. if err = watchRepo(sess, userID, repoID, false); err != nil {
  505. return err
  506. }
  507. }
  508. if len(repoIDs) > 0 {
  509. if _, err = sess.
  510. Where("user_id = ?", userID).
  511. In("repo_id", repoIDs).
  512. Delete(new(Access)); err != nil {
  513. return err
  514. }
  515. }
  516. // Delete member in his/her teams.
  517. teams, err := getUserOrgTeams(sess, org.ID, userID)
  518. if err != nil {
  519. return err
  520. }
  521. for _, t := range teams {
  522. if err = removeTeamMember(sess, t, userID); err != nil {
  523. return err
  524. }
  525. }
  526. return nil
  527. }
  528. // RemoveOrgUser removes user from given organization.
  529. func RemoveOrgUser(orgID, userID int64) error {
  530. sess := x.NewSession()
  531. defer sess.Close()
  532. if err := sess.Begin(); err != nil {
  533. return err
  534. }
  535. if err := removeOrgUser(sess, orgID, userID); err != nil {
  536. return err
  537. }
  538. return sess.Commit()
  539. }
  540. func removeOrgRepo(e Engine, orgID, repoID int64) error {
  541. teamRepos := make([]*TeamRepo, 0, 10)
  542. if err := e.Find(&teamRepos, &TeamRepo{OrgID: orgID, RepoID: repoID}); err != nil {
  543. return err
  544. }
  545. if len(teamRepos) == 0 {
  546. return nil
  547. }
  548. if _, err := e.Delete(&TeamRepo{
  549. OrgID: orgID,
  550. RepoID: repoID,
  551. }); err != nil {
  552. return err
  553. }
  554. teamIDs := make([]int64, len(teamRepos))
  555. for i, teamRepo := range teamRepos {
  556. teamIDs[i] = teamRepo.TeamID
  557. }
  558. _, err := e.Decr("num_repos").In("id", teamIDs).Update(new(Team))
  559. return err
  560. }
  561. func (org *User) getUserTeams(e Engine, userID int64, cols ...string) ([]*Team, error) {
  562. teams := make([]*Team, 0, org.NumTeams)
  563. return teams, e.
  564. Where("`team_user`.org_id = ?", org.ID).
  565. Join("INNER", "team_user", "`team_user`.team_id = team.id").
  566. Join("INNER", "`user`", "`user`.id=team_user.uid").
  567. And("`team_user`.uid = ?", userID).
  568. Asc("`user`.name").
  569. Cols(cols...).
  570. Find(&teams)
  571. }
  572. func (org *User) getUserTeamIDs(e Engine, userID int64) ([]int64, error) {
  573. teamIDs := make([]int64, 0, org.NumTeams)
  574. return teamIDs, e.
  575. Table("team").
  576. Cols("team.id").
  577. Where("`team_user`.org_id = ?", org.ID).
  578. Join("INNER", "team_user", "`team_user`.team_id = team.id").
  579. And("`team_user`.uid = ?", userID).
  580. Find(&teamIDs)
  581. }
  582. // TeamsWithAccessToRepo returns all teamsthat have given access level to the repository.
  583. func (org *User) TeamsWithAccessToRepo(repoID int64, mode AccessMode) ([]*Team, error) {
  584. return GetTeamsWithAccessToRepo(org.ID, repoID, mode)
  585. }
  586. // GetUserTeamIDs returns of all team IDs of the organization that user is member of.
  587. func (org *User) GetUserTeamIDs(userID int64) ([]int64, error) {
  588. return org.getUserTeamIDs(x, userID)
  589. }
  590. // GetUserTeams returns all teams that belong to user,
  591. // and that the user has joined.
  592. func (org *User) GetUserTeams(userID int64) ([]*Team, error) {
  593. return org.getUserTeams(x, userID)
  594. }
  595. // AccessibleReposEnvironment operations involving the repositories that are
  596. // accessible to a particular user
  597. type AccessibleReposEnvironment interface {
  598. CountRepos() (int64, error)
  599. RepoIDs(page, pageSize int) ([]int64, error)
  600. Repos(page, pageSize int) ([]*Repository, error)
  601. MirrorRepos() ([]*Repository, error)
  602. AddKeyword(keyword string)
  603. SetSort(SearchOrderBy)
  604. }
  605. type accessibleReposEnv struct {
  606. org *User
  607. userID int64
  608. teamIDs []int64
  609. e Engine
  610. keyword string
  611. orderBy SearchOrderBy
  612. }
  613. // AccessibleReposEnv an AccessibleReposEnvironment for the repositories in `org`
  614. // that are accessible to the specified user.
  615. func (org *User) AccessibleReposEnv(userID int64) (AccessibleReposEnvironment, error) {
  616. return org.accessibleReposEnv(x, userID)
  617. }
  618. func (org *User) accessibleReposEnv(e Engine, userID int64) (AccessibleReposEnvironment, error) {
  619. teamIDs, err := org.getUserTeamIDs(e, userID)
  620. if err != nil {
  621. return nil, err
  622. }
  623. return &accessibleReposEnv{
  624. org: org,
  625. userID: userID,
  626. teamIDs: teamIDs,
  627. e: e,
  628. orderBy: SearchOrderByRecentUpdated,
  629. }, nil
  630. }
  631. func (env *accessibleReposEnv) cond() builder.Cond {
  632. var cond builder.Cond = builder.Eq{
  633. "`repository`.owner_id": env.org.ID,
  634. "`repository`.is_private": false,
  635. }
  636. if len(env.teamIDs) > 0 {
  637. cond = cond.Or(builder.In("team_repo.team_id", env.teamIDs))
  638. }
  639. if env.keyword != "" {
  640. cond = cond.And(builder.Like{"`repository`.lower_name", strings.ToLower(env.keyword)})
  641. }
  642. return cond
  643. }
  644. func (env *accessibleReposEnv) CountRepos() (int64, error) {
  645. repoCount, err := env.e.
  646. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
  647. Where(env.cond()).
  648. Distinct("`repository`.id").
  649. Count(&Repository{})
  650. if err != nil {
  651. return 0, fmt.Errorf("count user repositories in organization: %v", err)
  652. }
  653. return repoCount, nil
  654. }
  655. func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) {
  656. if page <= 0 {
  657. page = 1
  658. }
  659. repoIDs := make([]int64, 0, pageSize)
  660. return repoIDs, env.e.
  661. Table("repository").
  662. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
  663. Where(env.cond()).
  664. GroupBy("`repository`.id,`repository`."+strings.Fields(string(env.orderBy))[0]).
  665. OrderBy(string(env.orderBy)).
  666. Limit(pageSize, (page-1)*pageSize).
  667. Cols("`repository`.id").
  668. Find(&repoIDs)
  669. }
  670. func (env *accessibleReposEnv) Repos(page, pageSize int) ([]*Repository, error) {
  671. repoIDs, err := env.RepoIDs(page, pageSize)
  672. if err != nil {
  673. return nil, fmt.Errorf("GetUserRepositoryIDs: %v", err)
  674. }
  675. repos := make([]*Repository, 0, len(repoIDs))
  676. if len(repoIDs) == 0 {
  677. return repos, nil
  678. }
  679. return repos, env.e.
  680. In("`repository`.id", repoIDs).
  681. OrderBy(string(env.orderBy)).
  682. Find(&repos)
  683. }
  684. func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) {
  685. repoIDs := make([]int64, 0, 10)
  686. return repoIDs, env.e.
  687. Table("repository").
  688. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true).
  689. Where(env.cond()).
  690. GroupBy("`repository`.id, `repository`.updated_unix").
  691. OrderBy(string(env.orderBy)).
  692. Cols("`repository`.id").
  693. Find(&repoIDs)
  694. }
  695. func (env *accessibleReposEnv) MirrorRepos() ([]*Repository, error) {
  696. repoIDs, err := env.MirrorRepoIDs()
  697. if err != nil {
  698. return nil, fmt.Errorf("MirrorRepoIDs: %v", err)
  699. }
  700. repos := make([]*Repository, 0, len(repoIDs))
  701. if len(repoIDs) == 0 {
  702. return repos, nil
  703. }
  704. return repos, env.e.
  705. In("`repository`.id", repoIDs).
  706. Find(&repos)
  707. }
  708. func (env *accessibleReposEnv) AddKeyword(keyword string) {
  709. env.keyword = keyword
  710. }
  711. func (env *accessibleReposEnv) SetSort(orderBy SearchOrderBy) {
  712. env.orderBy = orderBy
  713. }