summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/action.go3
-rw-r--r--models/branches.go11
-rw-r--r--models/fixture_generation.go5
-rw-r--r--models/issue.go5
-rw-r--r--models/issue_xref.go3
-rw-r--r--models/lfs_lock.go3
-rw-r--r--models/org.go3
-rw-r--r--models/org_team.go33
-rw-r--r--models/org_team_test.go23
-rw-r--r--models/perm/access/access.go (renamed from models/access.go)34
-rw-r--r--models/perm/access/access_test.go (renamed from models/access_test.go)37
-rw-r--r--models/perm/access/main_test.go32
-rw-r--r--models/perm/access/repo_permission.go (renamed from models/repo_permission.go)93
-rw-r--r--models/pull_list.go35
-rw-r--r--models/repo.go51
-rw-r--r--models/repo/collaboration.go150
-rw-r--r--models/repo/collaboration_test.go49
-rw-r--r--models/repo/main_test.go1
-rw-r--r--models/repo_collaboration.go154
-rw-r--r--models/repo_collaboration_test.go50
-rw-r--r--models/repo_permission_test.go55
-rw-r--r--models/repo_transfer.go7
-rw-r--r--models/review.go3
-rw-r--r--models/statistic.go3
-rw-r--r--models/user.go6
25 files changed, 452 insertions, 397 deletions
diff --git a/models/action.go b/models/action.go
index 7055ce81d6..6b662b3107 100644
--- a/models/action.go
+++ b/models/action.go
@@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
@@ -510,7 +511,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error {
permPR[i] = false
continue
}
- perm, err := GetUserRepoPermission(ctx, repo, user)
+ perm, err := access_model.GetUserRepoPermission(ctx, repo, user)
if err != nil {
permCode[i] = false
permIssue[i] = false
diff --git a/models/branches.go b/models/branches.go
index 47fd3dc0a4..008cb8653c 100644
--- a/models/branches.go
+++ b/models/branches.go
@@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
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 {
log.Error("repo_model.GetRepositoryByID: %v", err)
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)
return false
} else {
@@ -104,7 +105,7 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
}
// 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 {
// Then we need to fall back on whether the user has write permission
return permissionInRepo.CanWrite(unit.TypeCode)
@@ -139,7 +140,7 @@ func isUserOfficialReviewer(ctx context.Context, protectBranch *ProtectedBranch,
if !protectBranch.EnableApprovalsWhitelist {
// 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 {
return false, err
}
@@ -424,7 +425,7 @@ func updateApprovalWhitelist(ctx context.Context, repo *repo_model.Repository, c
whitelist = make([]int64, 0, len(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
} else if !reader {
continue
@@ -449,7 +450,7 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre
if err != nil {
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 {
return nil, fmt.Errorf("GetUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err)
}
diff --git a/models/fixture_generation.go b/models/fixture_generation.go
index 56baa1c345..f4644859eb 100644
--- a/models/fixture_generation.go
+++ b/models/fixture_generation.go
@@ -9,6 +9,7 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
)
@@ -22,14 +23,14 @@ func GetYamlFixturesAccess() (string, error) {
for _, repo := range repos {
repo.MustOwner()
- if err := RecalculateAccesses(repo); err != nil {
+ if err := access_model.RecalculateAccesses(db.DefaultContext, repo); err != nil {
return "", err
}
}
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 {
return "", err
}
diff --git a/models/issue.go b/models/issue.go
index 98e64adafd..d9540f25dd 100644
--- a/models/issue.go
+++ b/models/issue.go
@@ -19,6 +19,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
@@ -489,7 +490,7 @@ func ClearIssueLabels(issue *Issue, doer *user_model.User) (err error) {
return err
}
- perm, err := GetUserRepoPermission(ctx, issue.Repo, doer)
+ perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer)
if err != nil {
return err
}
@@ -2314,7 +2315,7 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u
continue
}
// 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 {
return nil, fmt.Errorf("GetUserRepoPermission [%d]: %v", user.ID, err)
}
diff --git a/models/issue_xref.go b/models/issue_xref.go
index cd1c122252..c4f0080edd 100644
--- a/models/issue_xref.go
+++ b/models/issue_xref.go
@@ -9,6 +9,7 @@ import (
"fmt"
"code.gitea.io/gitea/models/db"
+ 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"
"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
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 {
return nil, references.XRefActionNone, err
}
diff --git a/models/lfs_lock.go b/models/lfs_lock.go
index b5f8e4907f..4995305393 100644
--- a/models/lfs_lock.go
+++ b/models/lfs_lock.go
@@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
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 {
return err
}
- perm, err := GetUserRepoPermission(ctx, repo, u)
+ perm, err := access_model.GetUserRepoPermission(ctx, repo, u)
if err != nil {
return err
}
diff --git a/models/org.go b/models/org.go
index 1e5b403f12..1efa0504ea 100644
--- a/models/org.go
+++ b/models/org.go
@@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
+ 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"
@@ -142,7 +143,7 @@ func removeOrgUser(ctx context.Context, orgID, userID int64) error {
if _, err = sess.
Where("user_id = ?", userID).
In("repo_id", repoIDs).
- Delete(new(Access)); err != nil {
+ Delete(new(access_model.Access)); err != nil {
return err
}
}
diff --git a/models/org_team.go b/models/org_team.go
index 695f803dbf..40eb037452 100644
--- a/models/org_team.go
+++ b/models/org_team.go
@@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
+ 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"
"code.gitea.io/gitea/modules/log"
@@ -33,7 +34,7 @@ func addRepository(ctx context.Context, t *organization.Team, repo *repo_model.R
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)
}
@@ -62,7 +63,7 @@ func addAllRepositories(ctx context.Context, t *organization.Team) error {
}
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 {
return fmt.Errorf("addRepository: %v", err)
}
@@ -108,11 +109,6 @@ func AddRepository(t *organization.Team, repo *repo_model.Repository) (err error
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
func RemoveAllRepositories(t *organization.Team) (err error) {
if t.IncludesAllRepositories {
@@ -138,13 +134,13 @@ func removeAllRepositories(ctx context.Context, t *organization.Team) (err error
e := db.GetEngine(ctx)
// Delete all accesses.
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
}
// Remove watches from all users and now unaccessible repos
for _, user := range t.Members {
- has, err := hasAccess(ctx, user.ID, repo)
+ has, err := access_model.HasAccess(ctx, user.ID, repo)
if err != nil {
return err
} else if has {
@@ -177,8 +173,9 @@ func removeAllRepositories(ctx context.Context, t *organization.Team) (err error
return nil
}
-func hasRepository(ctx context.Context, t *organization.Team, repoID int64) bool {
- return organization.HasTeamRepo(ctx, t.OrgID, t.ID, repoID)
+// HasRepository returns true if given repository belong to team.
+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
@@ -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.
if recalculate {
- if err = recalculateTeamAccesses(ctx, repo, t.ID); err != nil {
+ if err = access_model.RecalculateTeamAccesses(ctx, repo, t.ID); err != nil {
return err
}
}
@@ -206,7 +203,7 @@ func removeRepository(ctx context.Context, t *organization.Team, repo *repo_mode
return fmt.Errorf("getTeamUsersByTeamID: %v", err)
}
for _, teamUser := range teamUsers {
- has, err := hasAccess(ctx, teamUser.UID, repo)
+ has, err := access_model.HasAccess(ctx, teamUser.UID, repo)
if err != nil {
return err
} else if has {
@@ -378,7 +375,7 @@ func UpdateTeam(t *organization.Team, authChanged, includeAllChanged bool) (err
}
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)
}
}
@@ -522,7 +519,7 @@ func AddTeamMember(team *organization.Team, userID int64) error {
In("repo_id", subQuery).
And("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)
}
@@ -533,9 +530,9 @@ func AddTeamMember(team *organization.Team, userID int64) error {
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 {
- 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 err = db.Insert(ctx, accesses); err != nil {
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.
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
}
diff --git a/models/org_team_test.go b/models/org_team_test.go
index e125f3c65b..35ee9af85a 100644
--- a/models/org_team_test.go
+++ b/models/org_team_test.go
@@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
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)
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)
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
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
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.True(t, accessMode < perm.AccessModeWrite)
}
@@ -198,3 +199,21 @@ func TestRemoveTeamMember(t *testing.T) {
err := RemoveTeamMember(team, 2)
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)
+}
diff --git a/models/access.go b/models/perm/access/access.go
index d49d3430dc..75a3a93a3b 100644
--- a/models/access.go
+++ b/models/perm/access/access.go
@@ -3,7 +3,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package access
import (
"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.
-func refreshCollaboratorAccesses(e db.Engine, repoID int64, accessMap map[int64]*userAccess) error {
- collaborators, err := getCollaborators(e, repoID, db.ListOptions{})
+func refreshCollaboratorAccesses(ctx context.Context, repoID int64, accessMap map[int64]*userAccess) error {
+ collaborators, err := repo_model.GetCollaborators(ctx, repoID, db.ListOptions{})
if err != nil {
return fmt.Errorf("getCollaborations: %v", err)
}
@@ -132,10 +132,10 @@ func refreshCollaboratorAccesses(e db.Engine, repoID int64, accessMap map[int64]
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
// 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)
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)
- if err = refreshCollaboratorAccesses(e, repo.ID, accessMap); err != nil {
+ if err = refreshCollaboratorAccesses(ctx, repo.ID, accessMap); err != nil {
return fmt.Errorf("refreshCollaboratorAccesses: %v", err)
}
@@ -164,7 +164,7 @@ func recalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, i
// have relations with repository.
if t.IsOwnerTeam() {
t.AccessMode = perm.AccessModeOwner
- } else if !hasRepository(ctx, t, repo.ID) {
+ } else if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repo.ID) {
continue
}
@@ -179,9 +179,9 @@ func recalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, i
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
-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
if !repo.IsPrivate {
minMode = perm.AccessModeWrite
@@ -189,7 +189,7 @@ func recalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid
accessMode := perm.AccessModeNone
e := db.GetEngine(ctx)
- collaborator, err := getCollaboration(e, repo.ID, uid)
+ collaborator, err := repo_model.GetCollaboration(ctx, repo.ID, uid)
if err != nil {
return err
} 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 {
return fmt.Errorf("delete old user accesses: %v", err)
} 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 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() {
- return recalculateTeamAccesses(ctx, repo, 0)
+ return RecalculateTeamAccesses(ctx, repo, 0)
}
e := db.GetEngine(ctx)
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 refreshAccesses(e, repo, accessMap)
}
-
-// RecalculateAccesses recalculates all accesses for repository.
-func RecalculateAccesses(repo *repo_model.Repository) error {
- return recalculateAccesses(db.DefaultContext, repo)
-}
diff --git a/models/access_test.go b/models/perm/access/access_test.go
index 7533381dca..a9ae9a30f4 100644
--- a/models/access_test.go
+++ b/models/perm/access/access_test.go
@@ -2,13 +2,12 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package access
import (
"testing"
"code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
@@ -80,17 +79,17 @@ func TestHasAccess(t *testing.T) {
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
assert.True(t, repo2.IsPrivate)
- has, err := HasAccess(user1.ID, repo1)
+ has, err := HasAccess(db.DefaultContext, user1.ID, repo1)
assert.NoError(t, err)
assert.True(t, has)
- _, err = HasAccess(user1.ID, repo2)
+ _, err = HasAccess(db.DefaultContext, user1.ID, repo2)
assert.NoError(t, err)
- _, err = HasAccess(user2.ID, repo1)
+ _, err = HasAccess(db.DefaultContext, user2.ID, repo1)
assert.NoError(t, err)
- _, err = HasAccess(user2.ID, repo2)
+ _, err = HasAccess(db.DefaultContext, user2.ID, repo2)
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)
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, RecalculateAccesses(repo1))
+ assert.NoError(t, RecalculateAccesses(db.DefaultContext, repo1))
access := &Access{UserID: 2, RepoID: 3}
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)
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, RecalculateAccesses(repo1))
+ assert.NoError(t, RecalculateAccesses(db.DefaultContext, repo1))
has, err := db.GetEngine(db.DefaultContext).Get(&Access{UserID: 4, RepoID: 4})
assert.NoError(t, err)
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)
-}
diff --git a/models/perm/access/main_test.go b/models/perm/access/main_test.go
new file mode 100644
index 0000000000..153ac2540d
--- /dev/null
+++ b/models/perm/access/main_test.go
@@ -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",
+ },
+ })
+}
diff --git a/models/repo_permission.go b/models/perm/access/repo_permission.go
index 8ba6b86145..090c78ff2c 100644
--- a/models/repo_permission.go
+++ b/models/perm/access/repo_permission.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
-package models
+package access
import (
"context"
@@ -103,39 +103,6 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool {
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
func (p *Permission) ColorFormat(s fmt.State) {
noColor := log.ColorBytes(log.Reset)
@@ -205,7 +172,7 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
var is bool
if user != nil {
- is, err = isCollaborator(e, repo.ID, user.ID)
+ is, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID)
if err != nil {
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
// user does not have access.
-func AccessLevel(user *user_model.User, repo *repo_model.Repository) (perm_model.AccessMode, error) {
- return accessLevelUnit(db.DefaultContext, user, repo, unit.TypeCode)
+func AccessLevel(user *user_model.User, repo *repo_model.Repository) (perm_model.AccessMode, error) { //nolint
+ return AccessLevelUnit(user, repo, unit.TypeCode)
}
// AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the
// 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)
}
@@ -385,24 +352,16 @@ func accessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_mode
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)
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
// 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???
-func CanBeAssigned(user *user_model.User, repo *repo_model.Repository, isPull 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) {
+func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model.Repository, _ bool) (bool, error) {
if user.IsOrganization() {
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
}
-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 err error
if userID > 0 {
@@ -429,9 +389,36 @@ func hasAccess(ctx context.Context, userID int64, repo *repo_model.Repository) (
return perm.HasAccess(), nil
}
-// HasAccess returns true if user has access to repo
-func HasAccess(userID int64, repo *repo_model.Repository) (bool, error) {
- return hasAccess(db.DefaultContext, userID, repo)
+// getUsersWithAccessMode returns users that have at least given access mode to the repository.
+func getUsersWithAccessMode(ctx context.Context, repo *repo_model.Repository, mode perm_model.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
}
// GetRepoReaders returns all users that have explicit read access or higher to the repository.
diff --git a/models/pull_list.go b/models/pull_list.go
index ca09e28a93..60b8299776 100644
--- a/models/pull_list.go
+++ b/models/pull_list.go
@@ -9,6 +9,8 @@ import (
"fmt"
"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"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
@@ -60,6 +62,39 @@ func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequ
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
// by given head information (repo and branch)
func HasUnmergedPullRequestsByHeadInfo(ctx context.Context, repoID int64, branch string) (bool, error) {
diff --git a/models/repo.go b/models/repo.go
index fb7bbba1e1..598eec7c9e 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -22,6 +22,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo"
"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 {
return true
}
- perm, err := GetUserRepoPermission(ctx, repo, user)
+ perm, err := access_model.GetUserRepoPermission(ctx, repo, user)
if err != nil {
log.Error("GetUserRepoPermission(): %v", err)
return false
@@ -302,38 +303,6 @@ func CanUserDelete(repo *repo_model.Repository, user *user_model.User) (bool, er
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.
func SetRepoReadBy(repoID, userID int64) error {
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)
} else if !isAdmin {
// Make creator repo admin if it wasn't assigned automatically
if err = addCollaborator(ctx, repo, doer); err != nil {
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)
}
}
- } 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.
return fmt.Errorf("recalculateAccesses: %v", err)
}
@@ -551,7 +520,7 @@ func UpdateRepositoryCtx(ctx context.Context, repo *repo_model.Repository, visib
}
if repo.Owner.IsOrganization() {
// 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)
}
}
@@ -659,7 +628,7 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
return err
}
for _, t := range teams {
- if !hasRepository(ctx, t, repoID) {
+ if !organization.HasTeamRepo(ctx, t.OrgID, t.ID, repoID) {
continue
} else if err = removeRepository(ctx, t, repo, false); err != nil {
return err
@@ -683,9 +652,9 @@ func DeleteRepository(doer *user_model.User, uid, repoID int64) error {
}
if err := db.DeleteBeans(ctx,
- &Access{RepoID: repo.ID},
+ &access_model.Access{RepoID: repo.ID},
&Action{RepoID: repo.ID},
- &Collaboration{RepoID: repoID},
+ &repo_model.Collaboration{RepoID: repoID},
&Comment{RefRepoID: repoID},
&CommitStatus{RepoID: repoID},
&DeletedBranch{RepoID: repoID},
@@ -1212,7 +1181,7 @@ func DeleteDeployKey(ctx context.Context, doer *user_model.User, id int64) error
if err != nil {
return fmt.Errorf("GetRepositoryByID: %v", err)
}
- has, err := IsUserRepoAdminCtx(ctx, repo, doer)
+ has, err := access_model.IsUserRepoAdminCtx(ctx, repo, doer)
if err != nil {
return fmt.Errorf("GetUserRepoPermission: %v", err)
} else if !has {
diff --git a/models/repo/collaboration.go b/models/repo/collaboration.go
new file mode 100644
index 0000000000..3ebb688143
--- /dev/null
+++ b/models/repo/collaboration.go
@@ -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()
+}
diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go
new file mode 100644
index 0000000000..a7d04498e9
--- /dev/null
+++ b/models/repo/collaboration_test.go
@@ -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)
+}
diff --git a/models/repo/main_test.go b/models/repo/main_test.go
index e375e8a9f3..375d0e0df1 100644
--- a/models/repo/main_test.go
+++ b/models/repo/main_test.go
@@ -26,6 +26,7 @@ func TestMain(m *testing.M) {
"topic.yml",
"repo_topic.yml",
"user.yml",
+ "collaboration.yml",
},
})
}
diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go
index d94b61b449..2069ce8cc3 100644
--- a/models/repo_collaboration.go
+++ b/models/repo_collaboration.go
@@ -12,31 +12,16 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
"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 {
- collaboration := &Collaboration{
+ collaboration := &repo_model.Collaboration{
RepoID: repo.ID,
UserID: u.ID,
}
@@ -54,7 +39,7 @@ func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_m
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.
@@ -72,132 +57,9 @@ func AddCollaborator(repo *repo_model.Repository, u *user_model.User) error {
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.
func DeleteCollaboration(repo *repo_model.Repository, uid int64) (err error) {
- collaboration := &Collaboration{
+ collaboration := &repo_model.Collaboration{
RepoID: repo.ID,
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 {
return err
- } else if err = recalculateAccesses(ctx, repo); err != nil {
+ } else if err = access_model.RecalculateAccesses(ctx, repo); err != nil {
return err
}
@@ -236,7 +98,7 @@ func reconsiderRepoIssuesAssignee(ctx context.Context, repo *repo_model.Reposito
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
}
@@ -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 {
- if has, err := hasAccess(ctx, uid, repo); err != nil || has {
+ if has, err := access_model.HasAccess(ctx, uid, repo); err != nil || has {
return err
}
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 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})
}
diff --git a/models/repo_collaboration_test.go b/models/repo_collaboration_test.go
index 8b4c712f07..b90490de92 100644
--- a/models/repo_collaboration_test.go
+++ b/models/repo_collaboration_test.go
@@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -31,56 +32,21 @@ func TestRepository_AddCollaborator(t *testing.T) {
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) {
assert.NoError(t, unittest.PrepareTestDatabase())
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)
- 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.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})
}
@@ -91,10 +57,10 @@ func TestRepository_DeleteCollaboration(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
assert.NoError(t, repo.GetOwner(db.DefaultContext))
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))
- 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})
}
diff --git a/models/repo_permission_test.go b/models/repo_permission_test.go
index 7e22437f99..80919e7cf1 100644
--- a/models/repo_permission_test.go
+++ b/models/repo_permission_test.go
@@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
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"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unittest"
@@ -27,7 +28,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
// plain 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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -36,7 +37,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
// change to collaborator
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -45,7 +46,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
// collaborator
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -54,7 +55,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
// owner
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -63,7 +64,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
// admin
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -80,7 +81,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
// plain 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)
for _, unit := range repo.Units {
assert.False(t, perm.CanRead(unit.Type))
@@ -89,15 +90,15 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
// change to collaborator to default write access
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
assert.True(t, perm.CanWrite(unit.Type))
}
- assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
- perm, err = GetUserRepoPermission(db.DefaultContext, repo, user)
+ assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
+ perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -106,7 +107,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
// owner
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -115,7 +116,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
// admin
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -132,7 +133,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
// plain 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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -141,15 +142,15 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
// change to collaborator to default write access
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
assert.True(t, perm.CanWrite(unit.Type))
}
- assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
- perm, err = GetUserRepoPermission(db.DefaultContext, repo, user)
+ assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
+ perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -158,7 +159,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
// org member team owner
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -167,7 +168,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
// org member team tester
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -177,7 +178,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
// admin
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -194,7 +195,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
// plain 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)
for _, unit := range repo.Units {
assert.False(t, perm.CanRead(unit.Type))
@@ -203,15 +204,15 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
// change to collaborator to default write access
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
assert.True(t, perm.CanWrite(unit.Type))
}
- assert.NoError(t, ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
- perm, err = GetUserRepoPermission(db.DefaultContext, repo, user)
+ assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, user.ID, perm_model.AccessModeRead))
+ perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -220,7 +221,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
// org member team owner
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)
for _, unit := range repo.Units {
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)
err = organization.UpdateTeamUnits(team, nil)
assert.NoError(t, err)
- perm, err = GetUserRepoPermission(db.DefaultContext, repo, owner)
+ perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner)
assert.NoError(t, err)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
@@ -240,7 +241,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
// org member team tester
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.True(t, perm.CanWrite(unit.TypeIssues))
assert.False(t, perm.CanWrite(unit.TypeCode))
@@ -248,7 +249,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
// org member team reviewer
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.False(t, perm.CanRead(unit.TypeIssues))
assert.False(t, perm.CanWrite(unit.TypeCode))
@@ -256,7 +257,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
// admin
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)
for _, unit := range repo.Units {
assert.True(t, perm.CanRead(unit.Type))
diff --git a/models/repo_transfer.go b/models/repo_transfer.go
index f9a758a20b..b283bc8c74 100644
--- a/models/repo_transfer.go
+++ b/models/repo_transfer.go
@@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
+ 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"
"code.gitea.io/gitea/modules/log"
@@ -280,13 +281,13 @@ func TransferOwnership(doer *user_model.User, newOwnerName string, repo *repo_mo
}
// Remove redundant collaborators.
- collaborators, err := getCollaborators(sess, repo.ID, db.ListOptions{})
+ collaborators, err := repo_model.GetCollaborators(ctx, repo.ID, db.ListOptions{})
if err != nil {
return fmt.Errorf("getCollaborators: %v", err)
}
// Dummy object.
- collaboration := &Collaboration{RepoID: repo.ID}
+ collaboration := &repo_model.Collaboration{RepoID: repo.ID}
for _, c := range collaborators {
if c.IsGhost() {
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.
return fmt.Errorf("recalculateAccesses: %v", err)
}
diff --git a/models/review.go b/models/review.go
index a9e29a10e0..8917ea714d 100644
--- a/models/review.go
+++ b/models/review.go
@@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
@@ -891,7 +892,7 @@ func CanMarkConversation(issue *Issue, doer *user_model.User) (permResult bool,
return false, err
}
- p, err := GetUserRepoPermission(db.DefaultContext, issue.Repo, doer)
+ p, err := access_model.GetUserRepoPermission(db.DefaultContext, issue.Repo, doer)
if err != nil {
return false, err
}
diff --git a/models/statistic.go b/models/statistic.go
index d858102be8..0f6359fb3e 100644
--- a/models/statistic.go
+++ b/models/statistic.go
@@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
project_model "code.gitea.io/gitea/models/project"
repo_model "code.gitea.io/gitea/models/repo"
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.Star, _ = e.Count(new(repo_model.Star))
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 {
Count int64
diff --git a/models/user.go b/models/user.go
index 11234a881d..e805c746cb 100644
--- a/models/user.go
+++ b/models/user.go
@@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
+ access_model "code.gitea.io/gitea/models/perm/access"
pull_model "code.gitea.io/gitea/models/pull"
repo_model "code.gitea.io/gitea/models/repo"
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,
&AccessToken{UID: u.ID},
- &Collaboration{UserID: u.ID},
- &Access{UserID: u.ID},
+ &repo_model.Collaboration{UserID: u.ID},
+ &access_model.Access{UserID: u.ID},
&repo_model.Watch{UserID: u.ID},
&repo_model.Star{UID: 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},
&issues.Reaction{UserID: u.ID},
&organization.TeamUser{UID: u.ID},
- &Collaboration{UserID: u.ID},
&Stopwatch{UserID: u.ID},
&user_model.Setting{UserID: u.ID},
&pull_model.AutoMerge{DoerID: u.ID},