mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Move access and repo permission to models/perm/access (#19350)
* Move access and repo permission to models/perm/access * Remove unnecessary code
This commit is contained in:
		| @@ -12,6 +12,8 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -205,7 +207,7 @@ func TestAPISearchRepo(t *testing.T) { | |||||||
| 					assert.Len(t, repoNames, expected.count) | 					assert.Len(t, repoNames, expected.count) | ||||||
| 					for _, repo := range body.Data { | 					for _, repo := range body.Data { | ||||||
| 						r := getRepo(t, repo.ID) | 						r := getRepo(t, repo.ID) | ||||||
| 						hasAccess, err := models.HasAccess(userID, r) | 						hasAccess, err := access_model.HasAccess(db.DefaultContext, userID, r) | ||||||
| 						assert.NoError(t, err, "Error when checking if User: %d has access to %s: %v", userID, repo.FullName, err) | 						assert.NoError(t, err, "Error when checking if User: %d has access to %s: %v", userID, repo.FullName, err) | ||||||
| 						assert.True(t, hasAccess, "User: %d does not have access to %s", userID, repo.FullName) | 						assert.True(t, hasAccess, "User: %d does not have access to %s", userID, repo.FullName) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -21,7 +22,7 @@ func assertUserDeleted(t *testing.T, userID int64) { | |||||||
| 	unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: userID}) | 	unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: userID}) | ||||||
| 	unittest.AssertNotExistsBean(t, &user_model.Follow{FollowID: userID}) | 	unittest.AssertNotExistsBean(t, &user_model.Follow{FollowID: userID}) | ||||||
| 	unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerID: userID}) | 	unittest.AssertNotExistsBean(t, &repo_model.Repository{OwnerID: userID}) | ||||||
| 	unittest.AssertNotExistsBean(t, &models.Access{UserID: userID}) | 	unittest.AssertNotExistsBean(t, &access_model.Access{UserID: userID}) | ||||||
| 	unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: userID}) | 	unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: userID}) | ||||||
| 	unittest.AssertNotExistsBean(t, &models.IssueUser{UID: userID}) | 	unittest.AssertNotExistsBean(t, &models.IssueUser{UID: userID}) | ||||||
| 	unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID}) | 	unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID}) | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -510,7 +511,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error { | |||||||
| 					permPR[i] = false | 					permPR[i] = false | ||||||
| 					continue | 					continue | ||||||
| 				} | 				} | ||||||
| 				perm, err := GetUserRepoPermission(ctx, repo, user) | 				perm, err := access_model.GetUserRepoPermission(ctx, repo, user) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					permCode[i] = false | 					permCode[i] = false | ||||||
| 					permIssue[i] = false | 					permIssue[i] = false | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -79,7 +80,7 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool { | |||||||
| 		} else if repo, err := repo_model.GetRepositoryByID(protectBranch.RepoID); err != nil { | 		} else if repo, err := repo_model.GetRepositoryByID(protectBranch.RepoID); err != nil { | ||||||
| 			log.Error("repo_model.GetRepositoryByID: %v", err) | 			log.Error("repo_model.GetRepositoryByID: %v", err) | ||||||
| 			return false | 			return false | ||||||
| 		} else if writeAccess, err := HasAccessUnit(user, repo, unit.TypeCode, perm.AccessModeWrite); err != nil { | 		} else if writeAccess, err := access_model.HasAccessUnit(db.DefaultContext, user, repo, unit.TypeCode, perm.AccessModeWrite); err != nil { | ||||||
| 			log.Error("HasAccessUnit: %v", err) | 			log.Error("HasAccessUnit: %v", err) | ||||||
| 			return false | 			return false | ||||||
| 		} else { | 		} else { | ||||||
| @@ -104,7 +105,7 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| // IsUserMergeWhitelisted checks if some user is whitelisted to merge to this branch | // IsUserMergeWhitelisted checks if some user is whitelisted to merge to this branch | ||||||
| func IsUserMergeWhitelisted(ctx context.Context, protectBranch *ProtectedBranch, userID int64, permissionInRepo Permission) bool { | func IsUserMergeWhitelisted(ctx context.Context, protectBranch *ProtectedBranch, userID int64, permissionInRepo access_model.Permission) bool { | ||||||
| 	if !protectBranch.EnableMergeWhitelist { | 	if !protectBranch.EnableMergeWhitelist { | ||||||
| 		// Then we need to fall back on whether the user has write permission | 		// Then we need to fall back on whether the user has write permission | ||||||
| 		return permissionInRepo.CanWrite(unit.TypeCode) | 		return permissionInRepo.CanWrite(unit.TypeCode) | ||||||
| @@ -139,7 +140,7 @@ func isUserOfficialReviewer(ctx context.Context, protectBranch *ProtectedBranch, | |||||||
|  |  | ||||||
| 	if !protectBranch.EnableApprovalsWhitelist { | 	if !protectBranch.EnableApprovalsWhitelist { | ||||||
| 		// Anyone with write access is considered official reviewer | 		// Anyone with write access is considered official reviewer | ||||||
| 		writeAccess, err := hasAccessUnit(ctx, user, repo, unit.TypeCode, perm.AccessModeWrite) | 		writeAccess, err := access_model.HasAccessUnit(ctx, user, repo, unit.TypeCode, perm.AccessModeWrite) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return false, err | 			return false, err | ||||||
| 		} | 		} | ||||||
| @@ -424,7 +425,7 @@ func updateApprovalWhitelist(ctx context.Context, repo *repo_model.Repository, c | |||||||
|  |  | ||||||
| 	whitelist = make([]int64, 0, len(newWhitelist)) | 	whitelist = make([]int64, 0, len(newWhitelist)) | ||||||
| 	for _, userID := range newWhitelist { | 	for _, userID := range newWhitelist { | ||||||
| 		if reader, err := IsRepoReader(ctx, repo, userID); err != nil { | 		if reader, err := access_model.IsRepoReader(ctx, repo, userID); err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} else if !reader { | 		} else if !reader { | ||||||
| 			continue | 			continue | ||||||
| @@ -449,7 +450,7 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) | 			return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) | ||||||
| 		} | 		} | ||||||
| 		perm, err := GetUserRepoPermission(ctx, repo, user) | 		perm, err := access_model.GetUserRepoPermission(ctx, repo, user) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, fmt.Errorf("GetUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) | 			return nil, fmt.Errorf("GetUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -22,14 +23,14 @@ func GetYamlFixturesAccess() (string, error) { | |||||||
|  |  | ||||||
| 	for _, repo := range repos { | 	for _, repo := range repos { | ||||||
| 		repo.MustOwner() | 		repo.MustOwner() | ||||||
| 		if err := RecalculateAccesses(repo); err != nil { | 		if err := access_model.RecalculateAccesses(db.DefaultContext, repo); err != nil { | ||||||
| 			return "", err | 			return "", err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var b strings.Builder | 	var b strings.Builder | ||||||
|  |  | ||||||
| 	accesses := make([]*Access, 0, 200) | 	accesses := make([]*access_model.Access, 0, 200) | ||||||
| 	if err := db.GetEngine(db.DefaultContext).OrderBy("user_id, repo_id").Find(&accesses); err != nil { | 	if err := db.GetEngine(db.DefaultContext).OrderBy("user_id, repo_id").Find(&accesses); err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ import ( | |||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	project_model "code.gitea.io/gitea/models/project" | 	project_model "code.gitea.io/gitea/models/project" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| @@ -489,7 +490,7 @@ func ClearIssueLabels(issue *Issue, doer *user_model.User) (err error) { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	perm, err := GetUserRepoPermission(ctx, issue.Repo, doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -2314,7 +2315,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		// Normal users must have read access to the referencing issue | 		// Normal users must have read access to the referencing issue | ||||||
| 		perm, err := GetUserRepoPermission(ctx, issue.Repo, user) | 		perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, user) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, fmt.Errorf("GetUserRepoPermission [%d]: %v", user.ID, err) | 			return nil, fmt.Errorf("GetUserRepoPermission [%d]: %v", user.ID, err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -215,7 +216,7 @@ func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossRefe | |||||||
|  |  | ||||||
| 	// Check doer permissions; set action to None if the doer can't change the destination | 	// Check doer permissions; set action to None if the doer can't change the destination | ||||||
| 	if refIssue.RepoID != ctx.OrigIssue.RepoID || ref.Action != references.XRefActionNone { | 	if refIssue.RepoID != ctx.OrigIssue.RepoID || ref.Action != references.XRefActionNone { | ||||||
| 		perm, err := GetUserRepoPermission(stdCtx, refIssue.Repo, ctx.Doer) | 		perm, err := access_model.GetUserRepoPermission(stdCtx, refIssue.Repo, ctx.Doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, references.XRefActionNone, err | 			return nil, references.XRefActionNone, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -171,7 +172,7 @@ func CheckLFSAccessForRepo(ctx context.Context, ownerID int64, repo *repo_model. | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	perm, err := GetUserRepoPermission(ctx, repo, u) | 	perm, err := access_model.GetUserRepoPermission(ctx, repo, u) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  |  | ||||||
| @@ -142,7 +143,7 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error { | |||||||
| 		if _, err = sess. | 		if _, err = sess. | ||||||
| 			Where("user_id = ?", userID). | 			Where("user_id = ?", userID). | ||||||
| 			In("repo_id", repoIDs). | 			In("repo_id", repoIDs). | ||||||
| 			Delete(new(Access)); err != nil { | 			Delete(new(access_model.Access)); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -33,7 +34,7 @@ func addRepository(ctx context.Context, t *organization.Team, repo *repo_model.R | |||||||
|  |  | ||||||
| 	t.NumRepos++ | 	t.NumRepos++ | ||||||
|  |  | ||||||
| 	if err = recalculateTeamAccesses(ctx, repo, 0); err != nil { | 	if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil { | ||||||
| 		return fmt.Errorf("recalculateAccesses: %v", err) | 		return fmt.Errorf("recalculateAccesses: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -62,7 +63,7 @@ func addAllRepositories(ctx context.Context, t *organization.Team) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, repo := range orgRepos { | 	for _, repo := range orgRepos { | ||||||
| 		if !hasRepository(ctx, t, repo.ID) { | 		if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repo.ID) { | ||||||
| 			if err := addRepository(ctx, t, &repo); err != nil { | 			if err := addRepository(ctx, t, &repo); err != nil { | ||||||
| 				return fmt.Errorf("addRepository: %v", err) | 				return fmt.Errorf("addRepository: %v", err) | ||||||
| 			} | 			} | ||||||
| @@ -108,11 +109,6 @@ func AddRepository(t *organization.Team, repo *repo_model.Repository) (err error | |||||||
| 	return committer.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // HasRepository returns true if given repository belong to team. |  | ||||||
| func HasRepository(t *organization.Team, repoID int64) bool { |  | ||||||
| 	return hasRepository(db.DefaultContext, t, repoID) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // RemoveAllRepositories removes all repositories from team and recalculates access | // RemoveAllRepositories removes all repositories from team and recalculates access | ||||||
| func RemoveAllRepositories(t *organization.Team) (err error) { | func RemoveAllRepositories(t *organization.Team) (err error) { | ||||||
| 	if t.IncludesAllRepositories { | 	if t.IncludesAllRepositories { | ||||||
| @@ -138,13 +134,13 @@ func removeAllRepositories(ctx context.Context, t *organization.Team) (err error | |||||||
| 	e := db.GetEngine(ctx) | 	e := db.GetEngine(ctx) | ||||||
| 	// Delete all accesses. | 	// Delete all accesses. | ||||||
| 	for _, repo := range t.Repos { | 	for _, repo := range t.Repos { | ||||||
| 		if err := recalculateTeamAccesses(ctx, repo, t.ID); err != nil { | 		if err := access_model.RecalculateTeamAccesses(ctx, repo, t.ID); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Remove watches from all users and now unaccessible repos | 		// Remove watches from all users and now unaccessible repos | ||||||
| 		for _, user := range t.Members { | 		for _, user := range t.Members { | ||||||
| 			has, err := hasAccess(ctx, user.ID, repo) | 			has, err := access_model.HasAccess(ctx, user.ID, repo) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} else if has { | 			} else if has { | ||||||
| @@ -177,8 +173,9 @@ func removeAllRepositories(ctx context.Context, t *organization.Team) (err error | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func hasRepository(ctx context.Context, t *organization.Team, repoID int64) bool { | // HasRepository returns true if given repository belong to team. | ||||||
| 	return organization.HasTeamRepo(ctx, t.OrgID, t.ID, repoID) | func HasRepository(t *organization.Team, repoID int64) bool { | ||||||
|  | 	return organization.HasTeamRepo(db.DefaultContext, t.OrgID, t.ID, repoID) | ||||||
| } | } | ||||||
|  |  | ||||||
| // removeRepository removes a repository from a team and recalculates access | // removeRepository removes a repository from a team and recalculates access | ||||||
| @@ -196,7 +193,7 @@ func removeRepository(ctx context.Context, t *organization.Team, repo *repo_mode | |||||||
|  |  | ||||||
| 	// Don't need to recalculate when delete a repository from organization. | 	// Don't need to recalculate when delete a repository from organization. | ||||||
| 	if recalculate { | 	if recalculate { | ||||||
| 		if err = recalculateTeamAccesses(ctx, repo, t.ID); err != nil { | 		if err = access_model.RecalculateTeamAccesses(ctx, repo, t.ID); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -206,7 +203,7 @@ func removeRepository(ctx context.Context, t *organization.Team, repo *repo_mode | |||||||
| 		return fmt.Errorf("getTeamUsersByTeamID: %v", err) | 		return fmt.Errorf("getTeamUsersByTeamID: %v", err) | ||||||
| 	} | 	} | ||||||
| 	for _, teamUser := range teamUsers { | 	for _, teamUser := range teamUsers { | ||||||
| 		has, err := hasAccess(ctx, teamUser.UID, repo) | 		has, err := access_model.HasAccess(ctx, teamUser.UID, repo) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} else if has { | 		} else if has { | ||||||
| @@ -378,7 +375,7 @@ func UpdateTeam(t *organization.Team, authChanged, includeAllChanged bool) (err | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		for _, repo := range t.Repos { | 		for _, repo := range t.Repos { | ||||||
| 			if err = recalculateTeamAccesses(ctx, repo, 0); err != nil { | 			if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil { | ||||||
| 				return fmt.Errorf("recalculateTeamAccesses: %v", err) | 				return fmt.Errorf("recalculateTeamAccesses: %v", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -522,7 +519,7 @@ func AddTeamMember(team *organization.Team, userID int64) error { | |||||||
| 		In("repo_id", subQuery). | 		In("repo_id", subQuery). | ||||||
| 		And("mode < ?", team.AccessMode). | 		And("mode < ?", team.AccessMode). | ||||||
| 		SetExpr("mode", team.AccessMode). | 		SetExpr("mode", team.AccessMode). | ||||||
| 		Update(new(Access)); err != nil { | 		Update(new(access_model.Access)); err != nil { | ||||||
| 		return fmt.Errorf("update user accesses: %v", err) | 		return fmt.Errorf("update user accesses: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -533,9 +530,9 @@ func AddTeamMember(team *organization.Team, userID int64) error { | |||||||
| 		return fmt.Errorf("select id accesses: %v", err) | 		return fmt.Errorf("select id accesses: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	accesses := make([]*Access, 0, 100) | 	accesses := make([]*access_model.Access, 0, 100) | ||||||
| 	for i, repoID := range repoIDs { | 	for i, repoID := range repoIDs { | ||||||
| 		accesses = append(accesses, &Access{RepoID: repoID, UserID: userID, Mode: team.AccessMode}) | 		accesses = append(accesses, &access_model.Access{RepoID: repoID, UserID: userID, Mode: team.AccessMode}) | ||||||
| 		if (i%100 == 0 || i == len(repoIDs)-1) && len(accesses) > 0 { | 		if (i%100 == 0 || i == len(repoIDs)-1) && len(accesses) > 0 { | ||||||
| 			if err = db.Insert(ctx, accesses); err != nil { | 			if err = db.Insert(ctx, accesses); err != nil { | ||||||
| 				return fmt.Errorf("insert new user accesses: %v", err) | 				return fmt.Errorf("insert new user accesses: %v", err) | ||||||
| @@ -595,7 +592,7 @@ func removeTeamMember(ctx context.Context, team *organization.Team, userID int64 | |||||||
|  |  | ||||||
| 	// Delete access to team repositories. | 	// Delete access to team repositories. | ||||||
| 	for _, repo := range team.Repos { | 	for _, repo := range team.Repos { | ||||||
| 		if err := recalculateUserAccess(ctx, repo, userID); err != nil { | 		if err := access_model.RecalculateUserAccess(ctx, repo, userID); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -129,7 +130,7 @@ func TestUpdateTeam(t *testing.T) { | |||||||
| 	team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"}).(*organization.Team) | 	team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"}).(*organization.Team) | ||||||
| 	assert.True(t, strings.HasPrefix(team.Description, "A long description!")) | 	assert.True(t, strings.HasPrefix(team.Description, "A long description!")) | ||||||
|  |  | ||||||
| 	access := unittest.AssertExistsAndLoadBean(t, &Access{UserID: 4, RepoID: 3}).(*Access) | 	access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3}).(*access_model.Access) | ||||||
| 	assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) | 	assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) | ||||||
|  |  | ||||||
| 	unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) | 	unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) | ||||||
| @@ -161,7 +162,7 @@ func TestDeleteTeam(t *testing.T) { | |||||||
| 	// check that team members don't have "leftover" access to repos | 	// check that team members don't have "leftover" access to repos | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | ||||||
| 	accessMode, err := AccessLevel(user, repo) | 	accessMode, err := access_model.AccessLevel(user, repo) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, accessMode < perm.AccessModeWrite) | 	assert.True(t, accessMode < perm.AccessModeWrite) | ||||||
| } | } | ||||||
| @@ -198,3 +199,21 @@ func TestRemoveTeamMember(t *testing.T) { | |||||||
| 	err := RemoveTeamMember(team, 2) | 	err := RemoveTeamMember(team, 2) | ||||||
| 	assert.True(t, organization.IsErrLastOrgOwner(err)) | 	assert.True(t, organization.IsErrLastOrgOwner(err)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestRepository_RecalculateAccesses3(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  | 	team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team) | ||||||
|  | 	user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}).(*user_model.User) | ||||||
|  |  | ||||||
|  | 	has, err := db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23}) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.False(t, has) | ||||||
|  |  | ||||||
|  | 	// adding user29 to team5 should add an explicit access row for repo 23 | ||||||
|  | 	// even though repo 23 is public | ||||||
|  | 	assert.NoError(t, AddTeamMember(team5, user29.ID)) | ||||||
|  |  | ||||||
|  | 	has, err = db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23}) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.True(t, has) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package access | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -118,8 +118,8 @@ func refreshAccesses(e db.Engine, repo *repo_model.Repository, accessMap map[int | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // refreshCollaboratorAccesses retrieves repository collaborations with their access modes. | // refreshCollaboratorAccesses retrieves repository collaborations with their access modes. | ||||||
| func refreshCollaboratorAccesses(e db.Engine, repoID int64, accessMap map[int64]*userAccess) error { | func refreshCollaboratorAccesses(ctx context.Context, repoID int64, accessMap map[int64]*userAccess) error { | ||||||
| 	collaborators, err := getCollaborators(e, repoID, db.ListOptions{}) | 	collaborators, err := repo_model.GetCollaborators(ctx, repoID, db.ListOptions{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("getCollaborations: %v", err) | 		return fmt.Errorf("getCollaborations: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -132,10 +132,10 @@ func refreshCollaboratorAccesses(e db.Engine, repoID int64, accessMap map[int64] | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // recalculateTeamAccesses recalculates new accesses for teams of an organization | // RecalculateTeamAccesses recalculates new accesses for teams of an organization | ||||||
| // except the team whose ID is given. It is used to assign a team ID when | // except the team whose ID is given. It is used to assign a team ID when | ||||||
| // remove repository from that team. | // remove repository from that team. | ||||||
| func recalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, ignTeamID int64) (err error) { | func RecalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, ignTeamID int64) (err error) { | ||||||
| 	accessMap := make(map[int64]*userAccess, 20) | 	accessMap := make(map[int64]*userAccess, 20) | ||||||
| 
 | 
 | ||||||
| 	if err = repo.GetOwner(ctx); err != nil { | 	if err = repo.GetOwner(ctx); err != nil { | ||||||
| @@ -146,7 +146,7 @@ func recalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, i | |||||||
| 
 | 
 | ||||||
| 	e := db.GetEngine(ctx) | 	e := db.GetEngine(ctx) | ||||||
| 
 | 
 | ||||||
| 	if err = refreshCollaboratorAccesses(e, repo.ID, accessMap); err != nil { | 	if err = refreshCollaboratorAccesses(ctx, repo.ID, accessMap); err != nil { | ||||||
| 		return fmt.Errorf("refreshCollaboratorAccesses: %v", err) | 		return fmt.Errorf("refreshCollaboratorAccesses: %v", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @@ -164,7 +164,7 @@ func recalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, i | |||||||
| 		// have relations with repository. | 		// have relations with repository. | ||||||
| 		if t.IsOwnerTeam() { | 		if t.IsOwnerTeam() { | ||||||
| 			t.AccessMode = perm.AccessModeOwner | 			t.AccessMode = perm.AccessModeOwner | ||||||
| 		} else if !hasRepository(ctx, t, repo.ID) { | 		} else if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repo.ID) { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @@ -179,9 +179,9 @@ func recalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, i | |||||||
| 	return refreshAccesses(e, repo, accessMap) | 	return refreshAccesses(e, repo, accessMap) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // recalculateUserAccess recalculates new access for a single user | // RecalculateUserAccess recalculates new access for a single user | ||||||
| // Usable if we know access only affected one user | // Usable if we know access only affected one user | ||||||
| func recalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid int64) (err error) { | func RecalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid int64) (err error) { | ||||||
| 	minMode := perm.AccessModeRead | 	minMode := perm.AccessModeRead | ||||||
| 	if !repo.IsPrivate { | 	if !repo.IsPrivate { | ||||||
| 		minMode = perm.AccessModeWrite | 		minMode = perm.AccessModeWrite | ||||||
| @@ -189,7 +189,7 @@ func recalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid | |||||||
| 
 | 
 | ||||||
| 	accessMode := perm.AccessModeNone | 	accessMode := perm.AccessModeNone | ||||||
| 	e := db.GetEngine(ctx) | 	e := db.GetEngine(ctx) | ||||||
| 	collaborator, err := getCollaboration(e, repo.ID, uid) | 	collaborator, err := repo_model.GetCollaboration(ctx, repo.ID, uid) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else if collaborator != nil { | 	} else if collaborator != nil { | ||||||
| @@ -222,27 +222,23 @@ func recalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid | |||||||
| 	if _, err = e.Delete(&Access{RepoID: repo.ID, UserID: uid}); err != nil { | 	if _, err = e.Delete(&Access{RepoID: repo.ID, UserID: uid}); err != nil { | ||||||
| 		return fmt.Errorf("delete old user accesses: %v", err) | 		return fmt.Errorf("delete old user accesses: %v", err) | ||||||
| 	} else if accessMode >= minMode { | 	} else if accessMode >= minMode { | ||||||
| 		if _, err = e.Insert(&Access{RepoID: repo.ID, UserID: uid, Mode: accessMode}); err != nil { | 		if err = db.Insert(ctx, &Access{RepoID: repo.ID, UserID: uid, Mode: accessMode}); err != nil { | ||||||
| 			return fmt.Errorf("insert new user accesses: %v", err) | 			return fmt.Errorf("insert new user accesses: %v", err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func recalculateAccesses(ctx context.Context, repo *repo_model.Repository) error { | // RecalculateAccesses recalculates all accesses for repository. | ||||||
|  | func RecalculateAccesses(ctx context.Context, repo *repo_model.Repository) error { | ||||||
| 	if repo.Owner.IsOrganization() { | 	if repo.Owner.IsOrganization() { | ||||||
| 		return recalculateTeamAccesses(ctx, repo, 0) | 		return RecalculateTeamAccesses(ctx, repo, 0) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	e := db.GetEngine(ctx) | 	e := db.GetEngine(ctx) | ||||||
| 	accessMap := make(map[int64]*userAccess, 20) | 	accessMap := make(map[int64]*userAccess, 20) | ||||||
| 	if err := refreshCollaboratorAccesses(e, repo.ID, accessMap); err != nil { | 	if err := refreshCollaboratorAccesses(ctx, repo.ID, accessMap); err != nil { | ||||||
| 		return fmt.Errorf("refreshCollaboratorAccesses: %v", err) | 		return fmt.Errorf("refreshCollaboratorAccesses: %v", err) | ||||||
| 	} | 	} | ||||||
| 	return refreshAccesses(e, repo, accessMap) | 	return refreshAccesses(e, repo, accessMap) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| // RecalculateAccesses recalculates all accesses for repository. |  | ||||||
| func RecalculateAccesses(repo *repo_model.Repository) error { |  | ||||||
| 	return recalculateAccesses(db.DefaultContext, repo) |  | ||||||
| } |  | ||||||
| @@ -2,13 +2,12 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package access | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" |  | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| @@ -80,17 +79,17 @@ func TestHasAccess(t *testing.T) { | |||||||
| 	repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | 	repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | ||||||
| 	assert.True(t, repo2.IsPrivate) | 	assert.True(t, repo2.IsPrivate) | ||||||
| 
 | 
 | ||||||
| 	has, err := HasAccess(user1.ID, repo1) | 	has, err := HasAccess(db.DefaultContext, user1.ID, repo1) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, has) | 	assert.True(t, has) | ||||||
| 
 | 
 | ||||||
| 	_, err = HasAccess(user1.ID, repo2) | 	_, err = HasAccess(db.DefaultContext, user1.ID, repo2) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 	_, err = HasAccess(user2.ID, repo1) | 	_, err = HasAccess(db.DefaultContext, user2.ID, repo1) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 
 | 
 | ||||||
| 	_, err = HasAccess(user2.ID, repo2) | 	_, err = HasAccess(db.DefaultContext, user2.ID, repo2) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -100,9 +99,9 @@ func TestRepository_RecalculateAccesses(t *testing.T) { | |||||||
| 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | ||||||
| 	assert.NoError(t, repo1.GetOwner(db.DefaultContext)) | 	assert.NoError(t, repo1.GetOwner(db.DefaultContext)) | ||||||
| 
 | 
 | ||||||
| 	_, err := db.GetEngine(db.DefaultContext).Delete(&Collaboration{UserID: 2, RepoID: 3}) | 	_, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 2, RepoID: 3}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, RecalculateAccesses(repo1)) | 	assert.NoError(t, RecalculateAccesses(db.DefaultContext, repo1)) | ||||||
| 
 | 
 | ||||||
| 	access := &Access{UserID: 2, RepoID: 3} | 	access := &Access{UserID: 2, RepoID: 3} | ||||||
| 	has, err := db.GetEngine(db.DefaultContext).Get(access) | 	has, err := db.GetEngine(db.DefaultContext).Get(access) | ||||||
| @@ -117,29 +116,11 @@ func TestRepository_RecalculateAccesses2(t *testing.T) { | |||||||
| 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) | 	repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) | ||||||
| 	assert.NoError(t, repo1.GetOwner(db.DefaultContext)) | 	assert.NoError(t, repo1.GetOwner(db.DefaultContext)) | ||||||
| 
 | 
 | ||||||
| 	_, err := db.GetEngine(db.DefaultContext).Delete(&Collaboration{UserID: 4, RepoID: 4}) | 	_, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 4, RepoID: 4}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.NoError(t, RecalculateAccesses(repo1)) | 	assert.NoError(t, RecalculateAccesses(db.DefaultContext, repo1)) | ||||||
| 
 | 
 | ||||||
| 	has, err := db.GetEngine(db.DefaultContext).Get(&Access{UserID: 4, RepoID: 4}) | 	has, err := db.GetEngine(db.DefaultContext).Get(&Access{UserID: 4, RepoID: 4}) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.False(t, has) | 	assert.False(t, has) | ||||||
| } | } | ||||||
| 
 |  | ||||||
| func TestRepository_RecalculateAccesses3(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
| 	team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team) |  | ||||||
| 	user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}).(*user_model.User) |  | ||||||
| 
 |  | ||||||
| 	has, err := db.GetEngine(db.DefaultContext).Get(&Access{UserID: 29, RepoID: 23}) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.False(t, has) |  | ||||||
| 
 |  | ||||||
| 	// adding user29 to team5 should add an explicit access row for repo 23 |  | ||||||
| 	// even though repo 23 is public |  | ||||||
| 	assert.NoError(t, AddTeamMember(team5, user29.ID)) |  | ||||||
| 
 |  | ||||||
| 	has, err = db.GetEngine(db.DefaultContext).Get(&Access{UserID: 29, RepoID: 23}) |  | ||||||
| 	assert.NoError(t, err) |  | ||||||
| 	assert.True(t, has) |  | ||||||
| } |  | ||||||
							
								
								
									
										32
									
								
								models/perm/access/main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								models/perm/access/main_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | // Copyright 2020 The Gitea Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package access | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
|  | 	_ "code.gitea.io/gitea/models/repo" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestMain(m *testing.M) { | ||||||
|  | 	unittest.MainTest(m, &unittest.TestOptions{ | ||||||
|  | 		GiteaRootPath: filepath.Join("..", "..", ".."), | ||||||
|  | 		FixtureFiles: []string{ | ||||||
|  | 			"access.yml", | ||||||
|  | 			"user.yml", | ||||||
|  | 			"repository.yml", | ||||||
|  | 			"collaboration.yml", | ||||||
|  | 			"org_user.yml", | ||||||
|  | 			"repo_unit.yml", | ||||||
|  | 			"team_user.yml", | ||||||
|  | 			"team_repo.yml", | ||||||
|  | 			"team.yml", | ||||||
|  | 			"team_unit.yml", | ||||||
|  | 		}, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| // Use of this source code is governed by a MIT-style | // Use of this source code is governed by a MIT-style | ||||||
| // license that can be found in the LICENSE file. | // license that can be found in the LICENSE file. | ||||||
| 
 | 
 | ||||||
| package models | package access | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| @@ -103,39 +103,6 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool { | |||||||
| 	return p.CanWrite(unit.TypeIssues) | 	return p.CanWrite(unit.TypeIssues) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CanWriteToBranch checks if the branch is writable by the user |  | ||||||
| func (p *Permission) CanWriteToBranch(user *user_model.User, branch string) bool { |  | ||||||
| 	if p.CanWrite(unit.TypeCode) { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if len(p.Units) < 1 { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for _, pr := range prs { |  | ||||||
| 		if pr.AllowMaintainerEdit { |  | ||||||
| 			err = pr.LoadBaseRepo() |  | ||||||
| 			if err != nil { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			prPerm, err := GetUserRepoPermission(db.DefaultContext, pr.BaseRepo, user) |  | ||||||
| 			if err != nil { |  | ||||||
| 				continue |  | ||||||
| 			} |  | ||||||
| 			if prPerm.CanWrite(unit.TypeCode) { |  | ||||||
| 				return true |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ColorFormat writes a colored string for these Permissions | // ColorFormat writes a colored string for these Permissions | ||||||
| func (p *Permission) ColorFormat(s fmt.State) { | func (p *Permission) ColorFormat(s fmt.State) { | ||||||
| 	noColor := log.ColorBytes(log.Reset) | 	noColor := log.ColorBytes(log.Reset) | ||||||
| @@ -205,7 +172,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use | |||||||
| 
 | 
 | ||||||
| 	var is bool | 	var is bool | ||||||
| 	if user != nil { | 	if user != nil { | ||||||
| 		is, err = isCollaborator(e, repo.ID, user.ID) | 		is, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return perm, err | 			return perm, err | ||||||
| 		} | 		} | ||||||
| @@ -367,13 +334,13 @@ func IsUserRepoAdminCtx(ctx context.Context, repo *repo_model.Repository, user * | |||||||
| 
 | 
 | ||||||
| // AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the | // AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the | ||||||
| // user does not have access. | // user does not have access. | ||||||
| func AccessLevel(user *user_model.User, repo *repo_model.Repository) (perm_model.AccessMode, error) { | func AccessLevel(user *user_model.User, repo *repo_model.Repository) (perm_model.AccessMode, error) { //nolint | ||||||
| 	return accessLevelUnit(db.DefaultContext, user, repo, unit.TypeCode) | 	return AccessLevelUnit(user, repo, unit.TypeCode) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the | // AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the | ||||||
| // user does not have access. | // user does not have access. | ||||||
| func AccessLevelUnit(user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) { | func AccessLevelUnit(user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) { //nolint | ||||||
| 	return accessLevelUnit(db.DefaultContext, user, repo, unitType) | 	return accessLevelUnit(db.DefaultContext, user, repo, unitType) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -385,24 +352,16 @@ func accessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_mode | |||||||
| 	return perm.UnitAccessMode(unitType), nil | 	return perm.UnitAccessMode(unitType), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func hasAccessUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) { | // HasAccessUnit returns true if user has testMode to the unit of the repository | ||||||
|  | func HasAccessUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) { | ||||||
| 	mode, err := accessLevelUnit(ctx, user, repo, unitType) | 	mode, err := accessLevelUnit(ctx, user, repo, unitType) | ||||||
| 	return testMode <= mode, err | 	return testMode <= mode, err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // HasAccessUnit returns true if user has testMode to the unit of the repository |  | ||||||
| func HasAccessUnit(user *user_model.User, repo *repo_model.Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) { |  | ||||||
| 	return hasAccessUnit(db.DefaultContext, user, repo, unitType, testMode) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // CanBeAssigned return true if user can be assigned to issue or pull requests in repo | // CanBeAssigned return true if user can be assigned to issue or pull requests in repo | ||||||
| // Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface. | // Currently any write access (code, issues or pr's) is assignable, to match assignee list in user interface. | ||||||
| // FIXME: user could send PullRequest also could be assigned??? | // FIXME: user could send PullRequest also could be assigned??? | ||||||
| func CanBeAssigned(user *user_model.User, repo *repo_model.Repository, isPull bool) (bool, error) { | func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) { | ||||||
| 	return canBeAssigned(db.DefaultContext, user, repo, isPull) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func canBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) { |  | ||||||
| 	if user.IsOrganization() { | 	if user.IsOrganization() { | ||||||
| 		return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID) | 		return false, fmt.Errorf("Organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID) | ||||||
| 	} | 	} | ||||||
| @@ -413,7 +372,8 @@ func canBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model. | |||||||
| 	return perm.CanAccessAny(perm_model.AccessModeWrite, unit.TypeCode, unit.TypeIssues, unit.TypePullRequests), nil | 	return perm.CanAccessAny(perm_model.AccessModeWrite, unit.TypeCode, unit.TypeIssues, unit.TypePullRequests), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func hasAccess(ctx context.Context, userID int64, repo *repo_model.Repository) (bool, error) { | // HasAccess returns true if user has access to repo | ||||||
|  | func HasAccess(ctx context.Context, userID int64, repo *repo_model.Repository) (bool, error) { | ||||||
| 	var user *user_model.User | 	var user *user_model.User | ||||||
| 	var err error | 	var err error | ||||||
| 	if userID > 0 { | 	if userID > 0 { | ||||||
| @@ -429,9 +389,36 @@ func hasAccess(ctx context.Context, userID int64, repo *repo_model.Repository) ( | |||||||
| 	return perm.HasAccess(), nil | 	return perm.HasAccess(), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // HasAccess returns true if user has access to repo | // getUsersWithAccessMode returns users that have at least given access mode to the repository. | ||||||
| func HasAccess(userID int64, repo *repo_model.Repository) (bool, error) { | func getUsersWithAccessMode(ctx context.Context, repo *repo_model.Repository, mode perm_model.AccessMode) (_ []*user_model.User, err error) { | ||||||
| 	return hasAccess(db.DefaultContext, userID, repo) | 	if err = repo.GetOwner(ctx); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
|  | 	accesses := make([]*Access, 0, 10) | ||||||
|  | 	if err = e.Where("repo_id = ? AND mode >= ?", repo.ID, mode).Find(&accesses); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Leave a seat for owner itself to append later, but if owner is an organization | ||||||
|  | 	// and just waste 1 unit is cheaper than re-allocate memory once. | ||||||
|  | 	users := make([]*user_model.User, 0, len(accesses)+1) | ||||||
|  | 	if len(accesses) > 0 { | ||||||
|  | 		userIDs := make([]int64, len(accesses)) | ||||||
|  | 		for i := 0; i < len(accesses); i++ { | ||||||
|  | 			userIDs[i] = accesses[i].UserID | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if err = e.In("id", userIDs).Find(&users); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if !repo.Owner.IsOrganization() { | ||||||
|  | 		users = append(users, repo.Owner) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return users, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GetRepoReaders returns all users that have explicit read access or higher to the repository. | // GetRepoReaders returns all users that have explicit read access or higher to the repository. | ||||||
| @@ -9,6 +9,8 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
|  | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| @@ -60,6 +62,39 @@ func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequ | |||||||
| 		Find(&prs) | 		Find(&prs) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CanMaintainerWriteToBranch check whether user is a matainer and could write to the branch | ||||||
|  | func CanMaintainerWriteToBranch(p access_model.Permission, branch string, user *user_model.User) bool { | ||||||
|  | 	if p.CanWrite(unit.TypeCode) { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(p.Units) < 1 { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, pr := range prs { | ||||||
|  | 		if pr.AllowMaintainerEdit { | ||||||
|  | 			err = pr.LoadBaseRepo() | ||||||
|  | 			if err != nil { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			prPerm, err := access_model.GetUserRepoPermission(db.DefaultContext, pr.BaseRepo, user) | ||||||
|  | 			if err != nil { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			if prPerm.CanWrite(unit.TypeCode) { | ||||||
|  | 				return true | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
| // HasUnmergedPullRequestsByHeadInfo checks if there are open and not merged pull request | // HasUnmergedPullRequestsByHeadInfo checks if there are open and not merged pull request | ||||||
| // by given head information (repo and branch) | // by given head information (repo and branch) | ||||||
| func HasUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch string) (bool, error) { | func HasUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch string) (bool, error) { | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import ( | |||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	project_model "code.gitea.io/gitea/models/project" | 	project_model "code.gitea.io/gitea/models/project" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| @@ -54,7 +55,7 @@ func checkRepoUnitUser(ctx context.Context, repo *repo_model.Repository, user *u | |||||||
| 	if user != nil && user.IsAdmin { | 	if user != nil && user.IsAdmin { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 	perm, err := GetUserRepoPermission(ctx, repo, user) | 	perm, err := access_model.GetUserRepoPermission(ctx, repo, user) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("GetUserRepoPermission(): %v", err) | 		log.Error("GetUserRepoPermission(): %v", err) | ||||||
| 		return false | 		return false | ||||||
| @@ -302,38 +303,6 @@ func CanUserDelete(repo *repo_model.Repository, user *user_model.User) (bool, er | |||||||
| 	return false, nil | 	return false, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // getUsersWithAccessMode returns users that have at least given access mode to the repository. |  | ||||||
| func getUsersWithAccessMode(ctx context.Context, repo *repo_model.Repository, mode perm.AccessMode) (_ []*user_model.User, err error) { |  | ||||||
| 	if err = repo.GetOwner(ctx); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	e := db.GetEngine(ctx) |  | ||||||
| 	accesses := make([]*Access, 0, 10) |  | ||||||
| 	if err = e.Where("repo_id = ? AND mode >= ?", repo.ID, mode).Find(&accesses); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Leave a seat for owner itself to append later, but if owner is an organization |  | ||||||
| 	// and just waste 1 unit is cheaper than re-allocate memory once. |  | ||||||
| 	users := make([]*user_model.User, 0, len(accesses)+1) |  | ||||||
| 	if len(accesses) > 0 { |  | ||||||
| 		userIDs := make([]int64, len(accesses)) |  | ||||||
| 		for i := 0; i < len(accesses); i++ { |  | ||||||
| 			userIDs[i] = accesses[i].UserID |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if err = e.In("id", userIDs).Find(&users); err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if !repo.Owner.IsOrganization() { |  | ||||||
| 		users = append(users, repo.Owner) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return users, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // SetRepoReadBy sets repo to be visited by given user. | // SetRepoReadBy sets repo to be visited by given user. | ||||||
| func SetRepoReadBy(repoID, userID int64) error { | func SetRepoReadBy(repoID, userID int64) error { | ||||||
| 	return setRepoNotificationStatusReadIfUnread(db.GetEngine(db.DefaultContext), userID, repoID) | 	return setRepoNotificationStatusReadIfUnread(db.GetEngine(db.DefaultContext), userID, repoID) | ||||||
| @@ -452,18 +421,18 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_ | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if isAdmin, err := IsUserRepoAdminCtx(ctx, repo, doer); err != nil { | 		if isAdmin, err := access_model.IsUserRepoAdminCtx(ctx, repo, doer); err != nil { | ||||||
| 			return fmt.Errorf("IsUserRepoAdminCtx: %v", err) | 			return fmt.Errorf("IsUserRepoAdminCtx: %v", err) | ||||||
| 		} else if !isAdmin { | 		} else if !isAdmin { | ||||||
| 			// Make creator repo admin if it wasn't assigned automatically | 			// Make creator repo admin if it wasn't assigned automatically | ||||||
| 			if err = addCollaborator(ctx, repo, doer); err != nil { | 			if err = addCollaborator(ctx, repo, doer); err != nil { | ||||||
| 				return fmt.Errorf("AddCollaborator: %v", err) | 				return fmt.Errorf("AddCollaborator: %v", err) | ||||||
| 			} | 			} | ||||||
| 			if err = changeCollaborationAccessMode(db.GetEngine(ctx), repo, doer.ID, perm.AccessModeAdmin); err != nil { | 			if err = repo_model.ChangeCollaborationAccessModeCtx(ctx, repo, doer.ID, perm.AccessModeAdmin); err != nil { | ||||||
| 				return fmt.Errorf("ChangeCollaborationAccessMode: %v", err) | 				return fmt.Errorf("ChangeCollaborationAccessMode: %v", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} else if err = recalculateAccesses(ctx, repo); err != nil { | 	} else if err = access_model.RecalculateAccesses(ctx, repo); err != nil { | ||||||
| 		// Organization automatically called this in addRepository method. | 		// Organization automatically called this in addRepository method. | ||||||
| 		return fmt.Errorf("recalculateAccesses: %v", err) | 		return fmt.Errorf("recalculateAccesses: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -551,7 +520,7 @@ func UpdateRepositoryCtx(ctx context.Context, repo *repo_model.Repository, visib | |||||||
| 		} | 		} | ||||||
| 		if repo.Owner.IsOrganization() { | 		if repo.Owner.IsOrganization() { | ||||||
| 			// Organization repository need to recalculate access table when visibility is changed. | 			// Organization repository need to recalculate access table when visibility is changed. | ||||||
| 			if err = recalculateTeamAccesses(ctx, repo, 0); err != nil { | 			if err = access_model.RecalculateTeamAccesses(ctx, repo, 0); err != nil { | ||||||
| 				return fmt.Errorf("recalculateTeamAccesses: %v", err) | 				return fmt.Errorf("recalculateTeamAccesses: %v", err) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -659,7 +628,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { | |||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		for _, t := range teams { | 		for _, t := range teams { | ||||||
| 			if !hasRepository(ctx, t, repoID) { | 			if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repoID) { | ||||||
| 				continue | 				continue | ||||||
| 			} else if err = removeRepository(ctx, t, repo, false); err != nil { | 			} else if err = removeRepository(ctx, t, repo, false); err != nil { | ||||||
| 				return err | 				return err | ||||||
| @@ -683,9 +652,9 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := db.DeleteBeans(ctx, | 	if err := db.DeleteBeans(ctx, | ||||||
| 		&Access{RepoID: repo.ID}, | 		&access_model.Access{RepoID: repo.ID}, | ||||||
| 		&Action{RepoID: repo.ID}, | 		&Action{RepoID: repo.ID}, | ||||||
| 		&Collaboration{RepoID: repoID}, | 		&repo_model.Collaboration{RepoID: repoID}, | ||||||
| 		&Comment{RefRepoID: repoID}, | 		&Comment{RefRepoID: repoID}, | ||||||
| 		&CommitStatus{RepoID: repoID}, | 		&CommitStatus{RepoID: repoID}, | ||||||
| 		&DeletedBranch{RepoID: repoID}, | 		&DeletedBranch{RepoID: repoID}, | ||||||
| @@ -1212,7 +1181,7 @@ func DeleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("GetRepositoryByID: %v", err) | 			return fmt.Errorf("GetRepositoryByID: %v", err) | ||||||
| 		} | 		} | ||||||
| 		has, err := IsUserRepoAdminCtx(ctx, repo, doer) | 		has, err := access_model.IsUserRepoAdminCtx(ctx, repo, doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("GetUserRepoPermission: %v", err) | 			return fmt.Errorf("GetUserRepoPermission: %v", err) | ||||||
| 		} else if !has { | 		} else if !has { | ||||||
|   | |||||||
							
								
								
									
										150
									
								
								models/repo/collaboration.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								models/repo/collaboration.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | |||||||
|  | // Copyright 2022 The Gitea Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package repo | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/timeutil" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Collaboration represent the relation between an individual and a repository. | ||||||
|  | type Collaboration struct { | ||||||
|  | 	ID          int64              `xorm:"pk autoincr"` | ||||||
|  | 	RepoID      int64              `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
|  | 	UserID      int64              `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
|  | 	Mode        perm.AccessMode    `xorm:"DEFAULT 2 NOT NULL"` | ||||||
|  | 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | ||||||
|  | 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func init() { | ||||||
|  | 	db.RegisterModel(new(Collaboration)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Collaborator represents a user with collaboration details. | ||||||
|  | type Collaborator struct { | ||||||
|  | 	*user_model.User | ||||||
|  | 	Collaboration *Collaboration | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetCollaborators returns the collaborators for a repository | ||||||
|  | func GetCollaborators(ctx context.Context, repoID int64, listOptions db.ListOptions) ([]*Collaborator, error) { | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
|  | 	collaborations, err := getCollaborations(e, repoID, listOptions) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, fmt.Errorf("getCollaborations: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	collaborators := make([]*Collaborator, 0, len(collaborations)) | ||||||
|  | 	for _, c := range collaborations { | ||||||
|  | 		user, err := user_model.GetUserByIDEngine(e, c.UserID) | ||||||
|  | 		if err != nil { | ||||||
|  | 			if user_model.IsErrUserNotExist(err) { | ||||||
|  | 				log.Warn("Inconsistent DB: User: %d is listed as collaborator of %-v but does not exist", c.UserID, repoID) | ||||||
|  | 				user = user_model.NewGhostUser() | ||||||
|  | 			} else { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		collaborators = append(collaborators, &Collaborator{ | ||||||
|  | 			User:          user, | ||||||
|  | 			Collaboration: c, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | 	return collaborators, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CountCollaborators returns total number of collaborators for a repository | ||||||
|  | func CountCollaborators(repoID int64) (int64, error) { | ||||||
|  | 	return db.GetEngine(db.DefaultContext).Where("repo_id = ? ", repoID).Count(&Collaboration{}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetCollaboration get collaboration for a repository id with a user id | ||||||
|  | func GetCollaboration(ctx context.Context, repoID, uid int64) (*Collaboration, error) { | ||||||
|  | 	collaboration := &Collaboration{ | ||||||
|  | 		RepoID: repoID, | ||||||
|  | 		UserID: uid, | ||||||
|  | 	} | ||||||
|  | 	has, err := db.GetEngine(ctx).Get(collaboration) | ||||||
|  | 	if !has { | ||||||
|  | 		collaboration = nil | ||||||
|  | 	} | ||||||
|  | 	return collaboration, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsCollaborator check if a user is a collaborator of a repository | ||||||
|  | func IsCollaborator(ctx context.Context, repoID, userID int64) (bool, error) { | ||||||
|  | 	return db.GetEngine(ctx).Get(&Collaboration{RepoID: repoID, UserID: userID}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func getCollaborations(e db.Engine, repoID int64, listOptions db.ListOptions) ([]*Collaboration, error) { | ||||||
|  | 	if listOptions.Page == 0 { | ||||||
|  | 		collaborations := make([]*Collaboration, 0, 8) | ||||||
|  | 		return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repoID}) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	e = db.SetEnginePagination(e, &listOptions) | ||||||
|  |  | ||||||
|  | 	collaborations := make([]*Collaboration, 0, listOptions.PageSize) | ||||||
|  | 	return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repoID}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ChangeCollaborationAccessMode sets new access mode for the collaboration. | ||||||
|  | func ChangeCollaborationAccessModeCtx(ctx context.Context, repo *Repository, uid int64, mode perm.AccessMode) error { | ||||||
|  | 	// Discard invalid input | ||||||
|  | 	if mode <= perm.AccessModeNone || mode > perm.AccessModeOwner { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	e := db.GetEngine(ctx) | ||||||
|  |  | ||||||
|  | 	collaboration := &Collaboration{ | ||||||
|  | 		RepoID: repo.ID, | ||||||
|  | 		UserID: uid, | ||||||
|  | 	} | ||||||
|  | 	has, err := e.Get(collaboration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("get collaboration: %v", err) | ||||||
|  | 	} else if !has { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if collaboration.Mode == mode { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	collaboration.Mode = mode | ||||||
|  |  | ||||||
|  | 	if _, err = e. | ||||||
|  | 		ID(collaboration.ID). | ||||||
|  | 		Cols("mode"). | ||||||
|  | 		Update(collaboration); err != nil { | ||||||
|  | 		return fmt.Errorf("update collaboration: %v", err) | ||||||
|  | 	} else if _, err = e.Exec("UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?", mode, uid, repo.ID); err != nil { | ||||||
|  | 		return fmt.Errorf("update access table: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ChangeCollaborationAccessMode sets new access mode for the collaboration. | ||||||
|  | func ChangeCollaborationAccessMode(repo *Repository, uid int64, mode perm.AccessMode) error { | ||||||
|  | 	ctx, committer, err := db.TxContext() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	defer committer.Close() | ||||||
|  |  | ||||||
|  | 	if err := ChangeCollaborationAccessModeCtx(ctx, repo, uid, mode); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return committer.Commit() | ||||||
|  | } | ||||||
							
								
								
									
										49
									
								
								models/repo/collaboration_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								models/repo/collaboration_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | // Copyright 2022 The Gitea Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package repo | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	"code.gitea.io/gitea/models/unittest" | ||||||
|  |  | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestRepository_GetCollaborators(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  | 	test := func(repoID int64) { | ||||||
|  | 		repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository) | ||||||
|  | 		collaborators, err := GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{}) | ||||||
|  | 		assert.NoError(t, err) | ||||||
|  | 		expectedLen, err := db.GetEngine(db.DefaultContext).Count(&Collaboration{RepoID: repoID}) | ||||||
|  | 		assert.NoError(t, err) | ||||||
|  | 		assert.Len(t, collaborators, int(expectedLen)) | ||||||
|  | 		for _, collaborator := range collaborators { | ||||||
|  | 			assert.EqualValues(t, collaborator.User.ID, collaborator.Collaboration.UserID) | ||||||
|  | 			assert.EqualValues(t, repoID, collaborator.Collaboration.RepoID) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	test(1) | ||||||
|  | 	test(2) | ||||||
|  | 	test(3) | ||||||
|  | 	test(4) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestRepository_IsCollaborator(t *testing.T) { | ||||||
|  | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
|  | 	test := func(repoID, userID int64, expected bool) { | ||||||
|  | 		repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: repoID}).(*Repository) | ||||||
|  | 		actual, err := IsCollaborator(db.DefaultContext, repo.ID, userID) | ||||||
|  | 		assert.NoError(t, err) | ||||||
|  | 		assert.Equal(t, expected, actual) | ||||||
|  | 	} | ||||||
|  | 	test(3, 2, true) | ||||||
|  | 	test(3, unittest.NonexistentID, false) | ||||||
|  | 	test(4, 2, false) | ||||||
|  | 	test(4, 4, true) | ||||||
|  | } | ||||||
| @@ -26,6 +26,7 @@ func TestMain(m *testing.M) { | |||||||
| 			"topic.yml", | 			"topic.yml", | ||||||
| 			"repo_topic.yml", | 			"repo_topic.yml", | ||||||
| 			"user.yml", | 			"user.yml", | ||||||
|  | 			"collaboration.yml", | ||||||
| 		}, | 		}, | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,31 +12,16 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" |  | ||||||
| 	"code.gitea.io/gitea/modules/timeutil" |  | ||||||
|  |  | ||||||
| 	"xorm.io/builder" | 	"xorm.io/builder" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Collaboration represent the relation between an individual and a repository. |  | ||||||
| type Collaboration struct { |  | ||||||
| 	ID          int64              `xorm:"pk autoincr"` |  | ||||||
| 	RepoID      int64              `xorm:"UNIQUE(s) INDEX NOT NULL"` |  | ||||||
| 	UserID      int64              `xorm:"UNIQUE(s) INDEX NOT NULL"` |  | ||||||
| 	Mode        perm.AccessMode    `xorm:"DEFAULT 2 NOT NULL"` |  | ||||||
| 	CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` |  | ||||||
| 	UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func init() { |  | ||||||
| 	db.RegisterModel(new(Collaboration)) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { | func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_model.User) error { | ||||||
| 	collaboration := &Collaboration{ | 	collaboration := &repo_model.Collaboration{ | ||||||
| 		RepoID: repo.ID, | 		RepoID: repo.ID, | ||||||
| 		UserID: u.ID, | 		UserID: u.ID, | ||||||
| 	} | 	} | ||||||
| @@ -54,7 +39,7 @@ func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_m | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return recalculateUserAccess(ctx, repo, u.ID) | 	return access_model.RecalculateUserAccess(ctx, repo, u.ID) | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddCollaborator adds new collaboration to a repository with default access mode. | // AddCollaborator adds new collaboration to a repository with default access mode. | ||||||
| @@ -72,132 +57,9 @@ func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error { | |||||||
| 	return committer.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| func getCollaborations(e db.Engine, repoID int64, listOptions db.ListOptions) ([]*Collaboration, error) { |  | ||||||
| 	if listOptions.Page == 0 { |  | ||||||
| 		collaborations := make([]*Collaboration, 0, 8) |  | ||||||
| 		return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repoID}) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	e = db.SetEnginePagination(e, &listOptions) |  | ||||||
|  |  | ||||||
| 	collaborations := make([]*Collaboration, 0, listOptions.PageSize) |  | ||||||
| 	return collaborations, e.Find(&collaborations, &Collaboration{RepoID: repoID}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Collaborator represents a user with collaboration details. |  | ||||||
| type Collaborator struct { |  | ||||||
| 	*user_model.User |  | ||||||
| 	Collaboration *Collaboration |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func getCollaborators(e db.Engine, repoID int64, listOptions db.ListOptions) ([]*Collaborator, error) { |  | ||||||
| 	collaborations, err := getCollaborations(e, repoID, listOptions) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil, fmt.Errorf("getCollaborations: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	collaborators := make([]*Collaborator, 0, len(collaborations)) |  | ||||||
| 	for _, c := range collaborations { |  | ||||||
| 		user, err := user_model.GetUserByIDEngine(e, c.UserID) |  | ||||||
| 		if err != nil { |  | ||||||
| 			if user_model.IsErrUserNotExist(err) { |  | ||||||
| 				log.Warn("Inconsistent DB: User: %d is listed as collaborator of %-v but does not exist", c.UserID, repoID) |  | ||||||
| 				user = user_model.NewGhostUser() |  | ||||||
| 			} else { |  | ||||||
| 				return nil, err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		collaborators = append(collaborators, &Collaborator{ |  | ||||||
| 			User:          user, |  | ||||||
| 			Collaboration: c, |  | ||||||
| 		}) |  | ||||||
| 	} |  | ||||||
| 	return collaborators, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetCollaborators returns the collaborators for a repository |  | ||||||
| func GetCollaborators(repoID int64, listOptions db.ListOptions) ([]*Collaborator, error) { |  | ||||||
| 	return getCollaborators(db.GetEngine(db.DefaultContext), repoID, listOptions) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CountCollaborators returns total number of collaborators for a repository |  | ||||||
| func CountCollaborators(repoID int64) (int64, error) { |  | ||||||
| 	return db.GetEngine(db.DefaultContext).Where("repo_id = ? ", repoID).Count(&Collaboration{}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func getCollaboration(e db.Engine, repoID, uid int64) (*Collaboration, error) { |  | ||||||
| 	collaboration := &Collaboration{ |  | ||||||
| 		RepoID: repoID, |  | ||||||
| 		UserID: uid, |  | ||||||
| 	} |  | ||||||
| 	has, err := e.Get(collaboration) |  | ||||||
| 	if !has { |  | ||||||
| 		collaboration = nil |  | ||||||
| 	} |  | ||||||
| 	return collaboration, err |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func isCollaborator(e db.Engine, repoID, userID int64) (bool, error) { |  | ||||||
| 	return e.Get(&Collaboration{RepoID: repoID, UserID: userID}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IsCollaborator check if a user is a collaborator of a repository |  | ||||||
| func IsCollaborator(repoID, userID int64) (bool, error) { |  | ||||||
| 	return isCollaborator(db.GetEngine(db.DefaultContext), repoID, userID) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func changeCollaborationAccessMode(e db.Engine, repo *repo_model.Repository, uid int64, mode perm.AccessMode) error { |  | ||||||
| 	// Discard invalid input |  | ||||||
| 	if mode <= perm.AccessModeNone || mode > perm.AccessModeOwner { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	collaboration := &Collaboration{ |  | ||||||
| 		RepoID: repo.ID, |  | ||||||
| 		UserID: uid, |  | ||||||
| 	} |  | ||||||
| 	has, err := e.Get(collaboration) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return fmt.Errorf("get collaboration: %v", err) |  | ||||||
| 	} else if !has { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if collaboration.Mode == mode { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	collaboration.Mode = mode |  | ||||||
|  |  | ||||||
| 	if _, err = e. |  | ||||||
| 		ID(collaboration.ID). |  | ||||||
| 		Cols("mode"). |  | ||||||
| 		Update(collaboration); err != nil { |  | ||||||
| 		return fmt.Errorf("update collaboration: %v", err) |  | ||||||
| 	} else if _, err = e.Exec("UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?", mode, uid, repo.ID); err != nil { |  | ||||||
| 		return fmt.Errorf("update access table: %v", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ChangeCollaborationAccessMode sets new access mode for the collaboration. |  | ||||||
| func ChangeCollaborationAccessMode(repo *repo_model.Repository, uid int64, mode perm.AccessMode) error { |  | ||||||
| 	ctx, committer, err := db.TxContext() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	defer committer.Close() |  | ||||||
|  |  | ||||||
| 	if err := changeCollaborationAccessMode(db.GetEngine(ctx), repo, uid, mode); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return committer.Commit() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // DeleteCollaboration removes collaboration relation between the user and repository. | // DeleteCollaboration removes collaboration relation between the user and repository. | ||||||
| func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) { | func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) { | ||||||
| 	collaboration := &Collaboration{ | 	collaboration := &repo_model.Collaboration{ | ||||||
| 		RepoID: repo.ID, | 		RepoID: repo.ID, | ||||||
| 		UserID: uid, | 		UserID: uid, | ||||||
| 	} | 	} | ||||||
| @@ -210,7 +72,7 @@ func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) { | |||||||
|  |  | ||||||
| 	if has, err := db.GetEngine(ctx).Delete(collaboration); err != nil || has == 0 { | 	if has, err := db.GetEngine(ctx).Delete(collaboration); err != nil || has == 0 { | ||||||
| 		return err | 		return err | ||||||
| 	} else if err = recalculateAccesses(ctx, repo); err != nil { | 	} else if err = access_model.RecalculateAccesses(ctx, repo); err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -236,7 +98,7 @@ func reconsiderRepoIssuesAssignee(ctx context.Context, repo *repo_model.Reposito | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if canAssigned, err := canBeAssigned(ctx, user, repo, true); err != nil || canAssigned { | 	if canAssigned, err := access_model.CanBeAssigned(ctx, user, repo, true); err != nil || canAssigned { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -249,7 +111,7 @@ func reconsiderRepoIssuesAssignee(ctx context.Context, repo *repo_model.Reposito | |||||||
| } | } | ||||||
|  |  | ||||||
| func reconsiderWatches(ctx context.Context, repo *repo_model.Repository, uid int64) error { | func reconsiderWatches(ctx context.Context, repo *repo_model.Repository, uid int64) error { | ||||||
| 	if has, err := hasAccess(ctx, uid, repo); err != nil || has { | 	if has, err := access_model.HasAccess(ctx, uid, repo); err != nil || has { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if err := repo_model.WatchRepoCtx(ctx, uid, repo.ID, false); err != nil { | 	if err := repo_model.WatchRepoCtx(ctx, uid, repo.ID, false); err != nil { | ||||||
| @@ -277,5 +139,5 @@ func IsOwnerMemberCollaborator(repo *repo_model.Repository, userID int64) (bool, | |||||||
| 		return true, nil | 		return true, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return db.GetEngine(db.DefaultContext).Get(&Collaboration{RepoID: repo.ID, UserID: userID}) | 	return db.GetEngine(db.DefaultContext).Get(&repo_model.Collaboration{RepoID: repo.ID, UserID: userID}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -31,56 +32,21 @@ func TestRepository_AddCollaborator(t *testing.T) { | |||||||
| 	testSuccess(3, 4) | 	testSuccess(3, 4) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestRepository_GetCollaborators(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
| 	test := func(repoID int64) { |  | ||||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) |  | ||||||
| 		collaborators, err := GetCollaborators(repo.ID, db.ListOptions{}) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 		expectedLen, err := db.GetEngine(db.DefaultContext).Count(&Collaboration{RepoID: repoID}) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 		assert.Len(t, collaborators, int(expectedLen)) |  | ||||||
| 		for _, collaborator := range collaborators { |  | ||||||
| 			assert.EqualValues(t, collaborator.User.ID, collaborator.Collaboration.UserID) |  | ||||||
| 			assert.EqualValues(t, repoID, collaborator.Collaboration.RepoID) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	test(1) |  | ||||||
| 	test(2) |  | ||||||
| 	test(3) |  | ||||||
| 	test(4) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestRepository_IsCollaborator(t *testing.T) { |  | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) |  | ||||||
|  |  | ||||||
| 	test := func(repoID, userID int64, expected bool) { |  | ||||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository) |  | ||||||
| 		actual, err := IsCollaborator(repo.ID, userID) |  | ||||||
| 		assert.NoError(t, err) |  | ||||||
| 		assert.Equal(t, expected, actual) |  | ||||||
| 	} |  | ||||||
| 	test(3, 2, true) |  | ||||||
| 	test(3, unittest.NonexistentID, false) |  | ||||||
| 	test(4, 2, false) |  | ||||||
| 	test(4, 4, true) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { | func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { | ||||||
| 	assert.NoError(t, unittest.PrepareTestDatabase()) | 	assert.NoError(t, unittest.PrepareTestDatabase()) | ||||||
|  |  | ||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) | ||||||
| 	assert.NoError(t, ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin)) | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin)) | ||||||
|  |  | ||||||
| 	collaboration := unittest.AssertExistsAndLoadBean(t, &Collaboration{RepoID: repo.ID, UserID: 4}).(*Collaboration) | 	collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}).(*repo_model.Collaboration) | ||||||
| 	assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode) | 	assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode) | ||||||
|  |  | ||||||
| 	access := unittest.AssertExistsAndLoadBean(t, &Access{UserID: 4, RepoID: repo.ID}).(*Access) | 	access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID}).(*access_model.Access) | ||||||
| 	assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) | 	assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) | ||||||
|  |  | ||||||
| 	assert.NoError(t, ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin)) | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin)) | ||||||
|  |  | ||||||
| 	assert.NoError(t, ChangeCollaborationAccessMode(repo, unittest.NonexistentID, perm.AccessModeAdmin)) | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, unittest.NonexistentID, perm.AccessModeAdmin)) | ||||||
|  |  | ||||||
| 	unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) | 	unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) | ||||||
| } | } | ||||||
| @@ -91,10 +57,10 @@ func TestRepository_DeleteCollaboration(t *testing.T) { | |||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository) | ||||||
| 	assert.NoError(t, repo.GetOwner(db.DefaultContext)) | 	assert.NoError(t, repo.GetOwner(db.DefaultContext)) | ||||||
| 	assert.NoError(t, DeleteCollaboration(repo, 4)) | 	assert.NoError(t, DeleteCollaboration(repo, 4)) | ||||||
| 	unittest.AssertNotExistsBean(t, &Collaboration{RepoID: repo.ID, UserID: 4}) | 	unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}) | ||||||
|  |  | ||||||
| 	assert.NoError(t, DeleteCollaboration(repo, 4)) | 	assert.NoError(t, DeleteCollaboration(repo, 4)) | ||||||
| 	unittest.AssertNotExistsBean(t, &Collaboration{RepoID: repo.ID, UserID: 4}) | 	unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}) | ||||||
|  |  | ||||||
| 	unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) | 	unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	perm_model "code.gitea.io/gitea/models/perm" | 	perm_model "code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| @@ -27,7 +28,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// plain user | 	// plain user | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | ||||||
| 	perm, err := GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -36,7 +37,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// change to collaborator | 	// change to collaborator | ||||||
| 	assert.NoError(t, AddCollaborator(repo, user)) | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -45,7 +46,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// collaborator | 	// collaborator | ||||||
| 	collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) | 	collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, collaborator) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, collaborator) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -54,7 +55,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// owner | 	// owner | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, owner) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -63,7 +64,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// admin | 	// admin | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, admin) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -80,7 +81,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// plain user | 	// plain user | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) | ||||||
| 	perm, err := GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.False(t, perm.CanRead(unit.Type)) | 		assert.False(t, perm.CanRead(unit.Type)) | ||||||
| @@ -89,15 +90,15 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// change to collaborator to default write access | 	// change to collaborator to default write access | ||||||
| 	assert.NoError(t, AddCollaborator(repo, user)) | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -106,7 +107,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// owner | 	// owner | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, owner) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -115,7 +116,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// admin | 	// admin | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, admin) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -132,7 +133,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// plain user | 	// plain user | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) | ||||||
| 	perm, err := GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -141,15 +142,15 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// change to collaborator to default write access | 	// change to collaborator to default write access | ||||||
| 	assert.NoError(t, AddCollaborator(repo, user)) | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -158,7 +159,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// org member team owner | 	// org member team owner | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, owner) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -167,7 +168,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// org member team tester | 	// org member team tester | ||||||
| 	member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) | 	member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, member) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, member) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -177,7 +178,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// admin | 	// admin | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, admin) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -194,7 +195,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// plain user | 	// plain user | ||||||
| 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) | 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User) | ||||||
| 	perm, err := GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.False(t, perm.CanRead(unit.Type)) | 		assert.False(t, perm.CanRead(unit.Type)) | ||||||
| @@ -203,15 +204,15 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// change to collaborator to default write access | 	// change to collaborator to default write access | ||||||
| 	assert.NoError(t, AddCollaborator(repo, user)) | 	assert.NoError(t, AddCollaborator(repo, user)) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| 		assert.True(t, perm.CanWrite(unit.Type)) | 		assert.True(t, perm.CanWrite(unit.Type)) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | 	assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead)) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, user) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -220,7 +221,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// org member team owner | 	// org member team owner | ||||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) | 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, owner) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -231,7 +232,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | |||||||
| 	team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team) | 	team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team) | ||||||
| 	err = organization.UpdateTeamUnits(team, nil) | 	err = organization.UpdateTeamUnits(team, nil) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, owner) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
| @@ -240,7 +241,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// org member team tester | 	// org member team tester | ||||||
| 	tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | 	tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, tester) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, tester) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, perm.CanWrite(unit.TypeIssues)) | 	assert.True(t, perm.CanWrite(unit.TypeIssues)) | ||||||
| 	assert.False(t, perm.CanWrite(unit.TypeCode)) | 	assert.False(t, perm.CanWrite(unit.TypeCode)) | ||||||
| @@ -248,7 +249,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// org member team reviewer | 	// org member team reviewer | ||||||
| 	reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}).(*user_model.User) | 	reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, reviewer) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, reviewer) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.False(t, perm.CanRead(unit.TypeIssues)) | 	assert.False(t, perm.CanRead(unit.TypeIssues)) | ||||||
| 	assert.False(t, perm.CanWrite(unit.TypeCode)) | 	assert.False(t, perm.CanWrite(unit.TypeCode)) | ||||||
| @@ -256,7 +257,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { | |||||||
|  |  | ||||||
| 	// admin | 	// admin | ||||||
| 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | 	admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) | ||||||
| 	perm, err = GetUserRepoPermission(db.DefaultContext, repo, admin) | 	perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	for _, unit := range repo.Units { | 	for _, unit := range repo.Units { | ||||||
| 		assert.True(t, perm.CanRead(unit.Type)) | 		assert.True(t, perm.CanRead(unit.Type)) | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -280,13 +281,13 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mo | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Remove redundant collaborators. | 	// Remove redundant collaborators. | ||||||
| 	collaborators, err := getCollaborators(sess, repo.ID, db.ListOptions{}) | 	collaborators, err := repo_model.GetCollaborators(ctx, repo.ID, db.ListOptions{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("getCollaborators: %v", err) | 		return fmt.Errorf("getCollaborators: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Dummy object. | 	// Dummy object. | ||||||
| 	collaboration := &Collaboration{RepoID: repo.ID} | 	collaboration := &repo_model.Collaboration{RepoID: repo.ID} | ||||||
| 	for _, c := range collaborators { | 	for _, c := range collaborators { | ||||||
| 		if c.IsGhost() { | 		if c.IsGhost() { | ||||||
| 			collaboration.ID = c.Collaboration.ID | 			collaboration.ID = c.Collaboration.ID | ||||||
| @@ -330,7 +331,7 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mo | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} else if err := recalculateAccesses(ctx, repo); err != nil { | 	} else if err := access_model.RecalculateAccesses(ctx, repo); err != nil { | ||||||
| 		// Organization called this in addRepository method. | 		// Organization called this in addRepository method. | ||||||
| 		return fmt.Errorf("recalculateAccesses: %v", err) | 		return fmt.Errorf("recalculateAccesses: %v", err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| @@ -891,7 +892,7 @@ func CanMarkConversation(issue *Issue, doer *user_model.User) (permResult bool, | |||||||
| 			return false, err | 			return false, err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		p, err := GetUserRepoPermission(db.DefaultContext, issue.Repo, doer) | 		p, err := access_model.GetUserRepoPermission(db.DefaultContext, issue.Repo, doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return false, err | 			return false, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	project_model "code.gitea.io/gitea/models/project" | 	project_model "code.gitea.io/gitea/models/project" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -56,7 +57,7 @@ func GetStatistic() (stats Statistic) { | |||||||
| 	stats.Counter.Watch, _ = e.Count(new(repo_model.Watch)) | 	stats.Counter.Watch, _ = e.Count(new(repo_model.Watch)) | ||||||
| 	stats.Counter.Star, _ = e.Count(new(repo_model.Star)) | 	stats.Counter.Star, _ = e.Count(new(repo_model.Star)) | ||||||
| 	stats.Counter.Action, _ = e.Count(new(Action)) | 	stats.Counter.Action, _ = e.Count(new(Action)) | ||||||
| 	stats.Counter.Access, _ = e.Count(new(Access)) | 	stats.Counter.Access, _ = e.Count(new(access_model.Access)) | ||||||
|  |  | ||||||
| 	type IssueCount struct { | 	type IssueCount struct { | ||||||
| 		Count    int64 | 		Count    int64 | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/issues" | 	"code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	pull_model "code.gitea.io/gitea/models/pull" | 	pull_model "code.gitea.io/gitea/models/pull" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -68,8 +69,8 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { | |||||||
|  |  | ||||||
| 	if err = db.DeleteBeans(ctx, | 	if err = db.DeleteBeans(ctx, | ||||||
| 		&AccessToken{UID: u.ID}, | 		&AccessToken{UID: u.ID}, | ||||||
| 		&Collaboration{UserID: u.ID}, | 		&repo_model.Collaboration{UserID: u.ID}, | ||||||
| 		&Access{UserID: u.ID}, | 		&access_model.Access{UserID: u.ID}, | ||||||
| 		&repo_model.Watch{UserID: u.ID}, | 		&repo_model.Watch{UserID: u.ID}, | ||||||
| 		&repo_model.Star{UID: u.ID}, | 		&repo_model.Star{UID: u.ID}, | ||||||
| 		&user_model.Follow{UserID: u.ID}, | 		&user_model.Follow{UserID: u.ID}, | ||||||
| @@ -80,7 +81,6 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) { | |||||||
| 		&user_model.UserOpenID{UID: u.ID}, | 		&user_model.UserOpenID{UID: u.ID}, | ||||||
| 		&issues.Reaction{UserID: u.ID}, | 		&issues.Reaction{UserID: u.ID}, | ||||||
| 		&organization.TeamUser{UID: u.ID}, | 		&organization.TeamUser{UID: u.ID}, | ||||||
| 		&Collaboration{UserID: u.ID}, |  | ||||||
| 		&Stopwatch{UserID: u.ID}, | 		&Stopwatch{UserID: u.ID}, | ||||||
| 		&user_model.Setting{UserID: u.ID}, | 		&user_model.Setting{UserID: u.ID}, | ||||||
| 		&pull_model.AutoMerge{DoerID: u.ID}, | 		&pull_model.AutoMerge{DoerID: u.ID}, | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ func RequireRepoWriter(unitType unit.Type) func(ctx *Context) { | |||||||
| // CanEnableEditor checks if the user is allowed to write to the branch of the repo | // CanEnableEditor checks if the user is allowed to write to the branch of the repo | ||||||
| func CanEnableEditor() func(ctx *Context) { | func CanEnableEditor() func(ctx *Context) { | ||||||
| 	return func(ctx *Context) { | 	return func(ctx *Context) { | ||||||
| 		if !ctx.Repo.Permission.CanWriteToBranch(ctx.Doer, ctx.Repo.BranchName) { | 		if !ctx.Repo.CanWriteToBranch(ctx.Doer, ctx.Repo.BranchName) { | ||||||
| 			ctx.NotFound("CanWriteToBranch denies permission", nil) | 			ctx.NotFound("CanWriteToBranch denies permission", nil) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	unit_model "code.gitea.io/gitea/models/unit" | 	unit_model "code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -54,7 +55,7 @@ type PullRequest struct { | |||||||
|  |  | ||||||
| // Repository contains information to operate a repository | // Repository contains information to operate a repository | ||||||
| type Repository struct { | type Repository struct { | ||||||
| 	models.Permission | 	access_model.Permission | ||||||
| 	IsWatching   bool | 	IsWatching   bool | ||||||
| 	IsViewBranch bool | 	IsViewBranch bool | ||||||
| 	IsViewTag    bool | 	IsViewTag    bool | ||||||
| @@ -77,9 +78,14 @@ type Repository struct { | |||||||
| 	PullRequest *PullRequest | 	PullRequest *PullRequest | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // CanWriteToBranch checks if the branch is writable by the user | ||||||
|  | func (r *Repository) CanWriteToBranch(user *user_model.User, branch string) bool { | ||||||
|  | 	return models.CanMaintainerWriteToBranch(r.Permission, branch, user) | ||||||
|  | } | ||||||
|  |  | ||||||
| // CanEnableEditor returns true if repository is editable and user has proper access level. | // CanEnableEditor returns true if repository is editable and user has proper access level. | ||||||
| func (r *Repository) CanEnableEditor(user *user_model.User) bool { | func (r *Repository) CanEnableEditor(user *user_model.User) bool { | ||||||
| 	return r.IsViewBranch && r.Permission.CanWriteToBranch(user, r.BranchName) && r.Repository.CanEnableEditor() && !r.Repository.IsArchived | 	return r.IsViewBranch && r.CanWriteToBranch(user, r.BranchName) && r.Repository.CanEnableEditor() && !r.Repository.IsArchived | ||||||
| } | } | ||||||
|  |  | ||||||
| // CanCreateBranch returns true if repository is editable and user has proper access level. | // CanCreateBranch returns true if repository is editable and user has proper access level. | ||||||
| @@ -285,7 +291,7 @@ func RetrieveTemplateRepo(ctx *Context, repo *repo_model.Repository) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, templateRepo, ctx.Doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, templateRepo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetUserRepoPermission", err) | 		ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 		return | 		return | ||||||
| @@ -351,7 +357,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.Repo.Permission, err = models.GetUserRepoPermission(ctx, repo, ctx.Doer) | 	ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetUserRepoPermission", err) | 		ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -44,16 +45,16 @@ func ToBranch(repo *repo_model.Repository, b *git.Branch, c *git.Commit, bp *mod | |||||||
| 		var canPush bool | 		var canPush bool | ||||||
| 		var err error | 		var err error | ||||||
| 		if user != nil { | 		if user != nil { | ||||||
| 			hasPerm, err = models.HasAccessUnit(user, repo, unit.TypeCode, perm.AccessModeWrite) | 			hasPerm, err = access_model.HasAccessUnit(db.DefaultContext, user, repo, unit.TypeCode, perm.AccessModeWrite) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			perms, err := models.GetUserRepoPermission(db.DefaultContext, repo, user) | 			perms, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| 			canPush = perms.CanWriteToBranch(user, b.Name) | 			canPush = models.CanMaintainerWriteToBranch(perms, b.Name, user) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return &api.Branch{ | 		return &api.Branch{ | ||||||
| @@ -82,7 +83,7 @@ func ToBranch(repo *repo_model.Repository, b *git.Branch, c *git.Commit, bp *mod | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if user != nil { | 	if user != nil { | ||||||
| 		permission, err := models.GetUserRepoPermission(db.DefaultContext, repo, user) | 		permission, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -7,8 +7,8 @@ package convert | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/packages" | 	"code.gitea.io/gitea/models/packages" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	api "code.gitea.io/gitea/modules/structs" | 	api "code.gitea.io/gitea/modules/structs" | ||||||
| ) | ) | ||||||
| @@ -17,7 +17,7 @@ import ( | |||||||
| func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_model.User) (*api.Package, error) { | func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_model.User) (*api.Package, error) { | ||||||
| 	var repo *api.Repository | 	var repo *api.Repository | ||||||
| 	if pd.Repository != nil { | 	if pd.Repository != nil { | ||||||
| 		permission, err := models.GetUserRepoPermission(ctx, pd.Repository, doer) | 		permission, err := access_model.GetUserRepoPermission(ctx, pd.Repository, doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -43,7 +44,7 @@ func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_mo | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	p, err := models.GetUserRepoPermission(ctx, pr.BaseRepo, doer) | 	p, err := access_model.GetUserRepoPermission(ctx, pr.BaseRepo, doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("GetUserRepoPermission[%d]: %v", pr.BaseRepoID, err) | 		log.Error("GetUserRepoPermission[%d]: %v", pr.BaseRepoID, err) | ||||||
| 		p.AccessMode = perm.AccessModeNone | 		p.AccessMode = perm.AccessModeNone | ||||||
| @@ -132,7 +133,7 @@ func ToAPIPullRequest(ctx context.Context, pr *models.PullRequest, doer *user_mo | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if pr.HeadRepo != nil && pr.Flow == models.PullRequestFlowGithub { | 	if pr.HeadRepo != nil && pr.Flow == models.PullRequestFlowGithub { | ||||||
| 		p, err := models.GetUserRepoPermission(ctx, pr.HeadRepo, doer) | 		p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) | 			log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) | ||||||
| 			p.AccessMode = perm.AccessModeNone | 			p.AccessMode = perm.AccessModeNone | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -52,7 +53,7 @@ func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *m | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(issue.Poster, issue.Repo) | 	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo) | ||||||
| 	var err error | 	var err error | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		if err = issue.LoadPullRequest(); err != nil { | 		if err = issue.LoadPullRequest(); err != nil { | ||||||
| @@ -82,8 +83,8 @@ func (m *webhookNotifier) NotifyIssueClearLabels(doer *user_model.User, issue *m | |||||||
| } | } | ||||||
|  |  | ||||||
| func (m *webhookNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) { | func (m *webhookNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, repo *repo_model.Repository) { | ||||||
| 	oldMode, _ := models.AccessLevel(doer, oldRepo) | 	oldMode, _ := access_model.AccessLevel(doer, oldRepo) | ||||||
| 	mode, _ := models.AccessLevel(doer, repo) | 	mode, _ := access_model.AccessLevel(doer, repo) | ||||||
|  |  | ||||||
| 	// forked webhook | 	// forked webhook | ||||||
| 	if err := webhook_services.PrepareWebhooks(oldRepo, webhook.HookEventFork, &api.ForkPayload{ | 	if err := webhook_services.PrepareWebhooks(oldRepo, webhook.HookEventFork, &api.ForkPayload{ | ||||||
| @@ -151,7 +152,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue | |||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		mode, _ := models.AccessLevelUnit(doer, issue.Repo, unit.TypePullRequests) | 		mode, _ := access_model.AccessLevelUnit(doer, issue.Repo, unit.TypePullRequests) | ||||||
|  |  | ||||||
| 		if err := issue.LoadPullRequest(); err != nil { | 		if err := issue.LoadPullRequest(); err != nil { | ||||||
| 			log.Error("LoadPullRequest failed: %v", err) | 			log.Error("LoadPullRequest failed: %v", err) | ||||||
| @@ -175,7 +176,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		mode, _ := models.AccessLevelUnit(doer, issue.Repo, unit.TypeIssues) | 		mode, _ := access_model.AccessLevelUnit(doer, issue.Repo, unit.TypeIssues) | ||||||
| 		apiIssue := &api.IssuePayload{ | 		apiIssue := &api.IssuePayload{ | ||||||
| 			Index:      issue.Index, | 			Index:      issue.Index, | ||||||
| 			Issue:      convert.ToAPIIssue(issue), | 			Issue:      convert.ToAPIIssue(issue), | ||||||
| @@ -199,7 +200,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *user_model.User, issue *m | |||||||
| 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeTitle User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) | 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeTitle User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(issue.Poster, issue.Repo) | 	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo) | ||||||
| 	var err error | 	var err error | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		if err = issue.LoadPullRequest(); err != nil { | 		if err = issue.LoadPullRequest(); err != nil { | ||||||
| @@ -243,7 +244,7 @@ func (m *webhookNotifier) NotifyIssueChangeStatus(doer *user_model.User, issue * | |||||||
| 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeStatus User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) | 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeStatus User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(issue.Poster, issue.Repo) | 	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo) | ||||||
| 	var err error | 	var err error | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		if err = issue.LoadPullRequest(); err != nil { | 		if err = issue.LoadPullRequest(); err != nil { | ||||||
| @@ -292,7 +293,7 @@ func (m *webhookNotifier) NotifyNewIssue(issue *models.Issue, mentions []*user_m | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(issue.Poster, issue.Repo) | 	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo) | ||||||
| 	if err := webhook_services.PrepareWebhooks(issue.Repo, webhook.HookEventIssues, &api.IssuePayload{ | 	if err := webhook_services.PrepareWebhooks(issue.Repo, webhook.HookEventIssues, &api.IssuePayload{ | ||||||
| 		Action:     api.HookIssueOpened, | 		Action:     api.HookIssueOpened, | ||||||
| 		Index:      issue.Index, | 		Index:      issue.Index, | ||||||
| @@ -321,7 +322,7 @@ func (m *webhookNotifier) NotifyNewPullRequest(pull *models.PullRequest, mention | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(pull.Issue.Poster, pull.Issue.Repo) | 	mode, _ := access_model.AccessLevel(pull.Issue.Poster, pull.Issue.Repo) | ||||||
| 	if err := webhook_services.PrepareWebhooks(pull.Issue.Repo, webhook.HookEventPullRequest, &api.PullRequestPayload{ | 	if err := webhook_services.PrepareWebhooks(pull.Issue.Repo, webhook.HookEventPullRequest, &api.PullRequestPayload{ | ||||||
| 		Action:      api.HookIssueOpened, | 		Action:      api.HookIssueOpened, | ||||||
| 		Index:       pull.Issue.Index, | 		Index:       pull.Issue.Index, | ||||||
| @@ -337,7 +338,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(doer *user_model.User, issue | |||||||
| 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeContent User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) | 	ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("webhook.NotifyIssueChangeContent User: %s[%d] Issue[%d] #%d in [%d]", doer.Name, doer.ID, issue.ID, issue.Index, issue.RepoID)) | ||||||
| 	defer finished() | 	defer finished() | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(issue.Poster, issue.Repo) | 	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo) | ||||||
| 	var err error | 	var err error | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		issue.PullRequest.Issue = issue | 		issue.PullRequest.Issue = issue | ||||||
| @@ -389,7 +390,7 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(doer, c.Issue.Repo) | 	mode, _ := access_model.AccessLevel(doer, c.Issue.Repo) | ||||||
| 	if c.Issue.IsPull { | 	if c.Issue.IsPull { | ||||||
| 		err = webhook_services.PrepareWebhooks(c.Issue.Repo, webhook.HookEventPullRequestComment, &api.IssueCommentPayload{ | 		err = webhook_services.PrepareWebhooks(c.Issue.Repo, webhook.HookEventPullRequestComment, &api.IssueCommentPayload{ | ||||||
| 			Action:  api.HookIssueCommentEdited, | 			Action:  api.HookIssueCommentEdited, | ||||||
| @@ -428,7 +429,7 @@ func (m *webhookNotifier) NotifyUpdateComment(doer *user_model.User, c *models.C | |||||||
| func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, | func (m *webhookNotifier) NotifyCreateIssueComment(doer *user_model.User, repo *repo_model.Repository, | ||||||
| 	issue *models.Issue, comment *models.Comment, mentions []*user_model.User, | 	issue *models.Issue, comment *models.Comment, mentions []*user_model.User, | ||||||
| ) { | ) { | ||||||
| 	mode, _ := models.AccessLevel(doer, repo) | 	mode, _ := access_model.AccessLevel(doer, repo) | ||||||
|  |  | ||||||
| 	var err error | 	var err error | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| @@ -473,7 +474,7 @@ func (m *webhookNotifier) NotifyDeleteComment(doer *user_model.User, comment *mo | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(doer, comment.Issue.Repo) | 	mode, _ := access_model.AccessLevel(doer, comment.Issue.Repo) | ||||||
|  |  | ||||||
| 	if comment.Issue.IsPull { | 	if comment.Issue.IsPull { | ||||||
| 		err = webhook_services.PrepareWebhooks(comment.Issue.Repo, webhook.HookEventPullRequestComment, &api.IssueCommentPayload{ | 		err = webhook_services.PrepareWebhooks(comment.Issue.Repo, webhook.HookEventPullRequestComment, &api.IssueCommentPayload{ | ||||||
| @@ -518,7 +519,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue * | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(issue.Poster, issue.Repo) | 	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo) | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		if err = issue.LoadPullRequest(); err != nil { | 		if err = issue.LoadPullRequest(); err != nil { | ||||||
| 			log.Error("loadPullRequest: %v", err) | 			log.Error("loadPullRequest: %v", err) | ||||||
| @@ -566,7 +567,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *user_model.User, issu | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(doer, issue.Repo) | 	mode, _ := access_model.AccessLevel(doer, issue.Repo) | ||||||
| 	if issue.IsPull { | 	if issue.IsPull { | ||||||
| 		err = issue.PullRequest.LoadIssue() | 		err = issue.PullRequest.LoadIssue() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| @@ -640,7 +641,7 @@ func (*webhookNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *use | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, err := models.AccessLevel(doer, pr.Issue.Repo) | 	mode, err := access_model.AccessLevel(doer, pr.Issue.Repo) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("models.AccessLevel: %v", err) | 		log.Error("models.AccessLevel: %v", err) | ||||||
| 		return | 		return | ||||||
| @@ -676,7 +677,7 @@ func (m *webhookNotifier) NotifyPullRequestChangeTargetBranch(doer *user_model.U | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	issue.PullRequest.Issue = issue | 	issue.PullRequest.Issue = issue | ||||||
| 	mode, _ := models.AccessLevel(issue.Poster, issue.Repo) | 	mode, _ := access_model.AccessLevel(issue.Poster, issue.Repo) | ||||||
| 	err = webhook_services.PrepareWebhooks(issue.Repo, webhook.HookEventPullRequest, &api.PullRequestPayload{ | 	err = webhook_services.PrepareWebhooks(issue.Repo, webhook.HookEventPullRequest, &api.PullRequestPayload{ | ||||||
| 		Action: api.HookIssueEdited, | 		Action: api.HookIssueEdited, | ||||||
| 		Index:  issue.Index, | 		Index:  issue.Index, | ||||||
| @@ -719,7 +720,7 @@ func (m *webhookNotifier) NotifyPullRequestReview(pr *models.PullRequest, review | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, err := models.AccessLevel(review.Issue.Poster, review.Issue.Repo) | 	mode, err := access_model.AccessLevel(review.Issue.Poster, review.Issue.Repo) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("models.AccessLevel: %v", err) | 		log.Error("models.AccessLevel: %v", err) | ||||||
| 		return | 		return | ||||||
| @@ -801,7 +802,7 @@ func sendReleaseHook(doer *user_model.User, rel *models.Release, action api.Hook | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	mode, _ := models.AccessLevel(doer, rel.Repo) | 	mode, _ := access_model.AccessLevel(doer, rel.Repo) | ||||||
| 	if err := webhook_services.PrepareWebhooks(rel.Repo, webhook.HookEventRelease, &api.ReleasePayload{ | 	if err := webhook_services.PrepareWebhooks(rel.Repo, webhook.HookEventRelease, &api.ReleasePayload{ | ||||||
| 		Action:     action, | 		Action:     action, | ||||||
| 		Release:    convert.ToRelease(rel), | 		Release:    convert.ToRelease(rel), | ||||||
|   | |||||||
| @@ -574,7 +574,7 @@ func Avatar(item interface{}, others ...interface{}) template.HTML { | |||||||
| 		if src != "" { | 		if src != "" { | ||||||
| 			return AvatarHTML(src, size, class, t.DisplayName()) | 			return AvatarHTML(src, size, class, t.DisplayName()) | ||||||
| 		} | 		} | ||||||
| 	case *models.Collaborator: | 	case *repo_model.Collaborator: | ||||||
| 		src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor) | 		src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor) | ||||||
| 		if src != "" { | 		if src != "" { | ||||||
| 			return AvatarHTML(src, size, class, t.DisplayName()) | 			return AvatarHTML(src, size, class, t.DisplayName()) | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ import ( | |||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -61,7 +61,7 @@ func LoadRepo(t *testing.T, ctx *context.Context, repoID int64) { | |||||||
| 	ctx.Repo.Owner, err = user_model.GetUserByID(ctx.Repo.Repository.OwnerID) | 	ctx.Repo.Owner, err = user_model.GetUserByID(ctx.Repo.Repository.OwnerID) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	ctx.Repo.RepoLink = ctx.Repo.Repository.Link() | 	ctx.Repo.RepoLink = ctx.Repo.Repository.Link() | ||||||
| 	ctx.Repo.Permission, err = models.GetUserRepoPermission(ctx, ctx.Repo.Repository, ctx.Doer) | 	ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, ctx.Doer) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -70,9 +70,9 @@ import ( | |||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -183,7 +183,7 @@ func repoAssignment() func(ctx *context.APIContext) { | |||||||
| 		repo.Owner = owner | 		repo.Owner = owner | ||||||
| 		ctx.Repo.Repository = repo | 		ctx.Repo.Repository = repo | ||||||
|  |  | ||||||
| 		ctx.Repo.Permission, err = models.GetUserRepoPermission(ctx, repo, ctx.Doer) | 		ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | 			ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	unit_model "code.gitea.io/gitea/models/unit" | 	unit_model "code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -547,7 +548,7 @@ func GetTeamRepos(ctx *context.APIContext) { | |||||||
| 	} | 	} | ||||||
| 	repos := make([]*api.Repository, len(teamRepos)) | 	repos := make([]*api.Repository, len(teamRepos)) | ||||||
| 	for i, repo := range teamRepos { | 	for i, repo := range teamRepos { | ||||||
| 		access, err := models.AccessLevel(ctx.Doer, repo) | 		access, err := access_model.AccessLevel(ctx.Doer, repo) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err) | 			ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err) | ||||||
| 			return | 			return | ||||||
| @@ -598,7 +599,7 @@ func GetTeamRepo(ctx *context.APIContext) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	access, err := models.AccessLevel(ctx.Doer, repo) | 	access, err := access_model.AccessLevel(ctx.Doer, repo) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err) | 		ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err) | ||||||
| 		return | 		return | ||||||
| @@ -655,7 +656,7 @@ func AddTeamRepository(ctx *context.APIContext) { | |||||||
| 	if ctx.Written() { | 	if ctx.Written() { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if access, err := models.AccessLevel(ctx.Doer, repo); err != nil { | 	if access, err := access_model.AccessLevel(ctx.Doer, repo); err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | ||||||
| 		return | 		return | ||||||
| 	} else if access < perm.AccessModeAdmin { | 	} else if access < perm.AccessModeAdmin { | ||||||
| @@ -705,7 +706,7 @@ func RemoveTeamRepository(ctx *context.APIContext) { | |||||||
| 	if ctx.Written() { | 	if ctx.Written() { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if access, err := models.AccessLevel(ctx.Doer, repo); err != nil { | 	if access, err := access_model.AccessLevel(ctx.Doer, repo); err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | ||||||
| 		return | 		return | ||||||
| 	} else if access < perm.AccessModeAdmin { | 	} else if access < perm.AccessModeAdmin { | ||||||
|   | |||||||
| @@ -11,6 +11,8 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
|  | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| @@ -49,13 +51,13 @@ func ListCollaborators(ctx *context.APIContext) { | |||||||
| 	//   "200": | 	//   "200": | ||||||
| 	//     "$ref": "#/responses/UserList" | 	//     "$ref": "#/responses/UserList" | ||||||
|  |  | ||||||
| 	count, err := models.CountCollaborators(ctx.Repo.Repository.ID) | 	count, err := repo_model.CountCollaborators(ctx.Repo.Repository.ID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.InternalServerError(err) | 		ctx.InternalServerError(err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	collaborators, err := models.GetCollaborators(ctx.Repo.Repository.ID, utils.GetListOptions(ctx)) | 	collaborators, err := repo_model.GetCollaborators(ctx, ctx.Repo.Repository.ID, utils.GetListOptions(ctx)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) | 		ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) | ||||||
| 		return | 		return | ||||||
| @@ -110,7 +112,7 @@ func IsCollaborator(ctx *context.APIContext) { | |||||||
| 		} | 		} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	isColab, err := models.IsCollaborator(ctx.Repo.Repository.ID, user.ID) | 	isColab, err := repo_model.IsCollaborator(ctx, ctx.Repo.Repository.ID, user.ID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "IsCollaborator", err) | 		ctx.Error(http.StatusInternalServerError, "IsCollaborator", err) | ||||||
| 		return | 		return | ||||||
| @@ -178,7 +180,7 @@ func AddCollaborator(ctx *context.APIContext) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if form.Permission != nil { | 	if form.Permission != nil { | ||||||
| 		if err := models.ChangeCollaborationAccessMode(ctx.Repo.Repository, collaborator.ID, perm.ParseAccessMode(*form.Permission)); err != nil { | 		if err := repo_model.ChangeCollaborationAccessMode(ctx.Repo.Repository, collaborator.ID, perm.ParseAccessMode(*form.Permission)); err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "ChangeCollaborationAccessMode", err) | 			ctx.Error(http.StatusInternalServerError, "ChangeCollaborationAccessMode", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| @@ -279,7 +281,7 @@ func GetRepoPermissions(ctx *context.APIContext) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	permission, err := models.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator) | 	permission, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -209,7 +209,7 @@ func GetEditorconfig(ctx *context.APIContext) { | |||||||
|  |  | ||||||
| // canWriteFiles returns true if repository is editable and user has proper access level. | // canWriteFiles returns true if repository is editable and user has proper access level. | ||||||
| func canWriteFiles(ctx *context.APIContext, branch string) bool { | func canWriteFiles(ctx *context.APIContext, branch string) bool { | ||||||
| 	return ctx.Repo.Permission.CanWriteToBranch(ctx.Doer, branch) && | 	return ctx.Repo.CanWriteToBranch(ctx.Doer, branch) && | ||||||
| 		!ctx.Repo.Repository.IsMirror && | 		!ctx.Repo.Repository.IsMirror && | ||||||
| 		!ctx.Repo.Repository.IsArchived | 		!ctx.Repo.Repository.IsArchived | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,9 +9,9 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -59,7 +59,7 @@ func ListForks(ctx *context.APIContext) { | |||||||
| 	} | 	} | ||||||
| 	apiForks := make([]*api.Repository, len(forks)) | 	apiForks := make([]*api.Repository, len(forks)) | ||||||
| 	for i, fork := range forks { | 	for i, fork := range forks { | ||||||
| 		access, err := models.AccessLevel(ctx.Doer, fork) | 		access, err := access_model.AccessLevel(ctx.Doer, fork) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -629,7 +630,7 @@ func CreateIssue(ctx *context.APIContext) { | |||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			valid, err := models.CanBeAssigned(assignee, ctx.Repo.Repository, false) | 			valid, err := access_model.CanBeAssigned(ctx, assignee, ctx.Repo.Repository, false) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) | 				ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) | ||||||
| 				return | 				return | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -203,7 +204,7 @@ func isXRefCommentAccessible(ctx stdCtx.Context, user *user_model.User, c *model | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 		perm, err := models.GetUserRepoPermission(ctx, c.RefRepo, user) | 		perm, err := access_model.GetUserRepoPermission(ctx, c.RefRepo, user) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	pull_model "code.gitea.io/gitea/models/pull" | 	pull_model "code.gitea.io/gitea/models/pull" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| @@ -402,7 +403,7 @@ func CreatePullRequest(ctx *context.APIContext) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		valid, err := models.CanBeAssigned(assignee, repo, true) | 		valid, err := access_model.CanBeAssigned(ctx, assignee, repo, true) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) | 			ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) | ||||||
| 			return | 			return | ||||||
| @@ -983,7 +984,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// user should have permission to read baseRepo's codes and pulls, NOT headRepo's | 	// user should have permission to read baseRepo's codes and pulls, NOT headRepo's | ||||||
| 	permBase, err := models.GetUserRepoPermission(ctx, baseRepo, ctx.Doer) | 	permBase, err := access_model.GetUserRepoPermission(ctx, baseRepo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		headGitRepo.Close() | 		headGitRepo.Close() | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | ||||||
| @@ -1002,7 +1003,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// user should have permission to read headrepo's codes | 	// user should have permission to read headrepo's codes | ||||||
| 	permHead, err := models.GetUserRepoPermission(ctx, headRepo, ctx.Doer) | 	permHead, err := access_model.GetUserRepoPermission(ctx, headRepo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		headGitRepo.Close() | 		headGitRepo.Close() | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | ||||||
| @@ -1197,7 +1198,7 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if ctx.Doer.ID != autoMerge.DoerID { | 	if ctx.Doer.ID != autoMerge.DoerID { | ||||||
| 		allowed, err := models.IsUserRepoAdminCtx(ctx, ctx.Repo.Repository, ctx.Doer) | 		allowed, err := access_model.IsUserRepoAdminCtx(ctx, ctx.Repo.Repository, ctx.Doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.InternalServerError(err) | 			ctx.InternalServerError(err) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| @@ -664,7 +665,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions | |||||||
|  |  | ||||||
| 	reviewers := make([]*user_model.User, 0, len(opts.Reviewers)) | 	reviewers := make([]*user_model.User, 0, len(opts.Reviewers)) | ||||||
|  |  | ||||||
| 	permDoer, err := models.GetUserRepoPermission(ctx, pr.Issue.Repo, ctx.Doer) | 	permDoer, err := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | 		ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	unit_model "code.gitea.io/gitea/models/unit" | 	unit_model "code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -209,7 +210,7 @@ func Search(ctx *context.APIContext) { | |||||||
| 			}) | 			}) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		accessMode, err := models.AccessLevel(ctx.Doer, repo) | 		accessMode, err := access_model.AccessLevel(ctx.Doer, repo) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.JSON(http.StatusInternalServerError, api.SearchError{ | 			ctx.JSON(http.StatusInternalServerError, api.SearchError{ | ||||||
| 				OK:    false, | 				OK:    false, | ||||||
| @@ -555,7 +556,7 @@ func GetByID(ctx *context.APIContext) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, repo, ctx.Doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | 		ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/convert" | 	"code.gitea.io/gitea/modules/convert" | ||||||
| @@ -38,7 +39,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) { | |||||||
|  |  | ||||||
| 	apiRepos := make([]*api.Repository, 0, len(repos)) | 	apiRepos := make([]*api.Repository, 0, len(repos)) | ||||||
| 	for i := range repos { | 	for i := range repos { | ||||||
| 		access, err := models.AccessLevel(ctx.Doer, repos[i]) | 		access, err := access_model.AccessLevel(ctx.Doer, repos[i]) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | ||||||
| 			return | 			return | ||||||
| @@ -123,7 +124,7 @@ func ListMyRepos(ctx *context.APIContext) { | |||||||
| 			ctx.Error(http.StatusInternalServerError, "GetOwner", err) | 			ctx.Error(http.StatusInternalServerError, "GetOwner", err) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		accessMode, err := models.AccessLevel(ctx.Doer, repo) | 		accessMode, err := access_model.AccessLevel(ctx.Doer, repo) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | 			ctx.Error(http.StatusInternalServerError, "AccessLevel", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ package user | |||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -28,7 +28,7 @@ func getStarredRepos(user *user_model.User, private bool, listOptions db.ListOpt | |||||||
|  |  | ||||||
| 	repos := make([]*api.Repository, len(starredRepos)) | 	repos := make([]*api.Repository, len(starredRepos)) | ||||||
| 	for i, starred := range starredRepos { | 	for i, starred := range starredRepos { | ||||||
| 		access, err := models.AccessLevel(user, starred) | 		access, err := access_model.AccessLevel(user, starred) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -7,8 +7,8 @@ package user | |||||||
| import ( | import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -26,7 +26,7 @@ func getWatchedRepos(user *user_model.User, private bool, listOptions db.ListOpt | |||||||
|  |  | ||||||
| 	repos := make([]*api.Repository, len(watchedRepos)) | 	repos := make([]*api.Repository, len(watchedRepos)) | ||||||
| 	for i, watched := range watchedRepos { | 	for i, watched := range watchedRepos { | ||||||
| 		access, err := models.AccessLevel(user, watched) | 		access, err := access_model.AccessLevel(user, watched) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, 0, err | 			return nil, 0, err | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| 	perm_model "code.gitea.io/gitea/models/perm" | 	perm_model "code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	gitea_context "code.gitea.io/gitea/modules/context" | 	gitea_context "code.gitea.io/gitea/modules/context" | ||||||
| @@ -30,7 +31,7 @@ type preReceiveContext struct { | |||||||
| 	// loadedPusher indicates that where the following information are loaded | 	// loadedPusher indicates that where the following information are loaded | ||||||
| 	loadedPusher        bool | 	loadedPusher        bool | ||||||
| 	user                *user_model.User // it's the org user if a DeployKey is used | 	user                *user_model.User // it's the org user if a DeployKey is used | ||||||
| 	userPerm            models.Permission | 	userPerm            access_model.Permission | ||||||
| 	deployKeyAccessMode perm_model.AccessMode | 	deployKeyAccessMode perm_model.AccessMode | ||||||
|  |  | ||||||
| 	canCreatePullRequest        bool | 	canCreatePullRequest        bool | ||||||
| @@ -55,7 +56,7 @@ func (ctx *preReceiveContext) CanWriteCode() bool { | |||||||
| 		if !ctx.loadPusherAndPermission() { | 		if !ctx.loadPusherAndPermission() { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 		ctx.canWriteCode = ctx.userPerm.CanWriteToBranch(ctx.user, ctx.branchName) || ctx.deployKeyAccessMode >= perm_model.AccessModeWrite | 		ctx.canWriteCode = models.CanMaintainerWriteToBranch(ctx.userPerm, ctx.branchName, ctx.user) || ctx.deployKeyAccessMode >= perm_model.AccessModeWrite | ||||||
| 		ctx.checkedCanWriteCode = true | 		ctx.checkedCanWriteCode = true | ||||||
| 	} | 	} | ||||||
| 	return ctx.canWriteCode | 	return ctx.canWriteCode | ||||||
| @@ -472,7 +473,7 @@ func (ctx *preReceiveContext) loadPusherAndPermission() bool { | |||||||
| 	} | 	} | ||||||
| 	ctx.user = user | 	ctx.user = user | ||||||
|  |  | ||||||
| 	userPerm, err := models.GetUserRepoPermission(ctx, ctx.Repo.Repository, user) | 	userPerm, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, user) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Unable to get Repo permission of repo %s/%s of User %s", ctx.Repo.Repository.OwnerName, ctx.Repo.Repository.Name, user.Name, err) | 		log.Error("Unable to get Repo permission of repo %s/%s of User %s", ctx.Repo.Repository.OwnerName, ctx.Repo.Repository.Name, user.Name, err) | ||||||
| 		ctx.JSON(http.StatusInternalServerError, private.Response{ | 		ctx.JSON(http.StatusInternalServerError, private.Response{ | ||||||
|   | |||||||
| @@ -10,9 +10,9 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	asymkey_model "code.gitea.io/gitea/models/asymkey" | 	asymkey_model "code.gitea.io/gitea/models/asymkey" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -320,7 +320,7 @@ func ServCommand(ctx *context.PrivateContext) { | |||||||
| 				mode = perm.AccessModeRead | 				mode = perm.AccessModeRead | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			perm, err := models.GetUserRepoPermission(ctx, repo, user) | 			perm, err := access_model.GetUserRepoPermission(ctx, repo, user) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Error("Unable to get permissions for %-v with key %d in %-v Error: %v", user, key.ID, repo, err) | 				log.Error("Unable to get permissions for %-v with key %d in %-v Error: %v", user, key.ID, repo, err) | ||||||
| 				ctx.JSON(http.StatusInternalServerError, private.ErrServCommand{ | 				ctx.JSON(http.StatusInternalServerError, private.ErrServCommand{ | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/httpcache" | 	"code.gitea.io/gitea/modules/httpcache" | ||||||
| @@ -106,7 +107,7 @@ func GetAttachment(ctx *context.Context) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	} else { // If we have the repository we check access | 	} else { // If we have the repository we check access | ||||||
| 		perm, err := models.GetUserRepoPermission(ctx, repository, ctx.Doer) | 		perm, err := access_model.GetUserRepoPermission(ctx, repository, ctx.Doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err.Error()) | 			ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err.Error()) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -412,7 +413,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { | |||||||
| 	// Now we need to assert that the ctx.Doer has permission to read | 	// Now we need to assert that the ctx.Doer has permission to read | ||||||
| 	// the baseRepo's code and pulls | 	// the baseRepo's code and pulls | ||||||
| 	// (NOT headRepo's) | 	// (NOT headRepo's) | ||||||
| 	permBase, err := models.GetUserRepoPermission(ctx, baseRepo, ctx.Doer) | 	permBase, err := access_model.GetUserRepoPermission(ctx, baseRepo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetUserRepoPermission", err) | 		ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 		return nil | 		return nil | ||||||
| @@ -431,7 +432,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { | |||||||
| 	// If we're not merging from the same repo: | 	// If we're not merging from the same repo: | ||||||
| 	if !isSameRepo { | 	if !isSameRepo { | ||||||
| 		// Assert ctx.Doer has permission to read headRepo's codes | 		// Assert ctx.Doer has permission to read headRepo's codes | ||||||
| 		permHead, err := models.GetUserRepoPermission(ctx, ci.HeadRepo, ctx.Doer) | 		permHead, err := access_model.GetUserRepoPermission(ctx, ci.HeadRepo, ctx.Doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("GetUserRepoPermission", err) | 			ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 			return nil | 			return nil | ||||||
|   | |||||||
| @@ -19,9 +19,9 @@ import ( | |||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" |  | ||||||
| 	"code.gitea.io/gitea/models/auth" | 	"code.gitea.io/gitea/models/auth" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -182,7 +182,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if repoExist { | 		if repoExist { | ||||||
| 			p, err := models.GetUserRepoPermission(ctx, repo, ctx.Doer) | 			p, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.ServerError("GetUserRepoPermission", err) | 				ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 				return | 				return | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	issues_model "code.gitea.io/gitea/models/issues" | 	issues_model "code.gitea.io/gitea/models/issues" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	project_model "code.gitea.io/gitea/models/project" | 	project_model "code.gitea.io/gitea/models/project" | ||||||
| 	pull_model "code.gitea.io/gitea/models/pull" | 	pull_model "code.gitea.io/gitea/models/pull" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| @@ -959,7 +960,7 @@ func ValidateRepoMetas(ctx *context.Context, form forms.CreateIssueForm, isPull | |||||||
| 				return nil, nil, 0, 0 | 				return nil, nil, 0, 0 | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			valid, err := models.CanBeAssigned(assignee, repo, isPull) | 			valid, err := access_model.CanBeAssigned(ctx, assignee, repo, isPull) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.ServerError("CanBeAssigned", err) | 				ctx.ServerError("CanBeAssigned", err) | ||||||
| 				return nil, nil, 0, 0 | 				return nil, nil, 0, 0 | ||||||
| @@ -1051,7 +1052,7 @@ func NewIssuePost(ctx *context.Context) { | |||||||
|  |  | ||||||
| // roleDescriptor returns the Role Descriptor for a comment in/with the given repo, poster and issue | // roleDescriptor returns the Role Descriptor for a comment in/with the given repo, poster and issue | ||||||
| func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *models.Issue) (models.RoleDescriptor, error) { | func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *models.Issue) (models.RoleDescriptor, error) { | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, repo, poster) | 	perm, err := access_model.GetUserRepoPermission(ctx, repo, poster) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return models.RoleDescriptorNone, err | 		return models.RoleDescriptorNone, err | ||||||
| 	} | 	} | ||||||
| @@ -1067,7 +1068,7 @@ func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *use | |||||||
| 		} else { | 		} else { | ||||||
|  |  | ||||||
| 			// Otherwise check if poster is the real repo admin. | 			// Otherwise check if poster is the real repo admin. | ||||||
| 			ok, err := models.IsUserRealRepoAdmin(repo, poster) | 			ok, err := access_model.IsUserRealRepoAdmin(repo, poster) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return models.RoleDescriptorNone, err | 				return models.RoleDescriptorNone, err | ||||||
| 			} | 			} | ||||||
| @@ -1526,7 +1527,7 @@ func ViewIssue(ctx *context.Context) { | |||||||
| 			if err := pull.LoadHeadRepoCtx(ctx); err != nil { | 			if err := pull.LoadHeadRepoCtx(ctx); err != nil { | ||||||
| 				log.Error("LoadHeadRepo: %v", err) | 				log.Error("LoadHeadRepo: %v", err) | ||||||
| 			} else if pull.HeadRepo != nil { | 			} else if pull.HeadRepo != nil { | ||||||
| 				perm, err := models.GetUserRepoPermission(ctx, pull.HeadRepo, ctx.Doer) | 				perm, err := access_model.GetUserRepoPermission(ctx, pull.HeadRepo, ctx.Doer) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					ctx.ServerError("GetUserRepoPermission", err) | 					ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 					return | 					return | ||||||
| @@ -1548,7 +1549,7 @@ func ViewIssue(ctx *context.Context) { | |||||||
| 			if err := pull.LoadBaseRepoCtx(ctx); err != nil { | 			if err := pull.LoadBaseRepoCtx(ctx); err != nil { | ||||||
| 				log.Error("LoadBaseRepo: %v", err) | 				log.Error("LoadBaseRepo: %v", err) | ||||||
| 			} | 			} | ||||||
| 			perm, err := models.GetUserRepoPermission(ctx, pull.BaseRepo, ctx.Doer) | 			perm, err := access_model.GetUserRepoPermission(ctx, pull.BaseRepo, ctx.Doer) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.ServerError("GetUserRepoPermission", err) | 				ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 				return | 				return | ||||||
| @@ -1978,7 +1979,7 @@ func UpdateIssueAssignee(ctx *context.Context) { | |||||||
| 				return | 				return | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			valid, err := models.CanBeAssigned(assignee, issue.Repo, issue.IsPull) | 			valid, err := access_model.CanBeAssigned(ctx, assignee, issue.Repo, issue.IsPull) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				ctx.ServerError("canBeAssigned", err) | 				ctx.ServerError("canBeAssigned", err) | ||||||
| 				return | 				return | ||||||
| @@ -2941,7 +2942,7 @@ func filterXRefComments(ctx *context.Context, issue *models.Issue) error { | |||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
| 			perm, err := models.GetUserRepoPermission(ctx, c.RefRepo, ctx.Doer) | 			perm, err := access_model.GetUserRepoPermission(ctx, c.RefRepo, ctx.Doer) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -70,7 +71,7 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, repo, ctx.Doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetUserRepoPermission", err) | 		ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 		return nil | 		return nil | ||||||
| @@ -1247,7 +1248,7 @@ func CleanUpPullRequest(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, pr.HeadRepo, ctx.Doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetUserRepoPermission", err) | 		ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -833,7 +833,7 @@ func Collaboration(ctx *context.Context) { | |||||||
| 	ctx.Data["Title"] = ctx.Tr("repo.settings") | 	ctx.Data["Title"] = ctx.Tr("repo.settings") | ||||||
| 	ctx.Data["PageIsSettingsCollaboration"] = true | 	ctx.Data["PageIsSettingsCollaboration"] = true | ||||||
|  |  | ||||||
| 	users, err := models.GetCollaborators(ctx.Repo.Repository.ID, db.ListOptions{}) | 	users, err := repo_model.GetCollaborators(ctx, ctx.Repo.Repository.ID, db.ListOptions{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetCollaborators", err) | 		ctx.ServerError("GetCollaborators", err) | ||||||
| 		return | 		return | ||||||
| @@ -887,7 +887,7 @@ func CollaborationPost(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if got, err := models.IsCollaborator(ctx.Repo.Repository.ID, u.ID); err == nil && got { | 	if got, err := repo_model.IsCollaborator(ctx, ctx.Repo.Repository.ID, u.ID); err == nil && got { | ||||||
| 		ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_duplicate")) | 		ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_duplicate")) | ||||||
| 		ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration") | 		ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration") | ||||||
| 		return | 		return | ||||||
| @@ -908,7 +908,7 @@ func CollaborationPost(ctx *context.Context) { | |||||||
|  |  | ||||||
| // ChangeCollaborationAccessMode response for changing access of a collaboration | // ChangeCollaborationAccessMode response for changing access of a collaboration | ||||||
| func ChangeCollaborationAccessMode(ctx *context.Context) { | func ChangeCollaborationAccessMode(ctx *context.Context) { | ||||||
| 	if err := models.ChangeCollaborationAccessMode( | 	if err := repo_model.ChangeCollaborationAccessMode( | ||||||
| 		ctx.Repo.Repository, | 		ctx.Repo.Repository, | ||||||
| 		ctx.FormInt64("uid"), | 		ctx.FormInt64("uid"), | ||||||
| 		perm.AccessMode(ctx.FormInt("mode"))); err != nil { | 		perm.AccessMode(ctx.FormInt("mode"))); err != nil { | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -125,7 +126,7 @@ func SettingsProtectedBranch(c *context.Context) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	users, err := models.GetRepoReaders(c.Repo.Repository) | 	users, err := access_model.GetRepoReaders(c.Repo.Repository) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.ServerError("Repo.Repository.GetReaders", err) | 		c.ServerError("Repo.Repository.GetReaders", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -130,7 +130,7 @@ func TestCollaborationPost(t *testing.T) { | |||||||
|  |  | ||||||
| 	assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) | 	assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) | ||||||
|  |  | ||||||
| 	exists, err := models.IsCollaborator(re.ID, 4) | 	exists, err := repo_model.IsCollaborator(ctx, re.ID, 4) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, exists) | 	assert.True(t, exists) | ||||||
| } | } | ||||||
| @@ -188,7 +188,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) { | |||||||
|  |  | ||||||
| 	assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) | 	assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) | ||||||
|  |  | ||||||
| 	exists, err := models.IsCollaborator(re.ID, 4) | 	exists, err := repo_model.IsCollaborator(ctx, re.ID, 4) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, exists) | 	assert.True(t, exists) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| @@ -143,7 +144,7 @@ func setTagsContext(ctx *context.Context) error { | |||||||
| 	} | 	} | ||||||
| 	ctx.Data["ProtectedTags"] = protectedTags | 	ctx.Data["ProtectedTags"] = protectedTags | ||||||
|  |  | ||||||
| 	users, err := models.GetRepoReaders(ctx.Repo.Repository) | 	users, err := access_model.GetRepoReaders(ctx.Repo.Repository) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("Repo.Repository.GetReaders", err) | 		ctx.ServerError("Repo.Repository.GetReaders", err) | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import ( | |||||||
| 	packages_model "code.gitea.io/gitea/models/packages" | 	packages_model "code.gitea.io/gitea/models/packages" | ||||||
| 	container_model "code.gitea.io/gitea/models/packages/container" | 	container_model "code.gitea.io/gitea/models/packages/container" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| @@ -67,7 +68,7 @@ func ListPackages(ctx *context.Context) { | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer) | 		permission, err := access_model.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("GetUserRepoPermission", err) | 			ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 			return | 			return | ||||||
| @@ -177,7 +178,7 @@ func ViewPackageVersion(ctx *context.Context) { | |||||||
|  |  | ||||||
| 	hasRepositoryAccess := false | 	hasRepositoryAccess := false | ||||||
| 	if pd.Repository != nil { | 	if pd.Repository != nil { | ||||||
| 		permission, err := models.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer) | 		permission, err := access_model.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ctx.ServerError("GetUserRepoPermission", err) | 			ctx.ServerError("GetUserRepoPermission", err) | ||||||
| 			return | 			return | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	pull_model "code.gitea.io/gitea/models/pull" | 	pull_model "code.gitea.io/gitea/models/pull" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -224,7 +225,7 @@ func handlePull(pullID int64, sha string) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, pr.HeadRepo, doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("GetUserRepoPermission: %v", err) | 		log.Error("GetUserRepoPermission: %v", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -80,7 +81,7 @@ func ReviewRequest(issue *models.Issue, doer, reviewer *user_model.User, isAdd b | |||||||
| } | } | ||||||
|  |  | ||||||
| // IsValidReviewRequest Check permission for ReviewRequest | // IsValidReviewRequest Check permission for ReviewRequest | ||||||
| func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, isAdd bool, issue *models.Issue, permDoer *models.Permission) error { | func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, isAdd bool, issue *models.Issue, permDoer *access_model.Permission) error { | ||||||
| 	if reviewer.IsOrganization() { | 	if reviewer.IsOrganization() { | ||||||
| 		return models.ErrNotValidReviewRequest{ | 		return models.ErrNotValidReviewRequest{ | ||||||
| 			Reason: "Organization can't be added as reviewer", | 			Reason: "Organization can't be added as reviewer", | ||||||
| @@ -96,14 +97,14 @@ func IsValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	permReviewer, err := models.GetUserRepoPermission(ctx, issue.Repo, reviewer) | 	permReviewer, err := access_model.GetUserRepoPermission(ctx, issue.Repo, reviewer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if permDoer == nil { | 	if permDoer == nil { | ||||||
| 		permDoer = new(models.Permission) | 		permDoer = new(access_model.Permission) | ||||||
| 		*permDoer, err = models.GetUserRepoPermission(ctx, issue.Repo, doer) | 		*permDoer, err = access_model.GetUserRepoPermission(ctx, issue.Repo, doer) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -179,7 +180,7 @@ func IsValidTeamReviewRequest(ctx context.Context, reviewer *organization.Team, | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	permission, err := models.GetUserRepoPermission(ctx, issue.Repo, doer) | 	permission, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Unable to GetUserRepoPermission for %-v in %-v#%d", doer, issue.Repo, issue.Index) | 		log.Error("Unable to GetUserRepoPermission for %-v in %-v#%d", doer, issue.Repo, issue.Index) | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/references" | 	"code.gitea.io/gitea/modules/references" | ||||||
| @@ -131,7 +132,7 @@ func UpdateIssuesCommit(doer *user_model.User, repo *repo_model.Repository, comm | |||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			perm, err := models.GetUserRepoPermission(db.DefaultContext, refRepo, doer) | 			perm, err := access_model.GetUserRepoPermission(db.DefaultContext, refRepo, doer) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/git" | 	"code.gitea.io/gitea/modules/git" | ||||||
| @@ -172,7 +173,7 @@ func AddAssigneeIfNotAssigned(issue *models.Issue, doer *user_model.User, assign | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	valid, err := models.CanBeAssigned(assignee, issue.Repo, issue.IsPull) | 	valid, err := access_model.CanBeAssigned(db.DefaultContext, assignee, issue.Repo, issue.IsPull) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ package issue | |||||||
| import ( | import ( | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/notification" | 	"code.gitea.io/gitea/modules/notification" | ||||||
| ) | ) | ||||||
| @@ -54,7 +55,7 @@ func RemoveLabel(issue *models.Issue, doer *user_model.User, label *models.Label | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, issue.Repo, doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -488,7 +489,7 @@ func authenticate(ctx *context.Context, repository *repo_model.Repository, autho | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// ctx.IsSigned is unnecessary here, this will be checked in perm.CanAccess | 	// ctx.IsSigned is unnecessary here, this will be checked in perm.CanAccess | ||||||
| 	perm, err := models.GetUserRepoPermission(ctx, repository, ctx.Doer) | 	perm, err := access_model.GetUserRepoPermission(ctx, repository, ctx.Doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("Unable to GetUserRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository) | 		log.Error("Unable to GetUserRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository) | ||||||
| 		return false | 		return false | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -60,7 +61,7 @@ func AddToTaskQueue(pr *models.PullRequest) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...) | // CheckPullMergable check if the pull mergable based on all conditions (branch protection, merge options, ...) | ||||||
| func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *models.Permission, pr *models.PullRequest, manuallMerge, force bool) error { | func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *access_model.Permission, pr *models.PullRequest, manuallMerge, force bool) error { | ||||||
| 	return db.WithTx(func(ctx context.Context) error { | 	return db.WithTx(func(ctx context.Context) error { | ||||||
| 		if pr.HasMerged { | 		if pr.HasMerged { | ||||||
| 			return ErrHasMerged | 			return ErrHasMerged | ||||||
| @@ -98,7 +99,7 @@ func CheckPullMergable(stdCtx context.Context, doer *user_model.User, perm *mode | |||||||
| 		if err := CheckPullBranchProtections(ctx, pr, false); err != nil { | 		if err := CheckPullBranchProtections(ctx, pr, false); err != nil { | ||||||
| 			if models.IsErrDisallowedToMerge(err) { | 			if models.IsErrDisallowedToMerge(err) { | ||||||
| 				if force { | 				if force { | ||||||
| 					if isRepoAdmin, err2 := models.IsUserRepoAdminCtx(ctx, pr.BaseRepo, doer); err2 != nil { | 					if isRepoAdmin, err2 := access_model.IsUserRepoAdminCtx(ctx, pr.BaseRepo, doer); err2 != nil { | ||||||
| 						return err2 | 						return err2 | ||||||
| 					} else if !isRepoAdmin { | 					} else if !isRepoAdmin { | ||||||
| 						return err | 						return err | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	"errors" | 	"errors" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	unit_model "code.gitea.io/gitea/models/unit" | 	unit_model "code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| ) | ) | ||||||
| @@ -26,7 +27,7 @@ func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *models.PullRe | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	permission, err := models.GetUserRepoPermission(ctx, pr.HeadRepo, doer) | 	permission, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	pull_model "code.gitea.io/gitea/models/pull" | 	pull_model "code.gitea.io/gitea/models/pull" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| @@ -751,7 +752,7 @@ func getDiffTree(ctx context.Context, repoPath, baseBranch, headBranch string) ( | |||||||
| } | } | ||||||
|  |  | ||||||
| // IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections | // IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections | ||||||
| func IsUserAllowedToMerge(ctx context.Context, pr *models.PullRequest, p models.Permission, user *user_model.User) (bool, error) { | func IsUserAllowedToMerge(ctx context.Context, pr *models.PullRequest, p access_model.Permission, user *user_model.User) (bool, error) { | ||||||
| 	if user == nil { | 	if user == nil { | ||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unit" | 	"code.gitea.io/gitea/models/unit" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -83,7 +84,7 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user * | |||||||
| 	if user == nil { | 	if user == nil { | ||||||
| 		return false, false, nil | 		return false, false, nil | ||||||
| 	} | 	} | ||||||
| 	headRepoPerm, err := models.GetUserRepoPermission(ctx, pull.HeadRepo, user) | 	headRepoPerm, err := access_model.GetUserRepoPermission(ctx, pull.HeadRepo, user) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, false, err | 		return false, false, err | ||||||
| 	} | 	} | ||||||
| @@ -115,7 +116,7 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *models.PullRequest, user * | |||||||
| 		return false, false, nil | 		return false, false, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	baseRepoPerm, err := models.GetUserRepoPermission(ctx, pull.BaseRepo, user) | 	baseRepoPerm, err := access_model.GetUserRepoPermission(ctx, pull.BaseRepo, user) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, false, err | 		return false, false, err | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/db" | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	"code.gitea.io/gitea/models/perm" | 	"code.gitea.io/gitea/models/perm" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| @@ -105,7 +106,7 @@ func StartRepositoryTransfer(doer, newOwner *user_model.User, repo *repo_model.R | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// In case the new owner would not have sufficient access to the repo, give access rights for read | 	// In case the new owner would not have sufficient access to the repo, give access rights for read | ||||||
| 	hasAccess, err := models.HasAccess(newOwner.ID, repo) | 	hasAccess, err := access_model.HasAccess(db.DefaultContext, newOwner.ID, repo) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -113,7 +114,7 @@ func StartRepositoryTransfer(doer, newOwner *user_model.User, repo *repo_model.R | |||||||
| 		if err := models.AddCollaborator(repo, newOwner); err != nil { | 		if err := models.AddCollaborator(repo, newOwner); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		if err := models.ChangeCollaborationAccessMode(repo, newOwner.ID, perm.AccessModeRead); err != nil { | 		if err := repo_model.ChangeCollaborationAccessMode(repo, newOwner.ID, perm.AccessModeRead); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,9 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
|  | 	"code.gitea.io/gitea/models/db" | ||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
|  | 	access_model "code.gitea.io/gitea/models/perm/access" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	"code.gitea.io/gitea/models/unittest" | 	"code.gitea.io/gitea/models/unittest" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
| @@ -65,13 +67,13 @@ func TestStartRepositoryTransferSetPermission(t *testing.T) { | |||||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) | ||||||
| 	repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) | 	repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User) | ||||||
|  |  | ||||||
| 	hasAccess, err := models.HasAccess(recipient.ID, repo) | 	hasAccess, err := access_model.HasAccess(db.DefaultContext, recipient.ID, repo) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.False(t, hasAccess) | 	assert.False(t, hasAccess) | ||||||
|  |  | ||||||
| 	assert.NoError(t, StartRepositoryTransfer(doer, recipient, repo, nil)) | 	assert.NoError(t, StartRepositoryTransfer(doer, recipient, repo, nil)) | ||||||
|  |  | ||||||
| 	hasAccess, err = models.HasAccess(recipient.ID, repo) | 	hasAccess, err = access_model.HasAccess(db.DefaultContext, recipient.ID, repo) | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.True(t, hasAccess) | 	assert.True(t, hasAccess) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user