From 13b67e227b40998d79d8bc96f12661b4ee92dfc6 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 11 Nov 2024 00:37:00 -0800 Subject: [PATCH 1/5] Make repo model depends on org model but not opposite --- models/org_team.go | 54 ++++++++++++++--------- models/organization/org_repo.go | 17 ------- models/organization/team.go | 17 +------ models/organization/team_list.go | 7 ++- models/organization/team_repo.go | 26 ----------- models/repo/org_repo.go | 40 +++++++++++++++++ routers/api/v1/org/team.go | 2 +- routers/api/v1/repo/teams.go | 2 +- routers/web/org/teams.go | 6 ++- routers/web/repo/setting/collaboration.go | 2 +- templates/org/team/repositories.tmpl | 2 +- 11 files changed, 86 insertions(+), 89 deletions(-) delete mode 100644 models/organization/org_repo.go create mode 100644 models/repo/org_repo.go diff --git a/models/org_team.go b/models/org_team.go index b6908478c7ea5..dd8f41f790126 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -56,7 +56,7 @@ func AddRepository(ctx context.Context, t *organization.Team, repo *repo_model.R // addAllRepositories adds all repositories to the team. // If the team already has some repositories they will be left unchanged. func addAllRepositories(ctx context.Context, t *organization.Team) error { - orgRepos, err := organization.GetOrgRepositories(ctx, t.OrgID) + orgRepos, err := repo_model.GetOrgRepositories(ctx, t.OrgID) if err != nil { return fmt.Errorf("get org repos: %w", err) } @@ -93,25 +93,24 @@ func RemoveAllRepositories(ctx context.Context, t *organization.Team) (err error return nil } - ctx, committer, err := db.TxContext(ctx) + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: t.ID, + }) if err != nil { - return err - } - defer committer.Close() - - if err = removeAllRepositories(ctx, t); err != nil { - return err + return fmt.Errorf("GetTeamRepositories: %w", err) } - return committer.Commit() + return db.WithTx(ctx, func(ctx context.Context) error { + return removeAllRepositories(ctx, t, repos) + }) } // removeAllRepositories removes all repositories from team and recalculates access // Note: Shall not be called if team includes all repositories -func removeAllRepositories(ctx context.Context, t *organization.Team) (err error) { +func removeAllRepositories(ctx context.Context, t *organization.Team, repos []*repo_model.Repository) (err error) { e := db.GetEngine(ctx) // Delete all accesses. - for _, repo := range t.Repos { + for _, repo := range repos { if err := access_model.RecalculateTeamAccesses(ctx, repo, t.ID); err != nil { return err } @@ -269,11 +268,14 @@ func UpdateTeam(ctx context.Context, t *organization.Team, authChanged, includeA // Update access for team members if needed. if authChanged { - if err = t.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: t.ID, + }) + if err != nil { return fmt.Errorf("LoadRepositories: %w", err) } - for _, repo := range t.Repos { + for _, repo := range repos { if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil { return fmt.Errorf("recalculateTeamAccesses: %w", err) } @@ -300,10 +302,6 @@ func DeleteTeam(ctx context.Context, t *organization.Team) error { } defer committer.Close() - if err := t.LoadRepositories(ctx); err != nil { - return err - } - if err := t.LoadMembers(ctx); err != nil { return err } @@ -325,7 +323,13 @@ func DeleteTeam(ctx context.Context, t *organization.Team) error { } if !t.IncludesAllRepositories { - if err := removeAllRepositories(ctx, t); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: t.ID, + }) + if err != nil { + return fmt.Errorf("GetTeamRepositories: %w", err) + } + if err := removeAllRepositories(ctx, t, repos); err != nil { return err } } @@ -431,7 +435,10 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode // FIXME: Update watch repos batchly if setting.Service.AutoWatchNewRepos { // Get team and its repositories. - if err := team.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: team.ID, + }) + if err != nil { log.Error("team.LoadRepositories failed: %v", err) } @@ -442,7 +449,7 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode log.Error("watch repo failed: %v", err) } } - }(team.Repos) + }(repos) } return nil @@ -462,7 +469,10 @@ func removeTeamMember(ctx context.Context, team *organization.Team, user *user_m team.NumMembers-- - if err := team.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: team.ID, + }) + if err != nil { return err } @@ -480,7 +490,7 @@ func removeTeamMember(ctx context.Context, team *organization.Team, user *user_m } // Delete access to team repositories. - for _, repo := range team.Repos { + for _, repo := range repos { if err := access_model.RecalculateUserAccess(ctx, repo, user.ID); err != nil { return err } diff --git a/models/organization/org_repo.go b/models/organization/org_repo.go deleted file mode 100644 index f7e59928f42ee..0000000000000 --- a/models/organization/org_repo.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package organization - -import ( - "context" - - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" -) - -// GetOrgRepositories get repos belonging to the given organization -func GetOrgRepositories(ctx context.Context, orgID int64) (repo_model.RepositoryList, error) { - var orgRepos []*repo_model.Repository - return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos) -} diff --git a/models/organization/team.go b/models/organization/team.go index fb7f0c04939e6..96666da39a778 100644 --- a/models/organization/team.go +++ b/models/organization/team.go @@ -11,7 +11,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -78,9 +77,8 @@ type Team struct { LowerName string Name string Description string - AccessMode perm.AccessMode `xorm:"'authorize'"` - Repos []*repo_model.Repository `xorm:"-"` - Members []*user_model.User `xorm:"-"` + AccessMode perm.AccessMode `xorm:"'authorize'"` + Members []*user_model.User `xorm:"-"` NumRepos int NumMembers int Units []*TeamUnit `xorm:"-"` @@ -155,17 +153,6 @@ func (t *Team) IsMember(ctx context.Context, userID int64) bool { return isMember } -// LoadRepositories returns paginated repositories in team of organization. -func (t *Team) LoadRepositories(ctx context.Context) (err error) { - if t.Repos != nil { - return nil - } - t.Repos, err = GetTeamRepositories(ctx, &SearchTeamRepoOptions{ - TeamID: t.ID, - }) - return err -} - // LoadMembers returns paginated members in team of organization. func (t *Team) LoadMembers(ctx context.Context) (err error) { t.Members, err = GetTeamMembers(ctx, &SearchMembersOptions{ diff --git a/models/organization/team_list.go b/models/organization/team_list.go index 5b45429acf310..2554a710b6cb7 100644 --- a/models/organization/team_list.go +++ b/models/organization/team_list.go @@ -9,7 +9,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "xorm.io/builder" @@ -98,11 +97,11 @@ func SearchTeam(ctx context.Context, opts *SearchTeamOptions) (TeamList, int64, } // GetRepoTeams gets the list of teams that has access to the repository -func GetRepoTeams(ctx context.Context, repo *repo_model.Repository) (teams TeamList, err error) { +func GetRepoTeams(ctx context.Context, orgID, repoID int64) (teams TeamList, err error) { return teams, db.GetEngine(ctx). Join("INNER", "team_repo", "team_repo.team_id = team.id"). - Where("team.org_id = ?", repo.OwnerID). - And("team_repo.repo_id=?", repo.ID). + Where("team.org_id = ?", orgID). + And("team_repo.repo_id=?", repoID). OrderBy("CASE WHEN name LIKE '" + OwnerTeamName + "' THEN '' ELSE name END"). Find(&teams) } diff --git a/models/organization/team_repo.go b/models/organization/team_repo.go index 1184e39263635..ff8f98138f31c 100644 --- a/models/organization/team_repo.go +++ b/models/organization/team_repo.go @@ -8,9 +8,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - repo_model "code.gitea.io/gitea/models/repo" - - "xorm.io/builder" ) // TeamRepo represents an team-repository relation. @@ -31,29 +28,6 @@ func HasTeamRepo(ctx context.Context, orgID, teamID, repoID int64) bool { return has } -type SearchTeamRepoOptions struct { - db.ListOptions - TeamID int64 -} - -// GetRepositories returns paginated repositories in team of organization. -func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (repo_model.RepositoryList, error) { - sess := db.GetEngine(ctx) - if opts.TeamID > 0 { - sess = sess.In("id", - builder.Select("repo_id"). - From("team_repo"). - Where(builder.Eq{"team_id": opts.TeamID}), - ) - } - if opts.PageSize > 0 { - sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) - } - var repos []*repo_model.Repository - return repos, sess.OrderBy("repository.name"). - Find(&repos) -} - // AddTeamRepo adds a repo for an organization's team func AddTeamRepo(ctx context.Context, orgID, teamID, repoID int64) error { _, err := db.GetEngine(ctx).Insert(&TeamRepo{ diff --git a/models/repo/org_repo.go b/models/repo/org_repo.go new file mode 100644 index 0000000000000..19bdc855df015 --- /dev/null +++ b/models/repo/org_repo.go @@ -0,0 +1,40 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "context" + + "code.gitea.io/gitea/models/db" + "xorm.io/builder" +) + +// GetOrgRepositories get repos belonging to the given organization +func GetOrgRepositories(ctx context.Context, orgID int64) (RepositoryList, error) { + var orgRepos []*Repository + return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos) +} + +type SearchTeamRepoOptions struct { + db.ListOptions + TeamID int64 +} + +// GetRepositories returns paginated repositories in team of organization. +func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (RepositoryList, error) { + sess := db.GetEngine(ctx) + if opts.TeamID > 0 { + sess = sess.In("id", + builder.Select("repo_id"). + From("team_repo"). + Where(builder.Eq{"team_id": opts.TeamID}), + ) + } + if opts.PageSize > 0 { + sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) + } + var repos []*Repository + return repos, sess.OrderBy("repository.name"). + Find(&repos) +} diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index c55837ff44fd4..3ebd226f0ee09 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -573,7 +573,7 @@ func GetTeamRepos(ctx *context.APIContext) { // "$ref": "#/responses/notFound" team := ctx.Org.Team - teamRepos, err := organization.GetTeamRepositories(ctx, &organization.SearchTeamRepoOptions{ + teamRepos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ ListOptions: utils.GetListOptions(ctx), TeamID: team.ID, }) diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index ddd325482da35..b1d6eecefe597 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -43,7 +43,7 @@ func ListTeams(ctx *context.APIContext) { return } - teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository) + teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 31b9601ce79d7..c385efe84d374 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -411,11 +411,15 @@ func TeamRepositories(ctx *context.Context) { return } - if err := ctx.Org.Team.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: ctx.Org.Team.ID, + }) + if err != nil { ctx.ServerError("GetRepositories", err) return } ctx.Data["Units"] = unit_model.Units + ctx.Data["TeamRepos"] = repos ctx.HTML(http.StatusOK, tplTeamRepositories) } diff --git a/routers/web/repo/setting/collaboration.go b/routers/web/repo/setting/collaboration.go index 18ecff8250858..e5547dcd0f06c 100644 --- a/routers/web/repo/setting/collaboration.go +++ b/routers/web/repo/setting/collaboration.go @@ -33,7 +33,7 @@ func Collaboration(ctx *context.Context) { } ctx.Data["Collaborators"] = users - teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository) + teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID) if err != nil { ctx.ServerError("GetRepoTeams", err) return diff --git a/templates/org/team/repositories.tmpl b/templates/org/team/repositories.tmpl index 502cf97992a7d..92c3d724ba621 100644 --- a/templates/org/team/repositories.tmpl +++ b/templates/org/team/repositories.tmpl @@ -27,7 +27,7 @@ {{end}}
- {{range .Team.Repos}} + {{range $.TeamRepos}}
{{template "repo/icon" .}} From fc0b2ca1d35e0a4c58527bd0a821b621a939a390 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 11 Nov 2024 00:37:00 -0800 Subject: [PATCH 2/5] Make repo model depends on org model but not opposite --- models/org_team.go | 54 ++++++++++++++--------- models/organization/org_repo.go | 17 ------- models/organization/team.go | 17 +------ models/organization/team_list.go | 7 ++- models/organization/team_repo.go | 26 ----------- models/repo/org_repo.go | 40 +++++++++++++++++ routers/api/v1/org/team.go | 2 +- routers/api/v1/repo/teams.go | 2 +- routers/web/org/teams.go | 6 ++- routers/web/repo/setting/collaboration.go | 2 +- templates/org/team/repositories.tmpl | 2 +- 11 files changed, 86 insertions(+), 89 deletions(-) delete mode 100644 models/organization/org_repo.go create mode 100644 models/repo/org_repo.go diff --git a/models/org_team.go b/models/org_team.go index b6908478c7ea5..dd8f41f790126 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -56,7 +56,7 @@ func AddRepository(ctx context.Context, t *organization.Team, repo *repo_model.R // addAllRepositories adds all repositories to the team. // If the team already has some repositories they will be left unchanged. func addAllRepositories(ctx context.Context, t *organization.Team) error { - orgRepos, err := organization.GetOrgRepositories(ctx, t.OrgID) + orgRepos, err := repo_model.GetOrgRepositories(ctx, t.OrgID) if err != nil { return fmt.Errorf("get org repos: %w", err) } @@ -93,25 +93,24 @@ func RemoveAllRepositories(ctx context.Context, t *organization.Team) (err error return nil } - ctx, committer, err := db.TxContext(ctx) + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: t.ID, + }) if err != nil { - return err - } - defer committer.Close() - - if err = removeAllRepositories(ctx, t); err != nil { - return err + return fmt.Errorf("GetTeamRepositories: %w", err) } - return committer.Commit() + return db.WithTx(ctx, func(ctx context.Context) error { + return removeAllRepositories(ctx, t, repos) + }) } // removeAllRepositories removes all repositories from team and recalculates access // Note: Shall not be called if team includes all repositories -func removeAllRepositories(ctx context.Context, t *organization.Team) (err error) { +func removeAllRepositories(ctx context.Context, t *organization.Team, repos []*repo_model.Repository) (err error) { e := db.GetEngine(ctx) // Delete all accesses. - for _, repo := range t.Repos { + for _, repo := range repos { if err := access_model.RecalculateTeamAccesses(ctx, repo, t.ID); err != nil { return err } @@ -269,11 +268,14 @@ func UpdateTeam(ctx context.Context, t *organization.Team, authChanged, includeA // Update access for team members if needed. if authChanged { - if err = t.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: t.ID, + }) + if err != nil { return fmt.Errorf("LoadRepositories: %w", err) } - for _, repo := range t.Repos { + for _, repo := range repos { if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil { return fmt.Errorf("recalculateTeamAccesses: %w", err) } @@ -300,10 +302,6 @@ func DeleteTeam(ctx context.Context, t *organization.Team) error { } defer committer.Close() - if err := t.LoadRepositories(ctx); err != nil { - return err - } - if err := t.LoadMembers(ctx); err != nil { return err } @@ -325,7 +323,13 @@ func DeleteTeam(ctx context.Context, t *organization.Team) error { } if !t.IncludesAllRepositories { - if err := removeAllRepositories(ctx, t); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: t.ID, + }) + if err != nil { + return fmt.Errorf("GetTeamRepositories: %w", err) + } + if err := removeAllRepositories(ctx, t, repos); err != nil { return err } } @@ -431,7 +435,10 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode // FIXME: Update watch repos batchly if setting.Service.AutoWatchNewRepos { // Get team and its repositories. - if err := team.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: team.ID, + }) + if err != nil { log.Error("team.LoadRepositories failed: %v", err) } @@ -442,7 +449,7 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode log.Error("watch repo failed: %v", err) } } - }(team.Repos) + }(repos) } return nil @@ -462,7 +469,10 @@ func removeTeamMember(ctx context.Context, team *organization.Team, user *user_m team.NumMembers-- - if err := team.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: team.ID, + }) + if err != nil { return err } @@ -480,7 +490,7 @@ func removeTeamMember(ctx context.Context, team *organization.Team, user *user_m } // Delete access to team repositories. - for _, repo := range team.Repos { + for _, repo := range repos { if err := access_model.RecalculateUserAccess(ctx, repo, user.ID); err != nil { return err } diff --git a/models/organization/org_repo.go b/models/organization/org_repo.go deleted file mode 100644 index f7e59928f42ee..0000000000000 --- a/models/organization/org_repo.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package organization - -import ( - "context" - - "code.gitea.io/gitea/models/db" - repo_model "code.gitea.io/gitea/models/repo" -) - -// GetOrgRepositories get repos belonging to the given organization -func GetOrgRepositories(ctx context.Context, orgID int64) (repo_model.RepositoryList, error) { - var orgRepos []*repo_model.Repository - return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos) -} diff --git a/models/organization/team.go b/models/organization/team.go index fb7f0c04939e6..96666da39a778 100644 --- a/models/organization/team.go +++ b/models/organization/team.go @@ -11,7 +11,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -78,9 +77,8 @@ type Team struct { LowerName string Name string Description string - AccessMode perm.AccessMode `xorm:"'authorize'"` - Repos []*repo_model.Repository `xorm:"-"` - Members []*user_model.User `xorm:"-"` + AccessMode perm.AccessMode `xorm:"'authorize'"` + Members []*user_model.User `xorm:"-"` NumRepos int NumMembers int Units []*TeamUnit `xorm:"-"` @@ -155,17 +153,6 @@ func (t *Team) IsMember(ctx context.Context, userID int64) bool { return isMember } -// LoadRepositories returns paginated repositories in team of organization. -func (t *Team) LoadRepositories(ctx context.Context) (err error) { - if t.Repos != nil { - return nil - } - t.Repos, err = GetTeamRepositories(ctx, &SearchTeamRepoOptions{ - TeamID: t.ID, - }) - return err -} - // LoadMembers returns paginated members in team of organization. func (t *Team) LoadMembers(ctx context.Context) (err error) { t.Members, err = GetTeamMembers(ctx, &SearchMembersOptions{ diff --git a/models/organization/team_list.go b/models/organization/team_list.go index 5b45429acf310..2554a710b6cb7 100644 --- a/models/organization/team_list.go +++ b/models/organization/team_list.go @@ -9,7 +9,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "xorm.io/builder" @@ -98,11 +97,11 @@ func SearchTeam(ctx context.Context, opts *SearchTeamOptions) (TeamList, int64, } // GetRepoTeams gets the list of teams that has access to the repository -func GetRepoTeams(ctx context.Context, repo *repo_model.Repository) (teams TeamList, err error) { +func GetRepoTeams(ctx context.Context, orgID, repoID int64) (teams TeamList, err error) { return teams, db.GetEngine(ctx). Join("INNER", "team_repo", "team_repo.team_id = team.id"). - Where("team.org_id = ?", repo.OwnerID). - And("team_repo.repo_id=?", repo.ID). + Where("team.org_id = ?", orgID). + And("team_repo.repo_id=?", repoID). OrderBy("CASE WHEN name LIKE '" + OwnerTeamName + "' THEN '' ELSE name END"). Find(&teams) } diff --git a/models/organization/team_repo.go b/models/organization/team_repo.go index 1184e39263635..ff8f98138f31c 100644 --- a/models/organization/team_repo.go +++ b/models/organization/team_repo.go @@ -8,9 +8,6 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - repo_model "code.gitea.io/gitea/models/repo" - - "xorm.io/builder" ) // TeamRepo represents an team-repository relation. @@ -31,29 +28,6 @@ func HasTeamRepo(ctx context.Context, orgID, teamID, repoID int64) bool { return has } -type SearchTeamRepoOptions struct { - db.ListOptions - TeamID int64 -} - -// GetRepositories returns paginated repositories in team of organization. -func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (repo_model.RepositoryList, error) { - sess := db.GetEngine(ctx) - if opts.TeamID > 0 { - sess = sess.In("id", - builder.Select("repo_id"). - From("team_repo"). - Where(builder.Eq{"team_id": opts.TeamID}), - ) - } - if opts.PageSize > 0 { - sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) - } - var repos []*repo_model.Repository - return repos, sess.OrderBy("repository.name"). - Find(&repos) -} - // AddTeamRepo adds a repo for an organization's team func AddTeamRepo(ctx context.Context, orgID, teamID, repoID int64) error { _, err := db.GetEngine(ctx).Insert(&TeamRepo{ diff --git a/models/repo/org_repo.go b/models/repo/org_repo.go new file mode 100644 index 0000000000000..19bdc855df015 --- /dev/null +++ b/models/repo/org_repo.go @@ -0,0 +1,40 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "context" + + "code.gitea.io/gitea/models/db" + "xorm.io/builder" +) + +// GetOrgRepositories get repos belonging to the given organization +func GetOrgRepositories(ctx context.Context, orgID int64) (RepositoryList, error) { + var orgRepos []*Repository + return orgRepos, db.GetEngine(ctx).Where("owner_id = ?", orgID).Find(&orgRepos) +} + +type SearchTeamRepoOptions struct { + db.ListOptions + TeamID int64 +} + +// GetRepositories returns paginated repositories in team of organization. +func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (RepositoryList, error) { + sess := db.GetEngine(ctx) + if opts.TeamID > 0 { + sess = sess.In("id", + builder.Select("repo_id"). + From("team_repo"). + Where(builder.Eq{"team_id": opts.TeamID}), + ) + } + if opts.PageSize > 0 { + sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) + } + var repos []*Repository + return repos, sess.OrderBy("repository.name"). + Find(&repos) +} diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index c55837ff44fd4..3ebd226f0ee09 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -573,7 +573,7 @@ func GetTeamRepos(ctx *context.APIContext) { // "$ref": "#/responses/notFound" team := ctx.Org.Team - teamRepos, err := organization.GetTeamRepositories(ctx, &organization.SearchTeamRepoOptions{ + teamRepos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ ListOptions: utils.GetListOptions(ctx), TeamID: team.ID, }) diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index ddd325482da35..b1d6eecefe597 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -43,7 +43,7 @@ func ListTeams(ctx *context.APIContext) { return } - teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository) + teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID) if err != nil { ctx.InternalServerError(err) return diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 31b9601ce79d7..c385efe84d374 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -411,11 +411,15 @@ func TeamRepositories(ctx *context.Context) { return } - if err := ctx.Org.Team.LoadRepositories(ctx); err != nil { + repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ + TeamID: ctx.Org.Team.ID, + }) + if err != nil { ctx.ServerError("GetRepositories", err) return } ctx.Data["Units"] = unit_model.Units + ctx.Data["TeamRepos"] = repos ctx.HTML(http.StatusOK, tplTeamRepositories) } diff --git a/routers/web/repo/setting/collaboration.go b/routers/web/repo/setting/collaboration.go index 18ecff8250858..e5547dcd0f06c 100644 --- a/routers/web/repo/setting/collaboration.go +++ b/routers/web/repo/setting/collaboration.go @@ -33,7 +33,7 @@ func Collaboration(ctx *context.Context) { } ctx.Data["Collaborators"] = users - teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository) + teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID) if err != nil { ctx.ServerError("GetRepoTeams", err) return diff --git a/templates/org/team/repositories.tmpl b/templates/org/team/repositories.tmpl index 502cf97992a7d..92c3d724ba621 100644 --- a/templates/org/team/repositories.tmpl +++ b/templates/org/team/repositories.tmpl @@ -27,7 +27,7 @@ {{end}}
- {{range .Team.Repos}} + {{range $.TeamRepos}}
{{template "repo/icon" .}} From 39da526c48402b13dc6b412a564a25a7551b3b4b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 12 Nov 2024 11:33:45 -0800 Subject: [PATCH 3/5] Move more content into repository model --- models/organization/org.go | 162 ------------------------------------ models/repo/org_repo.go | 166 +++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 162 deletions(-) diff --git a/models/organization/org.go b/models/organization/org.go index 725a99356e974..e41342e5fbcd3 100644 --- a/models/organization/org.go +++ b/models/organization/org.go @@ -12,7 +12,6 @@ import ( actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - repo_model "code.gitea.io/gitea/models/repo" secret_model "code.gitea.io/gitea/models/secret" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -651,164 +650,3 @@ func (org *Organization) GetUserTeamIDs(ctx context.Context, userID int64) ([]in func (org *Organization) GetUserTeams(ctx context.Context, userID int64) ([]*Team, error) { return org.getUserTeams(ctx, userID) } - -// AccessibleReposEnvironment operations involving the repositories that are -// accessible to a particular user -type AccessibleReposEnvironment interface { - CountRepos() (int64, error) - RepoIDs(page, pageSize int) ([]int64, error) - Repos(page, pageSize int) (repo_model.RepositoryList, error) - MirrorRepos() (repo_model.RepositoryList, error) - AddKeyword(keyword string) - SetSort(db.SearchOrderBy) -} - -type accessibleReposEnv struct { - org *Organization - user *user_model.User - team *Team - teamIDs []int64 - ctx context.Context - keyword string - orderBy db.SearchOrderBy -} - -// AccessibleReposEnv builds an AccessibleReposEnvironment for the repositories in `org` -// that are accessible to the specified user. -func AccessibleReposEnv(ctx context.Context, org *Organization, userID int64) (AccessibleReposEnvironment, error) { - var user *user_model.User - - if userID > 0 { - u, err := user_model.GetUserByID(ctx, userID) - if err != nil { - return nil, err - } - user = u - } - - teamIDs, err := org.getUserTeamIDs(ctx, userID) - if err != nil { - return nil, err - } - return &accessibleReposEnv{ - org: org, - user: user, - teamIDs: teamIDs, - ctx: ctx, - orderBy: db.SearchOrderByRecentUpdated, - }, nil -} - -// AccessibleTeamReposEnv an AccessibleReposEnvironment for the repositories in `org` -// that are accessible to the specified team. -func (org *Organization) AccessibleTeamReposEnv(ctx context.Context, team *Team) AccessibleReposEnvironment { - return &accessibleReposEnv{ - org: org, - team: team, - ctx: ctx, - orderBy: db.SearchOrderByRecentUpdated, - } -} - -func (env *accessibleReposEnv) cond() builder.Cond { - cond := builder.NewCond() - if env.team != nil { - cond = cond.And(builder.Eq{"team_repo.team_id": env.team.ID}) - } else { - if env.user == nil || !env.user.IsRestricted { - cond = cond.Or(builder.Eq{ - "`repository`.owner_id": env.org.ID, - "`repository`.is_private": false, - }) - } - if len(env.teamIDs) > 0 { - cond = cond.Or(builder.In("team_repo.team_id", env.teamIDs)) - } - } - if env.keyword != "" { - cond = cond.And(builder.Like{"`repository`.lower_name", strings.ToLower(env.keyword)}) - } - return cond -} - -func (env *accessibleReposEnv) CountRepos() (int64, error) { - repoCount, err := db.GetEngine(env.ctx). - Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). - Where(env.cond()). - Distinct("`repository`.id"). - Count(&repo_model.Repository{}) - if err != nil { - return 0, fmt.Errorf("count user repositories in organization: %w", err) - } - return repoCount, nil -} - -func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) { - if page <= 0 { - page = 1 - } - - repoIDs := make([]int64, 0, pageSize) - return repoIDs, db.GetEngine(env.ctx). - Table("repository"). - Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). - Where(env.cond()). - GroupBy("`repository`.id,`repository`."+strings.Fields(string(env.orderBy))[0]). - OrderBy(string(env.orderBy)). - Limit(pageSize, (page-1)*pageSize). - Cols("`repository`.id"). - Find(&repoIDs) -} - -func (env *accessibleReposEnv) Repos(page, pageSize int) (repo_model.RepositoryList, error) { - repoIDs, err := env.RepoIDs(page, pageSize) - if err != nil { - return nil, fmt.Errorf("GetUserRepositoryIDs: %w", err) - } - - repos := make([]*repo_model.Repository, 0, len(repoIDs)) - if len(repoIDs) == 0 { - return repos, nil - } - - return repos, db.GetEngine(env.ctx). - In("`repository`.id", repoIDs). - OrderBy(string(env.orderBy)). - Find(&repos) -} - -func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) { - repoIDs := make([]int64, 0, 10) - return repoIDs, db.GetEngine(env.ctx). - Table("repository"). - Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true). - Where(env.cond()). - GroupBy("`repository`.id, `repository`.updated_unix"). - OrderBy(string(env.orderBy)). - Cols("`repository`.id"). - Find(&repoIDs) -} - -func (env *accessibleReposEnv) MirrorRepos() (repo_model.RepositoryList, error) { - repoIDs, err := env.MirrorRepoIDs() - if err != nil { - return nil, fmt.Errorf("MirrorRepoIDs: %w", err) - } - - repos := make([]*repo_model.Repository, 0, len(repoIDs)) - if len(repoIDs) == 0 { - return repos, nil - } - - return repos, db.GetEngine(env.ctx). - In("`repository`.id", repoIDs). - Find(&repos) -} - -func (env *accessibleReposEnv) AddKeyword(keyword string) { - env.keyword = keyword -} - -func (env *accessibleReposEnv) SetSort(orderBy db.SearchOrderBy) { - env.orderBy = orderBy -} diff --git a/models/repo/org_repo.go b/models/repo/org_repo.go index 19bdc855df015..e405604108d67 100644 --- a/models/repo/org_repo.go +++ b/models/repo/org_repo.go @@ -5,8 +5,13 @@ package repo import ( "context" + "fmt" + "strings" "code.gitea.io/gitea/models/db" + org_model "code.gitea.io/gitea/models/organization" + user_model "code.gitea.io/gitea/models/user" + "xorm.io/builder" ) @@ -38,3 +43,164 @@ func GetTeamRepositories(ctx context.Context, opts *SearchTeamRepoOptions) (Repo return repos, sess.OrderBy("repository.name"). Find(&repos) } + +// AccessibleReposEnvironment operations involving the repositories that are +// accessible to a particular user +type AccessibleReposEnvironment interface { + CountRepos() (int64, error) + RepoIDs(page, pageSize int) ([]int64, error) + Repos(page, pageSize int) (RepositoryList, error) + MirrorRepos() (RepositoryList, error) + AddKeyword(keyword string) + SetSort(db.SearchOrderBy) +} + +type accessibleReposEnv struct { + org *org_model.Organization + user *user_model.User + team *org_model.Team + teamIDs []int64 + ctx context.Context + keyword string + orderBy db.SearchOrderBy +} + +// AccessibleReposEnv builds an AccessibleReposEnvironment for the repositories in `org` +// that are accessible to the specified user. +func AccessibleReposEnv(ctx context.Context, org *org_model.Organization, userID int64) (AccessibleReposEnvironment, error) { + var user *user_model.User + + if userID > 0 { + u, err := user_model.GetUserByID(ctx, userID) + if err != nil { + return nil, err + } + user = u + } + + teamIDs, err := org.getUserTeamIDs(ctx, userID) + if err != nil { + return nil, err + } + return &accessibleReposEnv{ + org: org, + user: user, + teamIDs: teamIDs, + ctx: ctx, + orderBy: db.SearchOrderByRecentUpdated, + }, nil +} + +// AccessibleTeamReposEnv an AccessibleReposEnvironment for the repositories in `org` +// that are accessible to the specified team. +func AccessibleTeamReposEnv(ctx context.Context, org *org_model.Organization, team *org_model.Team) AccessibleReposEnvironment { + return &accessibleReposEnv{ + org: org, + team: team, + ctx: ctx, + orderBy: db.SearchOrderByRecentUpdated, + } +} + +func (env *accessibleReposEnv) cond() builder.Cond { + cond := builder.NewCond() + if env.team != nil { + cond = cond.And(builder.Eq{"team_repo.team_id": env.team.ID}) + } else { + if env.user == nil || !env.user.IsRestricted { + cond = cond.Or(builder.Eq{ + "`repository`.owner_id": env.org.ID, + "`repository`.is_private": false, + }) + } + if len(env.teamIDs) > 0 { + cond = cond.Or(builder.In("team_repo.team_id", env.teamIDs)) + } + } + if env.keyword != "" { + cond = cond.And(builder.Like{"`repository`.lower_name", strings.ToLower(env.keyword)}) + } + return cond +} + +func (env *accessibleReposEnv) CountRepos() (int64, error) { + repoCount, err := db.GetEngine(env.ctx). + Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). + Where(env.cond()). + Distinct("`repository`.id"). + Count(&repo_model.Repository{}) + if err != nil { + return 0, fmt.Errorf("count user repositories in organization: %w", err) + } + return repoCount, nil +} + +func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) { + if page <= 0 { + page = 1 + } + + repoIDs := make([]int64, 0, pageSize) + return repoIDs, db.GetEngine(env.ctx). + Table("repository"). + Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). + Where(env.cond()). + GroupBy("`repository`.id,`repository`."+strings.Fields(string(env.orderBy))[0]). + OrderBy(string(env.orderBy)). + Limit(pageSize, (page-1)*pageSize). + Cols("`repository`.id"). + Find(&repoIDs) +} + +func (env *accessibleReposEnv) Repos(page, pageSize int) (repo_model.RepositoryList, error) { + repoIDs, err := env.RepoIDs(page, pageSize) + if err != nil { + return nil, fmt.Errorf("GetUserRepositoryIDs: %w", err) + } + + repos := make([]*repo_model.Repository, 0, len(repoIDs)) + if len(repoIDs) == 0 { + return repos, nil + } + + return repos, db.GetEngine(env.ctx). + In("`repository`.id", repoIDs). + OrderBy(string(env.orderBy)). + Find(&repos) +} + +func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) { + repoIDs := make([]int64, 0, 10) + return repoIDs, db.GetEngine(env.ctx). + Table("repository"). + Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id AND `repository`.is_mirror=?", true). + Where(env.cond()). + GroupBy("`repository`.id, `repository`.updated_unix"). + OrderBy(string(env.orderBy)). + Cols("`repository`.id"). + Find(&repoIDs) +} + +func (env *accessibleReposEnv) MirrorRepos() (repo_model.RepositoryList, error) { + repoIDs, err := env.MirrorRepoIDs() + if err != nil { + return nil, fmt.Errorf("MirrorRepoIDs: %w", err) + } + + repos := make([]*repo_model.Repository, 0, len(repoIDs)) + if len(repoIDs) == 0 { + return repos, nil + } + + return repos, db.GetEngine(env.ctx). + In("`repository`.id", repoIDs). + Find(&repos) +} + +func (env *accessibleReposEnv) AddKeyword(keyword string) { + env.keyword = keyword +} + +func (env *accessibleReposEnv) SetSort(orderBy db.SearchOrderBy) { + env.orderBy = orderBy +} From 11c0e380fb1add734021614dc10d3f00825e64d2 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 13 Nov 2024 23:06:08 -0800 Subject: [PATCH 4/5] Fix some dependent problems --- models/activities/action.go | 2 +- models/org.go | 2 +- models/organization/org.go | 47 ++++-------------------------- models/organization/org_test.go | 8 ++--- models/organization/team_test.go | 10 +++++-- models/repo/org_repo.go | 12 ++++---- services/org/org.go | 31 +++++++++++++++++++- services/repository/create_test.go | 26 ++++++++++------- 8 files changed, 70 insertions(+), 68 deletions(-) diff --git a/models/activities/action.go b/models/activities/action.go index 43da557fff398..8a13f258115d8 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -563,7 +563,7 @@ func activityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder. } if opts.RequestedTeam != nil { - env := organization.OrgFromUser(opts.RequestedUser).AccessibleTeamReposEnv(ctx, opts.RequestedTeam) + env := repo_model.AccessibleTeamReposEnv(ctx, organization.OrgFromUser(opts.RequestedUser), opts.RequestedTeam) teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos) if err != nil { return nil, fmt.Errorf("GetTeamRepositories: %w", err) diff --git a/models/org.go b/models/org.go index 69cc47137eb9d..7d1fe3bb829f5 100644 --- a/models/org.go +++ b/models/org.go @@ -60,7 +60,7 @@ func RemoveOrgUser(ctx context.Context, org *organization.Organization, user *us } // Delete all repository accesses and unwatch them. - env, err := organization.AccessibleReposEnv(ctx, org, user.ID) + env, err := repo_model.AccessibleReposEnv(ctx, org, user.ID) if err != nil { return fmt.Errorf("AccessibleReposEnv: %w", err) } diff --git a/models/organization/org.go b/models/organization/org.go index e41342e5fbcd3..3e55a36758963 100644 --- a/models/organization/org.go +++ b/models/organization/org.go @@ -9,10 +9,8 @@ import ( "fmt" "strings" - actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" - secret_model "code.gitea.io/gitea/models/secret" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -406,33 +404,6 @@ func GetOrgByName(ctx context.Context, name string) (*Organization, error) { return u, nil } -// DeleteOrganization deletes models associated to an organization. -func DeleteOrganization(ctx context.Context, org *Organization) error { - if org.Type != user_model.UserTypeOrganization { - return fmt.Errorf("%s is a user not an organization", org.Name) - } - - if err := db.DeleteBeans(ctx, - &Team{OrgID: org.ID}, - &OrgUser{OrgID: org.ID}, - &TeamUser{OrgID: org.ID}, - &TeamUnit{OrgID: org.ID}, - &TeamInvite{OrgID: org.ID}, - &secret_model.Secret{OwnerID: org.ID}, - &user_model.Blocking{BlockerID: org.ID}, - &actions_model.ActionRunner{OwnerID: org.ID}, - &actions_model.ActionRunnerToken{OwnerID: org.ID}, - ); err != nil { - return fmt.Errorf("DeleteBeans: %w", err) - } - - if _, err := db.GetEngine(ctx).ID(org.ID).Delete(new(user_model.User)); err != nil { - return fmt.Errorf("Delete: %w", err) - } - - return nil -} - // GetOrgUserMaxAuthorizeLevel returns highest authorize level of user in an organization func (org *Organization) GetOrgUserMaxAuthorizeLevel(ctx context.Context, uid int64) (perm.AccessMode, error) { var authorize perm.AccessMode @@ -603,7 +574,9 @@ func RemoveOrgRepo(ctx context.Context, orgID, repoID int64) error { return err } -func (org *Organization) getUserTeams(ctx context.Context, userID int64, cols ...string) ([]*Team, error) { +// GetUserTeams returns all teams that belong to user, +// and that the user has joined. +func (org *Organization) GetUserTeams(ctx context.Context, userID int64, cols ...string) ([]*Team, error) { teams := make([]*Team, 0, org.NumTeams) return teams, db.GetEngine(ctx). Where("`team_user`.org_id = ?", org.ID). @@ -615,7 +588,8 @@ func (org *Organization) getUserTeams(ctx context.Context, userID int64, cols .. Find(&teams) } -func (org *Organization) getUserTeamIDs(ctx context.Context, userID int64) ([]int64, error) { +// GetUserTeamIDs returns of all team IDs of the organization that user is member of. +func (org *Organization) GetUserTeamIDs(ctx context.Context, userID int64) ([]int64, error) { teamIDs := make([]int64, 0, org.NumTeams) return teamIDs, db.GetEngine(ctx). Table("team"). @@ -639,14 +613,3 @@ func getUserTeamIDsQueryBuilder(orgID, userID int64) *builder.Builder { func (org *Organization) TeamsWithAccessToRepo(ctx context.Context, repoID int64, mode perm.AccessMode) ([]*Team, error) { return GetTeamsWithAccessToRepo(ctx, org.ID, repoID, mode) } - -// GetUserTeamIDs returns of all team IDs of the organization that user is member of. -func (org *Organization) GetUserTeamIDs(ctx context.Context, userID int64) ([]int64, error) { - return org.getUserTeamIDs(ctx, userID) -} - -// GetUserTeams returns all teams that belong to user, -// and that the user has joined. -func (org *Organization) GetUserTeams(ctx context.Context, userID int64) ([]*Team, error) { - return org.getUserTeams(ctx, userID) -} diff --git a/models/organization/org_test.go b/models/organization/org_test.go index 7159f0fc46510..fa129c3ee37f5 100644 --- a/models/organization/org_test.go +++ b/models/organization/org_test.go @@ -318,7 +318,7 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID, expectedCount int64) { - env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) + env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) count, err := env.CountRepos() assert.NoError(t, err) @@ -332,7 +332,7 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expectedRepoIDs []int64) { - env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) + env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) repoIDs, err := env.RepoIDs(1, 100) assert.NoError(t, err) @@ -346,7 +346,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expectedRepoIDs []int64) { - env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) + env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) repos, err := env.Repos(1, 100) assert.NoError(t, err) @@ -365,7 +365,7 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) testSuccess := func(userID int64, expectedRepoIDs []int64) { - env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID) + env, err := repo_model.AccessibleReposEnv(db.DefaultContext, org, userID) assert.NoError(t, err) repos, err := env.MirrorRepos() assert.NoError(t, err) diff --git a/models/organization/team_test.go b/models/organization/team_test.go index 23a6affe24807..077677cf4cecc 100644 --- a/models/organization/team_test.go +++ b/models/organization/team_test.go @@ -8,6 +8,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "github.com/stretchr/testify/assert" @@ -42,9 +43,12 @@ func TestTeam_GetRepositories(t *testing.T) { test := func(teamID int64) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - assert.NoError(t, team.LoadRepositories(db.DefaultContext)) - assert.Len(t, team.Repos, team.NumRepos) - for _, repo := range team.Repos { + repos, err := repo_model.GetTeamRepositories(db.DefaultContext, &repo_model.SearchTeamRepoOptions{ + TeamID: team.ID, + }) + assert.NoError(t, err) + assert.Len(t, repos, team.NumRepos) + for _, repo := range repos { unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repo.ID}) } } diff --git a/models/repo/org_repo.go b/models/repo/org_repo.go index e405604108d67..5f0af2d475abd 100644 --- a/models/repo/org_repo.go +++ b/models/repo/org_repo.go @@ -78,7 +78,7 @@ func AccessibleReposEnv(ctx context.Context, org *org_model.Organization, userID user = u } - teamIDs, err := org.getUserTeamIDs(ctx, userID) + teamIDs, err := org.GetUserTeamIDs(ctx, userID) if err != nil { return nil, err } @@ -128,7 +128,7 @@ func (env *accessibleReposEnv) CountRepos() (int64, error) { Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). Where(env.cond()). Distinct("`repository`.id"). - Count(&repo_model.Repository{}) + Count(&Repository{}) if err != nil { return 0, fmt.Errorf("count user repositories in organization: %w", err) } @@ -152,13 +152,13 @@ func (env *accessibleReposEnv) RepoIDs(page, pageSize int) ([]int64, error) { Find(&repoIDs) } -func (env *accessibleReposEnv) Repos(page, pageSize int) (repo_model.RepositoryList, error) { +func (env *accessibleReposEnv) Repos(page, pageSize int) (RepositoryList, error) { repoIDs, err := env.RepoIDs(page, pageSize) if err != nil { return nil, fmt.Errorf("GetUserRepositoryIDs: %w", err) } - repos := make([]*repo_model.Repository, 0, len(repoIDs)) + repos := make([]*Repository, 0, len(repoIDs)) if len(repoIDs) == 0 { return repos, nil } @@ -181,13 +181,13 @@ func (env *accessibleReposEnv) MirrorRepoIDs() ([]int64, error) { Find(&repoIDs) } -func (env *accessibleReposEnv) MirrorRepos() (repo_model.RepositoryList, error) { +func (env *accessibleReposEnv) MirrorRepos() (RepositoryList, error) { repoIDs, err := env.MirrorRepoIDs() if err != nil { return nil, fmt.Errorf("MirrorRepoIDs: %w", err) } - repos := make([]*repo_model.Repository, 0, len(repoIDs)) + repos := make([]*Repository, 0, len(repoIDs)) if len(repoIDs) == 0 { return repos, nil } diff --git a/services/org/org.go b/services/org/org.go index c19572a123062..471e6fcaf162c 100644 --- a/services/org/org.go +++ b/services/org/org.go @@ -8,16 +8,45 @@ import ( "fmt" "code.gitea.io/gitea/models" + actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" org_model "code.gitea.io/gitea/models/organization" packages_model "code.gitea.io/gitea/models/packages" repo_model "code.gitea.io/gitea/models/repo" + secret_model "code.gitea.io/gitea/models/secret" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/util" repo_service "code.gitea.io/gitea/services/repository" ) +// deleteOrganization deletes models associated to an organization. +func deleteOrganization(ctx context.Context, org *org_model.Organization) error { + if org.Type != user_model.UserTypeOrganization { + return fmt.Errorf("%s is a user not an organization", org.Name) + } + + if err := db.DeleteBeans(ctx, + &org_model.Team{OrgID: org.ID}, + &org_model.OrgUser{OrgID: org.ID}, + &org_model.TeamUser{OrgID: org.ID}, + &org_model.TeamUnit{OrgID: org.ID}, + &org_model.TeamInvite{OrgID: org.ID}, + &secret_model.Secret{OwnerID: org.ID}, + &user_model.Blocking{BlockerID: org.ID}, + &actions_model.ActionRunner{OwnerID: org.ID}, + &actions_model.ActionRunnerToken{OwnerID: org.ID}, + ); err != nil { + return fmt.Errorf("DeleteBeans: %w", err) + } + + if _, err := db.GetEngine(ctx).ID(org.ID).Delete(new(user_model.User)); err != nil { + return fmt.Errorf("Delete: %w", err) + } + + return nil +} + // DeleteOrganization completely and permanently deletes everything of organization. func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge bool) error { ctx, committer, err := db.TxContext(ctx) @@ -48,7 +77,7 @@ func DeleteOrganization(ctx context.Context, org *org_model.Organization, purge return models.ErrUserOwnPackages{UID: org.ID} } - if err := org_model.DeleteOrganization(ctx, org); err != nil { + if err := deleteOrganization(ctx, org); err != nil { return fmt.Errorf("DeleteOrganization: %w", err) } diff --git a/services/repository/create_test.go b/services/repository/create_test.go index 41e6b615db7f3..b4fcc9a3b4c80 100644 --- a/services/repository/create_test.go +++ b/services/repository/create_test.go @@ -1,7 +1,7 @@ // Copyright 2023 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package repository +package repository_test import ( "fmt" @@ -11,9 +11,12 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" + repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/structs" + org_service "code.gitea.io/gitea/services/org" + repo_service "code.gitea.io/gitea/services/repository" "github.com/stretchr/testify/assert" ) @@ -23,12 +26,15 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { testTeamRepositories := func(teamID int64, repoIDs []int64) { team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - assert.NoError(t, team.LoadRepositories(db.DefaultContext), "%s: GetRepositories", team.Name) - assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name) - assert.Len(t, team.Repos, len(repoIDs), "%s: repo count", team.Name) + repos, err := repo_model.GetTeamRepositories(db.DefaultContext, &repo_model.SearchTeamRepoOptions{ + TeamID: team.ID, + }) + assert.NoError(t, err, "%s: GetRepositories", team.Name) + assert.Len(t, repos, team.NumRepos, "%s: len repo", team.Name) + assert.Len(t, repos, len(repoIDs), "%s: repo count", team.Name) for i, rid := range repoIDs { if rid > 0 { - assert.True(t, HasRepository(db.DefaultContext, team, rid), "%s: HasRepository(%d) %d", rid, i) + assert.True(t, repo_service.HasRepository(db.DefaultContext, team, rid), "%s: HasRepository(%d) %d", rid, i) } } } @@ -54,7 +60,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { // Create repos. repoIDs := make([]int64, 0) for i := 0; i < 3; i++ { - r, err := CreateRepositoryDirectly(db.DefaultContext, user, org.AsUser(), CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) + r, err := repo_service.CreateRepositoryDirectly(db.DefaultContext, user, org.AsUser(), repo_service.CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}) assert.NoError(t, err, "CreateRepository %d", i) if r != nil { repoIDs = append(repoIDs, r.ID) @@ -116,7 +122,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { } // Create repo and check teams repositories. - r, err := CreateRepositoryDirectly(db.DefaultContext, user, org.AsUser(), CreateRepoOptions{Name: "repo-last"}) + r, err := repo_service.CreateRepositoryDirectly(db.DefaultContext, user, org.AsUser(), repo_service.CreateRepoOptions{Name: "repo-last"}) assert.NoError(t, err, "CreateRepository last") if r != nil { repoIDs = append(repoIDs, r.ID) @@ -129,7 +135,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { } // Remove repo and check teams repositories. - assert.NoError(t, DeleteRepositoryDirectly(db.DefaultContext, user, repoIDs[0]), "DeleteRepository") + assert.NoError(t, repo_service.DeleteRepositoryDirectly(db.DefaultContext, user, repoIDs[0]), "DeleteRepository") teamRepos[0] = repoIDs[1:] teamRepos[1] = repoIDs[1:] teamRepos[3] = repoIDs[1:3] @@ -141,8 +147,8 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { // Wipe created items. for i, rid := range repoIDs { if i > 0 { // first repo already deleted. - assert.NoError(t, DeleteRepositoryDirectly(db.DefaultContext, user, rid), "DeleteRepository %d", i) + assert.NoError(t, repo_service.DeleteRepositoryDirectly(db.DefaultContext, user, rid), "DeleteRepository %d", i) } } - assert.NoError(t, organization.DeleteOrganization(db.DefaultContext, org), "DeleteOrganization") + assert.NoError(t, org_service.DeleteOrganization(db.DefaultContext, org, false), "DeleteOrganization") } From 728a6428c7c939205cd8e0a19f60e246f2ff5f98 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 16 Nov 2024 18:36:55 -0800 Subject: [PATCH 5/5] Move RepoTransfer into models/repo sub package --- models/error.go | 42 ------------ models/{repo_transfer.go => repo/transfer.go} | 66 +++++++++++++++---- routers/api/v1/repo/transfer.go | 7 +- routers/web/repo/repo.go | 3 +- routers/web/repo/setting/setting.go | 6 +- services/context/repo.go | 3 +- services/convert/repository.go | 7 +- services/repository/transfer.go | 8 +-- services/repository/transfer_test.go | 17 +++-- services/user/block.go | 3 +- tests/integration/api_user_block_test.go | 3 +- 11 files changed, 79 insertions(+), 86 deletions(-) rename models/{repo_transfer.go => repo/transfer.go} (73%) diff --git a/models/error.go b/models/error.go index 75c53245de5ae..865d5a442f66e 100644 --- a/models/error.go +++ b/models/error.go @@ -72,48 +72,6 @@ func (err ErrDeleteLastAdminUser) Error() string { return fmt.Sprintf("can not delete the last admin user [uid: %d]", err.UID) } -// ErrNoPendingRepoTransfer is an error type for repositories without a pending -// transfer request -type ErrNoPendingRepoTransfer struct { - RepoID int64 -} - -func (err ErrNoPendingRepoTransfer) Error() string { - return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", err.RepoID) -} - -// IsErrNoPendingTransfer is an error type when a repository has no pending -// transfers -func IsErrNoPendingTransfer(err error) bool { - _, ok := err.(ErrNoPendingRepoTransfer) - return ok -} - -func (err ErrNoPendingRepoTransfer) Unwrap() error { - return util.ErrNotExist -} - -// ErrRepoTransferInProgress represents the state of a repository that has an -// ongoing transfer -type ErrRepoTransferInProgress struct { - Uname string - Name string -} - -// IsErrRepoTransferInProgress checks if an error is a ErrRepoTransferInProgress. -func IsErrRepoTransferInProgress(err error) bool { - _, ok := err.(ErrRepoTransferInProgress) - return ok -} - -func (err ErrRepoTransferInProgress) Error() string { - return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name) -} - -func (err ErrRepoTransferInProgress) Unwrap() error { - return util.ErrAlreadyExist -} - // ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error. type ErrInvalidCloneAddr struct { Host string diff --git a/models/repo_transfer.go b/models/repo/transfer.go similarity index 73% rename from models/repo_transfer.go rename to models/repo/transfer.go index 37f591f65dcc2..43e15b33bcfc1 100644 --- a/models/repo_transfer.go +++ b/models/repo/transfer.go @@ -1,7 +1,7 @@ // Copyright 2021 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package models +package repo import ( "context" @@ -10,16 +10,58 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" - repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) +// ErrNoPendingRepoTransfer is an error type for repositories without a pending +// transfer request +type ErrNoPendingRepoTransfer struct { + RepoID int64 +} + +func (err ErrNoPendingRepoTransfer) Error() string { + return fmt.Sprintf("repository doesn't have a pending transfer [repo_id: %d]", err.RepoID) +} + +// IsErrNoPendingTransfer is an error type when a repository has no pending +// transfers +func IsErrNoPendingTransfer(err error) bool { + _, ok := err.(ErrNoPendingRepoTransfer) + return ok +} + +func (err ErrNoPendingRepoTransfer) Unwrap() error { + return util.ErrNotExist +} + +// ErrRepoTransferInProgress represents the state of a repository that has an +// ongoing transfer +type ErrRepoTransferInProgress struct { + Uname string + Name string +} + +// IsErrRepoTransferInProgress checks if an error is a ErrRepoTransferInProgress. +func IsErrRepoTransferInProgress(err error) bool { + _, ok := err.(ErrRepoTransferInProgress) + return ok +} + +func (err ErrRepoTransferInProgress) Error() string { + return fmt.Sprintf("repository is already being transferred [uname: %s, name: %s]", err.Uname, err.Name) +} + +func (err ErrRepoTransferInProgress) Unwrap() error { + return util.ErrAlreadyExist +} + // RepoTransfer is used to manage repository transfers -type RepoTransfer struct { +type RepoTransfer struct { //nolint ID int64 `xorm:"pk autoincr"` DoerID int64 Doer *user_model.User `xorm:"-"` @@ -126,7 +168,7 @@ func GetPendingRepositoryTransfers(ctx context.Context, opts *PendingRepositoryT // GetPendingRepositoryTransfer fetches the most recent and ongoing transfer // process for the repository -func GetPendingRepositoryTransfer(ctx context.Context, repo *repo_model.Repository) (*RepoTransfer, error) { +func GetPendingRepositoryTransfer(ctx context.Context, repo *Repository) (*RepoTransfer, error) { transfers, err := GetPendingRepositoryTransfers(ctx, &PendingRepositoryTransferOptions{RepoID: repo.ID}) if err != nil { return nil, err @@ -145,11 +187,11 @@ func DeleteRepositoryTransfer(ctx context.Context, repoID int64) error { } // TestRepositoryReadyForTransfer make sure repo is ready to transfer -func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error { +func TestRepositoryReadyForTransfer(status RepositoryStatus) error { switch status { - case repo_model.RepositoryBeingMigrated: + case RepositoryBeingMigrated: return errors.New("repo is not ready, currently migrating") - case repo_model.RepositoryPendingTransfer: + case RepositoryPendingTransfer: return ErrRepoTransferInProgress{} } return nil @@ -159,7 +201,7 @@ func TestRepositoryReadyForTransfer(status repo_model.RepositoryStatus) error { // it marks the repository transfer as "pending" func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repoID int64, teams []*organization.Team) error { return db.WithTx(ctx, func(ctx context.Context) error { - repo, err := repo_model.GetRepositoryByID(ctx, repoID) + repo, err := GetRepositoryByID(ctx, repoID) if err != nil { return err } @@ -169,16 +211,16 @@ func CreatePendingRepositoryTransfer(ctx context.Context, doer, newOwner *user_m return err } - repo.Status = repo_model.RepositoryPendingTransfer - if err := repo_model.UpdateRepositoryCols(ctx, repo, "status"); err != nil { + repo.Status = RepositoryPendingTransfer + if err := UpdateRepositoryCols(ctx, repo, "status"); err != nil { return err } // Check if new owner has repository with same name. - if has, err := repo_model.IsRepositoryModelExist(ctx, newOwner, repo.Name); err != nil { + if has, err := IsRepositoryModelExist(ctx, newOwner, repo.Name); err != nil { return fmt.Errorf("IsRepositoryExist: %w", err) } else if has { - return repo_model.ErrRepoAlreadyExist{ + return ErrRepoAlreadyExist{ Uname: newOwner.LowerName, Name: repo.Name, } diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index 776b336761ff8..787ec34404f0e 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -8,7 +8,6 @@ import ( "fmt" "net/http" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -108,7 +107,7 @@ func Transfer(ctx *context.APIContext) { oldFullname := ctx.Repo.Repository.FullName() if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, ctx.Repo.Repository, teams); err != nil { - if models.IsErrRepoTransferInProgress(err) { + if repo_model.IsErrRepoTransferInProgress(err) { ctx.Error(http.StatusConflict, "StartRepositoryTransfer", err) return } @@ -213,9 +212,9 @@ func RejectTransfer(ctx *context.APIContext) { } func acceptOrRejectRepoTransfer(ctx *context.APIContext, accept bool) error { - repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) + repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) if err != nil { - if models.IsErrNoPendingTransfer(err) { + if repo_model.IsErrNoPendingTransfer(err) { ctx.NotFound() return nil } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index be6f2d483ff31..ce699f5ab6c94 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -11,7 +11,6 @@ import ( "slices" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/organization" @@ -375,7 +374,7 @@ func Action(ctx *context.Context) { } func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error { - repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) + repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) if err != nil { return err } diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 485bd927fa932..e70b00e85d506 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -787,7 +787,7 @@ func SettingsPost(ctx *context.Context) { if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, repo, nil); err != nil { if repo_model.IsErrRepoAlreadyExist(err) { ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil) - } else if models.IsErrRepoTransferInProgress(err) { + } else if repo_model.IsErrRepoTransferInProgress(err) { ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil) } else if errors.Is(err, user_model.ErrBlockedUser) { ctx.RenderWithErr(ctx.Tr("repo.settings.transfer.blocked_user"), tplSettingsOptions, nil) @@ -813,9 +813,9 @@ func SettingsPost(ctx *context.Context) { return } - repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) + repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) if err != nil { - if models.IsErrNoPendingTransfer(err) { + if repo_model.IsErrNoPendingTransfer(err) { ctx.Flash.Error("repo.settings.transfer_abort_invalid") ctx.Redirect(repo.Link() + "/settings") } else { diff --git a/services/context/repo.go b/services/context/repo.go index e7b32d62832d4..31648f711de52 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -14,7 +14,6 @@ import ( "path" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" @@ -725,7 +724,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc { ctx.Data["PullRequestCtx"] = ctx.Repo.PullRequest if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer { - repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) + repoTransfer, err := repo_model.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository) if err != nil { ctx.ServerError("GetPendingRepositoryTransfer", err) return cancel diff --git a/services/convert/repository.go b/services/convert/repository.go index e026d0f4405f4..88ccd88fcfec6 100644 --- a/services/convert/repository.go +++ b/services/convert/repository.go @@ -7,7 +7,6 @@ import ( "context" "time" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/perm" access_model "code.gitea.io/gitea/models/perm/access" @@ -158,8 +157,8 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR var transfer *api.RepoTransfer if repo.Status == repo_model.RepositoryPendingTransfer { - t, err := models.GetPendingRepositoryTransfer(ctx, repo) - if err != nil && !models.IsErrNoPendingTransfer(err) { + t, err := repo_model.GetPendingRepositoryTransfer(ctx, repo) + if err != nil && !repo_model.IsErrNoPendingTransfer(err) { log.Warn("GetPendingRepositoryTransfer: %v", err) } else { if err := t.LoadAttributes(ctx); err != nil { @@ -248,7 +247,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR } // ToRepoTransfer convert a models.RepoTransfer to a structs.RepeTransfer -func ToRepoTransfer(ctx context.Context, t *models.RepoTransfer) *api.RepoTransfer { +func ToRepoTransfer(ctx context.Context, t *repo_model.RepoTransfer) *api.RepoTransfer { teams, _ := ToTeams(ctx, t.Teams, false) return &api.RepoTransfer{ diff --git a/services/repository/transfer.go b/services/repository/transfer.go index 301d89533781d..2bbc5dce49ea9 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -285,7 +285,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName wikiRenamed = true } - if err := models.DeleteRepositoryTransfer(ctx, repo.ID); err != nil { + if err := repo_model.DeleteRepositoryTransfer(ctx, repo.ID); err != nil { return fmt.Errorf("deleteRepositoryTransfer: %w", err) } repo.Status = repo_model.RepositoryReady @@ -388,7 +388,7 @@ func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo // StartRepositoryTransfer transfer a repo from one owner to a new one. // it make repository into pending transfer state, if doer can not create repo for new owner. func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository, teams []*organization.Team) error { - if err := models.TestRepositoryReadyForTransfer(repo.Status); err != nil { + if err := repo_model.TestRepositoryReadyForTransfer(repo.Status); err != nil { return err } @@ -425,7 +425,7 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use // Make repo as pending for transfer repo.Status = repo_model.RepositoryPendingTransfer - if err := models.CreatePendingRepositoryTransfer(ctx, doer, newOwner, repo.ID, teams); err != nil { + if err := repo_model.CreatePendingRepositoryTransfer(ctx, doer, newOwner, repo.ID, teams); err != nil { return err } @@ -449,7 +449,7 @@ func CancelRepositoryTransfer(ctx context.Context, repo *repo_model.Repository) return err } - if err := models.DeleteRepositoryTransfer(ctx, repo.ID); err != nil { + if err := repo_model.DeleteRepositoryTransfer(ctx, repo.ID); err != nil { return err } diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go index 67799eddcc361..7e987d665eefb 100644 --- a/services/repository/transfer_test.go +++ b/services/repository/transfer_test.go @@ -7,7 +7,6 @@ import ( "sync" "testing" - "code.gitea.io/gitea/models" activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" @@ -86,23 +85,23 @@ func TestRepositoryTransfer(t *testing.T) { doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) - transfer, err := models.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err := repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) assert.NoError(t, err) assert.NotNil(t, transfer) // Cancel transfer assert.NoError(t, CancelRepositoryTransfer(db.DefaultContext, repo)) - transfer, err = models.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) assert.Error(t, err) assert.Nil(t, transfer) - assert.True(t, models.IsErrNoPendingTransfer(err)) + assert.True(t, repo_model.IsErrNoPendingTransfer(err)) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - assert.NoError(t, models.CreatePendingRepositoryTransfer(db.DefaultContext, doer, user2, repo.ID, nil)) + assert.NoError(t, repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, user2, repo.ID, nil)) - transfer, err = models.GetPendingRepositoryTransfer(db.DefaultContext, repo) + transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) assert.Nil(t, err) assert.NoError(t, transfer.LoadAttributes(db.DefaultContext)) assert.Equal(t, "user2", transfer.Recipient.Name) @@ -110,12 +109,12 @@ func TestRepositoryTransfer(t *testing.T) { org6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // Only transfer can be started at any given time - err = models.CreatePendingRepositoryTransfer(db.DefaultContext, doer, org6, repo.ID, nil) + err = repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, org6, repo.ID, nil) assert.Error(t, err) - assert.True(t, models.IsErrRepoTransferInProgress(err)) + assert.True(t, repo_model.IsErrRepoTransferInProgress(err)) // Unknown user - err = models.CreatePendingRepositoryTransfer(db.DefaultContext, doer, &user_model.User{ID: 1000, LowerName: "user1000"}, repo.ID, nil) + err = repo_model.CreatePendingRepositoryTransfer(db.DefaultContext, doer, &user_model.User{ID: 1000, LowerName: "user1000"}, repo.ID, nil) assert.Error(t, err) // Cancel transfer diff --git a/services/user/block.go b/services/user/block.go index 0b3b618aae670..c24ce5273ca69 100644 --- a/services/user/block.go +++ b/services/user/block.go @@ -6,7 +6,6 @@ package user import ( "context" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" org_model "code.gitea.io/gitea/models/organization" @@ -194,7 +193,7 @@ func unwatchRepos(ctx context.Context, watcher, repoOwner *user_model.User) erro } func cancelRepositoryTransfers(ctx context.Context, sender, recipient *user_model.User) error { - transfers, err := models.GetPendingRepositoryTransfers(ctx, &models.PendingRepositoryTransferOptions{ + transfers, err := repo_model.GetPendingRepositoryTransfers(ctx, &repo_model.PendingRepositoryTransferOptions{ SenderID: sender.ID, RecipientID: recipient.ID, }) diff --git a/tests/integration/api_user_block_test.go b/tests/integration/api_user_block_test.go index 2cc3895a71dc7..ae6b9eb849645 100644 --- a/tests/integration/api_user_block_test.go +++ b/tests/integration/api_user_block_test.go @@ -8,7 +8,6 @@ import ( "net/http" "testing" - "code.gitea.io/gitea/models" auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" @@ -42,7 +41,7 @@ func TestBlockUser(t *testing.T) { } countRepositoryTransfers := func(t *testing.T, senderID, recipientID int64) int64 { - transfers, err := models.GetPendingRepositoryTransfers(db.DefaultContext, &models.PendingRepositoryTransferOptions{ + transfers, err := repo_model.GetPendingRepositoryTransfers(db.DefaultContext, &repo_model.PendingRepositoryTransferOptions{ SenderID: senderID, RecipientID: recipientID, })