| @@ -425,7 +425,7 @@ func TestGetFeeds2(t *testing.T) { | |||
| // test with an organization user | |||
| assert.NoError(t, PrepareTestDatabase()) | |||
| org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) | |||
| userID := AssertExistsAndLoadBean(t, &OrgUser{OrgID: org.ID, IsOwner: true}).(*OrgUser).UID | |||
| const userID = 2 // user2 is an owner of the organization | |||
| actions, err := GetFeeds(GetFeedsOptions{ | |||
| RequestedUser: org, | |||
| @@ -3,53 +3,39 @@ | |||
| uid: 2 | |||
| org_id: 3 | |||
| is_public: true | |||
| is_owner: true | |||
| num_teams: 1 | |||
| - | |||
| id: 2 | |||
| uid: 4 | |||
| org_id: 3 | |||
| is_public: false | |||
| is_owner: false | |||
| num_teams: 0 | |||
| - | |||
| id: 3 | |||
| uid: 5 | |||
| org_id: 6 | |||
| is_public: true | |||
| is_owner: true | |||
| num_teams: 1 | |||
| - | |||
| id: 4 | |||
| uid: 5 | |||
| org_id: 7 | |||
| is_public: false | |||
| is_owner: true | |||
| num_teams: 1 | |||
| - | |||
| id: 5 | |||
| uid: 15 | |||
| org_id: 17 | |||
| is_public: true | |||
| is_owner: true | |||
| num_teams: 1 | |||
| - | |||
| id: 6 | |||
| uid: 18 | |||
| org_id: 17 | |||
| is_public: false | |||
| is_owner: true | |||
| num_teams: 1 | |||
| - | |||
| id: 7 | |||
| uid: 20 | |||
| org_id: 19 | |||
| is_public: true | |||
| is_owner: true | |||
| num_teams: 1 | |||
| @@ -164,6 +164,8 @@ var migrations = []Migration{ | |||
| NewMigration("add pull request options", addPullRequestOptions), | |||
| // v55 -> v56 | |||
| NewMigration("add writable deploy keys", addModeToDeploKeys), | |||
| // v56 -> v57 | |||
| NewMigration("remove is_owner, num_teams columns from org_user", removeIsOwnerColumnFromOrgUser), | |||
| } | |||
| // Migrate database to current version | |||
| @@ -0,0 +1,33 @@ | |||
| // Copyright 2017 The Gitea Authors. All rights reserved. | |||
| // Use of this source code is governed by a MIT-style | |||
| // license that can be found in the LICENSE file. | |||
| package migrations | |||
| import ( | |||
| "fmt" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "github.com/go-xorm/xorm" | |||
| ) | |||
| func removeIsOwnerColumnFromOrgUser(x *xorm.Engine) (err error) { | |||
| switch { | |||
| case setting.UseSQLite3: | |||
| log.Warn("Unable to drop columns in SQLite") | |||
| case setting.UseMySQL, setting.UseTiDB, setting.UsePostgreSQL: | |||
| if _, err := x.Exec("ALTER TABLE org_user DROP COLUMN is_owner, DROP COLUMN num_teams"); err != nil { | |||
| return fmt.Errorf("DROP COLUMN org_user.is_owner, org_user.num_teams: %v", err) | |||
| } | |||
| case setting.UseMSSQL: | |||
| if _, err := x.Exec("ALTER TABLE org_user DROP COLUMN is_owner, num_teams"); err != nil { | |||
| return fmt.Errorf("DROP COLUMN org_user.is_owner, org_user.num_teams: %v", err) | |||
| } | |||
| default: | |||
| log.Fatal(4, "Unrecognized DB") | |||
| } | |||
| return nil | |||
| } | |||
| @@ -10,6 +10,8 @@ import ( | |||
| "os" | |||
| "strings" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "github.com/Unknwon/com" | |||
| "github.com/go-xorm/builder" | |||
| "github.com/go-xorm/xorm" | |||
| @@ -139,10 +141,8 @@ func CreateOrganization(org, owner *User) (err error) { | |||
| // Add initial creator to organization and owner team. | |||
| if _, err = sess.Insert(&OrgUser{ | |||
| UID: owner.ID, | |||
| OrgID: org.ID, | |||
| IsOwner: true, | |||
| NumTeams: 1, | |||
| UID: owner.ID, | |||
| OrgID: org.ID, | |||
| }); err != nil { | |||
| return fmt.Errorf("insert org-user relation: %v", err) | |||
| } | |||
| @@ -280,18 +280,25 @@ type OrgUser struct { | |||
| UID int64 `xorm:"INDEX UNIQUE(s)"` | |||
| OrgID int64 `xorm:"INDEX UNIQUE(s)"` | |||
| IsPublic bool `xorm:"INDEX"` | |||
| IsOwner bool | |||
| NumTeams int | |||
| } | |||
| func isOrganizationOwner(e Engine, orgID, uid int64) (bool, error) { | |||
| ownerTeam := &Team{ | |||
| OrgID: orgID, | |||
| Name: ownerTeamName, | |||
| } | |||
| if has, err := e.Get(ownerTeam); err != nil { | |||
| return false, err | |||
| } else if !has { | |||
| log.Error(4, "Organization does not have owner team: %d", orgID) | |||
| return false, nil | |||
| } | |||
| return isTeamMember(e, orgID, ownerTeam.ID, uid) | |||
| } | |||
| // IsOrganizationOwner returns true if given user is in the owner team. | |||
| func IsOrganizationOwner(orgID, uid int64) (bool, error) { | |||
| return x. | |||
| Where("is_owner=?", true). | |||
| And("uid=?", uid). | |||
| And("org_id=?", orgID). | |||
| Table("org_user"). | |||
| Exist() | |||
| return isOrganizationOwner(x, orgID, uid) | |||
| } | |||
| // IsOrganizationMember returns true if given user is member of organization. | |||
| @@ -336,9 +343,10 @@ func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) { | |||
| func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) { | |||
| orgs := make([]*User, 0, 10) | |||
| return orgs, sess. | |||
| Where("`org_user`.uid=?", userID). | |||
| And("`org_user`.is_owner=?", true). | |||
| Join("INNER", "`org_user`", "`org_user`.org_id=`user`.id"). | |||
| Join("INNER", "`team_user`", "`team_user`.org_id=`user`.id"). | |||
| Join("INNER", "`team`", "`team`.id=`team_user`.team_id"). | |||
| Where("`team_user`.uid=?", userID). | |||
| And("`team`.authorize=?", AccessModeOwner). | |||
| Asc("`user`.name"). | |||
| Find(&orgs) | |||
| } | |||
| @@ -518,22 +518,6 @@ func AddTeamMember(team *Team, userID int64) error { | |||
| } | |||
| } | |||
| // We make sure it exists before. | |||
| ou := new(OrgUser) | |||
| if _, err := sess. | |||
| Where("uid = ?", userID). | |||
| And("org_id = ?", team.OrgID). | |||
| Get(ou); err != nil { | |||
| return err | |||
| } | |||
| ou.NumTeams++ | |||
| if team.IsOwnerTeam() { | |||
| ou.IsOwner = true | |||
| } | |||
| if _, err := sess.ID(ou.ID).Cols("num_teams, is_owner").Update(ou); err != nil { | |||
| return err | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| @@ -574,25 +558,6 @@ func removeTeamMember(e Engine, team *Team, userID int64) error { | |||
| } | |||
| } | |||
| // This must exist. | |||
| ou := new(OrgUser) | |||
| _, err = e. | |||
| Where("uid = ?", userID). | |||
| And("org_id = ?", team.OrgID). | |||
| Get(ou) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| ou.NumTeams-- | |||
| if team.IsOwnerTeam() { | |||
| ou.IsOwner = false | |||
| } | |||
| if _, err = e. | |||
| ID(ou.ID). | |||
| Cols("num_teams"). | |||
| Update(ou); err != nil { | |||
| return err | |||
| } | |||
| return nil | |||
| } | |||
| @@ -368,16 +368,12 @@ func TestGetOrgUsersByUserID(t *testing.T) { | |||
| ID: orgUsers[0].ID, | |||
| OrgID: 6, | |||
| UID: 5, | |||
| IsOwner: true, | |||
| IsPublic: true, | |||
| NumTeams: 1}, *orgUsers[0]) | |||
| IsPublic: true}, *orgUsers[0]) | |||
| assert.Equal(t, OrgUser{ | |||
| ID: orgUsers[1].ID, | |||
| OrgID: 7, | |||
| UID: 5, | |||
| IsOwner: true, | |||
| IsPublic: false, | |||
| NumTeams: 1}, *orgUsers[1]) | |||
| IsPublic: false}, *orgUsers[1]) | |||
| } | |||
| publicOrgUsers, err := GetOrgUsersByUserID(5, false) | |||
| @@ -400,16 +396,12 @@ func TestGetOrgUsersByOrgID(t *testing.T) { | |||
| ID: orgUsers[0].ID, | |||
| OrgID: 3, | |||
| UID: 2, | |||
| IsOwner: true, | |||
| IsPublic: true, | |||
| NumTeams: 1}, *orgUsers[0]) | |||
| IsPublic: true}, *orgUsers[0]) | |||
| assert.Equal(t, OrgUser{ | |||
| ID: orgUsers[1].ID, | |||
| OrgID: 3, | |||
| UID: 4, | |||
| IsOwner: false, | |||
| IsPublic: false, | |||
| NumTeams: 0}, *orgUsers[1]) | |||
| IsPublic: false}, *orgUsers[1]) | |||
| } | |||
| orgUsers, err = GetOrgUsersByOrgID(NonexistentID) | |||