mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-30 19:15:23 +01:00 
			
		
		
		
	Move RepoTransfer from models to models/repo sub package (#32506)
`RepoTransfer` now is at models, but if we want to move it into `repo` model, it will depend on `Team`. So this PR also makes repo model depend on org model to make it possible. Just refactor, no code change. - [x] Move `DeleteOrganization` from `models/organization` to service layer - [x] Move `AccessibleTeamReposEnv` to `models/repo` - [x] Move `RepoTransfer` from `models` to `models/repo` - [x] Merge `getUserTeamIDs` and `GetUserTeamIDs`, Merge `GetUserTeams` and `getUserTeams`. - [x] Remove `Team`'s `Repos []*repo_model.Repository` to avoid dependency recycle.
This commit is contained in:
		
							parent
							
								
									b945742293
								
							
						
					
					
						commit
						e4c4629465
					
				| @ -511,7 +511,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) | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -9,11 +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" | ||||
| 	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" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| @ -407,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 | ||||
| @ -604,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). | ||||
| @ -616,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"). | ||||
| @ -640,175 +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) | ||||
| } | ||||
| 
 | ||||
| // 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 | ||||
| } | ||||
|  | ||||
| @ -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) | ||||
| } | ||||
| @ -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) | ||||
|  | ||||
| @ -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{ | ||||
|  | ||||
| @ -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) | ||||
| } | ||||
|  | ||||
| @ -8,10 +8,7 @@ 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" | ||||
| ) | ||||
| 
 | ||||
| // TeamRepo represents an team-repository relation. | ||||
| @ -32,29 +29,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{ | ||||
|  | ||||
| @ -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}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										206
									
								
								models/repo/org_repo.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								models/repo/org_repo.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,206 @@ | ||||
| // Copyright 2022 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
| 
 | ||||
| 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" | ||||
| ) | ||||
| 
 | ||||
| // 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) | ||||
| } | ||||
| 
 | ||||
| // 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(&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) (RepositoryList, error) { | ||||
| 	repoIDs, err := env.RepoIDs(page, pageSize) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("GetUserRepositoryIDs: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	repos := make([]*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() (RepositoryList, error) { | ||||
| 	repoIDs, err := env.MirrorRepoIDs() | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("MirrorRepoIDs: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	repos := make([]*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 | ||||
| } | ||||
| @ -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, | ||||
| 			} | ||||
| @ -573,19 +573,19 @@ 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, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err) | ||||
| 		ctx.Error(http.StatusInternalServerError, "GetTeamRepositories", err) | ||||
| 		return | ||||
| 	} | ||||
| 	repos := make([]*api.Repository, len(teamRepos)) | ||||
| 	for i, repo := range teamRepos { | ||||
| 		permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) | ||||
| 		if err != nil { | ||||
| 			ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err) | ||||
| 			ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | ||||
| 			return | ||||
| 		} | ||||
| 		repos[i] = convert.ToRepo(ctx, repo, permission) | ||||
|  | ||||
| @ -42,7 +42,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 | ||||
|  | ||||
| @ -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 | ||||
| 		} | ||||
|  | ||||
| @ -410,11 +410,15 @@ func TeamRepositories(ctx *context.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if err := ctx.Org.Team.LoadRepositories(ctx); err != nil { | ||||
| 		ctx.ServerError("GetRepositories", err) | ||||
| 	repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ | ||||
| 		TeamID: ctx.Org.Team.ID, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("GetTeamRepositories", err) | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Data["Units"] = unit_model.Units | ||||
| 	ctx.Data["TeamRepos"] = repos | ||||
| 	ctx.HTML(http.StatusOK, tplTeamRepositories) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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" | ||||
| @ -378,7 +377,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 | ||||
| 	} | ||||
|  | ||||
| @ -32,7 +32,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 | ||||
|  | ||||
| @ -788,7 +788,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) | ||||
| @ -814,9 +814,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 { | ||||
|  | ||||
| @ -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" | ||||
| @ -709,7 +708,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 | ||||
|  | ||||
| @ -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{ | ||||
|  | ||||
| @ -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) | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -141,11 +141,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 { | ||||
| 			return fmt.Errorf("LoadRepositories: %w", err) | ||||
| 		repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ | ||||
| 			TeamID: t.ID, | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("GetTeamRepositories: %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) | ||||
| 			} | ||||
| @ -172,10 +175,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 | ||||
| 	} | ||||
| @ -301,8 +300,11 @@ 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 { | ||||
| 			log.Error("team.LoadRepositories failed: %v", err) | ||||
| 		repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ | ||||
| 			TeamID: team.ID, | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			log.Error("GetTeamRepositories failed: %v", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// FIXME: in the goroutine, it can't access the "ctx", it could only use db.DefaultContext at the moment | ||||
| @ -312,7 +314,7 @@ func AddTeamMember(ctx context.Context, team *organization.Team, user *user_mode | ||||
| 					log.Error("watch repo failed: %v", err) | ||||
| 				} | ||||
| 			} | ||||
| 		}(team.Repos) | ||||
| 		}(repos) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| @ -332,7 +334,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 | ||||
| 	} | ||||
| 
 | ||||
| @ -350,7 +355,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 | ||||
| 		} | ||||
|  | ||||
| @ -189,9 +189,12 @@ 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: GetTeamRepositories", 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, repo_service.HasRepository(db.DefaultContext, team, rid), "%s: HasRepository(%d) %d", rid, i) | ||||
| @ -310,5 +313,5 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { | ||||
| 			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, DeleteOrganization(db.DefaultContext, org, false), "DeleteOrganization") | ||||
| } | ||||
|  | ||||
| @ -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) | ||||
| 	} | ||||
|  | ||||
| @ -63,7 +63,7 @@ func addRepositoryToTeam(ctx context.Context, t *organization.Team, repo *repo_m | ||||
| // If the team already has some repositories they will be left unchanged. | ||||
| func AddAllRepositoriesToTeam(ctx context.Context, t *organization.Team) error { | ||||
| 	return db.WithTx(ctx, func(ctx context.Context) 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) | ||||
| 		} | ||||
| @ -103,8 +103,15 @@ func RemoveAllRepositoriesFromTeam(ctx context.Context, t *organization.Team) (e | ||||
| // Note: Shall not be called if team includes all repositories | ||||
| func removeAllRepositoriesFromTeam(ctx context.Context, t *organization.Team) (err error) { | ||||
| 	e := db.GetEngine(ctx) | ||||
| 	repos, err := repo_model.GetTeamRepositories(ctx, &repo_model.SearchTeamRepoOptions{ | ||||
| 		TeamID: t.ID, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("GetTeamRepositories: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	// 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 | ||||
| 		} | ||||
|  | ||||
| @ -9,7 +9,6 @@ import ( | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	issues_model "code.gitea.io/gitea/models/issues" | ||||
| 	"code.gitea.io/gitea/models/organization" | ||||
| @ -285,7 +284,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 +387,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 +424,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 +448,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 | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -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.NoError(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 | ||||
|  | ||||
| @ -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, | ||||
| 	}) | ||||
|  | ||||
| @ -27,7 +27,7 @@ | ||||
| 				{{end}} | ||||
| 				<div class="ui{{if not $canAddRemove}} top{{end}} attached segment"> | ||||
| 					<div class="flex-list"> | ||||
| 						{{range .Team.Repos}} | ||||
| 						{{range $.TeamRepos}} | ||||
| 							<div class="flex-item tw-items-center"> | ||||
| 								<div class="flex-item-leading"> | ||||
| 									{{template "repo/icon" .}} | ||||
|  | ||||
| @ -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, | ||||
| 		}) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user