From 1fee11d69a437ec7e68b3f6b645827592fe77292 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 28 Nov 2021 19:58:28 +0800 Subject: [PATCH] Move accessmode into models/perm (#17828) --- cmd/serv.go | 15 ++-- .../api_helper_for_declarative_test.go | 7 +- integrations/api_keys_test.go | 7 +- integrations/api_private_serv_test.go | 25 +++--- integrations/git_test.go | 5 +- models/access.go | 84 ++++--------------- models/access_test.go | 17 ++-- models/branches.go | 7 +- models/error.go | 5 +- models/issue.go | 3 +- models/lfs_lock.go | 7 +- models/org.go | 15 ++-- models/org_team.go | 7 +- models/org_team_test.go | 7 +- models/perm/access_mode.go | 61 ++++++++++++++ models/repo.go | 19 +++-- models/repo_collaboration.go | 11 +-- models/repo_collaboration_test.go | 11 +-- models/repo_list.go | 3 +- models/repo_permission.go | 63 +++++++------- models/repo_permission_test.go | 7 +- models/review.go | 7 +- models/ssh_key.go | 19 +++-- models/ssh_key_deploy.go | 11 +-- models/ssh_key_principals.go | 3 +- modules/context/org.go | 3 +- modules/convert/convert.go | 5 +- modules/convert/notification.go | 3 +- modules/convert/pull.go | 13 +-- modules/convert/pull_test.go | 3 +- modules/convert/repository.go | 11 +-- modules/convert/user.go | 6 +- modules/notification/webhook/webhook.go | 21 ++--- modules/private/serv.go | 3 +- modules/repository/create_test.go | 9 +- routers/api/v1/org/org.go | 9 +- routers/api/v1/org/team.go | 13 +-- routers/api/v1/repo/collaborators.go | 4 +- routers/api/v1/repo/fork.go | 3 +- routers/api/v1/repo/hook.go | 8 +- routers/api/v1/repo/key.go | 3 +- routers/api/v1/repo/migrate.go | 3 +- routers/api/v1/repo/release.go | 3 +- routers/api/v1/repo/repo.go | 5 +- routers/api/v1/repo/transfer.go | 5 +- routers/api/v1/user/key.go | 3 +- routers/api/v1/user/repo.go | 3 +- routers/private/serv.go | 13 +-- routers/web/org/teams.go | 13 +-- routers/web/repo/http.go | 13 +-- routers/web/repo/projects.go | 9 +- routers/web/repo/setting.go | 3 +- routers/web/repo/setting_protected_branch.go | 3 +- routers/web/repo/settings_test.go | 5 +- routers/web/repo/tag.go | 3 +- routers/web/repo/webhook.go | 6 +- services/issue/assignee.go | 7 +- services/lfs/server.go | 11 +-- services/repository/transfer.go | 3 +- 59 files changed, 359 insertions(+), 295 deletions(-) create mode 100644 models/perm/access_mode.go diff --git a/cmd/serv.go b/cmd/serv.go index 13c27f1ac0..e1a1d4cb72 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -17,6 +17,7 @@ import ( "time" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -64,11 +65,11 @@ func setup(logPath string, debug bool) { } var ( - allowedCommands = map[string]models.AccessMode{ - "git-upload-pack": models.AccessModeRead, - "git-upload-archive": models.AccessModeRead, - "git-receive-pack": models.AccessModeWrite, - lfsAuthenticateVerb: models.AccessModeNone, + allowedCommands = map[string]perm.AccessMode{ + "git-upload-pack": perm.AccessModeRead, + "git-upload-archive": perm.AccessModeRead, + "git-receive-pack": perm.AccessModeWrite, + lfsAuthenticateVerb: perm.AccessModeNone, } alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`) ) @@ -214,9 +215,9 @@ func runServ(c *cli.Context) error { if verb == lfsAuthenticateVerb { if lfsVerb == "upload" { - requestedMode = models.AccessModeWrite + requestedMode = perm.AccessModeWrite } else if lfsVerb == "download" { - requestedMode = models.AccessModeRead + requestedMode = perm.AccessModeRead } else { return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb) } diff --git a/integrations/api_helper_for_declarative_test.go b/integrations/api_helper_for_declarative_test.go index 8745ada96d..a8aba3199c 100644 --- a/integrations/api_helper_for_declarative_test.go +++ b/integrations/api_helper_for_declarative_test.go @@ -14,6 +14,7 @@ import ( "time" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/queue" api "code.gitea.io/gitea/modules/structs" @@ -89,13 +90,13 @@ func doAPIEditRepository(ctx APITestContext, editRepoOption *api.EditRepoOption, } } -func doAPIAddCollaborator(ctx APITestContext, username string, mode models.AccessMode) func(*testing.T) { +func doAPIAddCollaborator(ctx APITestContext, username string, mode perm.AccessMode) func(*testing.T) { return func(t *testing.T) { permission := "read" - if mode == models.AccessModeAdmin { + if mode == perm.AccessModeAdmin { permission = "admin" - } else if mode > models.AccessModeRead { + } else if mode > perm.AccessModeRead { permission = "write" } addCollaboratorOption := &api.AddCollaboratorOption{ diff --git a/integrations/api_keys_test.go b/integrations/api_keys_test.go index 7c82bfbb69..9bcfa70461 100644 --- a/integrations/api_keys_test.go +++ b/integrations/api_keys_test.go @@ -11,6 +11,7 @@ import ( "testing" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" @@ -67,7 +68,7 @@ func TestCreateReadOnlyDeployKey(t *testing.T) { ID: newDeployKey.ID, Name: rawKeyBody.Title, Content: rawKeyBody.Key, - Mode: models.AccessModeRead, + Mode: perm.AccessModeRead, }) } @@ -92,7 +93,7 @@ func TestCreateReadWriteDeployKey(t *testing.T) { ID: newDeployKey.ID, Name: rawKeyBody.Title, Content: rawKeyBody.Key, - Mode: models.AccessModeWrite, + Mode: perm.AccessModeWrite, }) } @@ -119,7 +120,7 @@ func TestCreateUserKey(t *testing.T) { OwnerID: user.ID, Name: rawKeyBody.Title, Content: rawKeyBody.Key, - Mode: models.AccessModeWrite, + Mode: perm.AccessModeWrite, }) // Search by fingerprint diff --git a/integrations/api_private_serv_test.go b/integrations/api_private_serv_test.go index c3cb1cf328..388e5da00d 100644 --- a/integrations/api_private_serv_test.go +++ b/integrations/api_private_serv_test.go @@ -10,6 +10,7 @@ import ( "testing" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/private" "github.com/stretchr/testify/assert" @@ -43,7 +44,7 @@ func TestAPIPrivateServ(t *testing.T) { defer cancel() // Can push to a repo we own - results, err := private.ServCommand(ctx, 1, "user2", "repo1", models.AccessModeWrite, "git-upload-pack", "") + results, err := private.ServCommand(ctx, 1, "user2", "repo1", perm.AccessModeWrite, "git-upload-pack", "") assert.NoError(t, err) assert.False(t, results.IsWiki) assert.False(t, results.IsDeployKey) @@ -56,17 +57,17 @@ func TestAPIPrivateServ(t *testing.T) { assert.Equal(t, int64(1), results.RepoID) // Cannot push to a private repo we're not associated with - results, err = private.ServCommand(ctx, 1, "user15", "big_test_private_1", models.AccessModeWrite, "git-upload-pack", "") + results, err = private.ServCommand(ctx, 1, "user15", "big_test_private_1", perm.AccessModeWrite, "git-upload-pack", "") assert.Error(t, err) assert.Empty(t, results) // Cannot pull from a private repo we're not associated with - results, err = private.ServCommand(ctx, 1, "user15", "big_test_private_1", models.AccessModeRead, "git-upload-pack", "") + results, err = private.ServCommand(ctx, 1, "user15", "big_test_private_1", perm.AccessModeRead, "git-upload-pack", "") assert.Error(t, err) assert.Empty(t, results) // Can pull from a public repo we're not associated with - results, err = private.ServCommand(ctx, 1, "user15", "big_test_public_1", models.AccessModeRead, "git-upload-pack", "") + results, err = private.ServCommand(ctx, 1, "user15", "big_test_public_1", perm.AccessModeRead, "git-upload-pack", "") assert.NoError(t, err) assert.False(t, results.IsWiki) assert.False(t, results.IsDeployKey) @@ -79,7 +80,7 @@ func TestAPIPrivateServ(t *testing.T) { assert.Equal(t, int64(17), results.RepoID) // Cannot push to a public repo we're not associated with - results, err = private.ServCommand(ctx, 1, "user15", "big_test_public_1", models.AccessModeWrite, "git-upload-pack", "") + results, err = private.ServCommand(ctx, 1, "user15", "big_test_public_1", perm.AccessModeWrite, "git-upload-pack", "") assert.Error(t, err) assert.Empty(t, results) @@ -88,7 +89,7 @@ func TestAPIPrivateServ(t *testing.T) { assert.NoError(t, err) // Can pull from repo we're a deploy key for - results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_1", models.AccessModeRead, "git-upload-pack", "") + results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_1", perm.AccessModeRead, "git-upload-pack", "") assert.NoError(t, err) assert.False(t, results.IsWiki) assert.True(t, results.IsDeployKey) @@ -101,17 +102,17 @@ func TestAPIPrivateServ(t *testing.T) { assert.Equal(t, int64(19), results.RepoID) // Cannot push to a private repo with reading key - results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_1", models.AccessModeWrite, "git-upload-pack", "") + results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_1", perm.AccessModeWrite, "git-upload-pack", "") assert.Error(t, err) assert.Empty(t, results) // Cannot pull from a private repo we're not associated with - results, err = private.ServCommand(ctx, deployKey.ID, "user15", "big_test_private_2", models.AccessModeRead, "git-upload-pack", "") + results, err = private.ServCommand(ctx, deployKey.ID, "user15", "big_test_private_2", perm.AccessModeRead, "git-upload-pack", "") assert.Error(t, err) assert.Empty(t, results) // Cannot pull from a public repo we're not associated with - results, err = private.ServCommand(ctx, deployKey.ID, "user15", "big_test_public_1", models.AccessModeRead, "git-upload-pack", "") + results, err = private.ServCommand(ctx, deployKey.ID, "user15", "big_test_public_1", perm.AccessModeRead, "git-upload-pack", "") assert.Error(t, err) assert.Empty(t, results) @@ -120,12 +121,12 @@ func TestAPIPrivateServ(t *testing.T) { assert.NoError(t, err) // Cannot push to a private repo with reading key - results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_1", models.AccessModeWrite, "git-upload-pack", "") + results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_1", perm.AccessModeWrite, "git-upload-pack", "") assert.Error(t, err) assert.Empty(t, results) // Can pull from repo we're a writing deploy key for - results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_2", models.AccessModeRead, "git-upload-pack", "") + results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_2", perm.AccessModeRead, "git-upload-pack", "") assert.NoError(t, err) assert.False(t, results.IsWiki) assert.True(t, results.IsDeployKey) @@ -138,7 +139,7 @@ func TestAPIPrivateServ(t *testing.T) { assert.Equal(t, int64(20), results.RepoID) // Can push to repo we're a writing deploy key for - results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_2", models.AccessModeWrite, "git-upload-pack", "") + results, err = private.ServCommand(ctx, deployKey.KeyID, "user15", "big_test_private_2", perm.AccessModeWrite, "git-upload-pack", "") assert.NoError(t, err) assert.False(t, results.IsWiki) assert.True(t, results.IsDeployKey) diff --git a/integrations/git_test.go b/integrations/git_test.go index 71e3476abb..642c1f1223 100644 --- a/integrations/git_test.go +++ b/integrations/git_test.go @@ -18,6 +18,7 @@ import ( "time" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" @@ -58,7 +59,7 @@ func testGit(t *testing.T, u *url.URL) { defer util.RemoveAll(dstPath) t.Run("CreateRepoInDifferentUser", doAPICreateRepository(forkedUserCtx, false)) - t.Run("AddUserAsCollaborator", doAPIAddCollaborator(forkedUserCtx, httpContext.Username, models.AccessModeRead)) + t.Run("AddUserAsCollaborator", doAPIAddCollaborator(forkedUserCtx, httpContext.Username, perm.AccessModeRead)) t.Run("ForkFromDifferentUser", doAPIForkRepository(httpContext, forkedUserCtx.Username)) @@ -91,7 +92,7 @@ func testGit(t *testing.T, u *url.URL) { keyname := "my-testing-key" forkedUserCtx.Reponame = sshContext.Reponame t.Run("CreateRepoInDifferentUser", doAPICreateRepository(forkedUserCtx, false)) - t.Run("AddUserAsCollaborator", doAPIAddCollaborator(forkedUserCtx, sshContext.Username, models.AccessModeRead)) + t.Run("AddUserAsCollaborator", doAPIAddCollaborator(forkedUserCtx, sshContext.Username, perm.AccessModeRead)) t.Run("ForkFromDifferentUser", doAPIForkRepository(sshContext, forkedUserCtx.Username)) //Setup key the user ssh key diff --git a/models/access.go b/models/access.go index 01b37dd7ae..f7252019aa 100644 --- a/models/access.go +++ b/models/access.go @@ -9,60 +9,10 @@ import ( "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" ) -// AccessMode specifies the users access mode -type AccessMode int - -const ( - // AccessModeNone no access - AccessModeNone AccessMode = iota // 0 - // AccessModeRead read access - AccessModeRead // 1 - // AccessModeWrite write access - AccessModeWrite // 2 - // AccessModeAdmin admin access - AccessModeAdmin // 3 - // AccessModeOwner owner access - AccessModeOwner // 4 -) - -func (mode AccessMode) String() string { - switch mode { - case AccessModeRead: - return "read" - case AccessModeWrite: - return "write" - case AccessModeAdmin: - return "admin" - case AccessModeOwner: - return "owner" - default: - return "none" - } -} - -// ColorFormat provides a ColorFormatted version of this AccessMode -func (mode AccessMode) ColorFormat(s fmt.State) { - log.ColorFprintf(s, "%d:%s", - log.NewColoredIDValue(mode), - mode) -} - -// ParseAccessMode returns corresponding access mode to given permission string. -func ParseAccessMode(permission string) AccessMode { - switch permission { - case "write": - return AccessModeWrite - case "admin": - return AccessModeAdmin - default: - return AccessModeRead - } -} - // Access represents the highest access level of a user to the repository. The only access type // that is not in this table is the real owner of a repository. In case of an organization // repository, the members of the owners team are in this table. @@ -70,15 +20,15 @@ type Access struct { ID int64 `xorm:"pk autoincr"` UserID int64 `xorm:"UNIQUE(s)"` RepoID int64 `xorm:"UNIQUE(s)"` - Mode AccessMode + Mode perm.AccessMode } func init() { db.RegisterModel(new(Access)) } -func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (AccessMode, error) { - mode := AccessModeNone +func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (perm.AccessMode, error) { + mode := perm.AccessModeNone var userID int64 restricted := false @@ -88,7 +38,7 @@ func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (AccessMo } if !restricted && !repo.IsPrivate { - mode = AccessModeRead + mode = perm.AccessModeRead } if userID == 0 { @@ -96,7 +46,7 @@ func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (AccessMo } if userID == repo.OwnerID { - return AccessModeOwner, nil + return perm.AccessModeOwner, nil } a := &Access{UserID: userID, RepoID: repo.ID} @@ -106,8 +56,8 @@ func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (AccessMo return a.Mode, nil } -func maxAccessMode(modes ...AccessMode) AccessMode { - max := AccessModeNone +func maxAccessMode(modes ...perm.AccessMode) perm.AccessMode { + max := perm.AccessModeNone for _, mode := range modes { if mode > max { max = mode @@ -118,11 +68,11 @@ func maxAccessMode(modes ...AccessMode) AccessMode { type userAccess struct { User *user_model.User - Mode AccessMode + Mode perm.AccessMode } // updateUserAccess updates an access map so that user has at least mode -func updateUserAccess(accessMap map[int64]*userAccess, user *user_model.User, mode AccessMode) { +func updateUserAccess(accessMap map[int64]*userAccess, user *user_model.User, mode perm.AccessMode) { if ua, ok := accessMap[user.ID]; ok { ua.Mode = maxAccessMode(ua.Mode, mode) } else { @@ -132,9 +82,9 @@ func updateUserAccess(accessMap map[int64]*userAccess, user *user_model.User, mo // FIXME: do cross-comparison so reduce deletions and additions to the minimum? func (repo *Repository) refreshAccesses(e db.Engine, accessMap map[int64]*userAccess) (err error) { - minMode := AccessModeRead + minMode := perm.AccessModeRead if !repo.IsPrivate { - minMode = AccessModeWrite + minMode = perm.AccessModeWrite } newAccesses := make([]Access, 0, len(accessMap)) @@ -208,7 +158,7 @@ func (repo *Repository) recalculateTeamAccesses(e db.Engine, ignTeamID int64) (e // Owner team gets owner access, and skip for teams that do not // have relations with repository. if t.IsOwnerTeam() { - t.Authorize = AccessModeOwner + t.Authorize = perm.AccessModeOwner } else if !t.hasRepository(e, repo.ID) { continue } @@ -227,12 +177,12 @@ func (repo *Repository) recalculateTeamAccesses(e db.Engine, ignTeamID int64) (e // recalculateUserAccess recalculates new access for a single user // Usable if we know access only affected one user func (repo *Repository) recalculateUserAccess(e db.Engine, uid int64) (err error) { - minMode := AccessModeRead + minMode := perm.AccessModeRead if !repo.IsPrivate { - minMode = AccessModeWrite + minMode = perm.AccessModeWrite } - accessMode := AccessModeNone + accessMode := perm.AccessModeNone collaborator, err := repo.getCollaboration(e, uid) if err != nil { return err @@ -255,7 +205,7 @@ func (repo *Repository) recalculateUserAccess(e db.Engine, uid int64) (err error for _, t := range teams { if t.IsOwnerTeam() { - t.Authorize = AccessModeOwner + t.Authorize = perm.AccessModeOwner } accessMode = maxAccessMode(accessMode, t.Authorize) diff --git a/models/access_test.go b/models/access_test.go index a2fd05a033..05bd1656e9 100644 --- a/models/access_test.go +++ b/models/access_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -35,34 +36,34 @@ func TestAccessLevel(t *testing.T) { level, err := AccessLevel(user2, repo1) assert.NoError(t, err) - assert.Equal(t, AccessModeOwner, level) + assert.Equal(t, perm.AccessModeOwner, level) level, err = AccessLevel(user2, repo3) assert.NoError(t, err) - assert.Equal(t, AccessModeOwner, level) + assert.Equal(t, perm.AccessModeOwner, level) level, err = AccessLevel(user5, repo1) assert.NoError(t, err) - assert.Equal(t, AccessModeRead, level) + assert.Equal(t, perm.AccessModeRead, level) level, err = AccessLevel(user5, repo3) assert.NoError(t, err) - assert.Equal(t, AccessModeNone, level) + assert.Equal(t, perm.AccessModeNone, level) // restricted user has no access to a public repo level, err = AccessLevel(user29, repo1) assert.NoError(t, err) - assert.Equal(t, AccessModeNone, level) + assert.Equal(t, perm.AccessModeNone, level) // ... unless he's a collaborator level, err = AccessLevel(user29, repo4) assert.NoError(t, err) - assert.Equal(t, AccessModeWrite, level) + assert.Equal(t, perm.AccessModeWrite, level) // ... or a team member level, err = AccessLevel(user29, repo24) assert.NoError(t, err) - assert.Equal(t, AccessModeRead, level) + assert.Equal(t, perm.AccessModeRead, level) } func TestHasAccess(t *testing.T) { @@ -105,7 +106,7 @@ func TestRepository_RecalculateAccesses(t *testing.T) { has, err := db.GetEngine(db.DefaultContext).Get(access) assert.NoError(t, err) assert.True(t, has) - assert.Equal(t, AccessModeOwner, access.Mode) + assert.Equal(t, perm.AccessModeOwner, access.Mode) } func TestRepository_RecalculateAccesses2(t *testing.T) { diff --git a/models/branches.go b/models/branches.go index f5ed570ea2..3d377cf0fa 100644 --- a/models/branches.go +++ b/models/branches.go @@ -11,6 +11,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -76,7 +77,7 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool { } else if repo, err := GetRepositoryByID(protectBranch.RepoID); err != nil { log.Error("GetRepositoryByID: %v", err) return false - } else if writeAccess, err := HasAccessUnit(user, repo, unit.TypeCode, AccessModeWrite); err != nil { + } else if writeAccess, err := HasAccessUnit(user, repo, unit.TypeCode, perm.AccessModeWrite); err != nil { log.Error("HasAccessUnit: %v", err) return false } else { @@ -136,7 +137,7 @@ func (protectBranch *ProtectedBranch) isUserOfficialReviewer(e db.Engine, user * if !protectBranch.EnableApprovalsWhitelist { // Anyone with write access is considered official reviewer - writeAccess, err := hasAccessUnit(e, user, repo, unit.TypeCode, AccessModeWrite) + writeAccess, err := hasAccessUnit(e, user, repo, unit.TypeCode, perm.AccessModeWrite) if err != nil { return false, err } @@ -474,7 +475,7 @@ func updateTeamWhitelist(repo *Repository, currentWhitelist, newWhitelist []int6 return currentWhitelist, nil } - teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, AccessModeRead) + teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, perm.AccessModeRead) if err != nil { return nil, fmt.Errorf("GetTeamsWithAccessToRepo [org_id: %d, repo_id: %d]: %v", repo.OwnerID, repo.ID, err) } diff --git a/models/error.go b/models/error.go index 5ef96683e7..0b6c22450d 100644 --- a/models/error.go +++ b/models/error.go @@ -8,6 +8,7 @@ package models import ( "fmt" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/git" ) @@ -498,7 +499,7 @@ func (err ErrLFSLockNotExist) Error() string { type ErrLFSUnauthorizedAction struct { RepoID int64 UserName string - Mode AccessMode + Mode perm.AccessMode } // IsErrLFSUnauthorizedAction checks if an error is a ErrLFSUnauthorizedAction. @@ -508,7 +509,7 @@ func IsErrLFSUnauthorizedAction(err error) bool { } func (err ErrLFSUnauthorizedAction) Error() string { - if err.Mode == AccessModeWrite { + if err.Mode == perm.AccessModeWrite { return fmt.Sprintf("User %s doesn't have write access for lfs lock [rid: %d]", err.UserName, err.RepoID) } return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID) diff --git a/models/issue.go b/models/issue.go index 557d19e739..b0a6a35b87 100644 --- a/models/issue.go +++ b/models/issue.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -2086,7 +2087,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx context.Context, doer *user_ unittype = unit.TypePullRequests } for _, team := range teams { - if team.Authorize >= AccessModeOwner { + if team.Authorize >= perm.AccessModeOwner { checked = append(checked, team.ID) resolved[issue.Repo.Owner.LowerName+"/"+team.LowerName] = true continue diff --git a/models/lfs_lock.go b/models/lfs_lock.go index 15513ea1dd..7cd8e1279b 100644 --- a/models/lfs_lock.go +++ b/models/lfs_lock.go @@ -11,6 +11,7 @@ import ( "time" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -53,7 +54,7 @@ func cleanPath(p string) string { // CreateLFSLock creates a new lock. func CreateLFSLock(lock *LFSLock) (*LFSLock, error) { - err := CheckLFSAccessForRepo(lock.OwnerID, lock.Repo, AccessModeWrite) + err := CheckLFSAccessForRepo(lock.OwnerID, lock.Repo, perm.AccessModeWrite) if err != nil { return nil, err } @@ -124,7 +125,7 @@ func DeleteLFSLockByID(id int64, u *user_model.User, force bool) (*LFSLock, erro return nil, err } - err = CheckLFSAccessForRepo(u.ID, lock.Repo, AccessModeWrite) + err = CheckLFSAccessForRepo(u.ID, lock.Repo, perm.AccessModeWrite) if err != nil { return nil, err } @@ -138,7 +139,7 @@ func DeleteLFSLockByID(id int64, u *user_model.User, force bool) (*LFSLock, erro } // CheckLFSAccessForRepo check needed access mode base on action -func CheckLFSAccessForRepo(ownerID int64, repo *Repository, mode AccessMode) error { +func CheckLFSAccessForRepo(ownerID int64, repo *Repository, mode perm.AccessMode) error { if ownerID == 0 { return ErrLFSUnauthorizedAction{repo.ID, "undefined", mode} } diff --git a/models/org.go b/models/org.go index 63e1b99af5..040d129692 100644 --- a/models/org.go +++ b/models/org.go @@ -11,6 +11,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -263,7 +264,7 @@ func CreateOrganization(org *Organization, owner *user_model.User) (err error) { OrgID: org.ID, LowerName: strings.ToLower(ownerTeamName), Name: ownerTeamName, - Authorize: AccessModeOwner, + Authorize: perm.AccessModeOwner, NumMembers: 1, IncludesAllRepositories: true, CanCreateOrgRepo: true, @@ -420,8 +421,8 @@ func CanCreateOrgRepo(orgID, uid int64) (bool, error) { } // GetOrgUserMaxAuthorizeLevel returns highest authorize level of user in an organization -func (org *Organization) GetOrgUserMaxAuthorizeLevel(uid int64) (AccessMode, error) { - var authorize AccessMode +func (org *Organization) GetOrgUserMaxAuthorizeLevel(uid int64) (perm.AccessMode, error) { + var authorize perm.AccessMode _, err := db.GetEngine(db.DefaultContext). Select("max(team.authorize)"). Table("team"). @@ -442,7 +443,7 @@ func getUsersWhoCanCreateOrgRepo(e db.Engine, orgID int64) ([]*user_model.User, return users, e. Join("INNER", "`team_user`", "`team_user`.uid=`user`.id"). Join("INNER", "`team`", "`team`.id=`team_user`.team_id"). - Where(builder.Eq{"team.can_create_org_repo": true}.Or(builder.Eq{"team.authorize": AccessModeOwner})). + Where(builder.Eq{"team.can_create_org_repo": true}.Or(builder.Eq{"team.authorize": perm.AccessModeOwner})). And("team_user.org_id = ?", orgID).Asc("`user`.name").Find(&users) } @@ -564,7 +565,7 @@ func getOwnedOrgsByUserID(sess db.Engine, userID int64) ([]*Organization, error) Join("INNER", "`team_user`", "`team_user`.org_id=`user`.id"). Join("INNER", "`team`", "`team`.id=`team_user`.team_id"). Where("`team_user`.uid=?", userID). - And("`team`.authorize=?", AccessModeOwner). + And("`team`.authorize=?", perm.AccessModeOwner). Asc("`user`.name"). Find(&orgs) } @@ -624,7 +625,7 @@ func GetOrgsCanCreateRepoByUserID(userID int64) ([]*Organization, error) { Join("INNER", "`team_user`", "`team_user`.org_id = `user`.id"). Join("INNER", "`team`", "`team`.id = `team_user`.team_id"). Where(builder.Eq{"`team_user`.uid": userID}). - And(builder.Eq{"`team`.authorize": AccessModeOwner}.Or(builder.Eq{"`team`.can_create_org_repo": true})))). + And(builder.Eq{"`team`.authorize": perm.AccessModeOwner}.Or(builder.Eq{"`team`.can_create_org_repo": true})))). Asc("`user`.name"). Find(&orgs) } @@ -883,7 +884,7 @@ func (org *Organization) getUserTeamIDs(e db.Engine, userID int64) ([]int64, err } // TeamsWithAccessToRepo returns all teams that have given access level to the repository. -func (org *Organization) TeamsWithAccessToRepo(repoID int64, mode AccessMode) ([]*Team, error) { +func (org *Organization) TeamsWithAccessToRepo(repoID int64, mode perm.AccessMode) ([]*Team, error) { return GetTeamsWithAccessToRepo(org.ID, repoID, mode) } diff --git a/models/org_team.go b/models/org_team.go index 510a0dcfaa..dc16fa5030 100644 --- a/models/org_team.go +++ b/models/org_team.go @@ -13,6 +13,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -30,7 +31,7 @@ type Team struct { LowerName string Name string Description string - Authorize AccessMode + Authorize perm.AccessMode Repos []*Repository `xorm:"-"` Members []*user_model.User `xorm:"-"` NumRepos int @@ -143,7 +144,7 @@ func (t *Team) GetUnitNames() (res []string) { // HasWriteAccess returns true if team has at least write level access mode. func (t *Team) HasWriteAccess() bool { - return t.Authorize >= AccessModeWrite + return t.Authorize >= perm.AccessModeWrite } // IsOwnerTeam returns true if team is owner team. @@ -1001,7 +1002,7 @@ func removeTeamRepo(e db.Engine, teamID, repoID int64) error { } // GetTeamsWithAccessToRepo returns all teams in an organization that have given access level to the repository. -func GetTeamsWithAccessToRepo(orgID, repoID int64, mode AccessMode) ([]*Team, error) { +func GetTeamsWithAccessToRepo(orgID, repoID int64, mode perm.AccessMode) ([]*Team, error) { teams := make([]*Team, 0, 5) return teams, db.GetEngine(db.DefaultContext).Where("team.authorize >= ?", mode). Join("INNER", "team_repo", "team_repo.team_id = team.id"). diff --git a/models/org_team_test.go b/models/org_team_test.go index 450cf7dd55..084e376cc9 100644 --- a/models/org_team_test.go +++ b/models/org_team_test.go @@ -9,6 +9,7 @@ import ( "testing" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -209,14 +210,14 @@ func TestUpdateTeam(t *testing.T) { team.LowerName = "newname" team.Name = "newName" team.Description = strings.Repeat("A long description!", 100) - team.Authorize = AccessModeAdmin + team.Authorize = perm.AccessModeAdmin assert.NoError(t, UpdateTeam(team, true, false)) team = unittest.AssertExistsAndLoadBean(t, &Team{Name: "newName"}).(*Team) assert.True(t, strings.HasPrefix(team.Description, "A long description!")) access := unittest.AssertExistsAndLoadBean(t, &Access{UserID: 4, RepoID: 3}).(*Access) - assert.EqualValues(t, AccessModeAdmin, access.Mode) + assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) unittest.CheckConsistencyFor(t, &Team{ID: team.ID}) } @@ -249,7 +250,7 @@ func TestDeleteTeam(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository) accessMode, err := AccessLevel(user, repo) assert.NoError(t, err) - assert.True(t, accessMode < AccessModeWrite) + assert.True(t, accessMode < perm.AccessModeWrite) } func TestIsTeamMember(t *testing.T) { diff --git a/models/perm/access_mode.go b/models/perm/access_mode.go new file mode 100644 index 0000000000..f2c0a322a0 --- /dev/null +++ b/models/perm/access_mode.go @@ -0,0 +1,61 @@ +// Copyright 2019 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 perm + +import ( + "fmt" + + "code.gitea.io/gitea/modules/log" +) + +// AccessMode specifies the users access mode +type AccessMode int + +const ( + // AccessModeNone no access + AccessModeNone AccessMode = iota // 0 + // AccessModeRead read access + AccessModeRead // 1 + // AccessModeWrite write access + AccessModeWrite // 2 + // AccessModeAdmin admin access + AccessModeAdmin // 3 + // AccessModeOwner owner access + AccessModeOwner // 4 +) + +func (mode AccessMode) String() string { + switch mode { + case AccessModeRead: + return "read" + case AccessModeWrite: + return "write" + case AccessModeAdmin: + return "admin" + case AccessModeOwner: + return "owner" + default: + return "none" + } +} + +// ColorFormat provides a ColorFormatted version of this AccessMode +func (mode AccessMode) ColorFormat(s fmt.State) { + log.ColorFprintf(s, "%d:%s", + log.NewColoredIDValue(mode), + mode) +} + +// ParseAccessMode returns corresponding access mode to given permission string. +func ParseAccessMode(permission string) AccessMode { + switch permission { + case "write": + return AccessModeWrite + case "admin": + return AccessModeAdmin + default: + return AccessModeRead + } +} diff --git a/models/repo.go b/models/repo.go index 4cf3be6aa3..67879fefda 100644 --- a/models/repo.go +++ b/models/repo.go @@ -25,6 +25,7 @@ import ( admin_model "code.gitea.io/gitea/models/admin" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" @@ -542,7 +543,7 @@ func (repo *Repository) getAssignees(e db.Engine) (_ []*user_model.User, err err accesses := make([]*Access, 0, 10) if err = e. - Where("repo_id = ? AND mode >= ?", repo.ID, AccessModeWrite). + Where("repo_id = ? AND mode >= ?", repo.ID, perm.AccessModeWrite). Find(&accesses); err != nil { return nil, err } @@ -586,7 +587,7 @@ func (repo *Repository) getReviewers(e db.Engine, doerID, posterID int64) ([]*us // Anyone who can read the repository is a requestable reviewer if err := e. SQL("SELECT * FROM `user` WHERE id in (SELECT user_id FROM `access` WHERE repo_id = ? AND mode >= ? AND user_id NOT IN ( ?, ?)) ORDER BY name", - repo.ID, AccessModeRead, + repo.ID, perm.AccessModeRead, doerID, posterID). Find(&users); err != nil { return nil, err @@ -605,7 +606,7 @@ func (repo *Repository) getReviewers(e db.Engine, doerID, posterID int64) ([]*us "UNION "+ "SELECT uid AS user_id FROM `org_user` WHERE org_id = ? "+ ") AND id NOT IN (?, ?) ORDER BY name", - repo.ID, AccessModeRead, + repo.ID, perm.AccessModeRead, repo.ID, RepoWatchModeNormal, RepoWatchModeAuto, repo.OwnerID, doerID, posterID). @@ -634,7 +635,7 @@ func (repo *Repository) GetReviewerTeams() ([]*Team, error) { return nil, nil } - teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, AccessModeRead) + teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, perm.AccessModeRead) if err != nil { return nil, err } @@ -817,12 +818,12 @@ func (repo *Repository) CanEnableEditor() bool { // GetReaders returns all users that have explicit read access or higher to the repository. func (repo *Repository) GetReaders() (_ []*user_model.User, err error) { - return repo.getUsersWithAccessMode(db.GetEngine(db.DefaultContext), AccessModeRead) + return repo.getUsersWithAccessMode(db.GetEngine(db.DefaultContext), perm.AccessModeRead) } // GetWriters returns all users that have write access to the repository. func (repo *Repository) GetWriters() (_ []*user_model.User, err error) { - return repo.getUsersWithAccessMode(db.GetEngine(db.DefaultContext), AccessModeWrite) + return repo.getUsersWithAccessMode(db.GetEngine(db.DefaultContext), perm.AccessModeWrite) } // IsReader returns true if user has explicit read access or higher to the repository. @@ -830,11 +831,11 @@ func (repo *Repository) IsReader(userID int64) (bool, error) { if repo.OwnerID == userID { return true, nil } - return db.GetEngine(db.DefaultContext).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, AccessModeRead).Get(&Access{}) + return db.GetEngine(db.DefaultContext).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm.AccessModeRead).Get(&Access{}) } // getUsersWithAccessMode returns users that have at least given access mode to the repository. -func (repo *Repository) getUsersWithAccessMode(e db.Engine, mode AccessMode) (_ []*user_model.User, err error) { +func (repo *Repository) getUsersWithAccessMode(e db.Engine, mode perm.AccessMode) (_ []*user_model.User, err error) { if err = repo.getOwner(e); err != nil { return nil, err } @@ -1143,7 +1144,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *Repos if err = repo.addCollaborator(db.GetEngine(ctx), doer); err != nil { return fmt.Errorf("AddCollaborator: %v", err) } - if err = repo.changeCollaborationAccessMode(db.GetEngine(ctx), doer.ID, AccessModeAdmin); err != nil { + if err = repo.changeCollaborationAccessMode(db.GetEngine(ctx), doer.ID, perm.AccessModeAdmin); err != nil { return fmt.Errorf("ChangeCollaborationAccessMode: %v", err) } } diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go index 11d1a0e1d0..08682eef61 100644 --- a/models/repo_collaboration.go +++ b/models/repo_collaboration.go @@ -9,6 +9,7 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -22,7 +23,7 @@ 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 AccessMode `xorm:"DEFAULT 2 NOT NULL"` + Mode perm.AccessMode `xorm:"DEFAULT 2 NOT NULL"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` } @@ -43,7 +44,7 @@ func (repo *Repository) addCollaborator(e db.Engine, u *user_model.User) error { } else if has { return nil } - collaboration.Mode = AccessModeWrite + collaboration.Mode = perm.AccessModeWrite if _, err = e.InsertOne(collaboration); err != nil { return err @@ -141,9 +142,9 @@ func (repo *Repository) IsCollaborator(userID int64) (bool, error) { return repo.isCollaborator(db.GetEngine(db.DefaultContext), userID) } -func (repo *Repository) changeCollaborationAccessMode(e db.Engine, uid int64, mode AccessMode) error { +func (repo *Repository) changeCollaborationAccessMode(e db.Engine, uid int64, mode perm.AccessMode) error { // Discard invalid input - if mode <= AccessModeNone || mode > AccessModeOwner { + if mode <= perm.AccessModeNone || mode > perm.AccessModeOwner { return nil } @@ -176,7 +177,7 @@ func (repo *Repository) changeCollaborationAccessMode(e db.Engine, uid int64, mo } // ChangeCollaborationAccessMode sets new access mode for the collaboration. -func (repo *Repository) ChangeCollaborationAccessMode(uid int64, mode AccessMode) error { +func (repo *Repository) ChangeCollaborationAccessMode(uid int64, mode perm.AccessMode) error { ctx, committer, err := db.TxContext() if err != nil { return err diff --git a/models/repo_collaboration_test.go b/models/repo_collaboration_test.go index 94dd238cb6..94df6c27b3 100644 --- a/models/repo_collaboration_test.go +++ b/models/repo_collaboration_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -68,17 +69,17 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository) - assert.NoError(t, repo.ChangeCollaborationAccessMode(4, AccessModeAdmin)) + assert.NoError(t, repo.ChangeCollaborationAccessMode(4, perm.AccessModeAdmin)) collaboration := unittest.AssertExistsAndLoadBean(t, &Collaboration{RepoID: repo.ID, UserID: 4}).(*Collaboration) - assert.EqualValues(t, AccessModeAdmin, collaboration.Mode) + assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode) access := unittest.AssertExistsAndLoadBean(t, &Access{UserID: 4, RepoID: repo.ID}).(*Access) - assert.EqualValues(t, AccessModeAdmin, access.Mode) + assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) - assert.NoError(t, repo.ChangeCollaborationAccessMode(4, AccessModeAdmin)) + assert.NoError(t, repo.ChangeCollaborationAccessMode(4, perm.AccessModeAdmin)) - assert.NoError(t, repo.ChangeCollaborationAccessMode(unittest.NonexistentID, AccessModeAdmin)) + assert.NoError(t, repo.ChangeCollaborationAccessMode(unittest.NonexistentID, perm.AccessModeAdmin)) unittest.CheckConsistencyFor(t, &Repository{ID: repo.ID}) } diff --git a/models/repo_list.go b/models/repo_list.go index ff86f61577..dbcf0609bd 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -9,6 +9,7 @@ import ( "strings" "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/structs" "code.gitea.io/gitea/modules/util" @@ -431,7 +432,7 @@ func accessibleRepositoryCondition(user *user_model.User) builder.Cond { From("`access`"). Where(builder.And( builder.Eq{"user_id": user.ID}, - builder.Gt{"mode": int(AccessModeNone)}))), + builder.Gt{"mode": int(perm.AccessModeNone)}))), // 3. Repositories that we directly own builder.Eq{"`repository`.owner_id": user.ID}, // 4. Be able to see all repositories that we are in a team diff --git a/models/repo_permission.go b/models/repo_permission.go index 96abb9037a..61d3d24e37 100644 --- a/models/repo_permission.go +++ b/models/repo_permission.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + perm_model "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -15,49 +16,49 @@ import ( // Permission contains all the permissions related variables to a repository for a user type Permission struct { - AccessMode AccessMode + AccessMode perm_model.AccessMode Units []*RepoUnit - UnitsMode map[unit.Type]AccessMode + UnitsMode map[unit.Type]perm_model.AccessMode } // IsOwner returns true if current user is the owner of repository. func (p *Permission) IsOwner() bool { - return p.AccessMode >= AccessModeOwner + return p.AccessMode >= perm_model.AccessModeOwner } // IsAdmin returns true if current user has admin or higher access of repository. func (p *Permission) IsAdmin() bool { - return p.AccessMode >= AccessModeAdmin + return p.AccessMode >= perm_model.AccessModeAdmin } // HasAccess returns true if the current user has at least read access to any unit of this repository func (p *Permission) HasAccess() bool { if p.UnitsMode == nil { - return p.AccessMode >= AccessModeRead + return p.AccessMode >= perm_model.AccessModeRead } return len(p.UnitsMode) > 0 } // UnitAccessMode returns current user accessmode to the specify unit of the repository -func (p *Permission) UnitAccessMode(unitType unit.Type) AccessMode { +func (p *Permission) UnitAccessMode(unitType unit.Type) perm_model.AccessMode { if p.UnitsMode == nil { for _, u := range p.Units { if u.Type == unitType { return p.AccessMode } } - return AccessModeNone + return perm_model.AccessModeNone } return p.UnitsMode[unitType] } // CanAccess returns true if user has mode access to the unit of the repository -func (p *Permission) CanAccess(mode AccessMode, unitType unit.Type) bool { +func (p *Permission) CanAccess(mode perm_model.AccessMode, unitType unit.Type) bool { return p.UnitAccessMode(unitType) >= mode } // CanAccessAny returns true if user has mode access to any of the units of the repository -func (p *Permission) CanAccessAny(mode AccessMode, unitTypes ...unit.Type) bool { +func (p *Permission) CanAccessAny(mode perm_model.AccessMode, unitTypes ...unit.Type) bool { for _, u := range unitTypes { if p.CanAccess(mode, u) { return true @@ -68,12 +69,12 @@ func (p *Permission) CanAccessAny(mode AccessMode, unitTypes ...unit.Type) bool // CanRead returns true if user could read to this unit func (p *Permission) CanRead(unitType unit.Type) bool { - return p.CanAccess(AccessModeRead, unitType) + return p.CanAccess(perm_model.AccessModeRead, unitType) } // CanReadAny returns true if user has read access to any of the units of the repository func (p *Permission) CanReadAny(unitTypes ...unit.Type) bool { - return p.CanAccessAny(AccessModeRead, unitTypes...) + return p.CanAccessAny(perm_model.AccessModeRead, unitTypes...) } // CanReadIssuesOrPulls returns true if isPull is true and user could read pull requests and @@ -87,7 +88,7 @@ func (p *Permission) CanReadIssuesOrPulls(isPull bool) bool { // CanWrite returns true if user could write to this unit func (p *Permission) CanWrite(unitType unit.Type) bool { - return p.CanAccess(AccessModeWrite, unitType) + return p.CanAccess(perm_model.AccessModeWrite, unitType) } // CanWriteIssuesOrPulls returns true if isPull is true and user could write to pull requests and @@ -103,7 +104,7 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool { func (p *Permission) ColorFormat(s fmt.State) { noColor := log.ColorBytes(log.Reset) - format := "AccessMode: %-v, %d Units, %d UnitsMode(s): [ " + format := "perm_model.AccessMode: %-v, %d Units, %d UnitsMode(s): [ " args := []interface{}{ p.AccessMode, log.NewColoredValueBytes(len(p.Units), &noColor), @@ -163,7 +164,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User) // anonymous user visit private repo. // TODO: anonymous user visit public unit of private repo??? if user == nil && repo.IsPrivate { - perm.AccessMode = AccessModeNone + perm.AccessMode = perm_model.AccessModeNone return } @@ -182,7 +183,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User) // Prevent strangers from checking out public repo of private organization/users // Allow user if they are collaborator of a repo within a private user or a private organization but not a member of the organization itself if !hasOrgOrUserVisible(e, repo.Owner, user) && !isCollaborator { - perm.AccessMode = AccessModeNone + perm.AccessMode = perm_model.AccessModeNone return } @@ -194,13 +195,13 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User) // anonymous visit public repo if user == nil { - perm.AccessMode = AccessModeRead + perm.AccessMode = perm_model.AccessModeRead return } // Admin or the owner has super access to the repository if user.IsAdmin || user.ID == repo.OwnerID { - perm.AccessMode = AccessModeOwner + perm.AccessMode = perm_model.AccessModeOwner return } @@ -217,7 +218,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User) return } - perm.UnitsMode = make(map[unit.Type]AccessMode) + perm.UnitsMode = make(map[unit.Type]perm_model.AccessMode) // Collaborators on organization if isCollaborator { @@ -234,8 +235,8 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User) // if user in an owner team for _, team := range teams { - if team.Authorize >= AccessModeOwner { - perm.AccessMode = AccessModeOwner + if team.Authorize >= perm_model.AccessModeOwner { + perm.AccessMode = perm_model.AccessModeOwner perm.UnitsMode = nil return } @@ -256,7 +257,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User) // for a public repo on an organization, a non-restricted user has read permission on non-team defined units. if !found && !repo.IsPrivate && !user.IsRestricted { if _, ok := perm.UnitsMode[u.Type]; !ok { - perm.UnitsMode[u.Type] = AccessModeRead + perm.UnitsMode[u.Type] = perm_model.AccessModeRead } } } @@ -291,7 +292,7 @@ func IsUserRealRepoAdmin(repo *Repository, user *user_model.User) (bool, error) return false, err } - return accessMode >= AccessModeAdmin, nil + return accessMode >= perm_model.AccessModeAdmin, nil } // IsUserRepoAdmin return true if user has admin right of a repo @@ -311,7 +312,7 @@ func isUserRepoAdmin(e db.Engine, repo *Repository, user *user_model.User) (bool if err != nil { return false, err } - if mode >= AccessModeAdmin { + if mode >= perm_model.AccessModeAdmin { return true, nil } @@ -321,7 +322,7 @@ func isUserRepoAdmin(e db.Engine, repo *Repository, user *user_model.User) (bool } for _, team := range teams { - if team.Authorize >= AccessModeAdmin { + if team.Authorize >= perm_model.AccessModeAdmin { return true, nil } } @@ -330,31 +331,31 @@ func isUserRepoAdmin(e db.Engine, repo *Repository, user *user_model.User) (bool // 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 *Repository) (AccessMode, error) { +func AccessLevel(user *user_model.User, repo *Repository) (perm_model.AccessMode, error) { return accessLevelUnit(db.GetEngine(db.DefaultContext), 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 *Repository, unitType unit.Type) (AccessMode, error) { +func AccessLevelUnit(user *user_model.User, repo *Repository, unitType unit.Type) (perm_model.AccessMode, error) { return accessLevelUnit(db.GetEngine(db.DefaultContext), user, repo, unitType) } -func accessLevelUnit(e db.Engine, user *user_model.User, repo *Repository, unitType unit.Type) (AccessMode, error) { +func accessLevelUnit(e db.Engine, user *user_model.User, repo *Repository, unitType unit.Type) (perm_model.AccessMode, error) { perm, err := getUserRepoPermission(e, repo, user) if err != nil { - return AccessModeNone, err + return perm_model.AccessModeNone, err } return perm.UnitAccessMode(unitType), nil } -func hasAccessUnit(e db.Engine, user *user_model.User, repo *Repository, unitType unit.Type, testMode AccessMode) (bool, error) { +func hasAccessUnit(e db.Engine, user *user_model.User, repo *Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) { mode, err := accessLevelUnit(e, 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 *Repository, unitType unit.Type, testMode AccessMode) (bool, error) { +func HasAccessUnit(user *user_model.User, repo *Repository, unitType unit.Type, testMode perm_model.AccessMode) (bool, error) { return hasAccessUnit(db.GetEngine(db.DefaultContext), user, repo, unitType, testMode) } @@ -373,7 +374,7 @@ func canBeAssigned(e db.Engine, user *user_model.User, repo *Repository, _ bool) if err != nil { return false, err } - return perm.CanAccessAny(AccessModeWrite, unit.TypeCode, unit.TypeIssues, unit.TypePullRequests), nil + return perm.CanAccessAny(perm_model.AccessModeWrite, unit.TypeCode, unit.TypeIssues, unit.TypePullRequests), nil } func hasAccess(e db.Engine, userID int64, repo *Repository) (bool, error) { diff --git a/models/repo_permission_test.go b/models/repo_permission_test.go index ce046eba7a..795b5f2115 100644 --- a/models/repo_permission_test.go +++ b/models/repo_permission_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models/db" + perm_model "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -93,7 +94,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) { assert.True(t, perm.CanWrite(unit.Type)) } - assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, AccessModeRead)) + assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, perm_model.AccessModeRead)) perm, err = GetUserRepoPermission(repo, user) assert.NoError(t, err) for _, unit := range repo.Units { @@ -145,7 +146,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) { assert.True(t, perm.CanWrite(unit.Type)) } - assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, AccessModeRead)) + assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, perm_model.AccessModeRead)) perm, err = GetUserRepoPermission(repo, user) assert.NoError(t, err) for _, unit := range repo.Units { @@ -207,7 +208,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) { assert.True(t, perm.CanWrite(unit.Type)) } - assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, AccessModeRead)) + assert.NoError(t, repo.ChangeCollaborationAccessMode(user.ID, perm_model.AccessModeRead)) perm, err = GetUserRepoPermission(repo, user) assert.NoError(t, err) for _, unit := range repo.Units { diff --git a/models/review.go b/models/review.go index 1c4943f699..eebf796876 100644 --- a/models/review.go +++ b/models/review.go @@ -9,6 +9,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -277,7 +278,7 @@ func isOfficialReviewerTeam(e db.Engine, issue *Issue, team *Team) (bool, error) } if !pr.ProtectedBranch.EnableApprovalsWhitelist { - return team.Authorize >= AccessModeWrite, nil + return team.Authorize >= perm.AccessModeWrite, nil } return base.Int64sContains(pr.ProtectedBranch.ApprovalsWhitelistTeamIDs, team.ID), nil @@ -895,12 +896,12 @@ func CanMarkConversation(issue *Issue, doer *user_model.User) (permResult bool, return false, err } - perm, err := GetUserRepoPermission(issue.Repo, doer) + p, err := GetUserRepoPermission(issue.Repo, doer) if err != nil { return false, err } - permResult = perm.CanAccess(AccessModeWrite, unit.TypePullRequests) + permResult = p.CanAccess(perm.AccessModeWrite, unit.TypePullRequests) if !permResult { if permResult, err = IsOfficialReviewer(issue, doer); err != nil { return false, err diff --git a/models/ssh_key.go b/models/ssh_key.go index 780eb2e15c..0d97096149 100644 --- a/models/ssh_key.go +++ b/models/ssh_key.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" + "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" @@ -35,14 +36,14 @@ const ( // PublicKey represents a user or deploy SSH public key. type PublicKey struct { - ID int64 `xorm:"pk autoincr"` - OwnerID int64 `xorm:"INDEX NOT NULL"` - Name string `xorm:"NOT NULL"` - Fingerprint string `xorm:"INDEX NOT NULL"` - Content string `xorm:"TEXT NOT NULL"` - Mode AccessMode `xorm:"NOT NULL DEFAULT 2"` - Type KeyType `xorm:"NOT NULL DEFAULT 1"` - LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"` + ID int64 `xorm:"pk autoincr"` + OwnerID int64 `xorm:"INDEX NOT NULL"` + Name string `xorm:"NOT NULL"` + Fingerprint string `xorm:"INDEX NOT NULL"` + Content string `xorm:"TEXT NOT NULL"` + Mode perm.AccessMode `xorm:"NOT NULL DEFAULT 2"` + Type KeyType `xorm:"NOT NULL DEFAULT 1"` + LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"` CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` @@ -123,7 +124,7 @@ func AddPublicKey(ownerID int64, name, content string, loginSourceID int64) (*Pu Name: name, Fingerprint: fingerprint, Content: content, - Mode: AccessModeWrite, + Mode: perm.AccessModeWrite, Type: KeyTypeUser, LoginSourceID: loginSourceID, } diff --git a/models/ssh_key_deploy.go b/models/ssh_key_deploy.go index cf439f6282..187af3ca9b 100644 --- a/models/ssh_key_deploy.go +++ b/models/ssh_key_deploy.go @@ -9,6 +9,7 @@ import ( "time" "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/timeutil" @@ -33,7 +34,7 @@ type DeployKey struct { Fingerprint string Content string `xorm:"-"` - Mode AccessMode `xorm:"NOT NULL DEFAULT 1"` + Mode perm.AccessMode `xorm:"NOT NULL DEFAULT 1"` CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` @@ -59,7 +60,7 @@ func (key *DeployKey) GetContent() error { // IsReadOnly checks if the key can only be used for read operations func (key *DeployKey) IsReadOnly() bool { - return key.Mode == AccessModeRead + return key.Mode == perm.AccessModeRead } func init() { @@ -90,7 +91,7 @@ func checkDeployKey(e db.Engine, keyID, repoID int64, name string) error { } // addDeployKey adds new key-repo relation. -func addDeployKey(e db.Engine, keyID, repoID int64, name, fingerprint string, mode AccessMode) (*DeployKey, error) { +func addDeployKey(e db.Engine, keyID, repoID int64, name, fingerprint string, mode perm.AccessMode) (*DeployKey, error) { if err := checkDeployKey(e, keyID, repoID, name); err != nil { return nil, err } @@ -121,9 +122,9 @@ func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey return nil, err } - accessMode := AccessModeRead + accessMode := perm.AccessModeRead if !readOnly { - accessMode = AccessModeWrite + accessMode = perm.AccessModeWrite } ctx, committer, err := db.TxContext() diff --git a/models/ssh_key_principals.go b/models/ssh_key_principals.go index 63c38f6886..9a17a56f1a 100644 --- a/models/ssh_key_principals.go +++ b/models/ssh_key_principals.go @@ -10,6 +10,7 @@ import ( "strings" "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/setting" ) @@ -46,7 +47,7 @@ func AddPrincipalKey(ownerID int64, content string, loginSourceID int64) (*Publi OwnerID: ownerID, Name: content, Content: content, - Mode: AccessModeWrite, + Mode: perm.AccessModeWrite, Type: KeyTypePrincipal, LoginSourceID: loginSourceID, } diff --git a/modules/context/org.go b/modules/context/org.go index 2a3ebdd1e7..eb81f6644c 100644 --- a/modules/context/org.go +++ b/modules/context/org.go @@ -9,6 +9,7 @@ import ( "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" ) @@ -167,7 +168,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) { return } - ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= models.AccessModeAdmin + ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= perm.AccessModeAdmin ctx.Data["IsTeamAdmin"] = ctx.Org.IsTeamAdmin if requireTeamAdmin && !ctx.Org.IsTeamAdmin { ctx.NotFound("OrgAssignment", err) diff --git a/modules/convert/convert.go b/modules/convert/convert.go index f08a62588e..8c6a610625 100644 --- a/modules/convert/convert.go +++ b/modules/convert/convert.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/login" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" @@ -38,7 +39,7 @@ func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models. var hasPerm bool var err error if user != nil { - hasPerm, err = models.HasAccessUnit(user, repo, unit.TypeCode, models.AccessModeWrite) + hasPerm, err = models.HasAccessUnit(user, repo, unit.TypeCode, perm.AccessModeWrite) if err != nil { return nil, err } @@ -272,7 +273,7 @@ func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey { URL: fmt.Sprintf("%s%d", apiLink, key.ID), Title: key.Name, Created: key.CreatedUnix.AsTime(), - ReadOnly: key.Mode == models.AccessModeRead, // All deploy keys are read-only. + ReadOnly: key.Mode == perm.AccessModeRead, // All deploy keys are read-only. } } diff --git a/modules/convert/notification.go b/modules/convert/notification.go index 5f4fef02b9..a0bd4cdc27 100644 --- a/modules/convert/notification.go +++ b/modules/convert/notification.go @@ -8,6 +8,7 @@ import ( "net/url" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" api "code.gitea.io/gitea/modules/structs" ) @@ -23,7 +24,7 @@ func ToNotificationThread(n *models.Notification) *api.NotificationThread { //since user only get notifications when he has access to use minimal access mode if n.Repository != nil { - result.Repository = ToRepo(n.Repository, models.AccessModeRead) + result.Repository = ToRepo(n.Repository, perm.AccessModeRead) } //handle Subject diff --git a/modules/convert/pull.go b/modules/convert/pull.go index f892107f4b..ea1e4bb3c2 100644 --- a/modules/convert/pull.go +++ b/modules/convert/pull.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" @@ -41,10 +42,10 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *user_model.User) *api.PullRe return nil } - perm, err := models.GetUserRepoPermission(pr.BaseRepo, doer) + p, err := models.GetUserRepoPermission(pr.BaseRepo, doer) if err != nil { log.Error("GetUserRepoPermission[%d]: %v", pr.BaseRepoID, err) - perm.AccessMode = models.AccessModeNone + p.AccessMode = perm.AccessModeNone } apiPullRequest := &api.PullRequest{ @@ -74,7 +75,7 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *user_model.User) *api.PullRe Name: pr.BaseBranch, Ref: pr.BaseBranch, RepoID: pr.BaseRepoID, - Repository: ToRepo(pr.BaseRepo, perm.AccessMode), + Repository: ToRepo(pr.BaseRepo, p.AccessMode), }, Head: &api.PRBranchInfo{ Name: pr.HeadBranch, @@ -127,14 +128,14 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *user_model.User) *api.PullRe } if pr.HeadRepo != nil && pr.Flow == models.PullRequestFlowGithub { - perm, err := models.GetUserRepoPermission(pr.HeadRepo, doer) + p, err := models.GetUserRepoPermission(pr.HeadRepo, doer) if err != nil { log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) - perm.AccessMode = models.AccessModeNone + p.AccessMode = perm.AccessModeNone } apiPullRequest.Head.RepoID = pr.HeadRepo.ID - apiPullRequest.Head.Repository = ToRepo(pr.HeadRepo, perm.AccessMode) + apiPullRequest.Head.Repository = ToRepo(pr.HeadRepo, p.AccessMode) headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath()) if err != nil { diff --git a/modules/convert/pull_test.go b/modules/convert/pull_test.go index 844011b8cc..1bac5d3a4a 100644 --- a/modules/convert/pull_test.go +++ b/modules/convert/pull_test.go @@ -8,6 +8,7 @@ import ( "testing" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/structs" @@ -28,7 +29,7 @@ func TestPullRequest_APIFormat(t *testing.T) { Ref: "refs/pull/2/head", Sha: "4a357436d925b5c974181ff12a994538ddc5a269", RepoID: 1, - Repository: ToRepo(headRepo, models.AccessModeRead), + Repository: ToRepo(headRepo, perm.AccessModeRead), }, apiPullRequest.Head) //withOut HeadRepo diff --git a/modules/convert/repository.go b/modules/convert/repository.go index bb8217908d..46b2745b34 100644 --- a/modules/convert/repository.go +++ b/modules/convert/repository.go @@ -6,23 +6,24 @@ package convert import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" unit_model "code.gitea.io/gitea/models/unit" api "code.gitea.io/gitea/modules/structs" ) // ToRepo converts a Repository to api.Repository -func ToRepo(repo *models.Repository, mode models.AccessMode) *api.Repository { +func ToRepo(repo *models.Repository, mode perm.AccessMode) *api.Repository { return innerToRepo(repo, mode, false) } -func innerToRepo(repo *models.Repository, mode models.AccessMode, isParent bool) *api.Repository { +func innerToRepo(repo *models.Repository, mode perm.AccessMode, isParent bool) *api.Repository { var parent *api.Repository cloneLink := repo.CloneLink() permission := &api.Permission{ - Admin: mode >= models.AccessModeAdmin, - Push: mode >= models.AccessModeWrite, - Pull: mode >= models.AccessModeRead, + Admin: mode >= perm.AccessModeAdmin, + Push: mode >= perm.AccessModeWrite, + Pull: mode >= perm.AccessModeRead, } if !isParent { err := repo.GetBaseRepo() diff --git a/modules/convert/user.go b/modules/convert/user.go index ebe2f06460..dc4a8c49c7 100644 --- a/modules/convert/user.go +++ b/modules/convert/user.go @@ -5,7 +5,7 @@ package convert import ( - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" api "code.gitea.io/gitea/modules/structs" ) @@ -36,11 +36,11 @@ func ToUsers(doer *user_model.User, users []*user_model.User) []*api.User { // ToUserWithAccessMode convert user_model.User to api.User // AccessMode is not none show add some more information -func ToUserWithAccessMode(user *user_model.User, accessMode models.AccessMode) *api.User { +func ToUserWithAccessMode(user *user_model.User, accessMode perm.AccessMode) *api.User { if user == nil { return nil } - return toUser(user, accessMode != models.AccessModeNone, false) + return toUser(user, accessMode != perm.AccessModeNone, false) } // toUser convert user_model.User to api.User diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index bae9b78da0..378e7fd202 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -6,6 +6,7 @@ package webhook import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" @@ -91,7 +92,7 @@ func (m *webhookNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, r if u.IsOrganization() { if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{ Action: api.HookRepoCreated, - Repository: convert.ToRepo(repo, models.AccessModeOwner), + Repository: convert.ToRepo(repo, perm.AccessModeOwner), Organization: convert.ToUser(u, nil), Sender: convert.ToUser(doer, nil), }); err != nil { @@ -104,7 +105,7 @@ func (m *webhookNotifier) NotifyCreateRepository(doer *user_model.User, u *user_ // Add to hook queue for created repo after session commit. if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{ Action: api.HookRepoCreated, - Repository: convert.ToRepo(repo, models.AccessModeOwner), + Repository: convert.ToRepo(repo, perm.AccessModeOwner), Organization: convert.ToUser(u, nil), Sender: convert.ToUser(doer, nil), }); err != nil { @@ -117,7 +118,7 @@ func (m *webhookNotifier) NotifyDeleteRepository(doer *user_model.User, repo *mo if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{ Action: api.HookRepoDeleted, - Repository: convert.ToRepo(repo, models.AccessModeOwner), + Repository: convert.ToRepo(repo, perm.AccessModeOwner), Organization: convert.ToUser(u, nil), Sender: convert.ToUser(doer, nil), }); err != nil { @@ -129,7 +130,7 @@ func (m *webhookNotifier) NotifyMigrateRepository(doer *user_model.User, u *user // Add to hook queue for created repo after session commit. if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{ Action: api.HookRepoCreated, - Repository: convert.ToRepo(repo, models.AccessModeOwner), + Repository: convert.ToRepo(repo, perm.AccessModeOwner), Organization: convert.ToUser(u, nil), Sender: convert.ToUser(doer, nil), }); err != nil { @@ -504,7 +505,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue * Action: api.HookIssueLabelUpdated, Index: issue.Index, PullRequest: convert.ToAPIPullRequest(issue.PullRequest, nil), - Repository: convert.ToRepo(issue.Repo, models.AccessModeNone), + Repository: convert.ToRepo(issue.Repo, perm.AccessModeNone), Sender: convert.ToUser(doer, nil), }) } else { @@ -578,7 +579,7 @@ func (m *webhookNotifier) NotifyPushCommits(pusher *user_model.User, repo *model CompareURL: setting.AppURL + commits.CompareURL, Commits: apiCommits, HeadCommit: apiHeadCommit, - Repo: convert.ToRepo(repo, models.AccessModeOwner), + Repo: convert.ToRepo(repo, perm.AccessModeOwner), Pusher: apiPusher, Sender: apiPusher, }); err != nil { @@ -698,7 +699,7 @@ func (m *webhookNotifier) NotifyPullRequestReview(pr *models.PullRequest, review func (m *webhookNotifier) NotifyCreateRef(pusher *user_model.User, repo *models.Repository, refType, refFullName string) { apiPusher := convert.ToUser(pusher, nil) - apiRepo := convert.ToRepo(repo, models.AccessModeNone) + apiRepo := convert.ToRepo(repo, perm.AccessModeNone) refName := git.RefEndName(refFullName) gitRepo, err := git.OpenRepository(repo.RepoPath()) @@ -740,7 +741,7 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, p Action: api.HookIssueSynchronized, Index: pr.Issue.Index, PullRequest: convert.ToAPIPullRequest(pr, nil), - Repository: convert.ToRepo(pr.Issue.Repo, models.AccessModeNone), + Repository: convert.ToRepo(pr.Issue.Repo, perm.AccessModeNone), Sender: convert.ToUser(doer, nil), }); err != nil { log.Error("PrepareWebhooks [pull_id: %v]: %v", pr.ID, err) @@ -749,7 +750,7 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, p func (m *webhookNotifier) NotifyDeleteRef(pusher *user_model.User, repo *models.Repository, refType, refFullName string) { apiPusher := convert.ToUser(pusher, nil) - apiRepo := convert.ToRepo(repo, models.AccessModeNone) + apiRepo := convert.ToRepo(repo, perm.AccessModeNone) refName := git.RefEndName(refFullName) if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventDelete, &api.DeletePayload{ @@ -807,7 +808,7 @@ func (m *webhookNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *m CompareURL: setting.AppURL + commits.CompareURL, Commits: apiCommits, HeadCommit: apiHeadCommit, - Repo: convert.ToRepo(repo, models.AccessModeOwner), + Repo: convert.ToRepo(repo, perm.AccessModeOwner), Pusher: apiPusher, Sender: apiPusher, }); err != nil { diff --git a/modules/private/serv.go b/modules/private/serv.go index 7e4805d60c..4f5b19c597 100644 --- a/modules/private/serv.go +++ b/modules/private/serv.go @@ -11,6 +11,7 @@ import ( "net/url" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" @@ -74,7 +75,7 @@ func IsErrServCommand(err error) bool { } // ServCommand preps for a serv call -func ServCommand(ctx context.Context, keyID int64, ownerName, repoName string, mode models.AccessMode, verbs ...string) (*ServCommandResults, error) { +func ServCommand(ctx context.Context, keyID int64, ownerName, repoName string, mode perm.AccessMode, verbs ...string) (*ServCommandResults, error) { reqURL := setting.LocalURL + fmt.Sprintf("api/internal/serv/command/%d/%s/%s?mode=%d", keyID, url.PathEscape(ownerName), diff --git a/modules/repository/create_test.go b/modules/repository/create_test.go index d7d3281872..18995f4ecd 100644 --- a/modules/repository/create_test.go +++ b/modules/repository/create_test.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/structs" @@ -69,25 +70,25 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) { { OrgID: org.ID, Name: "team one", - Authorize: models.AccessModeRead, + Authorize: perm.AccessModeRead, IncludesAllRepositories: true, }, { OrgID: org.ID, Name: "team 2", - Authorize: models.AccessModeRead, + Authorize: perm.AccessModeRead, IncludesAllRepositories: false, }, { OrgID: org.ID, Name: "team three", - Authorize: models.AccessModeWrite, + Authorize: perm.AccessModeWrite, IncludesAllRepositories: true, }, { OrgID: org.ID, Name: "team 4", - Authorize: models.AccessModeWrite, + Authorize: perm.AccessModeWrite, IncludesAllRepositories: false, }, } diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 84065363f0..133cce3416 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models" "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/context" "code.gitea.io/gitea/modules/convert" @@ -155,16 +156,16 @@ func GetUserOrgsPermissions(ctx *context.APIContext) { return } - if authorizeLevel > models.AccessModeNone { + if authorizeLevel > perm.AccessModeNone { op.CanRead = true } - if authorizeLevel > models.AccessModeRead { + if authorizeLevel > perm.AccessModeRead { op.CanWrite = true } - if authorizeLevel > models.AccessModeWrite { + if authorizeLevel > perm.AccessModeWrite { op.IsAdmin = true } - if authorizeLevel > models.AccessModeAdmin { + if authorizeLevel > perm.AccessModeAdmin { op.IsOwner = true } diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index e78e487895..371f1dc86d 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -9,6 +9,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" unit_model "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -170,12 +171,12 @@ func CreateTeam(ctx *context.APIContext) { Description: form.Description, IncludesAllRepositories: form.IncludesAllRepositories, CanCreateOrgRepo: form.CanCreateOrgRepo, - Authorize: models.ParseAccessMode(form.Permission), + Authorize: perm.ParseAccessMode(form.Permission), } unitTypes := unit_model.FindUnitTypes(form.Units...) - if team.Authorize < models.AccessModeOwner { + if team.Authorize < perm.AccessModeOwner { var units = make([]*models.TeamUnit, 0, len(form.Units)) for _, tp := range unitTypes { units = append(units, &models.TeamUnit{ @@ -245,7 +246,7 @@ func EditTeam(ctx *context.APIContext) { isIncludeAllChanged := false if !team.IsOwnerTeam() && len(form.Permission) != 0 { // Validate permission level. - auth := models.ParseAccessMode(form.Permission) + auth := perm.ParseAccessMode(form.Permission) if team.Authorize != auth { isAuthChanged = true @@ -258,7 +259,7 @@ func EditTeam(ctx *context.APIContext) { } } - if team.Authorize < models.AccessModeOwner { + if team.Authorize < perm.AccessModeOwner { if len(form.Units) > 0 { var units = make([]*models.TeamUnit, 0, len(form.Units)) unitTypes := unit_model.FindUnitTypes(form.Units...) @@ -561,7 +562,7 @@ func AddTeamRepository(ctx *context.APIContext) { if access, err := models.AccessLevel(ctx.User, repo); err != nil { ctx.Error(http.StatusInternalServerError, "AccessLevel", err) return - } else if access < models.AccessModeAdmin { + } else if access < perm.AccessModeAdmin { ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") return } @@ -611,7 +612,7 @@ func RemoveTeamRepository(ctx *context.APIContext) { if access, err := models.AccessLevel(ctx.User, repo); err != nil { ctx.Error(http.StatusInternalServerError, "AccessLevel", err) return - } else if access < models.AccessModeAdmin { + } else if access < perm.AccessModeAdmin { ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") return } diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index fcc8f9a90f..80794fa444 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -9,7 +9,7 @@ import ( "errors" "net/http" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -177,7 +177,7 @@ func AddCollaborator(ctx *context.APIContext) { } if form.Permission != nil { - if err := ctx.Repo.Repository.ChangeCollaborationAccessMode(collaborator.ID, models.ParseAccessMode(*form.Permission)); err != nil { + if err := ctx.Repo.Repository.ChangeCollaborationAccessMode(collaborator.ID, perm.ParseAccessMode(*form.Permission)); err != nil { ctx.Error(http.StatusInternalServerError, "ChangeCollaborationAccessMode", err) return } diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 528b8fdecc..33321e6a02 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -10,6 +10,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -135,5 +136,5 @@ func CreateFork(ctx *context.APIContext) { } //TODO change back to 201 - ctx.JSON(http.StatusAccepted, convert.ToRepo(fork, models.AccessModeOwner)) + ctx.JSON(http.StatusAccepted, convert.ToRepo(fork, perm.AccessModeOwner)) } diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index 2969b92502..fdcaf5e389 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -8,7 +8,7 @@ package repo import ( "net/http" - "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -162,9 +162,9 @@ func TestHook(ctx *context.APIContext) { After: ctx.Repo.Commit.ID.String(), Commits: []*api.PayloadCommit{commit}, HeadCommit: commit, - Repo: convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), - Pusher: convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), - Sender: convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), + Repo: convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone), + Pusher: convert.ToUserWithAccessMode(ctx.User, perm.AccessModeNone), + Sender: convert.ToUserWithAccessMode(ctx.User, perm.AccessModeNone), }); err != nil { ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err) return diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index c20a4776cc..ad94da5b2d 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -11,6 +11,7 @@ import ( "net/url" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" @@ -21,7 +22,7 @@ import ( // appendPrivateInformation appends the owner and key type information to api.PublicKey func appendPrivateInformation(apiKey *api.DeployKey, key *models.DeployKey, repository *models.Repository) (*api.DeployKey, error) { - apiKey.ReadOnly = key.Mode == models.AccessModeRead + apiKey.ReadOnly = key.Mode == perm.AccessModeRead if repository.ID == key.RepoID { apiKey.Repository = convert.ToRepo(repository, key.Mode) } else { diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index bc594419f7..dba44efb21 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" "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/context" "code.gitea.io/gitea/modules/convert" @@ -207,7 +208,7 @@ func Migrate(ctx *context.APIContext) { } log.Trace("Repository migrated: %s/%s", repoOwner.Name, form.RepoName) - ctx.JSON(http.StatusCreated, convert.ToRepo(repo, models.AccessModeAdmin)) + ctx.JSON(http.StatusCreated, convert.ToRepo(repo, perm.AccessModeAdmin)) } func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, remoteAddr string, err error) { diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 08ebde4e0c..299eaddbc8 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -8,6 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -115,7 +116,7 @@ func ListReleases(ctx *context.APIContext) { opts := models.FindReleasesOptions{ ListOptions: listOptions, - IncludeDrafts: ctx.Repo.AccessMode >= models.AccessModeWrite || ctx.Repo.UnitAccessMode(unit.TypeReleases) >= models.AccessModeWrite, + IncludeDrafts: ctx.Repo.AccessMode >= perm.AccessModeWrite || ctx.Repo.UnitAccessMode(unit.TypeReleases) >= perm.AccessModeWrite, IncludeTags: false, IsDraft: ctx.FormOptionalBool("draft"), IsPreRelease: ctx.FormOptionalBool("pre-release"), diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index a74e13d3ab..2f37e10984 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -13,6 +13,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" @@ -276,7 +277,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err) } - ctx.JSON(http.StatusCreated, convert.ToRepo(repo, models.AccessModeOwner)) + ctx.JSON(http.StatusCreated, convert.ToRepo(repo, perm.AccessModeOwner)) } // Create one repository of mine @@ -420,7 +421,7 @@ func Generate(ctx *context.APIContext) { } log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) - ctx.JSON(http.StatusCreated, convert.ToRepo(repo, models.AccessModeOwner)) + ctx.JSON(http.StatusCreated, convert.ToRepo(repo, perm.AccessModeOwner)) } // CreateOrgRepoDeprecated create one repository of the organization diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index b3913bcd34..0a698383e5 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -9,6 +9,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -113,10 +114,10 @@ func Transfer(ctx *context.APIContext) { if ctx.Repo.Repository.Status == models.RepositoryPendingTransfer { log.Trace("Repository transfer initiated: %s -> %s", ctx.Repo.Repository.FullName(), newOwner.Name) - ctx.JSON(http.StatusCreated, convert.ToRepo(ctx.Repo.Repository, models.AccessModeAdmin)) + ctx.JSON(http.StatusCreated, convert.ToRepo(ctx.Repo.Repository, perm.AccessModeAdmin)) return } log.Trace("Repository transferred: %s -> %s", ctx.Repo.Repository.FullName(), newOwner.Name) - ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx.Repo.Repository, models.AccessModeAdmin)) + ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx.Repo.Repository, perm.AccessModeAdmin)) } diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index 719e1c0bdc..32291264bc 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -8,6 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -37,7 +38,7 @@ func appendPrivateInformation(apiKey *api.PublicKey, key *models.PublicKey, defa } else { apiKey.KeyType = "unknown" } - apiKey.ReadOnly = key.Mode == models.AccessModeRead + apiKey.ReadOnly = key.Mode == perm.AccessModeRead return apiKey, nil } diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index 0b0b522c15..760032460e 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -8,6 +8,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -37,7 +38,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) { ctx.Error(http.StatusInternalServerError, "AccessLevel", err) return } - if ctx.IsSigned && ctx.User.IsAdmin || access >= models.AccessModeRead { + if ctx.IsSigned && ctx.User.IsAdmin || access >= perm.AccessModeRead { apiRepos = append(apiRepos, convert.ToRepo(repos[i], access)) } } diff --git a/routers/private/serv.go b/routers/private/serv.go index 18057ededb..9cbd0c2c82 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -11,6 +11,7 @@ import ( "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" @@ -79,7 +80,7 @@ func ServCommand(ctx *context.PrivateContext) { keyID := ctx.ParamsInt64(":keyid") ownerName := ctx.Params(":owner") repoName := ctx.Params(":repo") - mode := models.AccessMode(ctx.FormInt("mode")) + mode := perm.AccessMode(ctx.FormInt("mode")) // Set the basic parts of the results to return results := private.ServCommandResults{ @@ -90,7 +91,7 @@ func ServCommand(ctx *context.PrivateContext) { // Now because we're not translating things properly let's just default some English strings here modeString := "read" - if mode > models.AccessModeRead { + if mode > perm.AccessModeRead { modeString = "write to" } @@ -172,7 +173,7 @@ func ServCommand(ctx *context.PrivateContext) { } // We can shortcut at this point if the repo is a mirror - if mode > models.AccessModeRead && repo.IsMirror { + if mode > perm.AccessModeRead && repo.IsMirror { ctx.JSON(http.StatusForbidden, private.ErrServCommand{ Results: results, Err: fmt.Sprintf("Mirror Repository %s/%s is read-only", results.OwnerName, results.RepoName), @@ -280,7 +281,7 @@ func ServCommand(ctx *context.PrivateContext) { } // Don't allow pushing if the repo is archived - if repoExist && mode > models.AccessModeRead && repo.IsArchived { + if repoExist && mode > perm.AccessModeRead && repo.IsArchived { ctx.JSON(http.StatusUnauthorized, private.ErrServCommand{ Results: results, Err: fmt.Sprintf("Repo: %s/%s is archived.", results.OwnerName, results.RepoName), @@ -290,7 +291,7 @@ func ServCommand(ctx *context.PrivateContext) { // Permissions checking: if repoExist && - (mode > models.AccessModeRead || + (mode > perm.AccessModeRead || repo.IsPrivate || owner.Visibility.IsPrivate() || (user != nil && user.IsRestricted) || // user will be nil if the key is a deploykey @@ -306,7 +307,7 @@ func ServCommand(ctx *context.PrivateContext) { } else { // Because of the special ref "refs/for" we will need to delay write permission check if git.SupportProcReceive && unitType == unit.TypeCode { - mode = models.AccessModeRead + mode = perm.AccessModeRead } perm, err := models.GetUserRepoPermission(repo, user) diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index da0830aad9..8d39f26976 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -12,6 +12,7 @@ import ( "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -235,12 +236,12 @@ func NewTeamPost(ctx *context.Context) { OrgID: ctx.Org.Organization.ID, Name: form.TeamName, Description: form.Description, - Authorize: models.ParseAccessMode(form.Permission), + Authorize: perm.ParseAccessMode(form.Permission), IncludesAllRepositories: includesAllRepositories, CanCreateOrgRepo: form.CanCreateOrgRepo, } - if t.Authorize < models.AccessModeOwner { + if t.Authorize < perm.AccessModeOwner { var units = make([]*models.TeamUnit, 0, len(form.Units)) for _, tp := range form.Units { units = append(units, &models.TeamUnit{ @@ -258,7 +259,7 @@ func NewTeamPost(ctx *context.Context) { return } - if t.Authorize < models.AccessModeAdmin && len(form.Units) == 0 { + if t.Authorize < perm.AccessModeAdmin && len(form.Units) == 0 { ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form) return } @@ -325,7 +326,7 @@ func EditTeamPost(ctx *context.Context) { var includesAllRepositories = form.RepoAccess == "all" if !t.IsOwnerTeam() { // Validate permission level. - auth := models.ParseAccessMode(form.Permission) + auth := perm.ParseAccessMode(form.Permission) t.Name = form.TeamName if t.Authorize != auth { @@ -339,7 +340,7 @@ func EditTeamPost(ctx *context.Context) { } } t.Description = form.Description - if t.Authorize < models.AccessModeOwner { + if t.Authorize < perm.AccessModeOwner { var units = make([]models.TeamUnit, 0, len(form.Units)) for _, tp := range form.Units { units = append(units, models.TeamUnit{ @@ -361,7 +362,7 @@ func EditTeamPost(ctx *context.Context) { return } - if t.Authorize < models.AccessModeAdmin && len(form.Units) == 0 { + if t.Authorize < perm.AccessModeAdmin && len(form.Units) == 0 { ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form) return } diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go index ce2d977518..d1978aefe2 100644 --- a/routers/web/repo/http.go +++ b/routers/web/repo/http.go @@ -22,6 +22,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/login" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" @@ -93,11 +94,11 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { isPull = ctx.Req.Method == "GET" } - var accessMode models.AccessMode + var accessMode perm.AccessMode if isPull { - accessMode = models.AccessModeRead + accessMode = perm.AccessModeRead } else { - accessMode = models.AccessModeWrite + accessMode = perm.AccessModeWrite } isWiki := false @@ -194,7 +195,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { } if repoExist { - perm, err := models.GetUserRepoPermission(repo, ctx.User) + p, err := models.GetUserRepoPermission(repo, ctx.User) if err != nil { ctx.ServerError("GetUserRepoPermission", err) return @@ -202,10 +203,10 @@ func httpBase(ctx *context.Context) (h *serviceHandler) { // Because of special ref "refs/for" .. , need delay write permission check if git.SupportProcReceive { - accessMode = models.AccessModeRead + accessMode = perm.AccessModeRead } - if !perm.CanAccess(accessMode, unitType) { + if !p.CanAccess(accessMode, unitType) { ctx.HandleText(http.StatusForbidden, "User permission denied") return } diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index bea9b7e419..c237544385 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -11,6 +11,7 @@ import ( "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" @@ -373,7 +374,7 @@ func DeleteProjectBoard(ctx *context.Context) { return } - if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, unit.TypeProjects) { + if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(perm.AccessModeWrite, unit.TypeProjects) { ctx.JSON(http.StatusForbidden, map[string]string{ "message": "Only authorized users are allowed to perform this action.", }) @@ -422,7 +423,7 @@ func DeleteProjectBoard(ctx *context.Context) { // AddBoardToProjectPost allows a new board to be added to a project. func AddBoardToProjectPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.EditProjectBoardForm) - if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, unit.TypeProjects) { + if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(perm.AccessModeWrite, unit.TypeProjects) { ctx.JSON(http.StatusForbidden, map[string]string{ "message": "Only authorized users are allowed to perform this action.", }) @@ -462,7 +463,7 @@ func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project, return nil, nil } - if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, unit.TypeProjects) { + if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(perm.AccessModeWrite, unit.TypeProjects) { ctx.JSON(http.StatusForbidden, map[string]string{ "message": "Only authorized users are allowed to perform this action.", }) @@ -556,7 +557,7 @@ func MoveIssueAcrossBoards(ctx *context.Context) { return } - if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(models.AccessModeWrite, unit.TypeProjects) { + if !ctx.Repo.IsOwner() && !ctx.Repo.IsAdmin() && !ctx.Repo.CanAccess(perm.AccessModeWrite, unit.TypeProjects) { ctx.JSON(http.StatusForbidden, map[string]string{ "message": "Only authorized users are allowed to perform this action.", }) diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index 20fa9ea785..76a24d9f40 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" @@ -846,7 +847,7 @@ func CollaborationPost(ctx *context.Context) { func ChangeCollaborationAccessMode(ctx *context.Context) { if err := ctx.Repo.Repository.ChangeCollaborationAccessMode( ctx.FormInt64("uid"), - models.AccessMode(ctx.FormInt("mode"))); err != nil { + perm.AccessMode(ctx.FormInt("mode"))); err != nil { log.Error("ChangeCollaborationAccessMode: %v", err) } } diff --git a/routers/web/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go index b13dfae683..e0580ac6de 100644 --- a/routers/web/repo/setting_protected_branch.go +++ b/routers/web/repo/setting_protected_branch.go @@ -11,6 +11,7 @@ import ( "time" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" @@ -156,7 +157,7 @@ func SettingsProtectedBranch(c *context.Context) { } if c.Repo.Owner.IsOrganization() { - teams, err := models.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, models.AccessModeRead) + teams, err := models.OrgFromUser(c.Repo.Owner).TeamsWithAccessToRepo(c.Repo.Repository.ID, perm.AccessModeRead) if err != nil { c.ServerError("Repo.Owner.TeamsWithAccessToRepo", err) return diff --git a/routers/web/repo/settings_test.go b/routers/web/repo/settings_test.go index 8e53babe7c..5f997bc36b 100644 --- a/routers/web/repo/settings_test.go +++ b/routers/web/repo/settings_test.go @@ -10,6 +10,7 @@ import ( "testing" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" @@ -62,7 +63,7 @@ func TestAddReadOnlyDeployKey(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ Name: addKeyForm.Title, Content: addKeyForm.Content, - Mode: models.AccessModeRead, + Mode: perm.AccessModeRead, }) } @@ -92,7 +93,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ Name: addKeyForm.Title, Content: addKeyForm.Content, - Mode: models.AccessModeWrite, + Mode: perm.AccessModeWrite, }) } diff --git a/routers/web/repo/tag.go b/routers/web/repo/tag.go index 4383b6214a..671c388cb1 100644 --- a/routers/web/repo/tag.go +++ b/routers/web/repo/tag.go @@ -10,6 +10,7 @@ import ( "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" @@ -149,7 +150,7 @@ func setTagsContext(ctx *context.Context) error { ctx.Data["Users"] = users if ctx.Repo.Owner.IsOrganization() { - teams, err := models.OrgFromUser(ctx.Repo.Owner).TeamsWithAccessToRepo(ctx.Repo.Repository.ID, models.AccessModeRead) + teams, err := models.OrgFromUser(ctx.Repo.Owner).TeamsWithAccessToRepo(ctx.Repo.Repository.ID, perm.AccessModeRead) if err != nil { ctx.ServerError("Repo.Owner.TeamsWithAccessToRepo", err) return err diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go index 28ca3e0de5..47d8413671 100644 --- a/routers/web/repo/webhook.go +++ b/routers/web/repo/webhook.go @@ -13,8 +13,8 @@ import ( "path" "strings" - "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/base" @@ -1159,7 +1159,7 @@ func TestWebhook(ctx *context.Context) { } } - apiUser := convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone) + apiUser := convert.ToUserWithAccessMode(ctx.User, perm.AccessModeNone) apiCommit := &api.PayloadCommit{ ID: commit.ID.String(), @@ -1181,7 +1181,7 @@ func TestWebhook(ctx *context.Context) { After: commit.ID.String(), Commits: []*api.PayloadCommit{apiCommit}, HeadCommit: apiCommit, - Repo: convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), + Repo: convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone), Pusher: apiUser, Sender: apiUser, } diff --git a/services/issue/assignee.go b/services/issue/assignee.go index 62d274a65f..14c040ad7a 100644 --- a/services/issue/assignee.go +++ b/services/issue/assignee.go @@ -6,6 +6,7 @@ package issue import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" @@ -111,7 +112,7 @@ func IsValidReviewRequest(reviewer, doer *user_model.User, isAdd bool, issue *mo var pemResult bool if isAdd { - pemResult = permReviewer.CanAccessAny(models.AccessModeRead, unit.TypePullRequests) + pemResult = permReviewer.CanAccessAny(perm.AccessModeRead, unit.TypePullRequests) if !pemResult { return models.ErrNotValidReviewRequest{ Reason: "Reviewer can't read", @@ -124,7 +125,7 @@ func IsValidReviewRequest(reviewer, doer *user_model.User, isAdd bool, issue *mo return nil } - pemResult = permDoer.CanAccessAny(models.AccessModeWrite, unit.TypePullRequests) + pemResult = permDoer.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests) if !pemResult { pemResult, err = models.IsOfficialReviewer(issue, doer) if err != nil { @@ -201,7 +202,7 @@ func IsValidTeamReviewRequest(reviewer *models.Team, doer *user_model.User, isAd } } - doerCanWrite := permission.CanAccessAny(models.AccessModeWrite, unit.TypePullRequests) + doerCanWrite := permission.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests) if !doerCanWrite { official, err := models.IsOfficialReviewer(issue, doer) if err != nil { diff --git a/services/lfs/server.go b/services/lfs/server.go index 28756e4f19..2b0c8265c0 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -19,6 +19,7 @@ import ( "strings" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" @@ -480,9 +481,9 @@ func writeStatusMessage(ctx *context.Context, status int, message string) { // authenticate uses the authorization string to determine whether // or not to proceed. This server assumes an HTTP Basic auth format. func authenticate(ctx *context.Context, repository *models.Repository, authorization string, requireSigned, requireWrite bool) bool { - accessMode := models.AccessModeRead + accessMode := perm.AccessModeRead if requireWrite { - accessMode = models.AccessModeWrite + accessMode = perm.AccessModeWrite } // ctx.IsSigned is unnecessary here, this will be checked in perm.CanAccess @@ -507,7 +508,7 @@ func authenticate(ctx *context.Context, repository *models.Repository, authoriza return true } -func handleLFSToken(tokenSHA string, target *models.Repository, mode models.AccessMode) (*user_model.User, error) { +func handleLFSToken(tokenSHA string, target *models.Repository, mode perm.AccessMode) (*user_model.User, error) { if !strings.Contains(tokenSHA, ".") { return nil, nil } @@ -530,7 +531,7 @@ func handleLFSToken(tokenSHA string, target *models.Repository, mode models.Acce return nil, fmt.Errorf("invalid token claim") } - if mode == models.AccessModeWrite && claims.Op != "upload" { + if mode == perm.AccessModeWrite && claims.Op != "upload" { return nil, fmt.Errorf("invalid token claim") } @@ -542,7 +543,7 @@ func handleLFSToken(tokenSHA string, target *models.Repository, mode models.Acce return u, nil } -func parseToken(authorization string, target *models.Repository, mode models.AccessMode) (*user_model.User, error) { +func parseToken(authorization string, target *models.Repository, mode perm.AccessMode) (*user_model.User, error) { if authorization == "" { return nil, fmt.Errorf("no token") } diff --git a/services/repository/transfer.go b/services/repository/transfer.go index e6b73fc9e0..d6aea70ffd 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/sync" @@ -104,7 +105,7 @@ func StartRepositoryTransfer(doer, newOwner *user_model.User, repo *models.Repos if err := repo.AddCollaborator(newOwner); err != nil { return err } - if err := repo.ChangeCollaborationAccessMode(newOwner.ID, models.AccessModeRead); err != nil { + if err := repo.ChangeCollaborationAccessMode(newOwner.ID, perm.AccessModeRead); err != nil { return err } }