From 7a0347315995b25bcb2dca4786504fb699b5f004 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 19 Nov 2021 19:41:40 +0800 Subject: [PATCH] Use a standalone struct name for Organization (#17632) * Use a standalone struct name for Organization * recover unnecessary change * make the code readable * Fix template failure * Fix template failure * Move HasMemberWithUserID to org * Fix test * Remove unnecessary user type check * Fix test Co-authored-by: wxiaoguang --- models/access.go | 5 +- models/action.go | 4 +- models/org.go | 200 +++++++++++++------ models/org_team.go | 17 +- models/org_test.go | 112 ++++++----- models/repo.go | 26 +-- models/repo_test.go | 2 +- models/repo_transfer.go | 7 +- models/user.go | 17 -- models/userlist_test.go | 21 +- modules/context/api_org.go | 2 +- modules/context/org.go | 22 +- modules/convert/convert.go | 4 +- modules/repository/create_test.go | 7 +- modules/repository/repo.go | 2 +- routers/api/v1/admin/org.go | 4 +- routers/api/v1/org/hook.go | 4 +- routers/api/v1/org/label.go | 8 +- routers/api/v1/org/org.go | 15 +- routers/api/v1/org/team.go | 2 +- routers/api/v1/repo/fork.go | 2 +- routers/api/v1/repo/migrate.go | 2 +- routers/api/v1/repo/repo.go | 6 +- routers/api/v1/repo/transfer.go | 4 +- routers/api/v1/user/repo.go | 2 +- routers/api/v1/utils/hook.go | 4 +- routers/web/org/home.go | 4 +- routers/web/org/org.go | 4 +- routers/web/org/setting.go | 14 +- routers/web/org/teams.go | 6 +- routers/web/repo/issue.go | 13 +- routers/web/repo/issue_label.go | 2 +- routers/web/repo/pull.go | 2 +- routers/web/repo/repo.go | 2 +- routers/web/repo/setting.go | 4 +- routers/web/repo/setting_protected_branch.go | 2 +- routers/web/repo/tag.go | 2 +- routers/web/user/home.go | 12 +- routers/web/user/oauth.go | 6 +- services/org/org.go | 8 +- services/org/org_test.go | 8 +- services/repository/repository.go | 2 +- services/user/user.go | 2 +- 43 files changed, 335 insertions(+), 259 deletions(-) diff --git a/models/access.go b/models/access.go index 7bbc04bd4..500bcc1e1 100644 --- a/models/access.go +++ b/models/access.go @@ -254,11 +254,12 @@ func (repo *Repository) recalculateTeamAccesses(e db.Engine, ignTeamID int64) (e return fmt.Errorf("refreshCollaboratorAccesses: %v", err) } - if err = repo.Owner.loadTeams(e); err != nil { + teams, err := OrgFromUser(repo.Owner).loadTeams(e) + if err != nil { return err } - for _, t := range repo.Owner.Teams { + for _, t := range teams { if t.ID == ignTeamID { continue } diff --git a/models/action.go b/models/action.go index 80ac3e16f..d790cd667 100644 --- a/models/action.go +++ b/models/action.go @@ -352,7 +352,7 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) { // check readable repositories by doer/actor if opts.Actor == nil || !opts.Actor.IsAdmin { if opts.RequestedUser.IsOrganization() { - env, err := opts.RequestedUser.AccessibleReposEnv(actorID) + env, err := OrgFromUser(opts.RequestedUser).AccessibleReposEnv(actorID) if err != nil { return nil, fmt.Errorf("AccessibleReposEnv: %v", err) } @@ -366,7 +366,7 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) { } if opts.RequestedTeam != nil { - env := opts.RequestedUser.AccessibleTeamReposEnv(opts.RequestedTeam) + env := OrgFromUser(opts.RequestedUser).AccessibleTeamReposEnv(opts.RequestedTeam) teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos) if err != nil { return nil, fmt.Errorf("GetTeamRepositories: %v", err) diff --git a/models/org.go b/models/org.go index e0b4d2724..c79af5c7b 100644 --- a/models/org.go +++ b/models/org.go @@ -21,60 +21,109 @@ import ( "xorm.io/xorm" ) +// Organization represents an organization +type Organization User + +// OrgFromUser converts user to organization +func OrgFromUser(user *User) *Organization { + return (*Organization)(user) +} + +// TableName represents the real table name of Organization +func (Organization) TableName() string { + return "user" +} + // IsOwnedBy returns true if given user is in the owner team. -func (org *User) IsOwnedBy(uid int64) (bool, error) { +func (org *Organization) IsOwnedBy(uid int64) (bool, error) { return IsOrganizationOwner(org.ID, uid) } // IsOrgMember returns true if given user is member of organization. -func (org *User) IsOrgMember(uid int64) (bool, error) { +func (org *Organization) IsOrgMember(uid int64) (bool, error) { return IsOrganizationMember(org.ID, uid) } // CanCreateOrgRepo returns true if given user can create repo in organization -func (org *User) CanCreateOrgRepo(uid int64) (bool, error) { +func (org *Organization) CanCreateOrgRepo(uid int64) (bool, error) { return CanCreateOrgRepo(org.ID, uid) } -func (org *User) getTeam(e db.Engine, name string) (*Team, error) { +func (org *Organization) getTeam(e db.Engine, name string) (*Team, error) { return getTeam(e, org.ID, name) } // GetTeam returns named team of organization. -func (org *User) GetTeam(name string) (*Team, error) { +func (org *Organization) GetTeam(name string) (*Team, error) { return org.getTeam(db.GetEngine(db.DefaultContext), name) } -func (org *User) getOwnerTeam(e db.Engine) (*Team, error) { +func (org *Organization) getOwnerTeam(e db.Engine) (*Team, error) { return org.getTeam(e, ownerTeamName) } // GetOwnerTeam returns owner team of organization. -func (org *User) GetOwnerTeam() (*Team, error) { +func (org *Organization) GetOwnerTeam() (*Team, error) { return org.getOwnerTeam(db.GetEngine(db.DefaultContext)) } -func (org *User) loadTeams(e db.Engine) error { - if org.Teams != nil { - return nil - } - return e. +func (org *Organization) loadTeams(e db.Engine) ([]*Team, error) { + var teams []*Team + return teams, e. Where("org_id=?", org.ID). OrderBy("CASE WHEN name LIKE '" + ownerTeamName + "' THEN '' ELSE name END"). - Find(&org.Teams) + Find(&teams) } // LoadTeams load teams if not loaded. -func (org *User) LoadTeams() error { +func (org *Organization) LoadTeams() ([]*Team, error) { return org.loadTeams(db.GetEngine(db.DefaultContext)) } // GetMembers returns all members of organization. -func (org *User) GetMembers() (err error) { - org.Members, org.MembersIsPublic, err = FindOrgMembers(&FindOrgMembersOpts{ +func (org *Organization) GetMembers() (UserList, map[int64]bool, error) { + return FindOrgMembers(&FindOrgMembersOpts{ OrgID: org.ID, }) - return +} + +// HasMemberWithUserID returns true if user with userID is part of the u organisation. +func (org *Organization) HasMemberWithUserID(userID int64) bool { + return org.hasMemberWithUserID(db.GetEngine(db.DefaultContext), userID) +} + +func (org *Organization) hasMemberWithUserID(e db.Engine, userID int64) bool { + isMember, err := isOrganizationMember(e, org.ID, userID) + if err != nil { + log.Error("IsOrganizationMember: %v", err) + return false + } + return isMember +} + +// AvatarLink returns the full avatar link with http host +func (org *Organization) AvatarLink() string { + return org.AsUser().AvatarLink() +} + +// HTMLURL returns the organization's full link. +func (org *Organization) HTMLURL() string { + return org.AsUser().HTMLURL() +} + +// OrganisationLink returns the organization sub page link. +func (org *Organization) OrganisationLink() string { + return org.AsUser().OrganisationLink() +} + +// ShortName ellipses username to length +func (org *Organization) ShortName(length int) string { + return org.AsUser().ShortName(length) +} + +// HomeLink returns the user or organization home page link. +func (org *Organization) HomeLink() string { + return org.AsUser().HomeLink() } // FindOrgMembersOpts represensts find org members conditions @@ -115,26 +164,42 @@ func FindOrgMembers(opts *FindOrgMembersOpts) (UserList, map[int64]bool, error) } // AddMember adds new member to organization. -func (org *User) AddMember(uid int64) error { +func (org *Organization) AddMember(uid int64) error { return AddOrgUser(org.ID, uid) } // RemoveMember removes member from organization. -func (org *User) RemoveMember(uid int64) error { +func (org *Organization) RemoveMember(uid int64) error { return RemoveOrgUser(org.ID, uid) } -func (org *User) removeOrgRepo(e db.Engine, repoID int64) error { +func (org *Organization) removeOrgRepo(e db.Engine, repoID int64) error { return removeOrgRepo(e, org.ID, repoID) } // RemoveOrgRepo removes all team-repository relations of organization. -func (org *User) RemoveOrgRepo(repoID int64) error { +func (org *Organization) RemoveOrgRepo(repoID int64) error { return org.removeOrgRepo(db.GetEngine(db.DefaultContext), repoID) } +// AsUser returns the org as user object +func (org *Organization) AsUser() *User { + return (*User)(org) +} + +// DisplayName returns full name if it's not empty, +// returns username otherwise. +func (org *Organization) DisplayName() string { + return org.AsUser().DisplayName() +} + +// CustomAvatarRelativePath returns user custom avatar relative path. +func (org *Organization) CustomAvatarRelativePath() string { + return org.Avatar +} + // CreateOrganization creates record of a new organization. -func CreateOrganization(org, owner *User) (err error) { +func CreateOrganization(org *Organization, owner *User) (err error) { if !owner.CanCreateOrganization() { return ErrUserNotAllowedCreateOrg{} } @@ -176,7 +241,7 @@ func CreateOrganization(org, owner *User) (err error) { if err = db.Insert(ctx, org); err != nil { return fmt.Errorf("insert organization: %v", err) } - if err = org.generateRandomAvatar(db.GetEngine(ctx)); err != nil { + if err = org.AsUser().generateRandomAvatar(db.GetEngine(ctx)); err != nil { return fmt.Errorf("generate random avatar: %v", err) } @@ -228,11 +293,11 @@ func CreateOrganization(org, owner *User) (err error) { } // GetOrgByName returns organization by given name. -func GetOrgByName(name string) (*User, error) { +func GetOrgByName(name string) (*Organization, error) { if len(name) == 0 { return nil, ErrOrgNotExist{0, name} } - u := &User{ + u := &Organization{ LowerName: strings.ToLower(name), Type: UserTypeOrganization, } @@ -249,12 +314,16 @@ func GetOrgByName(name string) (*User, error) { func CountOrganizations() int64 { count, _ := db.GetEngine(db.DefaultContext). Where("type=1"). - Count(new(User)) + Count(new(Organization)) return count } // DeleteOrganization deletes models associated to an organization. -func DeleteOrganization(ctx context.Context, org *User) error { +func DeleteOrganization(ctx context.Context, org *Organization) error { + if org.Type != UserTypeOrganization { + return fmt.Errorf("%s is a user not an organization", org.Name) + } + e := db.GetEngine(ctx) if err := deleteBeans(e, @@ -346,7 +415,7 @@ func CanCreateOrgRepo(orgID, uid int64) (bool, error) { } // GetOrgUserMaxAuthorizeLevel returns highest authorize level of user in an organization -func (org *User) GetOrgUserMaxAuthorizeLevel(uid int64) (AccessMode, error) { +func (org *Organization) GetOrgUserMaxAuthorizeLevel(uid int64) (AccessMode, error) { var authorize AccessMode _, err := db.GetEngine(db.DefaultContext). Select("max(team.authorize)"). @@ -372,8 +441,8 @@ func getUsersWhoCanCreateOrgRepo(e db.Engine, orgID int64) ([]*User, error) { And("team_user.org_id = ?", orgID).Asc("`user`.name").Find(&users) } -func getOrgsByUserID(sess *xorm.Session, userID int64, showAll bool) ([]*User, error) { - orgs := make([]*User, 0, 10) +func getOrgsByUserID(sess *xorm.Session, userID int64, showAll bool) ([]*Organization, error) { + orgs := make([]*Organization, 0, 10) if !showAll { sess.And("`org_user`.is_public=?", true) } @@ -386,14 +455,14 @@ func getOrgsByUserID(sess *xorm.Session, userID int64, showAll bool) ([]*User, e // GetOrgsByUserID returns a list of organizations that the given user ID // has joined. -func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) { +func GetOrgsByUserID(userID int64, showAll bool) ([]*Organization, error) { sess := db.NewSession(db.DefaultContext) defer sess.Close() return getOrgsByUserID(sess, userID, showAll) } // MinimalOrg represents a simple orgnization with only needed columns -type MinimalOrg = User +type MinimalOrg = Organization // GetUserOrgsList returns one user's all orgs list func GetUserOrgsList(user *User) ([]*MinimalOrg, error) { @@ -434,8 +503,8 @@ func GetUserOrgsList(user *User) ([]*MinimalOrg, error) { GroupBy(groupByStr) type OrgCount struct { - User `xorm:"extends"` - OrgCount int + Organization `xorm:"extends"` + OrgCount int } orgCounts := make([]*OrgCount, 0, 10) @@ -448,8 +517,8 @@ func GetUserOrgsList(user *User) ([]*MinimalOrg, error) { orgs := make([]*MinimalOrg, len(orgCounts)) for i, orgCount := range orgCounts { - orgCount.User.NumRepos = orgCount.OrgCount - orgs[i] = &orgCount.User + orgCount.Organization.NumRepos = orgCount.OrgCount + orgs[i] = &orgCount.Organization } return orgs, nil @@ -481,20 +550,20 @@ func hasOrgOrUserVisible(e db.Engine, orgOrUser, user *User) bool { return true } - if (orgOrUser.Visibility == structs.VisibleTypePrivate || user.IsRestricted) && !orgOrUser.hasMemberWithUserID(e, user.ID) { + if (orgOrUser.Visibility == structs.VisibleTypePrivate || user.IsRestricted) && !OrgFromUser(orgOrUser).hasMemberWithUserID(e, user.ID) { return false } return true } // HasOrgsVisible tells if the given user can see at least one of the orgs provided -func HasOrgsVisible(orgs []*User, user *User) bool { +func HasOrgsVisible(orgs []*Organization, user *User) bool { if len(orgs) == 0 { return false } for _, org := range orgs { - if HasOrgOrUserVisible(org, user) { + if HasOrgOrUserVisible(org.AsUser(), user) { return true } } @@ -622,9 +691,28 @@ func AddOrgUser(orgID, uid int64) error { return sess.Commit() } -func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { +// GetOrgByIDCtx returns the user object by given ID if exists. +func GetOrgByIDCtx(ctx context.Context, id int64) (*Organization, error) { + u := new(Organization) + has, err := db.GetEngine(ctx).ID(id).Get(u) + if err != nil { + return nil, err + } else if !has { + return nil, ErrUserNotExist{id, "", 0} + } + return u, nil +} + +// GetOrgByID returns the user object by given ID if exists. +func GetOrgByID(id int64) (*Organization, error) { + return GetOrgByIDCtx(db.DefaultContext, id) +} + +func removeOrgUser(ctx context.Context, orgID, userID int64) error { ou := new(OrgUser) + sess := db.GetEngine(ctx) + has, err := sess. Where("uid=?", userID). And("org_id=?", orgID). @@ -635,7 +723,7 @@ func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { return nil } - org, err := getUserByID(sess, orgID) + org, err := GetOrgByIDCtx(ctx, orgID) if err != nil { return fmt.Errorf("GetUserByID [%d]: %v", orgID, err) } @@ -694,7 +782,7 @@ func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { return err } for _, t := range teams { - if err = removeTeamMember(sess, t, userID); err != nil { + if err = removeTeamMember(ctx, t, userID); err != nil { return err } } @@ -704,15 +792,15 @@ func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { // RemoveOrgUser removes user from given organization. func RemoveOrgUser(orgID, userID int64) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } - if err := removeOrgUser(sess, orgID, userID); err != nil { + defer committer.Close() + if err := removeOrgUser(ctx, orgID, userID); err != nil { return err } - return sess.Commit() + return committer.Commit() } func removeOrgRepo(e db.Engine, orgID, repoID int64) error { @@ -741,7 +829,7 @@ func removeOrgRepo(e db.Engine, orgID, repoID int64) error { return err } -func (org *User) getUserTeams(e db.Engine, userID int64, cols ...string) ([]*Team, error) { +func (org *Organization) getUserTeams(e db.Engine, userID int64, cols ...string) ([]*Team, error) { teams := make([]*Team, 0, org.NumTeams) return teams, e. Where("`team_user`.org_id = ?", org.ID). @@ -753,7 +841,7 @@ func (org *User) getUserTeams(e db.Engine, userID int64, cols ...string) ([]*Tea Find(&teams) } -func (org *User) getUserTeamIDs(e db.Engine, userID int64) ([]int64, error) { +func (org *Organization) getUserTeamIDs(e db.Engine, userID int64) ([]int64, error) { teamIDs := make([]int64, 0, org.NumTeams) return teamIDs, e. Table("team"). @@ -765,18 +853,18 @@ func (org *User) getUserTeamIDs(e db.Engine, userID int64) ([]int64, error) { } // TeamsWithAccessToRepo returns all teams that have given access level to the repository. -func (org *User) TeamsWithAccessToRepo(repoID int64, mode AccessMode) ([]*Team, error) { +func (org *Organization) TeamsWithAccessToRepo(repoID int64, mode AccessMode) ([]*Team, error) { return GetTeamsWithAccessToRepo(org.ID, repoID, mode) } // GetUserTeamIDs returns of all team IDs of the organization that user is member of. -func (org *User) GetUserTeamIDs(userID int64) ([]int64, error) { +func (org *Organization) GetUserTeamIDs(userID int64) ([]int64, error) { return org.getUserTeamIDs(db.GetEngine(db.DefaultContext), userID) } // GetUserTeams returns all teams that belong to user, // and that the user has joined. -func (org *User) GetUserTeams(userID int64) ([]*Team, error) { +func (org *Organization) GetUserTeams(userID int64) ([]*Team, error) { return org.getUserTeams(db.GetEngine(db.DefaultContext), userID) } @@ -792,7 +880,7 @@ type AccessibleReposEnvironment interface { } type accessibleReposEnv struct { - org *User + org *Organization user *User team *Team teamIDs []int64 @@ -803,11 +891,11 @@ type accessibleReposEnv struct { // AccessibleReposEnv builds an AccessibleReposEnvironment for the repositories in `org` // that are accessible to the specified user. -func (org *User) AccessibleReposEnv(userID int64) (AccessibleReposEnvironment, error) { +func (org *Organization) AccessibleReposEnv(userID int64) (AccessibleReposEnvironment, error) { return org.accessibleReposEnv(db.GetEngine(db.DefaultContext), userID) } -func (org *User) accessibleReposEnv(e db.Engine, userID int64) (AccessibleReposEnvironment, error) { +func (org *Organization) accessibleReposEnv(e db.Engine, userID int64) (AccessibleReposEnvironment, error) { var user *User if userID > 0 { @@ -833,7 +921,7 @@ func (org *User) accessibleReposEnv(e db.Engine, userID int64) (AccessibleReposE // AccessibleTeamReposEnv an AccessibleReposEnvironment for the repositories in `org` // that are accessible to the specified team. -func (org *User) AccessibleTeamReposEnv(team *Team) AccessibleReposEnvironment { +func (org *Organization) AccessibleTeamReposEnv(team *Team) AccessibleReposEnvironment { return &accessibleReposEnv{ org: org, team: team, diff --git a/models/org_team.go b/models/org_team.go index 10178ec88..e3ad23c11 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -6,6 +6,7 @@ package models import ( + "context" "errors" "fmt" "sort" @@ -17,7 +18,6 @@ import ( "code.gitea.io/gitea/modules/setting" "xorm.io/builder" - "xorm.io/xorm" ) const ownerTeamName = "Owners" @@ -872,7 +872,8 @@ func AddTeamMember(team *Team, userID int64) error { return sess.Commit() } -func removeTeamMember(e *xorm.Session, team *Team, userID int64) error { +func removeTeamMember(ctx context.Context, team *Team, userID int64) error { + e := db.GetEngine(ctx) isMember, err := isTeamMember(e, team.OrgID, team.ID, userID) if err != nil || !isMember { return err @@ -926,7 +927,7 @@ func removeTeamMember(e *xorm.Session, team *Team, userID int64) error { }); err != nil { return err } else if count == 0 { - return removeOrgUser(e, team.OrgID, userID) + return removeOrgUser(ctx, team.OrgID, userID) } return nil @@ -934,15 +935,15 @@ func removeTeamMember(e *xorm.Session, team *Team, userID int64) error { // RemoveTeamMember removes member from given team of given organization. func RemoveTeamMember(team *Team, userID int64) error { - sess := db.NewSession(db.DefaultContext) - defer sess.Close() - if err := sess.Begin(); err != nil { + ctx, committer, err := db.TxContext() + if err != nil { return err } - if err := removeTeamMember(sess, team, userID); err != nil { + defer committer.Close() + if err := removeTeamMember(ctx, team, userID); err != nil { return err } - return sess.Commit() + return committer.Commit() } // IsUserInTeams returns if a user in some teams diff --git a/models/org_test.go b/models/org_test.go index 8580702a0..10ae87745 100644 --- a/models/org_test.go +++ b/models/org_test.go @@ -29,7 +29,7 @@ func TestUser_IsOwnedBy(t *testing.T) { {2, 2, false}, // user2 is not an organization {2, 3, false}, } { - org := unittest.AssertExistsAndLoadBean(t, &User{ID: testCase.OrgID}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: testCase.OrgID}).(*Organization) isOwner, err := org.IsOwnedBy(testCase.UserID) assert.NoError(t, err) assert.Equal(t, testCase.ExpectedOwner, isOwner) @@ -50,7 +50,7 @@ func TestUser_IsOrgMember(t *testing.T) { {2, 2, false}, // user2 is not an organization {2, 3, false}, } { - org := unittest.AssertExistsAndLoadBean(t, &User{ID: testCase.OrgID}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: testCase.OrgID}).(*Organization) isMember, err := org.IsOrgMember(testCase.UserID) assert.NoError(t, err) assert.Equal(t, testCase.ExpectedMember, isMember) @@ -59,7 +59,7 @@ func TestUser_IsOrgMember(t *testing.T) { func TestUser_GetTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) team, err := org.GetTeam("team1") assert.NoError(t, err) assert.Equal(t, org.ID, team.OrgID) @@ -68,56 +68,58 @@ func TestUser_GetTeam(t *testing.T) { _, err = org.GetTeam("does not exist") assert.True(t, IsErrTeamNotExist(err)) - nonOrg := unittest.AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + nonOrg := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 2}).(*Organization) _, err = nonOrg.GetTeam("team") assert.True(t, IsErrTeamNotExist(err)) } func TestUser_GetOwnerTeam(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) team, err := org.GetOwnerTeam() assert.NoError(t, err) assert.Equal(t, org.ID, team.OrgID) - nonOrg := unittest.AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + nonOrg := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 2}).(*Organization) _, err = nonOrg.GetOwnerTeam() assert.True(t, IsErrTeamNotExist(err)) } func TestUser_GetTeams(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) - assert.NoError(t, org.LoadTeams()) - if assert.Len(t, org.Teams, 4) { - assert.Equal(t, int64(1), org.Teams[0].ID) - assert.Equal(t, int64(2), org.Teams[1].ID) - assert.Equal(t, int64(12), org.Teams[2].ID) - assert.Equal(t, int64(7), org.Teams[3].ID) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) + teams, err := org.LoadTeams() + assert.NoError(t, err) + if assert.Len(t, teams, 4) { + assert.Equal(t, int64(1), teams[0].ID) + assert.Equal(t, int64(2), teams[1].ID) + assert.Equal(t, int64(12), teams[2].ID) + assert.Equal(t, int64(7), teams[3].ID) } } func TestUser_GetMembers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) - assert.NoError(t, org.GetMembers()) - if assert.Len(t, org.Members, 3) { - assert.Equal(t, int64(2), org.Members[0].ID) - assert.Equal(t, int64(28), org.Members[1].ID) - assert.Equal(t, int64(4), org.Members[2].ID) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) + members, _, err := org.GetMembers() + assert.NoError(t, err) + if assert.Len(t, members, 3) { + assert.Equal(t, int64(2), members[0].ID) + assert.Equal(t, int64(28), members[1].ID) + assert.Equal(t, int64(4), members[2].ID) } } func TestUser_AddMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) // add a user that is not a member unittest.AssertNotExistsBean(t, &OrgUser{UID: 5, OrgID: 3}) prevNumMembers := org.NumMembers assert.NoError(t, org.AddMember(5)) unittest.AssertExistsAndLoadBean(t, &OrgUser{UID: 5, OrgID: 3}) - org = unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org = unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) assert.Equal(t, prevNumMembers+1, org.NumMembers) // add a user that is already a member @@ -125,7 +127,7 @@ func TestUser_AddMember(t *testing.T) { prevNumMembers = org.NumMembers assert.NoError(t, org.AddMember(4)) unittest.AssertExistsAndLoadBean(t, &OrgUser{UID: 4, OrgID: 3}) - org = unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org = unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) assert.Equal(t, prevNumMembers, org.NumMembers) unittest.CheckConsistencyFor(t, &User{}) @@ -133,14 +135,14 @@ func TestUser_AddMember(t *testing.T) { func TestUser_RemoveMember(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) // remove a user that is a member unittest.AssertExistsAndLoadBean(t, &OrgUser{UID: 4, OrgID: 3}) prevNumMembers := org.NumMembers assert.NoError(t, org.RemoveMember(4)) unittest.AssertNotExistsBean(t, &OrgUser{UID: 4, OrgID: 3}) - org = unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org = unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) assert.Equal(t, prevNumMembers-1, org.NumMembers) // remove a user that is not a member @@ -148,7 +150,7 @@ func TestUser_RemoveMember(t *testing.T) { prevNumMembers = org.NumMembers assert.NoError(t, org.RemoveMember(5)) unittest.AssertNotExistsBean(t, &OrgUser{UID: 5, OrgID: 3}) - org = unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org = unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) assert.Equal(t, prevNumMembers, org.NumMembers) unittest.CheckConsistencyFor(t, &User{}, &Team{}) @@ -156,7 +158,7 @@ func TestUser_RemoveMember(t *testing.T) { func TestUser_RemoveOrgRepo(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) repo := unittest.AssertExistsAndLoadBean(t, &Repository{OwnerID: org.ID}).(*Repository) // remove a repo that does belong to org @@ -183,14 +185,14 @@ func TestCreateOrganization(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) const newOrgName = "neworg" - org := &User{ + org := &Organization{ Name: newOrgName, } unittest.AssertNotExistsBean(t, &User{Name: newOrgName, Type: UserTypeOrganization}) assert.NoError(t, CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &User{Name: newOrgName, Type: UserTypeOrganization}).(*User) + &Organization{Name: newOrgName, Type: UserTypeOrganization}).(*Organization) ownerTeam := unittest.AssertExistsAndLoadBean(t, &Team{Name: ownerTeamName, OrgID: org.ID}).(*Team) unittest.AssertExistsAndLoadBean(t, &TeamUser{UID: owner.ID, TeamID: ownerTeam.ID}) @@ -203,16 +205,16 @@ func TestCreateOrganization2(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &User{ID: 5}).(*User) const newOrgName = "neworg" - org := &User{ + org := &Organization{ Name: newOrgName, } - unittest.AssertNotExistsBean(t, &User{Name: newOrgName, Type: UserTypeOrganization}) + unittest.AssertNotExistsBean(t, &Organization{Name: newOrgName, Type: UserTypeOrganization}) err := CreateOrganization(org, owner) assert.Error(t, err) assert.True(t, IsErrUserNotAllowedCreateOrg(err)) - unittest.AssertNotExistsBean(t, &User{Name: newOrgName, Type: UserTypeOrganization}) - unittest.CheckConsistencyFor(t, &User{}, &Team{}) + unittest.AssertNotExistsBean(t, &Organization{Name: newOrgName, Type: UserTypeOrganization}) + unittest.CheckConsistencyFor(t, &Organization{}, &Team{}) } func TestCreateOrganization3(t *testing.T) { @@ -220,7 +222,7 @@ func TestCreateOrganization3(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) owner := unittest.AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) - org := &User{Name: "user3"} // should already exist + org := &Organization{Name: "user3"} // should already exist unittest.AssertExistsAndLoadBean(t, &User{Name: org.Name}) // sanity check err := CreateOrganization(org, owner) assert.Error(t, err) @@ -233,10 +235,10 @@ func TestCreateOrganization4(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) owner := unittest.AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) - err := CreateOrganization(&User{Name: "assets"}, owner) + err := CreateOrganization(&Organization{Name: "assets"}, owner) assert.Error(t, err) assert.True(t, IsErrNameReserved(err)) - unittest.CheckConsistencyFor(t, &User{}, &Team{}) + unittest.CheckConsistencyFor(t, &Organization{}, &Team{}) } func TestGetOrgByName(t *testing.T) { @@ -478,7 +480,7 @@ func TestRemoveOrgUser(t *testing.T) { func TestUser_GetUserTeamIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) testSuccess := func(userID int64, expected []int64) { teamIDs, err := org.GetUserTeamIDs(userID) assert.NoError(t, err) @@ -491,7 +493,7 @@ func TestUser_GetUserTeamIDs(t *testing.T) { func TestAccessibleReposEnv_CountRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) testSuccess := func(userID, expectedCount int64) { env, err := org.AccessibleReposEnv(userID) assert.NoError(t, err) @@ -505,7 +507,7 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) { func TestAccessibleReposEnv_RepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) testSuccess := func(userID, _, pageSize int64, expectedRepoIDs []int64) { env, err := org.AccessibleReposEnv(userID) assert.NoError(t, err) @@ -519,7 +521,7 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) { func TestAccessibleReposEnv_Repos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) testSuccess := func(userID int64, expectedRepoIDs []int64) { env, err := org.AccessibleReposEnv(userID) assert.NoError(t, err) @@ -538,7 +540,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) { func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + org := unittest.AssertExistsAndLoadBean(t, &Organization{ID: 3}).(*Organization) testSuccess := func(userID int64, expectedRepoIDs []int64) { env, err := org.AccessibleReposEnv(userID) assert.NoError(t, err) @@ -561,7 +563,7 @@ func TestHasOrgVisibleTypePublic(t *testing.T) { user3 := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) const newOrgName = "test-org-public" - org := &User{ + org := &Organization{ Name: newOrgName, Visibility: structs.VisibleTypePublic, } @@ -569,10 +571,10 @@ func TestHasOrgVisibleTypePublic(t *testing.T) { unittest.AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization}) assert.NoError(t, CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &User{Name: org.Name, Type: UserTypeOrganization}).(*User) - test1 := HasOrgOrUserVisible(org, owner) - test2 := HasOrgOrUserVisible(org, user3) - test3 := HasOrgOrUserVisible(org, nil) + &Organization{Name: org.Name, Type: UserTypeOrganization}).(*Organization) + test1 := HasOrgOrUserVisible(org.AsUser(), owner) + test2 := HasOrgOrUserVisible(org.AsUser(), user3) + test3 := HasOrgOrUserVisible(org.AsUser(), nil) assert.True(t, test1) // owner of org assert.True(t, test2) // user not a part of org assert.True(t, test3) // logged out user @@ -584,7 +586,7 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) { user3 := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) const newOrgName = "test-org-limited" - org := &User{ + org := &Organization{ Name: newOrgName, Visibility: structs.VisibleTypeLimited, } @@ -592,10 +594,10 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) { unittest.AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization}) assert.NoError(t, CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &User{Name: org.Name, Type: UserTypeOrganization}).(*User) - test1 := HasOrgOrUserVisible(org, owner) - test2 := HasOrgOrUserVisible(org, user3) - test3 := HasOrgOrUserVisible(org, nil) + &Organization{Name: org.Name, Type: UserTypeOrganization}).(*Organization) + test1 := HasOrgOrUserVisible(org.AsUser(), owner) + test2 := HasOrgOrUserVisible(org.AsUser(), user3) + test3 := HasOrgOrUserVisible(org.AsUser(), nil) assert.True(t, test1) // owner of org assert.True(t, test2) // user not a part of org assert.False(t, test3) // logged out user @@ -607,7 +609,7 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) { user3 := unittest.AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) const newOrgName = "test-org-private" - org := &User{ + org := &Organization{ Name: newOrgName, Visibility: structs.VisibleTypePrivate, } @@ -615,10 +617,10 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) { unittest.AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization}) assert.NoError(t, CreateOrganization(org, owner)) org = unittest.AssertExistsAndLoadBean(t, - &User{Name: org.Name, Type: UserTypeOrganization}).(*User) - test1 := HasOrgOrUserVisible(org, owner) - test2 := HasOrgOrUserVisible(org, user3) - test3 := HasOrgOrUserVisible(org, nil) + &Organization{Name: org.Name, Type: UserTypeOrganization}).(*Organization) + test1 := HasOrgOrUserVisible(org.AsUser(), owner) + test2 := HasOrgOrUserVisible(org.AsUser(), user3) + test3 := HasOrgOrUserVisible(org.AsUser(), nil) assert.True(t, test1) // owner of org assert.False(t, test2) // user not a part of org assert.False(t, test3) // logged out user diff --git a/models/repo.go b/models/repo.go index d62b3ec2b..387750292 100644 --- a/models/repo.go +++ b/models/repo.go @@ -783,7 +783,7 @@ func (repo *Repository) CanUserDelete(user *User) (bool, error) { } if repo.Owner.IsOrganization() { - isOwner, err := repo.Owner.IsOwnedBy(user.ID) + isOwner, err := OrgFromUser(repo.Owner).IsOwnedBy(user.ID) if err != nil { return false, err } else if isOwner { @@ -1118,10 +1118,11 @@ func CreateRepository(ctx context.Context, doer, u *User, repo *Repository, over // Give access to all members in teams with access to all repositories. if u.IsOrganization() { - if err := u.loadTeams(db.GetEngine(ctx)); err != nil { + teams, err := OrgFromUser(u).loadTeams(db.GetEngine(ctx)) + if err != nil { return fmt.Errorf("loadTeams: %v", err) } - for _, t := range u.Teams { + for _, t := range teams { if t.IncludesAllRepositories { if err := t.addRepository(db.GetEngine(ctx), repo); err != nil { return fmt.Errorf("addRepository: %v", err) @@ -1444,11 +1445,6 @@ func DeleteRepository(doer *User, uid, repoID int64) error { if err != nil { return err } - if org.IsOrganization() { - if err = org.loadTeams(sess); err != nil { - return err - } - } repo := &Repository{OwnerID: uid} has, err := sess.ID(repoID).Get(repo) @@ -1476,7 +1472,11 @@ func DeleteRepository(doer *User, uid, repoID int64) error { } if org.IsOrganization() { - for _, t := range org.Teams { + teams, err := OrgFromUser(org).loadTeams(sess) + if err != nil { + return err + } + for _, t := range teams { if !t.hasRepository(sess, repoID) { continue } else if err = t.removeRepository(sess, repo, false); err != nil { @@ -1790,8 +1790,8 @@ func GetUserMirrorRepositories(userID int64) ([]*Repository, error) { Find(&repos) } -func getRepositoryCount(e db.Engine, u *User) (int64, error) { - return e.Count(&Repository{OwnerID: u.ID}) +func getRepositoryCount(e db.Engine, ownerID int64) (int64, error) { + return e.Count(&Repository{OwnerID: ownerID}) } func getPublicRepositoryCount(e db.Engine, u *User) (int64, error) { @@ -1803,8 +1803,8 @@ func getPrivateRepositoryCount(e db.Engine, u *User) (int64, error) { } // GetRepositoryCount returns the total number of repositories of user. -func GetRepositoryCount(ctx context.Context, u *User) (int64, error) { - return getRepositoryCount(db.GetEngine(ctx), u) +func GetRepositoryCount(ctx context.Context, ownerID int64) (int64, error) { + return getRepositoryCount(db.GetEngine(ctx), ownerID) } // GetPublicRepositoryCount returns the total number of public repositories of user. diff --git a/models/repo_test.go b/models/repo_test.go index e6f4ea1c3..ec1bcc048 100644 --- a/models/repo_test.go +++ b/models/repo_test.go @@ -71,7 +71,7 @@ func TestMetas(t *testing.T) { func TestGetRepositoryCount(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - count, err1 := GetRepositoryCount(db.DefaultContext, &User{ID: int64(10)}) + count, err1 := GetRepositoryCount(db.DefaultContext, 10) privateCount, err2 := GetPrivateRepositoryCount(&User{ID: int64(10)}) publicCount, err3 := GetPublicRepositoryCount(&User{ID: int64(10)}) assert.NoError(t, err1) diff --git a/models/repo_transfer.go b/models/repo_transfer.go index 082c3d19d..7b766ff4c 100644 --- a/models/repo_transfer.go +++ b/models/repo_transfer.go @@ -299,16 +299,17 @@ func TransferOwnership(doer *User, newOwnerName string, repo *Repository) (err e // Remove old team-repository relations. if oldOwner.IsOrganization() { - if err := oldOwner.removeOrgRepo(sess, repo.ID); err != nil { + if err := OrgFromUser(oldOwner).removeOrgRepo(sess, repo.ID); err != nil { return fmt.Errorf("removeOrgRepo: %v", err) } } if newOwner.IsOrganization() { - if err := newOwner.loadTeams(sess); err != nil { + teams, err := OrgFromUser(newOwner).loadTeams(sess) + if err != nil { return fmt.Errorf("LoadTeams: %v", err) } - for _, t := range newOwner.Teams { + for _, t := range teams { if t.IncludesAllRepositories { if err := t.addRepository(sess, repo); err != nil { return fmt.Errorf("addRepository: %v", err) diff --git a/models/user.go b/models/user.go index 1bdb43579..db2345cb3 100644 --- a/models/user.go +++ b/models/user.go @@ -161,9 +161,6 @@ type User struct { // For organization NumTeams int NumMembers int - Teams []*Team `xorm:"-"` - Members UserList `xorm:"-"` - MembersIsPublic map[int64]bool `xorm:"-"` Visibility structs.VisibleType `xorm:"NOT NULL DEFAULT 0"` RepoAdminChangeTeamAccess bool `xorm:"NOT NULL DEFAULT false"` @@ -516,20 +513,6 @@ func (u *User) IsUserOrgOwner(orgID int64) bool { return isOwner } -// HasMemberWithUserID returns true if user with userID is part of the u organisation. -func (u *User) HasMemberWithUserID(userID int64) bool { - return u.hasMemberWithUserID(db.GetEngine(db.DefaultContext), userID) -} - -func (u *User) hasMemberWithUserID(e db.Engine, userID int64) bool { - isMember, err := isOrganizationMember(e, u.ID, userID) - if err != nil { - log.Error("IsOrganizationMember: %v", err) - return false - } - return isMember -} - // IsPublicMember returns true if user public his/her membership in given organization. func (u *User) IsPublicMember(orgID int64) bool { isMember, err := IsPublicMembership(orgID, u.ID) diff --git a/models/userlist_test.go b/models/userlist_test.go index 2b8518c92..c16a7b6ee 100644 --- a/models/userlist_test.go +++ b/models/userlist_test.go @@ -33,10 +33,11 @@ func TestUserListIsPublicMember(t *testing.T) { } func testUserListIsPublicMember(t *testing.T, orgID int64, expected map[int64]bool) { - org, err := GetUserByID(orgID) + org, err := GetOrgByID(orgID) assert.NoError(t, err) - assert.NoError(t, org.GetMembers()) - assert.Equal(t, expected, org.MembersIsPublic) + _, membersIsPublic, err := org.GetMembers() + assert.NoError(t, err) + assert.Equal(t, expected, membersIsPublic) } func TestUserListIsUserOrgOwner(t *testing.T) { @@ -59,10 +60,11 @@ func TestUserListIsUserOrgOwner(t *testing.T) { } func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bool) { - org, err := GetUserByID(orgID) + org, err := GetOrgByID(orgID) + assert.NoError(t, err) + members, _, err := org.GetMembers() assert.NoError(t, err) - assert.NoError(t, org.GetMembers()) - assert.Equal(t, expected, org.Members.IsUserOrgOwner(orgID)) + assert.Equal(t, expected, members.IsUserOrgOwner(orgID)) } func TestUserListIsTwoFaEnrolled(t *testing.T) { @@ -85,8 +87,9 @@ func TestUserListIsTwoFaEnrolled(t *testing.T) { } func testUserListIsTwoFaEnrolled(t *testing.T, orgID int64, expected map[int64]bool) { - org, err := GetUserByID(orgID) + org, err := GetOrgByID(orgID) + assert.NoError(t, err) + members, _, err := org.GetMembers() assert.NoError(t, err) - assert.NoError(t, org.GetMembers()) - assert.Equal(t, expected, org.Members.GetTwoFaStatus()) + assert.Equal(t, expected, members.GetTwoFaStatus()) } diff --git a/modules/context/api_org.go b/modules/context/api_org.go index 3a2c8c559..6d86fa6ed 100644 --- a/modules/context/api_org.go +++ b/modules/context/api_org.go @@ -10,6 +10,6 @@ import ( // APIOrganization contains organization and team type APIOrganization struct { - Organization *models.User + Organization *models.Organization Team *models.Team } diff --git a/modules/context/org.go b/modules/context/org.go index d7257361f..54cc3a9d8 100644 --- a/modules/context/org.go +++ b/modules/context/org.go @@ -18,11 +18,12 @@ type Organization struct { IsMember bool IsTeamMember bool // Is member of team. IsTeamAdmin bool // In owner team or team that has admin permission level. - Organization *models.User + Organization *models.Organization OrgLink string CanCreateOrgRepo bool - Team *models.Team + Team *models.Team + Teams []*models.Team } // HandleOrgAssignment handles organization assignment @@ -49,7 +50,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { orgName := ctx.Params(":org") var err error - ctx.Org.Organization, err = models.GetUserByName(orgName) + ctx.Org.Organization, err = models.GetOrgByName(orgName) if err != nil { if models.IsErrUserNotExist(err) { redirectUserID, err := user_model.LookupUserRedirect(orgName) @@ -68,12 +69,6 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { org := ctx.Org.Organization ctx.Data["Org"] = org - // Force redirection when username is actually a user. - if !org.IsOrganization() { - ctx.Redirect(org.HomeLink()) - return - } - // Admin has super access. if ctx.IsSigned && ctx.User.IsAdmin { ctx.Org.IsOwner = true @@ -118,18 +113,19 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember ctx.Data["CanCreateOrgRepo"] = ctx.Org.CanCreateOrgRepo - ctx.Org.OrgLink = org.OrganisationLink() + ctx.Org.OrgLink = org.AsUser().OrganisationLink() ctx.Data["OrgLink"] = ctx.Org.OrgLink // Team. if ctx.Org.IsMember { if ctx.Org.IsOwner { - if err := org.LoadTeams(); err != nil { + ctx.Org.Teams, err = org.LoadTeams() + if err != nil { ctx.ServerError("LoadTeams", err) return } } else { - org.Teams, err = org.GetUserTeams(ctx.User.ID) + ctx.Org.Teams, err = org.GetUserTeams(ctx.User.ID) if err != nil { ctx.ServerError("GetUserTeams", err) return @@ -140,7 +136,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { teamName := ctx.Params(":team") if len(teamName) > 0 { teamExists := false - for _, team := range org.Teams { + for _, team := range ctx.Org.Teams { if team.LowerName == strings.ToLower(teamName) { teamExists = true ctx.Org.Team = team diff --git a/modules/convert/convert.go b/modules/convert/convert.go index 80d5ffff0..4229e6cc7 100644 --- a/modules/convert/convert.go +++ b/modules/convert/convert.go @@ -277,10 +277,10 @@ func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey { } // ToOrganization convert models.User to api.Organization -func ToOrganization(org *models.User) *api.Organization { +func ToOrganization(org *models.Organization) *api.Organization { return &api.Organization{ ID: org.ID, - AvatarURL: org.AvatarLink(), + AvatarURL: org.AsUser().AvatarLink(), UserName: org.Name, FullName: org.FullName, Description: org.Description, diff --git a/modules/repository/create_test.go b/modules/repository/create_test.go index 55fc51558..12fc7afee 100644 --- a/modules/repository/create_test.go +++ b/modules/repository/create_test.go @@ -36,7 +36,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { assert.NoError(t, err, "GetUserByID") // Create org. - org := &models.User{ + org := &models.Organization{ Name: "All_repo", IsActive: true, Type: models.UserTypeOrganization, @@ -52,7 +52,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { // Create repos. repoIds := make([]int64, 0) for i := 0; i < 3; i++ { - r, err := CreateRepository(user, org, models.CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) + r, err := CreateRepository(user, org.AsUser(), models.CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) assert.NoError(t, err, "CreateRepository %d", i) if r != nil { repoIds = append(repoIds, r.ID) @@ -114,8 +114,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { } // Create repo and check teams repositories. - org.Teams = nil // Reset teams to allow their reloading. - r, err := CreateRepository(user, org, models.CreateRepoOptions{Name: "repo-last"}) + r, err := CreateRepository(user, org.AsUser(), models.CreateRepoOptions{Name: "repo-last"}) assert.NoError(t, err, "CreateRepository last") if r != nil { repoIds = append(repoIds, r.ID) diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 871ba617a..5eec5a731 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -50,7 +50,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *models.User, repo *models. repoPath := models.RepoPath(u.Name, opts.RepoName) if u.IsOrganization() { - t, err := u.GetOwnerTeam() + t, err := models.OrgFromUser(u).GetOwnerTeam() if err != nil { return nil, err } diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go index 5da87fa7d..2633865d2 100644 --- a/routers/api/v1/admin/org.go +++ b/routers/api/v1/admin/org.go @@ -54,7 +54,7 @@ func CreateOrg(ctx *context.APIContext) { visibility = api.VisibilityModes[form.Visibility] } - org := &models.User{ + org := &models.Organization{ Name: form.UserName, FullName: form.FullName, Description: form.Description, @@ -117,7 +117,7 @@ func GetAllOrgs(ctx *context.APIContext) { } orgs := make([]*api.Organization, len(users)) for i := range users { - orgs[i] = convert.ToOrganization(users[i]) + orgs[i] = convert.ToOrganization(models.OrgFromUser(users[i])) } ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go index 6c8161617..b9d1fa2f6 100644 --- a/routers/api/v1/org/hook.go +++ b/routers/api/v1/org/hook.go @@ -59,7 +59,7 @@ func ListHooks(ctx *context.APIContext) { hooks := make([]*api.Hook, len(orgHooks)) for i, hook := range orgHooks { - hooks[i] = convert.ToHook(ctx.Org.Organization.HomeLink(), hook) + hooks[i] = convert.ToHook(ctx.Org.Organization.AsUser().HomeLink(), hook) } ctx.SetTotalCountHeader(count) @@ -95,7 +95,7 @@ func GetHook(ctx *context.APIContext) { if err != nil { return } - ctx.JSON(http.StatusOK, convert.ToHook(org.HomeLink(), hook)) + ctx.JSON(http.StatusOK, convert.ToHook(org.AsUser().HomeLink(), hook)) } // CreateHook create a hook for an organization diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index b37528418..7d4c12d36 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -56,7 +56,7 @@ func ListLabels(ctx *context.APIContext) { } ctx.SetTotalCountHeader(count) - ctx.JSON(http.StatusOK, convert.ToLabelList(labels, nil, ctx.Org.Organization)) + ctx.JSON(http.StatusOK, convert.ToLabelList(labels, nil, ctx.Org.Organization.AsUser())) } // CreateLabel create a label for a repository @@ -104,7 +104,7 @@ func CreateLabel(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, convert.ToLabel(label, nil, ctx.Org.Organization)) + ctx.JSON(http.StatusCreated, convert.ToLabel(label, nil, ctx.Org.Organization.AsUser())) } // GetLabel get label by organization and label id @@ -149,7 +149,7 @@ func GetLabel(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, ctx.Org.Organization)) + ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, ctx.Org.Organization.AsUser())) } // EditLabel modify a label for an Organization @@ -214,7 +214,7 @@ func EditLabel(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, ctx.Org.Organization)) + ctx.JSON(http.StatusOK, convert.ToLabel(label, nil, ctx.Org.Organization.AsUser())) } // DeleteLabel delete a label for an organization diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index e82e8552e..bbf127f89 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -31,7 +31,7 @@ func listUserOrgs(ctx *context.APIContext, u *models.User) { } maxResults := len(orgs) - orgs, _ = util.PaginateSlice(orgs, listOptions.Page, listOptions.PageSize).([]*models.User) + orgs, _ = util.PaginateSlice(orgs, listOptions.Page, listOptions.PageSize).([]*models.Organization) apiOrgs := make([]*api.Organization, len(orgs)) for i := range orgs { @@ -141,7 +141,8 @@ func GetUserOrgsPermissions(ctx *context.APIContext) { return } - authorizeLevel, err := o.GetOrgUserMaxAuthorizeLevel(u.ID) + org := models.OrgFromUser(o) + authorizeLevel, err := org.GetOrgUserMaxAuthorizeLevel(u.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetOrgUserAuthorizeLevel", err) return @@ -160,7 +161,7 @@ func GetUserOrgsPermissions(ctx *context.APIContext) { op.IsOwner = true } - op.CanCreateRepository, err = o.CanCreateOrgRepo(u.ID) + op.CanCreateRepository, err = org.CanCreateOrgRepo(u.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "CanCreateOrgRepo", err) return @@ -212,7 +213,7 @@ func GetAll(ctx *context.APIContext) { } orgs := make([]*api.Organization, len(publicOrgs)) for i := range publicOrgs { - orgs[i] = convert.ToOrganization(publicOrgs[i]) + orgs[i] = convert.ToOrganization(models.OrgFromUser(publicOrgs[i])) } ctx.SetLinkHeader(int(maxResults), listOptions.PageSize) @@ -252,7 +253,7 @@ func Create(ctx *context.APIContext) { visibility = api.VisibilityModes[form.Visibility] } - org := &models.User{ + org := &models.Organization{ Name: form.UserName, FullName: form.FullName, Description: form.Description, @@ -295,7 +296,7 @@ func Get(ctx *context.APIContext) { // "200": // "$ref": "#/responses/Organization" - if !models.HasOrgOrUserVisible(ctx.Org.Organization, ctx.User) { + if !models.HasOrgOrUserVisible(ctx.Org.Organization.AsUser(), ctx.User) { ctx.NotFound("HasOrgOrUserVisible", nil) return } @@ -337,7 +338,7 @@ func Edit(ctx *context.APIContext) { if form.RepoAdminChangeTeamAccess != nil { org.RepoAdminChangeTeamAccess = *form.RepoAdminChangeTeamAccess } - if err := models.UpdateUserCols(org, + if err := models.UpdateUserCols(org.AsUser(), "full_name", "description", "website", "location", "visibility", "repo_admin_change_team_access", ); err != nil { diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index 0dc1b68ae..e78e48789 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -102,7 +102,7 @@ func ListUserTeams(ctx *context.APIContext) { for i := range teams { apiOrg, ok := cache[teams[i].OrgID] if !ok { - org, err := models.GetUserByID(teams[i].OrgID) + org, err := models.GetOrgByID(teams[i].OrgID) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUserByID", err) return diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index b3504faad..45d3c815a 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -120,7 +120,7 @@ func CreateFork(ctx *context.APIContext) { ctx.Error(http.StatusForbidden, "isMemberNot", fmt.Sprintf("User is no Member of Organisation '%s'", org.Name)) return } - forker = org + forker = org.AsUser() } fork, err := repo_service.ForkRepository(ctx.User, forker, models.ForkRepoOptions{ diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index 00390dfb5..1880a8836 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -86,7 +86,7 @@ func Migrate(ctx *context.APIContext) { if repoOwner.IsOrganization() { // Check ownership of organization. - isOwner, err := repoOwner.IsOwnedBy(ctx.User.ID) + isOwner, err := models.OrgFromUser(repoOwner).IsOwnedBy(ctx.User.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "IsOwnedBy", err) return diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 22f9da614..872ce2287 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -393,7 +393,7 @@ func Generate(ctx *context.APIContext) { } if !ctx.User.IsAdmin { - canCreate, err := ctxUser.CanCreateOrgRepo(ctx.User.ID) + canCreate, err := models.OrgFromUser(ctxUser).CanCreateOrgRepo(ctx.User.ID) if err != nil { ctx.ServerError("CanCreateOrgRepo", err) return @@ -489,7 +489,7 @@ func CreateOrgRepo(ctx *context.APIContext) { return } - if !models.HasOrgOrUserVisible(org, ctx.User) { + if !models.HasOrgOrUserVisible(org.AsUser(), ctx.User) { ctx.NotFound("HasOrgOrUserVisible", nil) return } @@ -504,7 +504,7 @@ func CreateOrgRepo(ctx *context.APIContext) { return } } - CreateUserRepo(ctx, org, *opt) + CreateUserRepo(ctx, org.AsUser(), *opt) } // Get one repository diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index c13a2e485..f16e2bb08 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -64,7 +64,7 @@ func Transfer(ctx *context.APIContext) { } if newOwner.Type == models.UserTypeOrganization { - if !ctx.User.IsAdmin && newOwner.Visibility == api.VisibleTypePrivate && !newOwner.HasMemberWithUserID(ctx.User.ID) { + if !ctx.User.IsAdmin && newOwner.Visibility == api.VisibleTypePrivate && !models.OrgFromUser(newOwner).HasMemberWithUserID(ctx.User.ID) { // The user shouldn't know about this organization ctx.Error(http.StatusNotFound, "", "The new owner does not exist or cannot be found") return @@ -78,7 +78,7 @@ func Transfer(ctx *context.APIContext) { return } - org := convert.ToOrganization(newOwner) + org := convert.ToOrganization(models.OrgFromUser(newOwner)) for _, tID := range *opts.TeamIDs { team, err := models.GetTeamByID(tID) if err != nil { diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index 5116c17ab..3c9a17a0b 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -157,5 +157,5 @@ func ListOrgRepos(ctx *context.APIContext) { // "200": // "$ref": "#/responses/RepositoryList" - listUserRepos(ctx, ctx.Org.Organization, ctx.IsSigned) + listUserRepos(ctx, ctx.Org.Organization.AsUser(), ctx.IsSigned) } diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index aef9b8f4c..1f0a35ce2 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -75,7 +75,7 @@ func AddOrgHook(ctx *context.APIContext, form *api.CreateHookOption) { org := ctx.Org.Organization hook, ok := addHook(ctx, form, org.ID, 0) if ok { - ctx.JSON(http.StatusCreated, convert.ToHook(org.HomeLink(), hook)) + ctx.JSON(http.StatusCreated, convert.ToHook(org.AsUser().HomeLink(), hook)) } } @@ -185,7 +185,7 @@ func EditOrgHook(ctx *context.APIContext, form *api.EditHookOption, hookID int64 if err != nil { return } - ctx.JSON(http.StatusOK, convert.ToHook(org.HomeLink(), updated)) + ctx.JSON(http.StatusOK, convert.ToHook(org.AsUser().HomeLink(), updated)) } // EditRepoHook edit webhook `w` according to `form`. Writes to `ctx` accordingly diff --git a/routers/web/org/home.go b/routers/web/org/home.go index 89bd12a18..0752fa12c 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -30,7 +30,7 @@ func Home(ctx *context.Context) { org := ctx.Org.Organization - if !models.HasOrgOrUserVisible(org, ctx.User) { + if !models.HasOrgOrUserVisible(org.AsUser(), ctx.User) { ctx.NotFound("HasOrgOrUserVisible", nil) return } @@ -140,7 +140,7 @@ func Home(ctx *context.Context) { ctx.Data["Total"] = count ctx.Data["MembersTotal"] = membersCount ctx.Data["Members"] = members - ctx.Data["Teams"] = org.Teams + ctx.Data["Teams"] = ctx.Org.Teams ctx.Data["DisableNewPullMirrors"] = setting.Mirror.DisableNewPull diff --git a/routers/web/org/org.go b/routers/web/org/org.go index beba3daca..6722f8d10 100644 --- a/routers/web/org/org.go +++ b/routers/web/org/org.go @@ -49,7 +49,7 @@ func CreatePost(ctx *context.Context) { return } - org := &models.User{ + org := &models.Organization{ Name: form.OrgName, IsActive: true, Type: models.UserTypeOrganization, @@ -75,5 +75,5 @@ func CreatePost(ctx *context.Context) { } log.Trace("Organization created: %s", org.Name) - ctx.Redirect(org.DashboardLink()) + ctx.Redirect(org.AsUser().DashboardLink()) } diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go index f27cb4083..f05dbd8bc 100644 --- a/routers/web/org/setting.go +++ b/routers/web/org/setting.go @@ -68,7 +68,7 @@ func SettingsPost(ctx *context.Context) { ctx.Data["OrgName"] = true ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), tplSettingsOptions, &form) return - } else if err = models.ChangeUserName(org, form.Name); err != nil { + } else if err = models.ChangeUserName(org.AsUser(), form.Name); err != nil { if err == models.ErrUserNameIllegal { ctx.Data["OrgName"] = true ctx.RenderWithErr(ctx.Tr("form.illegal_username"), tplSettingsOptions, &form) @@ -100,18 +100,20 @@ func SettingsPost(ctx *context.Context) { visibilityChanged := form.Visibility != org.Visibility org.Visibility = form.Visibility - if err := models.UpdateUser(org); err != nil { + if err := models.UpdateUser(org.AsUser()); err != nil { ctx.ServerError("UpdateUser", err) return } // update forks visibility if visibilityChanged { - if err := org.GetRepositories(db.ListOptions{Page: 1, PageSize: org.NumRepos}); err != nil { + repos, _, err := models.GetUserRepositories(&models.SearchRepoOptions{ + Actor: org.AsUser(), Private: true, ListOptions: db.ListOptions{Page: 1, PageSize: org.NumRepos}}) + if err != nil { ctx.ServerError("GetRepositories", err) return } - for _, repo := range org.Repos { + for _, repo := range repos { repo.OwnerName = org.Name if err := models.UpdateRepository(repo, true); err != nil { ctx.ServerError("UpdateRepository", err) @@ -134,7 +136,7 @@ func SettingsPost(ctx *context.Context) { func SettingsAvatar(ctx *context.Context) { form := web.GetForm(ctx).(*forms.AvatarForm) form.Source = forms.AvatarLocal - if err := userSetting.UpdateAvatarSetting(ctx, form, ctx.Org.Organization); err != nil { + if err := userSetting.UpdateAvatarSetting(ctx, form, ctx.Org.Organization.AsUser()); err != nil { ctx.Flash.Error(err.Error()) } else { ctx.Flash.Success(ctx.Tr("org.settings.update_avatar_success")) @@ -145,7 +147,7 @@ func SettingsAvatar(ctx *context.Context) { // SettingsDeleteAvatar response for delete avatar on settings page func SettingsDeleteAvatar(ctx *context.Context) { - if err := ctx.Org.Organization.DeleteAvatar(); err != nil { + if err := ctx.Org.Organization.AsUser().DeleteAvatar(); err != nil { ctx.Flash.Error(err.Error()) } diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 28ffac4dd..ac6a42904 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -38,13 +38,13 @@ func Teams(ctx *context.Context) { ctx.Data["Title"] = org.FullName ctx.Data["PageIsOrgTeams"] = true - for _, t := range org.Teams { + for _, t := range ctx.Org.Teams { if err := t.GetMembers(&models.SearchMembersOptions{}); err != nil { ctx.ServerError("GetMembers", err) return } } - ctx.Data["Teams"] = org.Teams + ctx.Data["Teams"] = ctx.Org.Teams ctx.HTML(http.StatusOK, tplTeams) } @@ -158,7 +158,7 @@ func TeamsAction(ctx *context.Context) { case "team": ctx.Redirect(ctx.Org.OrgLink + "/teams/" + url.PathEscape(ctx.Org.Team.LowerName)) case "home": - ctx.Redirect(ctx.Org.Organization.HomeLink()) + ctx.Redirect(ctx.Org.Organization.AsUser().HomeLink()) default: ctx.Redirect(ctx.Org.OrgLink + "/teams") } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 95363258e..129287b96 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -2644,13 +2644,15 @@ func handleTeamMentions(ctx *context.Context) { return } - isAdmin := false + var isAdmin bool var err error + var teams []*models.Team + var org = models.OrgFromUser(ctx.Repo.Owner) // Admin has super access. if ctx.User.IsAdmin { isAdmin = true } else { - isAdmin, err = ctx.Repo.Owner.IsOwnedBy(ctx.User.ID) + isAdmin, err = org.IsOwnedBy(ctx.User.ID) if err != nil { ctx.ServerError("IsOwnedBy", err) return @@ -2658,19 +2660,20 @@ func handleTeamMentions(ctx *context.Context) { } if isAdmin { - if err := ctx.Repo.Owner.LoadTeams(); err != nil { + teams, err = org.LoadTeams() + if err != nil { ctx.ServerError("LoadTeams", err) return } } else { - ctx.Repo.Owner.Teams, err = ctx.Repo.Owner.GetUserTeams(ctx.User.ID) + teams, err = org.GetUserTeams(ctx.User.ID) if err != nil { ctx.ServerError("GetUserTeams", err) return } } - ctx.Data["MentionableTeams"] = ctx.Repo.Owner.Teams + ctx.Data["MentionableTeams"] = teams ctx.Data["MentionableTeamsOrg"] = ctx.Repo.Owner.Name ctx.Data["MentionableTeamsOrgAvatar"] = ctx.Repo.Owner.AvatarLink() } diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index b97f57175..c6fa8c4c8 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -88,7 +88,7 @@ func RetrieveLabels(ctx *context.Context) { ctx.ServerError("org.IsOwnedBy", err) return } - ctx.Org.OrgLink = org.OrganisationLink() + ctx.Org.OrgLink = org.AsUser().OrganisationLink() ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner ctx.Data["OrganizationLink"] = ctx.Org.OrgLink } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 433727821..d5aa480d1 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -217,7 +217,7 @@ func ForkPost(ctx *context.Context) { // Check ownership of organization. if ctxUser.IsOrganization() { - isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID) + isOwner, err := models.OrgFromUser(ctxUser).IsOwnedBy(ctx.User.ID) if err != nil { ctx.ServerError("IsOwnedBy", err) return diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 5e15415d6..2d6189824 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -94,7 +94,7 @@ func checkContextUser(ctx *context.Context, uid int64) *models.User { return nil } if !ctx.User.IsAdmin { - canCreate, err := org.CanCreateOrgRepo(ctx.User.ID) + canCreate, err := models.OrgFromUser(org).CanCreateOrgRepo(ctx.User.ID) if err != nil { ctx.ServerError("CanCreateOrgRepo", err) return nil diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index 641052316..9b5f63598 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -588,7 +588,7 @@ func SettingsPost(ctx *context.Context) { } if newOwner.Type == models.UserTypeOrganization { - if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !newOwner.HasMemberWithUserID(ctx.User.ID) { + if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !models.OrgFromUser(newOwner).HasMemberWithUserID(ctx.User.ID) { // The user shouldn't know about this organization ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), tplSettingsOptions, nil) return @@ -879,7 +879,7 @@ func AddTeamPost(ctx *context.Context) { return } - team, err := ctx.Repo.Owner.GetTeam(name) + team, err := models.OrgFromUser(ctx.Repo.Owner).GetTeam(name) if err != nil { if models.IsErrTeamNotExist(err) { ctx.Flash.Error(ctx.Tr("form.team_not_exist")) diff --git a/routers/web/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go index 32105b1d4..b13dfae68 100644 --- a/routers/web/repo/setting_protected_branch.go +++ b/routers/web/repo/setting_protected_branch.go @@ -156,7 +156,7 @@ func SettingsProtectedBranch(c *context.Context) { } if c.Repo.Owner.IsOrganization() { - teams, err := c.Repo.Owner.TeamsWithAccessToRepo(c.Repo.Repository.ID, models.AccessModeRead) + teams, err := models.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, models.AccessModeRead) if err != nil { c.ServerError("Repo.Owner.TeamsWithAccessToRepo", err) return diff --git a/routers/web/repo/tag.go b/routers/web/repo/tag.go index b4d268759..4383b6214 100644 --- a/routers/web/repo/tag.go +++ b/routers/web/repo/tag.go @@ -149,7 +149,7 @@ func setTagsContext(ctx *context.Context) error { ctx.Data["Users"] = users if ctx.Repo.Owner.IsOrganization() { - teams, err := ctx.Repo.Owner.TeamsWithAccessToRepo(ctx.Repo.Repository.ID, models.AccessModeRead) + teams, err := models.OrgFromUser(ctx.Repo.Owner).TeamsWithAccessToRepo(ctx.Repo.Repository.ID, models.AccessModeRead) if err != nil { ctx.ServerError("Repo.Owner.TeamsWithAccessToRepo", err) return err diff --git a/routers/web/user/home.go b/routers/web/user/home.go index b9f5d044f..c0ecd0c2a 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -47,8 +47,8 @@ func getDashboardContextUser(ctx *context.Context) *models.User { ctxUser := ctx.User orgName := ctx.Params(":org") if len(orgName) > 0 { - ctxUser = ctx.Org.Organization - ctx.Data["Teams"] = ctx.Org.Organization.Teams + ctxUser = ctx.Org.Organization.AsUser() + ctx.Data["Teams"] = ctx.Org.Teams } ctx.Data["ContextUser"] = ctxUser @@ -97,9 +97,9 @@ func Dashboard(ctx *context.Context) { if ctxUser.IsOrganization() { var env models.AccessibleReposEnvironment if ctx.Org.Team != nil { - env = ctxUser.AccessibleTeamReposEnv(ctx.Org.Team) + env = models.OrgFromUser(ctxUser).AccessibleTeamReposEnv(ctx.Org.Team) } else { - env, err = ctxUser.AccessibleReposEnv(ctx.User.ID) + env, err = models.OrgFromUser(ctxUser).AccessibleReposEnv(ctx.User.ID) if err != nil { ctx.ServerError("AccessibleReposEnv", err) return @@ -756,9 +756,9 @@ func getActiveTeamOrOrgRepoIds(ctxUser *models.User, team *models.Team, unitType var env models.AccessibleReposEnvironment if team != nil { - env = ctxUser.AccessibleTeamReposEnv(team) + env = models.OrgFromUser(ctxUser).AccessibleTeamReposEnv(team) } else { - env, err = ctxUser.AccessibleReposEnv(ctxUser.ID) + env, err = models.OrgFromUser(ctxUser).AccessibleReposEnv(ctxUser.ID) if err != nil { return nil, fmt.Errorf("AccessibleReposEnv: %v", err) } diff --git a/routers/web/user/oauth.go b/routers/web/user/oauth.go index 3210d033d..7b1854c52 100644 --- a/routers/web/user/oauth.go +++ b/routers/web/user/oauth.go @@ -283,11 +283,11 @@ func getOAuthGroupsForUser(user *models.User) ([]string, error) { var groups []string for _, org := range orgs { groups = append(groups, org.Name) - - if err := org.LoadTeams(); err != nil { + teams, err := org.LoadTeams() + if err != nil { return nil, fmt.Errorf("LoadTeams: %v", err) } - for _, team := range org.Teams { + for _, team := range teams { if team.IsMember(user.ID) { groups = append(groups, org.Name+":"+team.LowerName) } diff --git a/services/org/org.go b/services/org/org.go index cb1f1eca0..c2b21d10a 100644 --- a/services/org/org.go +++ b/services/org/org.go @@ -14,11 +14,7 @@ import ( ) // DeleteOrganization completely and permanently deletes everything of organization. -func DeleteOrganization(org *models.User) error { - if !org.IsOrganization() { - return fmt.Errorf("%s is a user not an organization", org.Name) - } - +func DeleteOrganization(org *models.Organization) error { ctx, commiter, err := db.TxContext() if err != nil { return err @@ -26,7 +22,7 @@ func DeleteOrganization(org *models.User) error { defer commiter.Close() // Check ownership of repository. - count, err := models.GetRepositoryCount(ctx, org) + count, err := models.GetRepositoryCount(ctx, org.ID) if err != nil { return fmt.Errorf("GetRepositoryCount: %v", err) } else if count > 0 { diff --git a/services/org/org_test.go b/services/org/org_test.go index 5fec086d1..3c620c055 100644 --- a/services/org/org_test.go +++ b/services/org/org_test.go @@ -20,18 +20,18 @@ func TestMain(m *testing.M) { func TestDeleteOrganization(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) - org := unittest.AssertExistsAndLoadBean(t, &models.User{ID: 6}).(*models.User) + org := unittest.AssertExistsAndLoadBean(t, &models.Organization{ID: 6}).(*models.Organization) assert.NoError(t, DeleteOrganization(org)) - unittest.AssertNotExistsBean(t, &models.User{ID: 6}) + unittest.AssertNotExistsBean(t, &models.Organization{ID: 6}) unittest.AssertNotExistsBean(t, &models.OrgUser{OrgID: 6}) unittest.AssertNotExistsBean(t, &models.Team{OrgID: 6}) - org = unittest.AssertExistsAndLoadBean(t, &models.User{ID: 3}).(*models.User) + org = unittest.AssertExistsAndLoadBean(t, &models.Organization{ID: 3}).(*models.Organization) err := DeleteOrganization(org) assert.Error(t, err) assert.True(t, models.IsErrUserOwnRepos(err)) - user := unittest.AssertExistsAndLoadBean(t, &models.User{ID: 5}).(*models.User) + user := unittest.AssertExistsAndLoadBean(t, &models.Organization{ID: 5}).(*models.Organization) assert.Error(t, DeleteOrganization(user)) unittest.CheckConsistencyFor(t, &models.User{}, &models.Team{}) } diff --git a/services/repository/repository.go b/services/repository/repository.go index 98d160c22..1d390247f 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -45,7 +45,7 @@ func DeleteRepository(doer *models.User, repo *models.Repository) error { func PushCreateRepo(authUser, owner *models.User, repoName string) (*models.Repository, error) { if !authUser.IsAdmin { if owner.IsOrganization() { - if ok, err := owner.CanCreateOrgRepo(authUser.ID); err != nil { + if ok, err := models.CanCreateOrgRepo(owner.ID, authUser.ID); err != nil { return nil, err } else if !ok { return nil, fmt.Errorf("cannot push-create repository for org") diff --git a/services/user/user.go b/services/user/user.go index a08e40f86..733cc4a36 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -35,7 +35,7 @@ func DeleteUser(u *models.User) error { // cannot perform delete operation. // Check ownership of repository. - count, err := models.GetRepositoryCount(ctx, u) + count, err := models.GetRepositoryCount(ctx, u.ID) if err != nil { return fmt.Errorf("GetRepositoryCount: %v", err) } else if count > 0 {