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.

583 lines
15 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
  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 models
  5. import (
  6. "errors"
  7. "fmt"
  8. "os"
  9. "strings"
  10. "github.com/go-xorm/builder"
  11. "github.com/go-xorm/xorm"
  12. )
  13. var (
  14. ErrOrgNotExist = errors.New("Organization does not exist")
  15. ErrTeamNotExist = errors.New("Team does not exist")
  16. )
  17. // IsOwnedBy returns true if given user is in the owner team.
  18. func (org *User) IsOwnedBy(uid int64) bool {
  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 {
  23. return org.IsOrganization() && IsOrganizationMember(org.ID, uid)
  24. }
  25. func (org *User) getTeam(e Engine, name string) (*Team, error) {
  26. return getTeam(e, org.ID, name)
  27. }
  28. // GetTeam returns named team of organization.
  29. func (org *User) GetTeam(name string) (*Team, error) {
  30. return org.getTeam(x, name)
  31. }
  32. func (org *User) getOwnerTeam(e Engine) (*Team, error) {
  33. return org.getTeam(e, OWNER_TEAM)
  34. }
  35. // GetOwnerTeam returns owner team of organization.
  36. func (org *User) GetOwnerTeam() (*Team, error) {
  37. return org.getOwnerTeam(x)
  38. }
  39. func (org *User) getTeams(e Engine) error {
  40. return e.
  41. Where("org_id=?", org.ID).
  42. OrderBy("CASE WHEN name LIKE '" + OWNER_TEAM + "' THEN '' ELSE name END").
  43. Find(&org.Teams)
  44. }
  45. // GetTeams returns all teams that belong to organization.
  46. func (org *User) GetTeams() error {
  47. return org.getTeams(x)
  48. }
  49. // GetMembers returns all members of organization.
  50. func (org *User) GetMembers() error {
  51. ous, err := GetOrgUsersByOrgID(org.ID)
  52. if err != nil {
  53. return err
  54. }
  55. var ids = make([]int64, len(ous))
  56. for i, ou := range ous {
  57. ids[i] = ou.Uid
  58. }
  59. org.Members, err = GetUsersByIDs(ids)
  60. return err
  61. }
  62. // AddMember adds new member to organization.
  63. func (org *User) AddMember(uid int64) error {
  64. return AddOrgUser(org.ID, uid)
  65. }
  66. // RemoveMember removes member from organization.
  67. func (org *User) RemoveMember(uid int64) error {
  68. return RemoveOrgUser(org.ID, uid)
  69. }
  70. func (org *User) removeOrgRepo(e Engine, repoID int64) error {
  71. return removeOrgRepo(e, org.ID, repoID)
  72. }
  73. // RemoveOrgRepo removes all team-repository relations of organization.
  74. func (org *User) RemoveOrgRepo(repoID int64) error {
  75. return org.removeOrgRepo(x, repoID)
  76. }
  77. // CreateOrganization creates record of a new organization.
  78. func CreateOrganization(org, owner *User) (err error) {
  79. if err = IsUsableUsername(org.Name); err != nil {
  80. return err
  81. }
  82. isExist, err := IsUserExist(0, org.Name)
  83. if err != nil {
  84. return err
  85. } else if isExist {
  86. return ErrUserAlreadyExist{org.Name}
  87. }
  88. org.LowerName = strings.ToLower(org.Name)
  89. org.Rands = GetUserSalt()
  90. org.Salt = GetUserSalt()
  91. org.UseCustomAvatar = true
  92. org.MaxRepoCreation = -1
  93. org.NumTeams = 1
  94. org.NumMembers = 1
  95. sess := x.NewSession()
  96. defer sessionRelease(sess)
  97. if err = sess.Begin(); err != nil {
  98. return err
  99. }
  100. if _, err = sess.Insert(org); err != nil {
  101. return fmt.Errorf("insert organization: %v", err)
  102. }
  103. org.GenerateRandomAvatar()
  104. // Add initial creator to organization and owner team.
  105. if _, err = sess.Insert(&OrgUser{
  106. Uid: owner.ID,
  107. OrgID: org.ID,
  108. IsOwner: true,
  109. NumTeams: 1,
  110. }); err != nil {
  111. return fmt.Errorf("insert org-user relation: %v", err)
  112. }
  113. // Create default owner team.
  114. t := &Team{
  115. OrgID: org.ID,
  116. LowerName: strings.ToLower(OWNER_TEAM),
  117. Name: OWNER_TEAM,
  118. Authorize: AccessModeOwner,
  119. NumMembers: 1,
  120. }
  121. if _, err = sess.Insert(t); err != nil {
  122. return fmt.Errorf("insert owner team: %v", err)
  123. }
  124. if _, err = sess.Insert(&TeamUser{
  125. Uid: owner.ID,
  126. OrgID: org.ID,
  127. TeamID: t.ID,
  128. }); err != nil {
  129. return fmt.Errorf("insert team-user relation: %v", err)
  130. }
  131. if err = os.MkdirAll(UserPath(org.Name), os.ModePerm); err != nil {
  132. return fmt.Errorf("create directory: %v", err)
  133. }
  134. return sess.Commit()
  135. }
  136. // GetOrgByName returns organization by given name.
  137. func GetOrgByName(name string) (*User, error) {
  138. if len(name) == 0 {
  139. return nil, ErrOrgNotExist
  140. }
  141. u := &User{
  142. LowerName: strings.ToLower(name),
  143. Type: UserTypeOrganization,
  144. }
  145. has, err := x.Get(u)
  146. if err != nil {
  147. return nil, err
  148. } else if !has {
  149. return nil, ErrOrgNotExist
  150. }
  151. return u, nil
  152. }
  153. // CountOrganizations returns number of organizations.
  154. func CountOrganizations() int64 {
  155. count, _ := x.
  156. Where("type=1").
  157. Count(new(User))
  158. return count
  159. }
  160. // Organizations returns number of organizations in given page.
  161. func Organizations(page, pageSize int) ([]*User, error) {
  162. orgs := make([]*User, 0, pageSize)
  163. return orgs, x.
  164. Limit(pageSize, (page-1)*pageSize).
  165. Where("type=1").
  166. Asc("name").
  167. Find(&orgs)
  168. }
  169. // DeleteOrganization completely and permanently deletes everything of organization.
  170. func DeleteOrganization(org *User) (err error) {
  171. if err := DeleteUser(org); err != nil {
  172. return err
  173. }
  174. sess := x.NewSession()
  175. defer sessionRelease(sess)
  176. if err = sess.Begin(); err != nil {
  177. return err
  178. }
  179. if err = deleteBeans(sess,
  180. &Team{OrgID: org.ID},
  181. &OrgUser{OrgID: org.ID},
  182. &TeamUser{OrgID: org.ID},
  183. ); err != nil {
  184. return fmt.Errorf("deleteBeans: %v", err)
  185. }
  186. if err = deleteUser(sess, org); err != nil {
  187. return fmt.Errorf("deleteUser: %v", err)
  188. }
  189. return sess.Commit()
  190. }
  191. // ________ ____ ___
  192. // \_____ \_______ ____ | | \______ ___________
  193. // / | \_ __ \/ ___\| | / ___// __ \_ __ \
  194. // / | \ | \/ /_/ > | /\___ \\ ___/| | \/
  195. // \_______ /__| \___ /|______//____ >\___ >__|
  196. // \/ /_____/ \/ \/
  197. // OrgUser represents an organization-user relation.
  198. type OrgUser struct {
  199. ID int64 `xorm:"pk autoincr"`
  200. Uid int64 `xorm:"INDEX UNIQUE(s)"`
  201. OrgID int64 `xorm:"INDEX UNIQUE(s)"`
  202. IsPublic bool
  203. IsOwner bool
  204. NumTeams int
  205. }
  206. // IsOrganizationOwner returns true if given user is in the owner team.
  207. func IsOrganizationOwner(orgId, uid int64) bool {
  208. has, _ := x.
  209. Where("is_owner=?", true).
  210. And("uid=?", uid).
  211. And("org_id=?", orgId).
  212. Get(new(OrgUser))
  213. return has
  214. }
  215. // IsOrganizationMember returns true if given user is member of organization.
  216. func IsOrganizationMember(orgId, uid int64) bool {
  217. has, _ := x.
  218. Where("uid=?", uid).
  219. And("org_id=?", orgId).
  220. Get(new(OrgUser))
  221. return has
  222. }
  223. // IsPublicMembership returns true if given user public his/her membership.
  224. func IsPublicMembership(orgId, uid int64) bool {
  225. has, _ := x.
  226. Where("uid=?", uid).
  227. And("org_id=?", orgId).
  228. And("is_public=?", true).
  229. Get(new(OrgUser))
  230. return has
  231. }
  232. func getOrgsByUserID(sess *xorm.Session, userID int64, showAll bool) ([]*User, error) {
  233. orgs := make([]*User, 0, 10)
  234. if !showAll {
  235. sess.And("`org_user`.is_public=?", true)
  236. }
  237. return orgs, sess.
  238. And("`org_user`.uid=?", userID).
  239. Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").
  240. Asc("`user`.name").
  241. Find(&orgs)
  242. }
  243. // GetOrgsByUserID returns a list of organizations that the given user ID
  244. // has joined.
  245. func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) {
  246. return getOrgsByUserID(x.NewSession(), userID, showAll)
  247. }
  248. // GetOrgsByUserIDDesc returns a list of organizations that the given user ID
  249. // has joined, ordered descending by the given condition.
  250. func GetOrgsByUserIDDesc(userID int64, desc string, showAll bool) ([]*User, error) {
  251. return getOrgsByUserID(x.NewSession().Desc(desc), userID, showAll)
  252. }
  253. func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
  254. orgs := make([]*User, 0, 10)
  255. return orgs, sess.
  256. Where("`org_user`.uid=?", userID).
  257. And("`org_user`.is_owner=?", true).
  258. Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id").
  259. Asc("`user`.name").
  260. Find(&orgs)
  261. }
  262. // GetOwnedOrgsByUserID returns a list of organizations are owned by given user ID.
  263. func GetOwnedOrgsByUserID(userID int64) ([]*User, error) {
  264. sess := x.NewSession()
  265. return getOwnedOrgsByUserID(sess, userID)
  266. }
  267. // GetOwnedOrganizationsByUserIDDesc returns a list of organizations are owned by
  268. // given user ID, ordered descending by the given condition.
  269. func GetOwnedOrgsByUserIDDesc(userID int64, desc string) ([]*User, error) {
  270. sess := x.NewSession()
  271. return getOwnedOrgsByUserID(sess.Desc(desc), userID)
  272. }
  273. // GetOrgUsersByUserID returns all organization-user relations by user ID.
  274. func GetOrgUsersByUserID(uid int64, all bool) ([]*OrgUser, error) {
  275. ous := make([]*OrgUser, 0, 10)
  276. sess := x.
  277. Join("LEFT", "user", "`org_user`.org_id=`user`.id").
  278. Where("`org_user`.uid=?", uid)
  279. if !all {
  280. // Only show public organizations
  281. sess.And("is_public=?", true)
  282. }
  283. err := sess.
  284. Asc("`user`.name").
  285. Find(&ous)
  286. return ous, err
  287. }
  288. // GetOrgUsersByOrgID returns all organization-user relations by organization ID.
  289. func GetOrgUsersByOrgID(orgID int64) ([]*OrgUser, error) {
  290. ous := make([]*OrgUser, 0, 10)
  291. err := x.
  292. Where("org_id=?", orgID).
  293. Find(&ous)
  294. return ous, err
  295. }
  296. // ChangeOrgUserStatus changes public or private membership status.
  297. func ChangeOrgUserStatus(orgID, uid int64, public bool) error {
  298. ou := new(OrgUser)
  299. has, err := x.
  300. Where("uid=?", uid).
  301. And("org_id=?", orgID).
  302. Get(ou)
  303. if err != nil {
  304. return err
  305. } else if !has {
  306. return nil
  307. }
  308. ou.IsPublic = public
  309. _, err = x.Id(ou.ID).AllCols().Update(ou)
  310. return err
  311. }
  312. // AddOrgUser adds new user to given organization.
  313. func AddOrgUser(orgID, uid int64) error {
  314. if IsOrganizationMember(orgID, uid) {
  315. return nil
  316. }
  317. sess := x.NewSession()
  318. defer sess.Close()
  319. if err := sess.Begin(); err != nil {
  320. return err
  321. }
  322. ou := &OrgUser{
  323. Uid: uid,
  324. OrgID: orgID,
  325. }
  326. if _, err := sess.Insert(ou); err != nil {
  327. sess.Rollback()
  328. return err
  329. } else if _, err = sess.Exec("UPDATE `user` SET num_members = num_members + 1 WHERE id = ?", orgID); err != nil {
  330. sess.Rollback()
  331. return err
  332. }
  333. return sess.Commit()
  334. }
  335. // RemoveOrgUser removes user from given organization.
  336. func RemoveOrgUser(orgID, userID int64) error {
  337. ou := new(OrgUser)
  338. has, err := x.
  339. Where("uid=?", userID).
  340. And("org_id=?", orgID).
  341. Get(ou)
  342. if err != nil {
  343. return fmt.Errorf("get org-user: %v", err)
  344. } else if !has {
  345. return nil
  346. }
  347. user, err := GetUserByID(userID)
  348. if err != nil {
  349. return fmt.Errorf("GetUserByID [%d]: %v", userID, err)
  350. }
  351. org, err := GetUserByID(orgID)
  352. if err != nil {
  353. return fmt.Errorf("GetUserByID [%d]: %v", orgID, err)
  354. }
  355. // FIXME: only need to get IDs here, not all fields of repository.
  356. repos, _, err := org.GetUserRepositories(user.ID, 1, org.NumRepos)
  357. if err != nil {
  358. return fmt.Errorf("GetUserRepositories [%d]: %v", user.ID, err)
  359. }
  360. // Check if the user to delete is the last member in owner team.
  361. if IsOrganizationOwner(orgID, userID) {
  362. t, err := org.GetOwnerTeam()
  363. if err != nil {
  364. return err
  365. }
  366. if t.NumMembers == 1 {
  367. return ErrLastOrgOwner{UID: userID}
  368. }
  369. }
  370. sess := x.NewSession()
  371. defer sessionRelease(sess)
  372. if err := sess.Begin(); err != nil {
  373. return err
  374. }
  375. if _, err := sess.Id(ou.ID).Delete(ou); err != nil {
  376. return err
  377. } else if _, err = sess.Exec("UPDATE `user` SET num_members=num_members-1 WHERE id=?", orgID); err != nil {
  378. return err
  379. }
  380. // Delete all repository accesses and unwatch them.
  381. repoIDs := make([]int64, len(repos))
  382. for i := range repos {
  383. repoIDs = append(repoIDs, repos[i].ID)
  384. if err = watchRepo(sess, user.ID, repos[i].ID, false); err != nil {
  385. return err
  386. }
  387. }
  388. if len(repoIDs) > 0 {
  389. if _, err = sess.
  390. Where("user_id = ?", user.ID).
  391. In("repo_id", repoIDs).
  392. Delete(new(Access)); err != nil {
  393. return err
  394. }
  395. }
  396. // Delete member in his/her teams.
  397. teams, err := getUserTeams(sess, org.ID, user.ID)
  398. if err != nil {
  399. return err
  400. }
  401. for _, t := range teams {
  402. if err = removeTeamMember(sess, org.ID, t.ID, user.ID); err != nil {
  403. return err
  404. }
  405. }
  406. return sess.Commit()
  407. }
  408. func removeOrgRepo(e Engine, orgID, repoID int64) error {
  409. _, err := e.Delete(&TeamRepo{
  410. OrgID: orgID,
  411. RepoID: repoID,
  412. })
  413. return err
  414. }
  415. // RemoveOrgRepo removes all team-repository relations of given organization.
  416. func RemoveOrgRepo(orgID, repoID int64) error {
  417. return removeOrgRepo(x, orgID, repoID)
  418. }
  419. func (org *User) getUserTeams(e Engine, userID int64, cols ...string) ([]*Team, error) {
  420. teams := make([]*Team, 0, org.NumTeams)
  421. return teams, e.
  422. Where("`team_user`.org_id = ?", org.ID).
  423. Join("INNER", "team_user", "`team_user`.team_id = team.id").
  424. Join("INNER", "user", "`user`.id=team_user.uid").
  425. And("`team_user`.uid = ?", userID).
  426. Asc("`user`.name").
  427. Cols(cols...).
  428. Find(&teams)
  429. }
  430. // GetUserTeamIDs returns of all team IDs of the organization that user is memeber of.
  431. func (org *User) GetUserTeamIDs(userID int64) ([]int64, error) {
  432. teams, err := org.getUserTeams(x, userID, "team.id")
  433. if err != nil {
  434. return nil, fmt.Errorf("getUserTeams [%d]: %v", userID, err)
  435. }
  436. teamIDs := make([]int64, len(teams))
  437. for i := range teams {
  438. teamIDs[i] = teams[i].ID
  439. }
  440. return teamIDs, nil
  441. }
  442. // GetTeams returns all teams that belong to organization,
  443. // and that the user has joined.
  444. func (org *User) GetUserTeams(userID int64) ([]*Team, error) {
  445. return org.getUserTeams(x, userID)
  446. }
  447. // GetUserRepositories returns a range of repositories in organization
  448. // that the user with the given userID has access to,
  449. // and total number of records based on given condition.
  450. func (org *User) GetUserRepositories(userID int64, page, pageSize int) ([]*Repository, int64, error) {
  451. teamIDs, err := org.GetUserTeamIDs(userID)
  452. if err != nil {
  453. return nil, 0, fmt.Errorf("GetUserTeamIDs: %v", err)
  454. }
  455. if len(teamIDs) == 0 {
  456. // user has no team but "IN ()" is invalid SQL
  457. teamIDs = []int64{-1} // there is no repo with id=-1
  458. }
  459. if page <= 0 {
  460. page = 1
  461. }
  462. repos := make([]*Repository, 0, pageSize)
  463. if err := x.
  464. Select("`repository`.*").
  465. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
  466. Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
  467. Or(builder.In("team_repo.team_id", teamIDs)).
  468. GroupBy("`repository`.id").
  469. OrderBy("updated_unix DESC").
  470. Limit(pageSize, (page-1)*pageSize).
  471. Find(&repos); err != nil {
  472. return nil, 0, fmt.Errorf("get repositories: %v", err)
  473. }
  474. repoCount, err := x.
  475. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id").
  476. Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
  477. Or(builder.In("team_repo.team_id", teamIDs)).
  478. GroupBy("`repository`.id").
  479. Count(&Repository{})
  480. if err != nil {
  481. return nil, 0, fmt.Errorf("count user repositories in organization: %v", err)
  482. }
  483. return repos, repoCount, nil
  484. }
  485. // GetUserRepositories returns mirror repositories of the organization
  486. // that the user with the given userID has access to.
  487. func (org *User) GetUserMirrorRepositories(userID int64) ([]*Repository, error) {
  488. teamIDs, err := org.GetUserTeamIDs(userID)
  489. if err != nil {
  490. return nil, fmt.Errorf("GetUserTeamIDs: %v", err)
  491. }
  492. if len(teamIDs) == 0 {
  493. teamIDs = []int64{-1}
  494. }
  495. repos := make([]*Repository, 0, 10)
  496. return repos, x.
  497. Select("`repository`.*").
  498. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true).
  499. Where("(`repository`.owner_id=? AND `repository`.is_private=?)", org.ID, false).
  500. Or(builder.In("team_repo.team_id", teamIDs)).
  501. GroupBy("`repository`.id").
  502. OrderBy("updated_unix DESC").
  503. Find(&repos)
  504. }