Move accessmode into models/perm (#17828)

tokarchuk/v1.17
Lunny Xiao 3 years ago committed by GitHub
parent 24a8d54bfb
commit 1fee11d69a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      cmd/serv.go
  2. 7
      integrations/api_helper_for_declarative_test.go
  3. 7
      integrations/api_keys_test.go
  4. 25
      integrations/api_private_serv_test.go
  5. 5
      integrations/git_test.go
  6. 84
      models/access.go
  7. 17
      models/access_test.go
  8. 7
      models/branches.go
  9. 5
      models/error.go
  10. 3
      models/issue.go
  11. 7
      models/lfs_lock.go
  12. 15
      models/org.go
  13. 7
      models/org_team.go
  14. 7
      models/org_team_test.go
  15. 61
      models/perm/access_mode.go
  16. 19
      models/repo.go
  17. 11
      models/repo_collaboration.go
  18. 11
      models/repo_collaboration_test.go
  19. 3
      models/repo_list.go
  20. 63
      models/repo_permission.go
  21. 7
      models/repo_permission_test.go
  22. 7
      models/review.go
  23. 5
      models/ssh_key.go
  24. 11
      models/ssh_key_deploy.go
  25. 3
      models/ssh_key_principals.go
  26. 3
      modules/context/org.go
  27. 5
      modules/convert/convert.go
  28. 3
      modules/convert/notification.go
  29. 13
      modules/convert/pull.go
  30. 3
      modules/convert/pull_test.go
  31. 11
      modules/convert/repository.go
  32. 6
      modules/convert/user.go
  33. 21
      modules/notification/webhook/webhook.go
  34. 3
      modules/private/serv.go
  35. 9
      modules/repository/create_test.go
  36. 9
      routers/api/v1/org/org.go
  37. 13
      routers/api/v1/org/team.go
  38. 4
      routers/api/v1/repo/collaborators.go
  39. 3
      routers/api/v1/repo/fork.go
  40. 8
      routers/api/v1/repo/hook.go
  41. 3
      routers/api/v1/repo/key.go
  42. 3
      routers/api/v1/repo/migrate.go
  43. 3
      routers/api/v1/repo/release.go
  44. 5
      routers/api/v1/repo/repo.go
  45. 5
      routers/api/v1/repo/transfer.go
  46. 3
      routers/api/v1/user/key.go
  47. 3
      routers/api/v1/user/repo.go
  48. 13
      routers/private/serv.go
  49. 13
      routers/web/org/teams.go
  50. 13
      routers/web/repo/http.go
  51. 9
      routers/web/repo/projects.go
  52. 3
      routers/web/repo/setting.go
  53. 3
      routers/web/repo/setting_protected_branch.go
  54. 5
      routers/web/repo/settings_test.go
  55. 3
      routers/web/repo/tag.go
  56. 6
      routers/web/repo/webhook.go
  57. 7
      services/issue/assignee.go
  58. 11
      services/lfs/server.go
  59. 3
      services/repository/transfer.go

@ -17,6 +17,7 @@ import (
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -64,11 +65,11 @@ func setup(logPath string, debug bool) {
} }
var ( var (
allowedCommands = map[string]models.AccessMode{ allowedCommands = map[string]perm.AccessMode{
"git-upload-pack": models.AccessModeRead, "git-upload-pack": perm.AccessModeRead,
"git-upload-archive": models.AccessModeRead, "git-upload-archive": perm.AccessModeRead,
"git-receive-pack": models.AccessModeWrite, "git-receive-pack": perm.AccessModeWrite,
lfsAuthenticateVerb: models.AccessModeNone, lfsAuthenticateVerb: perm.AccessModeNone,
} }
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`) alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
) )
@ -214,9 +215,9 @@ func runServ(c *cli.Context) error {
if verb == lfsAuthenticateVerb { if verb == lfsAuthenticateVerb {
if lfsVerb == "upload" { if lfsVerb == "upload" {
requestedMode = models.AccessModeWrite requestedMode = perm.AccessModeWrite
} else if lfsVerb == "download" { } else if lfsVerb == "download" {
requestedMode = models.AccessModeRead requestedMode = perm.AccessModeRead
} else { } else {
return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb) return fail("Unknown LFS verb", "Unknown lfs verb %s", lfsVerb)
} }

@ -14,6 +14,7 @@ import (
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/queue" "code.gitea.io/gitea/modules/queue"
api "code.gitea.io/gitea/modules/structs" 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) { return func(t *testing.T) {
permission := "read" permission := "read"
if mode == models.AccessModeAdmin { if mode == perm.AccessModeAdmin {
permission = "admin" permission = "admin"
} else if mode > models.AccessModeRead { } else if mode > perm.AccessModeRead {
permission = "write" permission = "write"
} }
addCollaboratorOption := &api.AddCollaboratorOption{ addCollaboratorOption := &api.AddCollaboratorOption{

@ -11,6 +11,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
@ -67,7 +68,7 @@ func TestCreateReadOnlyDeployKey(t *testing.T) {
ID: newDeployKey.ID, ID: newDeployKey.ID,
Name: rawKeyBody.Title, Name: rawKeyBody.Title,
Content: rawKeyBody.Key, Content: rawKeyBody.Key,
Mode: models.AccessModeRead, Mode: perm.AccessModeRead,
}) })
} }
@ -92,7 +93,7 @@ func TestCreateReadWriteDeployKey(t *testing.T) {
ID: newDeployKey.ID, ID: newDeployKey.ID,
Name: rawKeyBody.Title, Name: rawKeyBody.Title,
Content: rawKeyBody.Key, Content: rawKeyBody.Key,
Mode: models.AccessModeWrite, Mode: perm.AccessModeWrite,
}) })
} }
@ -119,7 +120,7 @@ func TestCreateUserKey(t *testing.T) {
OwnerID: user.ID, OwnerID: user.ID,
Name: rawKeyBody.Title, Name: rawKeyBody.Title,
Content: rawKeyBody.Key, Content: rawKeyBody.Key,
Mode: models.AccessModeWrite, Mode: perm.AccessModeWrite,
}) })
// Search by fingerprint // Search by fingerprint

@ -10,6 +10,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/private" "code.gitea.io/gitea/modules/private"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -43,7 +44,7 @@ func TestAPIPrivateServ(t *testing.T) {
defer cancel() defer cancel()
// Can push to a repo we own // 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.NoError(t, err)
assert.False(t, results.IsWiki) assert.False(t, results.IsWiki)
assert.False(t, results.IsDeployKey) assert.False(t, results.IsDeployKey)
@ -56,17 +57,17 @@ func TestAPIPrivateServ(t *testing.T) {
assert.Equal(t, int64(1), results.RepoID) assert.Equal(t, int64(1), results.RepoID)
// Cannot push to a private repo we're not associated with // 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.Error(t, err)
assert.Empty(t, results) assert.Empty(t, results)
// Cannot pull from a private repo we're not associated with // 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.Error(t, err)
assert.Empty(t, results) assert.Empty(t, results)
// Can pull from a public repo we're not associated with // 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.NoError(t, err)
assert.False(t, results.IsWiki) assert.False(t, results.IsWiki)
assert.False(t, results.IsDeployKey) assert.False(t, results.IsDeployKey)
@ -79,7 +80,7 @@ func TestAPIPrivateServ(t *testing.T) {
assert.Equal(t, int64(17), results.RepoID) assert.Equal(t, int64(17), results.RepoID)
// Cannot push to a public repo we're not associated with // 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.Error(t, err)
assert.Empty(t, results) assert.Empty(t, results)
@ -88,7 +89,7 @@ func TestAPIPrivateServ(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Can pull from repo we're a deploy key for // 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.NoError(t, err)
assert.False(t, results.IsWiki) assert.False(t, results.IsWiki)
assert.True(t, results.IsDeployKey) assert.True(t, results.IsDeployKey)
@ -101,17 +102,17 @@ func TestAPIPrivateServ(t *testing.T) {
assert.Equal(t, int64(19), results.RepoID) assert.Equal(t, int64(19), results.RepoID)
// Cannot push to a private repo with reading key // 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.Error(t, err)
assert.Empty(t, results) assert.Empty(t, results)
// Cannot pull from a private repo we're not associated with // 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.Error(t, err)
assert.Empty(t, results) assert.Empty(t, results)
// Cannot pull from a public repo we're not associated with // 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.Error(t, err)
assert.Empty(t, results) assert.Empty(t, results)
@ -120,12 +121,12 @@ func TestAPIPrivateServ(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Cannot push to a private repo with reading key // 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.Error(t, err)
assert.Empty(t, results) assert.Empty(t, results)
// Can pull from repo we're a writing deploy key for // 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.NoError(t, err)
assert.False(t, results.IsWiki) assert.False(t, results.IsWiki)
assert.True(t, results.IsDeployKey) assert.True(t, results.IsDeployKey)
@ -138,7 +139,7 @@ func TestAPIPrivateServ(t *testing.T) {
assert.Equal(t, int64(20), results.RepoID) assert.Equal(t, int64(20), results.RepoID)
// Can push to repo we're a writing deploy key for // 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.NoError(t, err)
assert.False(t, results.IsWiki) assert.False(t, results.IsWiki)
assert.True(t, results.IsDeployKey) assert.True(t, results.IsDeployKey)

@ -18,6 +18,7 @@ import (
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
@ -58,7 +59,7 @@ func testGit(t *testing.T, u *url.URL) {
defer util.RemoveAll(dstPath) defer util.RemoveAll(dstPath)
t.Run("CreateRepoInDifferentUser", doAPICreateRepository(forkedUserCtx, false)) 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)) t.Run("ForkFromDifferentUser", doAPIForkRepository(httpContext, forkedUserCtx.Username))
@ -91,7 +92,7 @@ func testGit(t *testing.T, u *url.URL) {
keyname := "my-testing-key" keyname := "my-testing-key"
forkedUserCtx.Reponame = sshContext.Reponame forkedUserCtx.Reponame = sshContext.Reponame
t.Run("CreateRepoInDifferentUser", doAPICreateRepository(forkedUserCtx, false)) 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)) t.Run("ForkFromDifferentUser", doAPIForkRepository(sshContext, forkedUserCtx.Username))
//Setup key the user ssh key //Setup key the user ssh key

@ -9,60 +9,10 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" 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 // 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 // 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. // repository, the members of the owners team are in this table.
@ -70,15 +20,15 @@ type Access struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"UNIQUE(s)"` UserID int64 `xorm:"UNIQUE(s)"`
RepoID int64 `xorm:"UNIQUE(s)"` RepoID int64 `xorm:"UNIQUE(s)"`
Mode AccessMode Mode perm.AccessMode
} }
func init() { func init() {
db.RegisterModel(new(Access)) db.RegisterModel(new(Access))
} }
func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (AccessMode, error) { func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (perm.AccessMode, error) {
mode := AccessModeNone mode := perm.AccessModeNone
var userID int64 var userID int64
restricted := false restricted := false
@ -88,7 +38,7 @@ func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (AccessMo
} }
if !restricted && !repo.IsPrivate { if !restricted && !repo.IsPrivate {
mode = AccessModeRead mode = perm.AccessModeRead
} }
if userID == 0 { if userID == 0 {
@ -96,7 +46,7 @@ func accessLevel(e db.Engine, user *user_model.User, repo *Repository) (AccessMo
} }
if userID == repo.OwnerID { if userID == repo.OwnerID {
return AccessModeOwner, nil return perm.AccessModeOwner, nil
} }
a := &Access{UserID: userID, RepoID: repo.ID} 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 return a.Mode, nil
} }
func maxAccessMode(modes ...AccessMode) AccessMode { func maxAccessMode(modes ...perm.AccessMode) perm.AccessMode {
max := AccessModeNone max := perm.AccessModeNone
for _, mode := range modes { for _, mode := range modes {
if mode > max { if mode > max {
max = mode max = mode
@ -118,11 +68,11 @@ func maxAccessMode(modes ...AccessMode) AccessMode {
type userAccess struct { type userAccess struct {
User *user_model.User User *user_model.User
Mode AccessMode Mode perm.AccessMode
} }
// updateUserAccess updates an access map so that user has at least mode // 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 { if ua, ok := accessMap[user.ID]; ok {
ua.Mode = maxAccessMode(ua.Mode, mode) ua.Mode = maxAccessMode(ua.Mode, mode)
} else { } 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? // 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) { func (repo *Repository) refreshAccesses(e db.Engine, accessMap map[int64]*userAccess) (err error) {
minMode := AccessModeRead minMode := perm.AccessModeRead
if !repo.IsPrivate { if !repo.IsPrivate {
minMode = AccessModeWrite minMode = perm.AccessModeWrite
} }
newAccesses := make([]Access, 0, len(accessMap)) 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 // Owner team gets owner access, and skip for teams that do not
// have relations with repository. // have relations with repository.
if t.IsOwnerTeam() { if t.IsOwnerTeam() {
t.Authorize = AccessModeOwner t.Authorize = perm.AccessModeOwner
} else if !t.hasRepository(e, repo.ID) { } else if !t.hasRepository(e, repo.ID) {
continue continue
} }
@ -227,12 +177,12 @@ func (repo *Repository) recalculateTeamAccesses(e db.Engine, ignTeamID int64) (e
// recalculateUserAccess recalculates new access for a single user // recalculateUserAccess recalculates new access for a single user
// Usable if we know access only affected one user // Usable if we know access only affected one user
func (repo *Repository) recalculateUserAccess(e db.Engine, uid int64) (err error) { func (repo *Repository) recalculateUserAccess(e db.Engine, uid int64) (err error) {
minMode := AccessModeRead minMode := perm.AccessModeRead
if !repo.IsPrivate { if !repo.IsPrivate {
minMode = AccessModeWrite minMode = perm.AccessModeWrite
} }
accessMode := AccessModeNone accessMode := perm.AccessModeNone
collaborator, err := repo.getCollaboration(e, uid) collaborator, err := repo.getCollaboration(e, uid)
if err != nil { if err != nil {
return err return err
@ -255,7 +205,7 @@ func (repo *Repository) recalculateUserAccess(e db.Engine, uid int64) (err error
for _, t := range teams { for _, t := range teams {
if t.IsOwnerTeam() { if t.IsOwnerTeam() {
t.Authorize = AccessModeOwner t.Authorize = perm.AccessModeOwner
} }
accessMode = maxAccessMode(accessMode, t.Authorize) accessMode = maxAccessMode(accessMode, t.Authorize)

@ -8,6 +8,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
@ -35,34 +36,34 @@ func TestAccessLevel(t *testing.T) {
level, err := AccessLevel(user2, repo1) level, err := AccessLevel(user2, repo1)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, AccessModeOwner, level) assert.Equal(t, perm.AccessModeOwner, level)
level, err = AccessLevel(user2, repo3) level, err = AccessLevel(user2, repo3)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, AccessModeOwner, level) assert.Equal(t, perm.AccessModeOwner, level)
level, err = AccessLevel(user5, repo1) level, err = AccessLevel(user5, repo1)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, AccessModeRead, level) assert.Equal(t, perm.AccessModeRead, level)
level, err = AccessLevel(user5, repo3) level, err = AccessLevel(user5, repo3)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, AccessModeNone, level) assert.Equal(t, perm.AccessModeNone, level)
// restricted user has no access to a public repo // restricted user has no access to a public repo
level, err = AccessLevel(user29, repo1) level, err = AccessLevel(user29, repo1)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, AccessModeNone, level) assert.Equal(t, perm.AccessModeNone, level)
// ... unless he's a collaborator // ... unless he's a collaborator
level, err = AccessLevel(user29, repo4) level, err = AccessLevel(user29, repo4)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, AccessModeWrite, level) assert.Equal(t, perm.AccessModeWrite, level)
// ... or a team member // ... or a team member
level, err = AccessLevel(user29, repo24) level, err = AccessLevel(user29, repo24)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, AccessModeRead, level) assert.Equal(t, perm.AccessModeRead, level)
} }
func TestHasAccess(t *testing.T) { func TestHasAccess(t *testing.T) {
@ -105,7 +106,7 @@ func TestRepository_RecalculateAccesses(t *testing.T) {
has, err := db.GetEngine(db.DefaultContext).Get(access) has, err := db.GetEngine(db.DefaultContext).Get(access)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, has) assert.True(t, has)
assert.Equal(t, AccessModeOwner, access.Mode) assert.Equal(t, perm.AccessModeOwner, access.Mode)
} }
func TestRepository_RecalculateAccesses2(t *testing.T) { func TestRepository_RecalculateAccesses2(t *testing.T) {

@ -11,6 +11,7 @@ import (
"time" "time"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
@ -76,7 +77,7 @@ func (protectBranch *ProtectedBranch) CanUserPush(userID int64) bool {
} else if repo, err := GetRepositoryByID(protectBranch.RepoID); err != nil { } else if repo, err := GetRepositoryByID(protectBranch.RepoID); err != nil {
log.Error("GetRepositoryByID: %v", err) log.Error("GetRepositoryByID: %v", err)
return false 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) log.Error("HasAccessUnit: %v", err)
return false return false
} else { } else {
@ -136,7 +137,7 @@ func (protectBranch *ProtectedBranch) isUserOfficialReviewer(e db.Engine, user *
if !protectBranch.EnableApprovalsWhitelist { if !protectBranch.EnableApprovalsWhitelist {
// Anyone with write access is considered official reviewer // Anyone with write access is considered official reviewer
writeAccess, err := hasAccessUnit(e, user, repo, unit.TypeCode, AccessModeWrite) writeAccess, err := hasAccessUnit(e, user, repo, unit.TypeCode, perm.AccessModeWrite)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -474,7 +475,7 @@ func updateTeamWhitelist(repo *Repository, currentWhitelist, newWhitelist []int6
return currentWhitelist, nil return currentWhitelist, nil
} }
teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, AccessModeRead) teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, perm.AccessModeRead)
if err != nil { if err != nil {
return nil, fmt.Errorf("GetTeamsWithAccessToRepo [org_id: %d, repo_id: %d]: %v", repo.OwnerID, repo.ID, err) return nil, fmt.Errorf("GetTeamsWithAccessToRepo [org_id: %d, repo_id: %d]: %v", repo.OwnerID, repo.ID, err)
} }

@ -8,6 +8,7 @@ package models
import ( import (
"fmt" "fmt"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
) )
@ -498,7 +499,7 @@ func (err ErrLFSLockNotExist) Error() string {
type ErrLFSUnauthorizedAction struct { type ErrLFSUnauthorizedAction struct {
RepoID int64 RepoID int64
UserName string UserName string
Mode AccessMode Mode perm.AccessMode
} }
// IsErrLFSUnauthorizedAction checks if an error is a ErrLFSUnauthorizedAction. // IsErrLFSUnauthorizedAction checks if an error is a ErrLFSUnauthorizedAction.
@ -508,7 +509,7 @@ func IsErrLFSUnauthorizedAction(err error) bool {
} }
func (err ErrLFSUnauthorizedAction) Error() string { 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 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) return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)

@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
@ -2086,7 +2087,7 @@ func (issue *Issue) ResolveMentionsByVisibility(ctx context.Context, doer *user_
unittype = unit.TypePullRequests unittype = unit.TypePullRequests
} }
for _, team := range teams { for _, team := range teams {
if team.Authorize >= AccessModeOwner { if team.Authorize >= perm.AccessModeOwner {
checked = append(checked, team.ID) checked = append(checked, team.ID)
resolved[issue.Repo.Owner.LowerName+"/"+team.LowerName] = true resolved[issue.Repo.Owner.LowerName+"/"+team.LowerName] = true
continue continue

@ -11,6 +11,7 @@ import (
"time" "time"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -53,7 +54,7 @@ func cleanPath(p string) string {
// CreateLFSLock creates a new lock. // CreateLFSLock creates a new lock.
func CreateLFSLock(lock *LFSLock) (*LFSLock, error) { func CreateLFSLock(lock *LFSLock) (*LFSLock, error) {
err := CheckLFSAccessForRepo(lock.OwnerID, lock.Repo, AccessModeWrite) err := CheckLFSAccessForRepo(lock.OwnerID, lock.Repo, perm.AccessModeWrite)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -124,7 +125,7 @@ func DeleteLFSLockByID(id int64, u *user_model.User, force bool) (*LFSLock, erro
return nil, err return nil, err
} }
err = CheckLFSAccessForRepo(u.ID, lock.Repo, AccessModeWrite) err = CheckLFSAccessForRepo(u.ID, lock.Repo, perm.AccessModeWrite)
if err != nil { if err != nil {
return nil, err 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 // 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 { if ownerID == 0 {
return ErrLFSUnauthorizedAction{repo.ID, "undefined", mode} return ErrLFSUnauthorizedAction{repo.ID, "undefined", mode}
} }

@ -11,6 +11,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -263,7 +264,7 @@ func CreateOrganization(org *Organization, owner *user_model.User) (err error) {
OrgID: org.ID, OrgID: org.ID,
LowerName: strings.ToLower(ownerTeamName), LowerName: strings.ToLower(ownerTeamName),
Name: ownerTeamName, Name: ownerTeamName,
Authorize: AccessModeOwner, Authorize: perm.AccessModeOwner,
NumMembers: 1, NumMembers: 1,
IncludesAllRepositories: true, IncludesAllRepositories: true,
CanCreateOrgRepo: true, CanCreateOrgRepo: true,
@ -420,8 +421,8 @@ func CanCreateOrgRepo(orgID, uid int64) (bool, error) {
} }
// GetOrgUserMaxAuthorizeLevel returns highest authorize level of user in an organization // GetOrgUserMaxAuthorizeLevel returns highest authorize level of user in an organization
func (org *Organization) GetOrgUserMaxAuthorizeLevel(uid int64) (AccessMode, error) { func (org *Organization) GetOrgUserMaxAuthorizeLevel(uid int64) (perm.AccessMode, error) {
var authorize AccessMode var authorize perm.AccessMode
_, err := db.GetEngine(db.DefaultContext). _, err := db.GetEngine(db.DefaultContext).
Select("max(team.authorize)"). Select("max(team.authorize)").
Table("team"). Table("team").
@ -442,7 +443,7 @@ func getUsersWhoCanCreateOrgRepo(e db.Engine, orgID int64) ([]*user_model.User,
return users, e. return users, e.
Join("INNER", "`team_user`", "`team_user`.uid=`user`.id"). Join("INNER", "`team_user`", "`team_user`.uid=`user`.id").
Join("INNER", "`team`", "`team`.id=`team_user`.team_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) 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_user`", "`team_user`.org_id=`user`.id").
Join("INNER", "`team`", "`team`.id=`team_user`.team_id"). Join("INNER", "`team`", "`team`.id=`team_user`.team_id").
Where("`team_user`.uid=?", userID). Where("`team_user`.uid=?", userID).
And("`team`.authorize=?", AccessModeOwner). And("`team`.authorize=?", perm.AccessModeOwner).
Asc("`user`.name"). Asc("`user`.name").
Find(&orgs) 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_user`", "`team_user`.org_id = `user`.id").
Join("INNER", "`team`", "`team`.id = `team_user`.team_id"). Join("INNER", "`team`", "`team`.id = `team_user`.team_id").
Where(builder.Eq{"`team_user`.uid": userID}). 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"). Asc("`user`.name").
Find(&orgs) 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. // 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) return GetTeamsWithAccessToRepo(org.ID, repoID, mode)
} }

@ -13,6 +13,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -30,7 +31,7 @@ type Team struct {
LowerName string LowerName string
Name string Name string
Description string Description string
Authorize AccessMode Authorize perm.AccessMode
Repos []*Repository `xorm:"-"` Repos []*Repository `xorm:"-"`
Members []*user_model.User `xorm:"-"` Members []*user_model.User `xorm:"-"`
NumRepos int NumRepos int
@ -143,7 +144,7 @@ func (t *Team) GetUnitNames() (res []string) {
// HasWriteAccess returns true if team has at least write level access mode. // HasWriteAccess returns true if team has at least write level access mode.
func (t *Team) HasWriteAccess() bool { func (t *Team) HasWriteAccess() bool {
return t.Authorize >= AccessModeWrite return t.Authorize >= perm.AccessModeWrite
} }
// IsOwnerTeam returns true if team is owner team. // 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. // 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) teams := make([]*Team, 0, 5)
return teams, db.GetEngine(db.DefaultContext).Where("team.authorize >= ?", mode). return teams, db.GetEngine(db.DefaultContext).Where("team.authorize >= ?", mode).
Join("INNER", "team_repo", "team_repo.team_id = team.id"). Join("INNER", "team_repo", "team_repo.team_id = team.id").

@ -9,6 +9,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
@ -209,14 +210,14 @@ func TestUpdateTeam(t *testing.T) {
team.LowerName = "newname" team.LowerName = "newname"
team.Name = "newName" team.Name = "newName"
team.Description = strings.Repeat("A long description!", 100) team.Description = strings.Repeat("A long description!", 100)
team.Authorize = AccessModeAdmin team.Authorize = perm.AccessModeAdmin
assert.NoError(t, UpdateTeam(team, true, false)) assert.NoError(t, UpdateTeam(team, true, false))
team = unittest.AssertExistsAndLoadBean(t, &Team{Name: "newName"}).(*Team) team = unittest.AssertExistsAndLoadBean(t, &Team{Name: "newName"}).(*Team)
assert.True(t, strings.HasPrefix(team.Description, "A long description!")) assert.True(t, strings.HasPrefix(team.Description, "A long description!"))
access := unittest.AssertExistsAndLoadBean(t, &Access{UserID: 4, RepoID: 3}).(*Access) access := unittest.AssertExistsAndLoadBean(t, &Access{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}) unittest.CheckConsistencyFor(t, &Team{ID: team.ID})
} }
@ -249,7 +250,7 @@ func TestDeleteTeam(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository) repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
accessMode, err := AccessLevel(user, repo) accessMode, err := AccessLevel(user, repo)
assert.NoError(t, err) assert.NoError(t, err)
assert.True(t, accessMode < AccessModeWrite) assert.True(t, accessMode < perm.AccessModeWrite)
} }
func TestIsTeamMember(t *testing.T) { func TestIsTeamMember(t *testing.T) {

@ -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
}
}

@ -25,6 +25,7 @@ import (
admin_model "code.gitea.io/gitea/models/admin" admin_model "code.gitea.io/gitea/models/admin"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" 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) accesses := make([]*Access, 0, 10)
if err = e. if err = e.
Where("repo_id = ? AND mode >= ?", repo.ID, AccessModeWrite). Where("repo_id = ? AND mode >= ?", repo.ID, perm.AccessModeWrite).
Find(&accesses); err != nil { Find(&accesses); err != nil {
return nil, err 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 // Anyone who can read the repository is a requestable reviewer
if err := e. 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", 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). doerID, posterID).
Find(&users); err != nil { Find(&users); err != nil {
return nil, err return nil, err
@ -605,7 +606,7 @@ func (repo *Repository) getReviewers(e db.Engine, doerID, posterID int64) ([]*us
"UNION "+ "UNION "+
"SELECT uid AS user_id FROM `org_user` WHERE org_id = ? "+ "SELECT uid AS user_id FROM `org_user` WHERE org_id = ? "+
") AND id NOT IN (?, ?) ORDER BY name", ") AND id NOT IN (?, ?) ORDER BY name",
repo.ID, AccessModeRead, repo.ID, perm.AccessModeRead,
repo.ID, RepoWatchModeNormal, RepoWatchModeAuto, repo.ID, RepoWatchModeNormal, RepoWatchModeAuto,
repo.OwnerID, repo.OwnerID,
doerID, posterID). doerID, posterID).
@ -634,7 +635,7 @@ func (repo *Repository) GetReviewerTeams() ([]*Team, error) {
return nil, nil return nil, nil
} }
teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, AccessModeRead) teams, err := GetTeamsWithAccessToRepo(repo.OwnerID, repo.ID, perm.AccessModeRead)
if err != nil { if err != nil {
return nil, err 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. // GetReaders returns all users that have explicit read access or higher to the repository.
func (repo *Repository) GetReaders() (_ []*user_model.User, err error) { 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. // GetWriters returns all users that have write access to the repository.
func (repo *Repository) GetWriters() (_ []*user_model.User, err error) { 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. // 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 { if repo.OwnerID == userID {
return true, nil 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. // 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 { if err = repo.getOwner(e); err != nil {
return nil, err 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 { if err = repo.addCollaborator(db.GetEngine(ctx), doer); err != nil {
return fmt.Errorf("AddCollaborator: %v", err) 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) return fmt.Errorf("ChangeCollaborationAccessMode: %v", err)
} }
} }

@ -9,6 +9,7 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -22,7 +23,7 @@ type Collaboration struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
UserID 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"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` 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 { } else if has {
return nil return nil
} }
collaboration.Mode = AccessModeWrite collaboration.Mode = perm.AccessModeWrite
if _, err = e.InsertOne(collaboration); err != nil { if _, err = e.InsertOne(collaboration); err != nil {
return err return err
@ -141,9 +142,9 @@ func (repo *Repository) IsCollaborator(userID int64) (bool, error) {
return repo.isCollaborator(db.GetEngine(db.DefaultContext), userID) 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 // Discard invalid input
if mode <= AccessModeNone || mode > AccessModeOwner { if mode <= perm.AccessModeNone || mode > perm.AccessModeOwner {
return nil return nil
} }
@ -176,7 +177,7 @@ func (repo *Repository) changeCollaborationAccessMode(e db.Engine, uid int64, mo
} }
// ChangeCollaborationAccessMode sets new access mode for the collaboration. // 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() ctx, committer, err := db.TxContext()
if err != nil { if err != nil {
return err return err

@ -8,6 +8,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
@ -68,17 +69,17 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &Repository{ID: 4}).(*Repository) 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) 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) 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}) unittest.CheckConsistencyFor(t, &Repository{ID: repo.ID})
} }

@ -9,6 +9,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -431,7 +432,7 @@ func accessibleRepositoryCondition(user *user_model.User) builder.Cond {
From("`access`"). From("`access`").
Where(builder.And( Where(builder.And(
builder.Eq{"user_id": user.ID}, builder.Eq{"user_id": user.ID},
builder.Gt{"mode": int(AccessModeNone)}))), builder.Gt{"mode": int(perm.AccessModeNone)}))),
// 3. Repositories that we directly own // 3. Repositories that we directly own
builder.Eq{"`repository`.owner_id": user.ID}, builder.Eq{"`repository`.owner_id": user.ID},
// 4. Be able to see all repositories that we are in a team // 4. Be able to see all repositories that we are in a team

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/models/db" "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/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -15,49 +16,49 @@ import (
// Permission contains all the permissions related variables to a repository for a user // Permission contains all the permissions related variables to a repository for a user
type Permission struct { type Permission struct {
AccessMode AccessMode AccessMode perm_model.AccessMode
Units []*RepoUnit 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. // IsOwner returns true if current user is the owner of repository.
func (p *Permission) IsOwner() bool { 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. // IsAdmin returns true if current user has admin or higher access of repository.
func (p *Permission) IsAdmin() bool { 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 // HasAccess returns true if the current user has at least read access to any unit of this repository
func (p *Permission) HasAccess() bool { func (p *Permission) HasAccess() bool {
if p.UnitsMode == nil { if p.UnitsMode == nil {
return p.AccessMode >= AccessModeRead return p.AccessMode >= perm_model.AccessModeRead
} }
return len(p.UnitsMode) > 0 return len(p.UnitsMode) > 0
} }
// UnitAccessMode returns current user accessmode to the specify unit of the repository // 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 { if p.UnitsMode == nil {
for _, u := range p.Units { for _, u := range p.Units {
if u.Type == unitType { if u.Type == unitType {
return p.AccessMode return p.AccessMode
} }
} }
return AccessModeNone return perm_model.AccessModeNone
} }
return p.UnitsMode[unitType] return p.UnitsMode[unitType]
} }
// CanAccess returns true if user has mode access to the unit of the repository // 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 return p.UnitAccessMode(unitType) >= mode
} }
// CanAccessAny returns true if user has mode access to any of the units of the repository // 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 { for _, u := range unitTypes {
if p.CanAccess(mode, u) { if p.CanAccess(mode, u) {
return true 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 // CanRead returns true if user could read to this unit
func (p *Permission) CanRead(unitType unit.Type) bool { 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 // CanReadAny returns true if user has read access to any of the units of the repository
func (p *Permission) CanReadAny(unitTypes ...unit.Type) bool { 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 // 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 // CanWrite returns true if user could write to this unit
func (p *Permission) CanWrite(unitType unit.Type) bool { 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 // 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) { func (p *Permission) ColorFormat(s fmt.State) {
noColor := log.ColorBytes(log.Reset) 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{}{ args := []interface{}{
p.AccessMode, p.AccessMode,
log.NewColoredValueBytes(len(p.Units), &noColor), 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. // anonymous user visit private repo.
// TODO: anonymous user visit public unit of private repo??? // TODO: anonymous user visit public unit of private repo???
if user == nil && repo.IsPrivate { if user == nil && repo.IsPrivate {
perm.AccessMode = AccessModeNone perm.AccessMode = perm_model.AccessModeNone
return 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 // 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 // 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 { if !hasOrgOrUserVisible(e, repo.Owner, user) && !isCollaborator {
perm.AccessMode = AccessModeNone perm.AccessMode = perm_model.AccessModeNone
return return
} }
@ -194,13 +195,13 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
// anonymous visit public repo // anonymous visit public repo
if user == nil { if user == nil {
perm.AccessMode = AccessModeRead perm.AccessMode = perm_model.AccessModeRead
return return
} }
// Admin or the owner has super access to the repository // Admin or the owner has super access to the repository
if user.IsAdmin || user.ID == repo.OwnerID { if user.IsAdmin || user.ID == repo.OwnerID {
perm.AccessMode = AccessModeOwner perm.AccessMode = perm_model.AccessModeOwner
return return
} }
@ -217,7 +218,7 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
return return
} }
perm.UnitsMode = make(map[unit.Type]AccessMode) perm.UnitsMode = make(map[unit.Type]perm_model.AccessMode)
// Collaborators on organization // Collaborators on organization
if isCollaborator { if isCollaborator {
@ -234,8 +235,8 @@ func getUserRepoPermission(e db.Engine, repo *Repository, user *user_model.User)
// if user in an owner team // if user in an owner team
for _, team := range teams { for _, team := range teams {
if team.Authorize >= AccessModeOwner { if team.Authorize >= perm_model.AccessModeOwner {
perm.AccessMode = AccessModeOwner perm.AccessMode = perm_model.AccessModeOwner
perm.UnitsMode = nil perm.UnitsMode = nil
return 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. // 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 !found && !repo.IsPrivate && !user.IsRestricted {
if _, ok := perm.UnitsMode[u.Type]; !ok { 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 false, err
} }
return accessMode >= AccessModeAdmin, nil return accessMode >= perm_model.AccessModeAdmin, nil
} }
// IsUserRepoAdmin return true if user has admin right of a repo // 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 { if err != nil {
return false, err return false, err
} }
if mode >= AccessModeAdmin { if mode >= perm_model.AccessModeAdmin {
return true, nil return true, nil
} }
@ -321,7 +322,7 @@ func isUserRepoAdmin(e db.Engine, repo *Repository, user *user_model.User) (bool
} }
for _, team := range teams { for _, team := range teams {
if team.Authorize >= AccessModeAdmin { if team.Authorize >= perm_model.AccessModeAdmin {
return true, nil 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 // AccessLevel returns the Access a user has to a repository. Will return NoneAccess if the
// user does not have access. // user does not have access.
func AccessLevel(user *user_model.User, repo *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) 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 // AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the
// user does not have access. // user does not have access.
func AccessLevelUnit(user *user_model.User, repo *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) 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) perm, err := getUserRepoPermission(e, repo, user)
if err != nil { if err != nil {
return AccessModeNone, err return perm_model.AccessModeNone, err
} }
return perm.UnitAccessMode(unitType), nil 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) mode, err := accessLevelUnit(e, user, repo, unitType)
return testMode <= mode, err return testMode <= mode, err
} }
// HasAccessUnit returns true if user has testMode to the unit of the repository // 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) 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 { if err != nil {
return false, err 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) { func hasAccess(e db.Engine, userID int64, repo *Repository) (bool, error) {

@ -8,6 +8,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models/db" "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/unit"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
@ -93,7 +94,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type)) 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) perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err) assert.NoError(t, err)
for _, unit := range repo.Units { for _, unit := range repo.Units {
@ -145,7 +146,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type)) 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) perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err) assert.NoError(t, err)
for _, unit := range repo.Units { for _, unit := range repo.Units {
@ -207,7 +208,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
assert.True(t, perm.CanWrite(unit.Type)) 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) perm, err = GetUserRepoPermission(repo, user)
assert.NoError(t, err) assert.NoError(t, err)
for _, unit := range repo.Units { for _, unit := range repo.Units {

@ -9,6 +9,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
@ -277,7 +278,7 @@ func isOfficialReviewerTeam(e db.Engine, issue *Issue, team *Team) (bool, error)
} }
if !pr.ProtectedBranch.EnableApprovalsWhitelist { if !pr.ProtectedBranch.EnableApprovalsWhitelist {
return team.Authorize >= AccessModeWrite, nil return team.Authorize >= perm.AccessModeWrite, nil
} }
return base.Int64sContains(pr.ProtectedBranch.ApprovalsWhitelistTeamIDs, team.ID), 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 return false, err
} }
perm, err := GetUserRepoPermission(issue.Repo, doer) p, err := GetUserRepoPermission(issue.Repo, doer)
if err != nil { if err != nil {
return false, err return false, err
} }
permResult = perm.CanAccess(AccessModeWrite, unit.TypePullRequests) permResult = p.CanAccess(perm.AccessModeWrite, unit.TypePullRequests)
if !permResult { if !permResult {
if permResult, err = IsOfficialReviewer(issue, doer); err != nil { if permResult, err = IsOfficialReviewer(issue, doer); err != nil {
return false, err return false, err

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/login" "code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
@ -40,7 +41,7 @@ type PublicKey struct {
Name string `xorm:"NOT NULL"` Name string `xorm:"NOT NULL"`
Fingerprint string `xorm:"INDEX NOT NULL"` Fingerprint string `xorm:"INDEX NOT NULL"`
Content string `xorm:"TEXT NOT NULL"` Content string `xorm:"TEXT NOT NULL"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 2"` Mode perm.AccessMode `xorm:"NOT NULL DEFAULT 2"`
Type KeyType `xorm:"NOT NULL DEFAULT 1"` Type KeyType `xorm:"NOT NULL DEFAULT 1"`
LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"` LoginSourceID int64 `xorm:"NOT NULL DEFAULT 0"`
@ -123,7 +124,7 @@ func AddPublicKey(ownerID int64, name, content string, loginSourceID int64) (*Pu
Name: name, Name: name,
Fingerprint: fingerprint, Fingerprint: fingerprint,
Content: content, Content: content,
Mode: AccessModeWrite, Mode: perm.AccessModeWrite,
Type: KeyTypeUser, Type: KeyTypeUser,
LoginSourceID: loginSourceID, LoginSourceID: loginSourceID,
} }

@ -9,6 +9,7 @@ import (
"time" "time"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/timeutil"
@ -33,7 +34,7 @@ type DeployKey struct {
Fingerprint string Fingerprint string
Content string `xorm:"-"` Content string `xorm:"-"`
Mode AccessMode `xorm:"NOT NULL DEFAULT 1"` Mode perm.AccessMode `xorm:"NOT NULL DEFAULT 1"`
CreatedUnix timeutil.TimeStamp `xorm:"created"` CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix timeutil.TimeStamp `xorm:"updated"` 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 // IsReadOnly checks if the key can only be used for read operations
func (key *DeployKey) IsReadOnly() bool { func (key *DeployKey) IsReadOnly() bool {
return key.Mode == AccessModeRead return key.Mode == perm.AccessModeRead
} }
func init() { func init() {
@ -90,7 +91,7 @@ func checkDeployKey(e db.Engine, keyID, repoID int64, name string) error {
} }
// addDeployKey adds new key-repo relation. // 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 { if err := checkDeployKey(e, keyID, repoID, name); err != nil {
return nil, err return nil, err
} }
@ -121,9 +122,9 @@ func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey
return nil, err return nil, err
} }
accessMode := AccessModeRead accessMode := perm.AccessModeRead
if !readOnly { if !readOnly {
accessMode = AccessModeWrite accessMode = perm.AccessModeWrite
} }
ctx, committer, err := db.TxContext() ctx, committer, err := db.TxContext()

@ -10,6 +10,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
) )
@ -46,7 +47,7 @@ func AddPrincipalKey(ownerID int64, content string, loginSourceID int64) (*Publi
OwnerID: ownerID, OwnerID: ownerID,
Name: content, Name: content,
Content: content, Content: content,
Mode: AccessModeWrite, Mode: perm.AccessModeWrite,
Type: KeyTypePrincipal, Type: KeyTypePrincipal,
LoginSourceID: loginSourceID, LoginSourceID: loginSourceID,
} }

@ -9,6 +9,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
) )
@ -167,7 +168,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
return 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 ctx.Data["IsTeamAdmin"] = ctx.Org.IsTeamAdmin
if requireTeamAdmin && !ctx.Org.IsTeamAdmin { if requireTeamAdmin && !ctx.Org.IsTeamAdmin {
ctx.NotFound("OrgAssignment", err) ctx.NotFound("OrgAssignment", err)

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login" "code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook" "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 hasPerm bool
var err error var err error
if user != nil { 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 { if err != nil {
return nil, err return nil, err
} }
@ -272,7 +273,7 @@ func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey {
URL: fmt.Sprintf("%s%d", apiLink, key.ID), URL: fmt.Sprintf("%s%d", apiLink, key.ID),
Title: key.Name, Title: key.Name,
Created: key.CreatedUnix.AsTime(), 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.
} }
} }

@ -8,6 +8,7 @@ import (
"net/url" "net/url"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
api "code.gitea.io/gitea/modules/structs" 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 //since user only get notifications when he has access to use minimal access mode
if n.Repository != nil { if n.Repository != nil {
result.Repository = ToRepo(n.Repository, models.AccessModeRead) result.Repository = ToRepo(n.Repository, perm.AccessModeRead)
} }
//handle Subject //handle Subject

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -41,10 +42,10 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *user_model.User) *api.PullRe
return nil return nil
} }
perm, err := models.GetUserRepoPermission(pr.BaseRepo, doer) p, err := models.GetUserRepoPermission(pr.BaseRepo, doer)
if err != nil { if err != nil {
log.Error("GetUserRepoPermission[%d]: %v", pr.BaseRepoID, err) log.Error("GetUserRepoPermission[%d]: %v", pr.BaseRepoID, err)
perm.AccessMode = models.AccessModeNone p.AccessMode = perm.AccessModeNone
} }
apiPullRequest := &api.PullRequest{ apiPullRequest := &api.PullRequest{
@ -74,7 +75,7 @@ func ToAPIPullRequest(pr *models.PullRequest, doer *user_model.User) *api.PullRe
Name: pr.BaseBranch, Name: pr.BaseBranch,
Ref: pr.BaseBranch, Ref: pr.BaseBranch,
RepoID: pr.BaseRepoID, RepoID: pr.BaseRepoID,
Repository: ToRepo(pr.BaseRepo, perm.AccessMode), Repository: ToRepo(pr.BaseRepo, p.AccessMode),
}, },
Head: &api.PRBranchInfo{ Head: &api.PRBranchInfo{
Name: pr.HeadBranch, 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 { 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 { if err != nil {
log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err)
perm.AccessMode = models.AccessModeNone p.AccessMode = perm.AccessModeNone
} }
apiPullRequest.Head.RepoID = pr.HeadRepo.ID 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()) headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
if err != nil { if err != nil {

@ -8,6 +8,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
@ -28,7 +29,7 @@ func TestPullRequest_APIFormat(t *testing.T) {
Ref: "refs/pull/2/head", Ref: "refs/pull/2/head",
Sha: "4a357436d925b5c974181ff12a994538ddc5a269", Sha: "4a357436d925b5c974181ff12a994538ddc5a269",
RepoID: 1, RepoID: 1,
Repository: ToRepo(headRepo, models.AccessModeRead), Repository: ToRepo(headRepo, perm.AccessModeRead),
}, apiPullRequest.Head) }, apiPullRequest.Head)
//withOut HeadRepo //withOut HeadRepo

@ -6,23 +6,24 @@ package convert
import ( import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
unit_model "code.gitea.io/gitea/models/unit" unit_model "code.gitea.io/gitea/models/unit"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
) )
// ToRepo converts a Repository to api.Repository // 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) 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 var parent *api.Repository
cloneLink := repo.CloneLink() cloneLink := repo.CloneLink()
permission := &api.Permission{ permission := &api.Permission{
Admin: mode >= models.AccessModeAdmin, Admin: mode >= perm.AccessModeAdmin,
Push: mode >= models.AccessModeWrite, Push: mode >= perm.AccessModeWrite,
Pull: mode >= models.AccessModeRead, Pull: mode >= perm.AccessModeRead,
} }
if !isParent { if !isParent {
err := repo.GetBaseRepo() err := repo.GetBaseRepo()

@ -5,7 +5,7 @@
package convert package convert
import ( import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
) )
@ -36,11 +36,11 @@ func ToUsers(doer *user_model.User, users []*user_model.User) []*api.User {
// ToUserWithAccessMode convert user_model.User to api.User // ToUserWithAccessMode convert user_model.User to api.User
// AccessMode is not none show add some more information // 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 { if user == nil {
return 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 // toUser convert user_model.User to api.User

@ -6,6 +6,7 @@ package webhook
import ( import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/models/webhook"
@ -91,7 +92,7 @@ func (m *webhookNotifier) NotifyForkRepository(doer *user_model.User, oldRepo, r
if u.IsOrganization() { if u.IsOrganization() {
if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{ if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoCreated, Action: api.HookRepoCreated,
Repository: convert.ToRepo(repo, models.AccessModeOwner), Repository: convert.ToRepo(repo, perm.AccessModeOwner),
Organization: convert.ToUser(u, nil), Organization: convert.ToUser(u, nil),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}); err != 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. // Add to hook queue for created repo after session commit.
if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{ if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoCreated, Action: api.HookRepoCreated,
Repository: convert.ToRepo(repo, models.AccessModeOwner), Repository: convert.ToRepo(repo, perm.AccessModeOwner),
Organization: convert.ToUser(u, nil), Organization: convert.ToUser(u, nil),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}); err != 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{ if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoDeleted, Action: api.HookRepoDeleted,
Repository: convert.ToRepo(repo, models.AccessModeOwner), Repository: convert.ToRepo(repo, perm.AccessModeOwner),
Organization: convert.ToUser(u, nil), Organization: convert.ToUser(u, nil),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}); err != 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. // Add to hook queue for created repo after session commit.
if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{ if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventRepository, &api.RepositoryPayload{
Action: api.HookRepoCreated, Action: api.HookRepoCreated,
Repository: convert.ToRepo(repo, models.AccessModeOwner), Repository: convert.ToRepo(repo, perm.AccessModeOwner),
Organization: convert.ToUser(u, nil), Organization: convert.ToUser(u, nil),
Sender: convert.ToUser(doer, nil), Sender: convert.ToUser(doer, nil),
}); err != nil { }); err != nil {
@ -504,7 +505,7 @@ func (m *webhookNotifier) NotifyIssueChangeLabels(doer *user_model.User, issue *
Action: api.HookIssueLabelUpdated, Action: api.HookIssueLabelUpdated,
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(issue.PullRequest, nil), 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), Sender: convert.ToUser(doer, nil),
}) })
} else { } else {
@ -578,7 +579,7 @@ func (m *webhookNotifier) NotifyPushCommits(pusher *user_model.User, repo *model
CompareURL: setting.AppURL + commits.CompareURL, CompareURL: setting.AppURL + commits.CompareURL,
Commits: apiCommits, Commits: apiCommits,
HeadCommit: apiHeadCommit, HeadCommit: apiHeadCommit,
Repo: convert.ToRepo(repo, models.AccessModeOwner), Repo: convert.ToRepo(repo, perm.AccessModeOwner),
Pusher: apiPusher, Pusher: apiPusher,
Sender: apiPusher, Sender: apiPusher,
}); err != nil { }); 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) { func (m *webhookNotifier) NotifyCreateRef(pusher *user_model.User, repo *models.Repository, refType, refFullName string) {
apiPusher := convert.ToUser(pusher, nil) apiPusher := convert.ToUser(pusher, nil)
apiRepo := convert.ToRepo(repo, models.AccessModeNone) apiRepo := convert.ToRepo(repo, perm.AccessModeNone)
refName := git.RefEndName(refFullName) refName := git.RefEndName(refFullName)
gitRepo, err := git.OpenRepository(repo.RepoPath()) gitRepo, err := git.OpenRepository(repo.RepoPath())
@ -740,7 +741,7 @@ func (m *webhookNotifier) NotifyPullRequestSynchronized(doer *user_model.User, p
Action: api.HookIssueSynchronized, Action: api.HookIssueSynchronized,
Index: pr.Issue.Index, Index: pr.Issue.Index,
PullRequest: convert.ToAPIPullRequest(pr, nil), 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), Sender: convert.ToUser(doer, nil),
}); err != nil { }); err != nil {
log.Error("PrepareWebhooks [pull_id: %v]: %v", pr.ID, err) 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) { func (m *webhookNotifier) NotifyDeleteRef(pusher *user_model.User, repo *models.Repository, refType, refFullName string) {
apiPusher := convert.ToUser(pusher, nil) apiPusher := convert.ToUser(pusher, nil)
apiRepo := convert.ToRepo(repo, models.AccessModeNone) apiRepo := convert.ToRepo(repo, perm.AccessModeNone)
refName := git.RefEndName(refFullName) refName := git.RefEndName(refFullName)
if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventDelete, &api.DeletePayload{ 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, CompareURL: setting.AppURL + commits.CompareURL,
Commits: apiCommits, Commits: apiCommits,
HeadCommit: apiHeadCommit, HeadCommit: apiHeadCommit,
Repo: convert.ToRepo(repo, models.AccessModeOwner), Repo: convert.ToRepo(repo, perm.AccessModeOwner),
Pusher: apiPusher, Pusher: apiPusher,
Sender: apiPusher, Sender: apiPusher,
}); err != nil { }); err != nil {

@ -11,6 +11,7 @@ import (
"net/url" "net/url"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -74,7 +75,7 @@ func IsErrServCommand(err error) bool {
} }
// ServCommand preps for a serv call // 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", reqURL := setting.LocalURL + fmt.Sprintf("api/internal/serv/command/%d/%s/%s?mode=%d",
keyID, keyID,
url.PathEscape(ownerName), url.PathEscape(ownerName),

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
@ -69,25 +70,25 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
{ {
OrgID: org.ID, OrgID: org.ID,
Name: "team one", Name: "team one",
Authorize: models.AccessModeRead, Authorize: perm.AccessModeRead,
IncludesAllRepositories: true, IncludesAllRepositories: true,
}, },
{ {
OrgID: org.ID, OrgID: org.ID,
Name: "team 2", Name: "team 2",
Authorize: models.AccessModeRead, Authorize: perm.AccessModeRead,
IncludesAllRepositories: false, IncludesAllRepositories: false,
}, },
{ {
OrgID: org.ID, OrgID: org.ID,
Name: "team three", Name: "team three",
Authorize: models.AccessModeWrite, Authorize: perm.AccessModeWrite,
IncludesAllRepositories: true, IncludesAllRepositories: true,
}, },
{ {
OrgID: org.ID, OrgID: org.ID,
Name: "team 4", Name: "team 4",
Authorize: models.AccessModeWrite, Authorize: perm.AccessModeWrite,
IncludesAllRepositories: false, IncludesAllRepositories: false,
}, },
} }

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -155,16 +156,16 @@ func GetUserOrgsPermissions(ctx *context.APIContext) {
return return
} }
if authorizeLevel > models.AccessModeNone { if authorizeLevel > perm.AccessModeNone {
op.CanRead = true op.CanRead = true
} }
if authorizeLevel > models.AccessModeRead { if authorizeLevel > perm.AccessModeRead {
op.CanWrite = true op.CanWrite = true
} }
if authorizeLevel > models.AccessModeWrite { if authorizeLevel > perm.AccessModeWrite {
op.IsAdmin = true op.IsAdmin = true
} }
if authorizeLevel > models.AccessModeAdmin { if authorizeLevel > perm.AccessModeAdmin {
op.IsOwner = true op.IsOwner = true
} }

@ -9,6 +9,7 @@ import (
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
unit_model "code.gitea.io/gitea/models/unit" unit_model "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -170,12 +171,12 @@ func CreateTeam(ctx *context.APIContext) {
Description: form.Description, Description: form.Description,
IncludesAllRepositories: form.IncludesAllRepositories, IncludesAllRepositories: form.IncludesAllRepositories,
CanCreateOrgRepo: form.CanCreateOrgRepo, CanCreateOrgRepo: form.CanCreateOrgRepo,
Authorize: models.ParseAccessMode(form.Permission), Authorize: perm.ParseAccessMode(form.Permission),
} }
unitTypes := unit_model.FindUnitTypes(form.Units...) 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)) var units = make([]*models.TeamUnit, 0, len(form.Units))
for _, tp := range unitTypes { for _, tp := range unitTypes {
units = append(units, &models.TeamUnit{ units = append(units, &models.TeamUnit{
@ -245,7 +246,7 @@ func EditTeam(ctx *context.APIContext) {
isIncludeAllChanged := false isIncludeAllChanged := false
if !team.IsOwnerTeam() && len(form.Permission) != 0 { if !team.IsOwnerTeam() && len(form.Permission) != 0 {
// Validate permission level. // Validate permission level.
auth := models.ParseAccessMode(form.Permission) auth := perm.ParseAccessMode(form.Permission)
if team.Authorize != auth { if team.Authorize != auth {
isAuthChanged = true 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 { if len(form.Units) > 0 {
var units = make([]*models.TeamUnit, 0, len(form.Units)) var units = make([]*models.TeamUnit, 0, len(form.Units))
unitTypes := unit_model.FindUnitTypes(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 { if access, err := models.AccessLevel(ctx.User, repo); err != nil {
ctx.Error(http.StatusInternalServerError, "AccessLevel", err) ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
return return
} else if access < models.AccessModeAdmin { } else if access < perm.AccessModeAdmin {
ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository")
return return
} }
@ -611,7 +612,7 @@ func RemoveTeamRepository(ctx *context.APIContext) {
if access, err := models.AccessLevel(ctx.User, repo); err != nil { if access, err := models.AccessLevel(ctx.User, repo); err != nil {
ctx.Error(http.StatusInternalServerError, "AccessLevel", err) ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
return return
} else if access < models.AccessModeAdmin { } else if access < perm.AccessModeAdmin {
ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository")
return return
} }

@ -9,7 +9,7 @@ import (
"errors" "errors"
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -177,7 +177,7 @@ func AddCollaborator(ctx *context.APIContext) {
} }
if form.Permission != nil { 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) ctx.Error(http.StatusInternalServerError, "ChangeCollaborationAccessMode", err)
return return
} }

@ -10,6 +10,7 @@ import (
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -135,5 +136,5 @@ func CreateFork(ctx *context.APIContext) {
} }
//TODO change back to 201 //TODO change back to 201
ctx.JSON(http.StatusAccepted, convert.ToRepo(fork, models.AccessModeOwner)) ctx.JSON(http.StatusAccepted, convert.ToRepo(fork, perm.AccessModeOwner))
} }

@ -8,7 +8,7 @@ package repo
import ( import (
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -162,9 +162,9 @@ func TestHook(ctx *context.APIContext) {
After: ctx.Repo.Commit.ID.String(), After: ctx.Repo.Commit.ID.String(),
Commits: []*api.PayloadCommit{commit}, Commits: []*api.PayloadCommit{commit},
HeadCommit: commit, HeadCommit: commit,
Repo: convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), Repo: convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone),
Pusher: convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), Pusher: convert.ToUserWithAccessMode(ctx.User, perm.AccessModeNone),
Sender: convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), Sender: convert.ToUserWithAccessMode(ctx.User, perm.AccessModeNone),
}); err != nil { }); err != nil {
ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err) ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err)
return return

@ -11,6 +11,7 @@ import (
"net/url" "net/url"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -21,7 +22,7 @@ import (
// appendPrivateInformation appends the owner and key type information to api.PublicKey // 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) { 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 { if repository.ID == key.RepoID {
apiKey.Repository = convert.ToRepo(repository, key.Mode) apiKey.Repository = convert.ToRepo(repository, key.Mode)
} else { } else {

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -207,7 +208,7 @@ func Migrate(ctx *context.APIContext) {
} }
log.Trace("Repository migrated: %s/%s", repoOwner.Name, form.RepoName) 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) { func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, remoteAddr string, err error) {

@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -115,7 +116,7 @@ func ListReleases(ctx *context.APIContext) {
opts := models.FindReleasesOptions{ opts := models.FindReleasesOptions{
ListOptions: listOptions, 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, IncludeTags: false,
IsDraft: ctx.FormOptionalBool("draft"), IsDraft: ctx.FormOptionalBool("draft"),
IsPreRelease: ctx.FormOptionalBool("pre-release"), IsPreRelease: ctx.FormOptionalBool("pre-release"),

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
unit_model "code.gitea.io/gitea/models/unit" unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "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.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 // 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) 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 // CreateOrgRepoDeprecated create one repository of the organization

@ -9,6 +9,7 @@ import (
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -113,10 +114,10 @@ func Transfer(ctx *context.APIContext) {
if ctx.Repo.Repository.Status == models.RepositoryPendingTransfer { if ctx.Repo.Repository.Status == models.RepositoryPendingTransfer {
log.Trace("Repository transfer initiated: %s -> %s", ctx.Repo.Repository.FullName(), newOwner.Name) 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 return
} }
log.Trace("Repository transferred: %s -> %s", ctx.Repo.Repository.FullName(), newOwner.Name) 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))
} }

@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -37,7 +38,7 @@ func appendPrivateInformation(apiKey *api.PublicKey, key *models.PublicKey, defa
} else { } else {
apiKey.KeyType = "unknown" apiKey.KeyType = "unknown"
} }
apiKey.ReadOnly = key.Mode == models.AccessModeRead apiKey.ReadOnly = key.Mode == perm.AccessModeRead
return apiKey, nil return apiKey, nil
} }

@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/convert"
@ -37,7 +38,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
ctx.Error(http.StatusInternalServerError, "AccessLevel", err) ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
return 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)) apiRepos = append(apiRepos, convert.ToRepo(repos[i], access))
} }
} }

@ -11,6 +11,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
@ -79,7 +80,7 @@ func ServCommand(ctx *context.PrivateContext) {
keyID := ctx.ParamsInt64(":keyid") keyID := ctx.ParamsInt64(":keyid")
ownerName := ctx.Params(":owner") ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo") 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 // Set the basic parts of the results to return
results := private.ServCommandResults{ 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 // Now because we're not translating things properly let's just default some English strings here
modeString := "read" modeString := "read"
if mode > models.AccessModeRead { if mode > perm.AccessModeRead {
modeString = "write to" modeString = "write to"
} }
@ -172,7 +173,7 @@ func ServCommand(ctx *context.PrivateContext) {
} }
// We can shortcut at this point if the repo is a mirror // 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{ ctx.JSON(http.StatusForbidden, private.ErrServCommand{
Results: results, Results: results,
Err: fmt.Sprintf("Mirror Repository %s/%s is read-only", results.OwnerName, results.RepoName), 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 // 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{ ctx.JSON(http.StatusUnauthorized, private.ErrServCommand{
Results: results, Results: results,
Err: fmt.Sprintf("Repo: %s/%s is archived.", results.OwnerName, results.RepoName), Err: fmt.Sprintf("Repo: %s/%s is archived.", results.OwnerName, results.RepoName),
@ -290,7 +291,7 @@ func ServCommand(ctx *context.PrivateContext) {
// Permissions checking: // Permissions checking:
if repoExist && if repoExist &&
(mode > models.AccessModeRead || (mode > perm.AccessModeRead ||
repo.IsPrivate || repo.IsPrivate ||
owner.Visibility.IsPrivate() || owner.Visibility.IsPrivate() ||
(user != nil && user.IsRestricted) || // user will be nil if the key is a deploykey (user != nil && user.IsRestricted) || // user will be nil if the key is a deploykey
@ -306,7 +307,7 @@ func ServCommand(ctx *context.PrivateContext) {
} else { } else {
// Because of the special ref "refs/for" we will need to delay write permission check // Because of the special ref "refs/for" we will need to delay write permission check
if git.SupportProcReceive && unitType == unit.TypeCode { if git.SupportProcReceive && unitType == unit.TypeCode {
mode = models.AccessModeRead mode = perm.AccessModeRead
} }
perm, err := models.GetUserRepoPermission(repo, user) perm, err := models.GetUserRepoPermission(repo, user)

@ -12,6 +12,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
unit_model "code.gitea.io/gitea/models/unit" unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
@ -235,12 +236,12 @@ func NewTeamPost(ctx *context.Context) {
OrgID: ctx.Org.Organization.ID, OrgID: ctx.Org.Organization.ID,
Name: form.TeamName, Name: form.TeamName,
Description: form.Description, Description: form.Description,
Authorize: models.ParseAccessMode(form.Permission), Authorize: perm.ParseAccessMode(form.Permission),
IncludesAllRepositories: includesAllRepositories, IncludesAllRepositories: includesAllRepositories,
CanCreateOrgRepo: form.CanCreateOrgRepo, CanCreateOrgRepo: form.CanCreateOrgRepo,
} }
if t.Authorize < models.AccessModeOwner { if t.Authorize < perm.AccessModeOwner {
var units = make([]*models.TeamUnit, 0, len(form.Units)) var units = make([]*models.TeamUnit, 0, len(form.Units))
for _, tp := range form.Units { for _, tp := range form.Units {
units = append(units, &models.TeamUnit{ units = append(units, &models.TeamUnit{
@ -258,7 +259,7 @@ func NewTeamPost(ctx *context.Context) {
return 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) ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
return return
} }
@ -325,7 +326,7 @@ func EditTeamPost(ctx *context.Context) {
var includesAllRepositories = form.RepoAccess == "all" var includesAllRepositories = form.RepoAccess == "all"
if !t.IsOwnerTeam() { if !t.IsOwnerTeam() {
// Validate permission level. // Validate permission level.
auth := models.ParseAccessMode(form.Permission) auth := perm.ParseAccessMode(form.Permission)
t.Name = form.TeamName t.Name = form.TeamName
if t.Authorize != auth { if t.Authorize != auth {
@ -339,7 +340,7 @@ func EditTeamPost(ctx *context.Context) {
} }
} }
t.Description = form.Description t.Description = form.Description
if t.Authorize < models.AccessModeOwner { if t.Authorize < perm.AccessModeOwner {
var units = make([]models.TeamUnit, 0, len(form.Units)) var units = make([]models.TeamUnit, 0, len(form.Units))
for _, tp := range form.Units { for _, tp := range form.Units {
units = append(units, models.TeamUnit{ units = append(units, models.TeamUnit{
@ -361,7 +362,7 @@ func EditTeamPost(ctx *context.Context) {
return 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) ctx.RenderWithErr(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
return return
} }

@ -22,6 +22,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/login" "code.gitea.io/gitea/models/login"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
@ -93,11 +94,11 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
isPull = ctx.Req.Method == "GET" isPull = ctx.Req.Method == "GET"
} }
var accessMode models.AccessMode var accessMode perm.AccessMode
if isPull { if isPull {
accessMode = models.AccessModeRead accessMode = perm.AccessModeRead
} else { } else {
accessMode = models.AccessModeWrite accessMode = perm.AccessModeWrite
} }
isWiki := false isWiki := false
@ -194,7 +195,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
} }
if repoExist { if repoExist {
perm, err := models.GetUserRepoPermission(repo, ctx.User) p, err := models.GetUserRepoPermission(repo, ctx.User)
if err != nil { if err != nil {
ctx.ServerError("GetUserRepoPermission", err) ctx.ServerError("GetUserRepoPermission", err)
return return
@ -202,10 +203,10 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
// Because of special ref "refs/for" .. , need delay write permission check // Because of special ref "refs/for" .. , need delay write permission check
if git.SupportProcReceive { 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") ctx.HandleText(http.StatusForbidden, "User permission denied")
return return
} }

@ -11,6 +11,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
@ -373,7 +374,7 @@ func DeleteProjectBoard(ctx *context.Context) {
return 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{ ctx.JSON(http.StatusForbidden, map[string]string{
"message": "Only authorized users are allowed to perform this action.", "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. // AddBoardToProjectPost allows a new board to be added to a project.
func AddBoardToProjectPost(ctx *context.Context) { func AddBoardToProjectPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.EditProjectBoardForm) 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{ ctx.JSON(http.StatusForbidden, map[string]string{
"message": "Only authorized users are allowed to perform this action.", "message": "Only authorized users are allowed to perform this action.",
}) })
@ -462,7 +463,7 @@ func checkProjectBoardChangePermissions(ctx *context.Context) (*models.Project,
return nil, nil 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{ ctx.JSON(http.StatusForbidden, map[string]string{
"message": "Only authorized users are allowed to perform this action.", "message": "Only authorized users are allowed to perform this action.",
}) })
@ -556,7 +557,7 @@ func MoveIssueAcrossBoards(ctx *context.Context) {
return 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{ ctx.JSON(http.StatusForbidden, map[string]string{
"message": "Only authorized users are allowed to perform this action.", "message": "Only authorized users are allowed to perform this action.",
}) })

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
unit_model "code.gitea.io/gitea/models/unit" unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
@ -846,7 +847,7 @@ func CollaborationPost(ctx *context.Context) {
func ChangeCollaborationAccessMode(ctx *context.Context) { func ChangeCollaborationAccessMode(ctx *context.Context) {
if err := ctx.Repo.Repository.ChangeCollaborationAccessMode( if err := ctx.Repo.Repository.ChangeCollaborationAccessMode(
ctx.FormInt64("uid"), ctx.FormInt64("uid"),
models.AccessMode(ctx.FormInt("mode"))); err != nil { perm.AccessMode(ctx.FormInt("mode"))); err != nil {
log.Error("ChangeCollaborationAccessMode: %v", err) log.Error("ChangeCollaborationAccessMode: %v", err)
} }
} }

@ -11,6 +11,7 @@ import (
"time" "time"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
@ -156,7 +157,7 @@ func SettingsProtectedBranch(c *context.Context) {
} }
if c.Repo.Owner.IsOrganization() { 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 { if err != nil {
c.ServerError("Repo.Owner.TeamsWithAccessToRepo", err) c.ServerError("Repo.Owner.TeamsWithAccessToRepo", err)
return return

@ -10,6 +10,7 @@ import (
"testing" "testing"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
@ -62,7 +63,7 @@ func TestAddReadOnlyDeployKey(t *testing.T) {
unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ unittest.AssertExistsAndLoadBean(t, &models.DeployKey{
Name: addKeyForm.Title, Name: addKeyForm.Title,
Content: addKeyForm.Content, Content: addKeyForm.Content,
Mode: models.AccessModeRead, Mode: perm.AccessModeRead,
}) })
} }
@ -92,7 +93,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) {
unittest.AssertExistsAndLoadBean(t, &models.DeployKey{ unittest.AssertExistsAndLoadBean(t, &models.DeployKey{
Name: addKeyForm.Title, Name: addKeyForm.Title,
Content: addKeyForm.Content, Content: addKeyForm.Content,
Mode: models.AccessModeWrite, Mode: perm.AccessModeWrite,
}) })
} }

@ -10,6 +10,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -149,7 +150,7 @@ func setTagsContext(ctx *context.Context) error {
ctx.Data["Users"] = users ctx.Data["Users"] = users
if ctx.Repo.Owner.IsOrganization() { 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 { if err != nil {
ctx.ServerError("Repo.Owner.TeamsWithAccessToRepo", err) ctx.ServerError("Repo.Owner.TeamsWithAccessToRepo", err)
return err return err

@ -13,8 +13,8 @@ import (
"path" "path"
"strings" "strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/base" "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{ apiCommit := &api.PayloadCommit{
ID: commit.ID.String(), ID: commit.ID.String(),
@ -1181,7 +1181,7 @@ func TestWebhook(ctx *context.Context) {
After: commit.ID.String(), After: commit.ID.String(),
Commits: []*api.PayloadCommit{apiCommit}, Commits: []*api.PayloadCommit{apiCommit},
HeadCommit: apiCommit, HeadCommit: apiCommit,
Repo: convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), Repo: convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone),
Pusher: apiUser, Pusher: apiUser,
Sender: apiUser, Sender: apiUser,
} }

@ -6,6 +6,7 @@ package issue
import ( import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
@ -111,7 +112,7 @@ func IsValidReviewRequest(reviewer, doer *user_model.User, isAdd bool, issue *mo
var pemResult bool var pemResult bool
if isAdd { if isAdd {
pemResult = permReviewer.CanAccessAny(models.AccessModeRead, unit.TypePullRequests) pemResult = permReviewer.CanAccessAny(perm.AccessModeRead, unit.TypePullRequests)
if !pemResult { if !pemResult {
return models.ErrNotValidReviewRequest{ return models.ErrNotValidReviewRequest{
Reason: "Reviewer can't read", Reason: "Reviewer can't read",
@ -124,7 +125,7 @@ func IsValidReviewRequest(reviewer, doer *user_model.User, isAdd bool, issue *mo
return nil return nil
} }
pemResult = permDoer.CanAccessAny(models.AccessModeWrite, unit.TypePullRequests) pemResult = permDoer.CanAccessAny(perm.AccessModeWrite, unit.TypePullRequests)
if !pemResult { if !pemResult {
pemResult, err = models.IsOfficialReviewer(issue, doer) pemResult, err = models.IsOfficialReviewer(issue, doer)
if err != nil { 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 { if !doerCanWrite {
official, err := models.IsOfficialReviewer(issue, doer) official, err := models.IsOfficialReviewer(issue, doer)
if err != nil { if err != nil {

@ -19,6 +19,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
@ -480,9 +481,9 @@ func writeStatusMessage(ctx *context.Context, status int, message string) {
// authenticate uses the authorization string to determine whether // authenticate uses the authorization string to determine whether
// or not to proceed. This server assumes an HTTP Basic auth format. // 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 { func authenticate(ctx *context.Context, repository *models.Repository, authorization string, requireSigned, requireWrite bool) bool {
accessMode := models.AccessModeRead accessMode := perm.AccessModeRead
if requireWrite { if requireWrite {
accessMode = models.AccessModeWrite accessMode = perm.AccessModeWrite
} }
// ctx.IsSigned is unnecessary here, this will be checked in perm.CanAccess // 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 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, ".") { if !strings.Contains(tokenSHA, ".") {
return nil, nil return nil, nil
} }
@ -530,7 +531,7 @@ func handleLFSToken(tokenSHA string, target *models.Repository, mode models.Acce
return nil, fmt.Errorf("invalid token claim") 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") return nil, fmt.Errorf("invalid token claim")
} }
@ -542,7 +543,7 @@ func handleLFSToken(tokenSHA string, target *models.Repository, mode models.Acce
return u, nil 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 == "" { if authorization == "" {
return nil, fmt.Errorf("no token") return nil, fmt.Errorf("no token")
} }

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/sync" "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 { if err := repo.AddCollaborator(newOwner); err != nil {
return err return err
} }
if err := repo.ChangeCollaborationAccessMode(newOwner.ID, models.AccessModeRead); err != nil { if err := repo.ChangeCollaborationAccessMode(newOwner.ID, perm.AccessModeRead); err != nil {
return err return err
} }
} }

Loading…
Cancel
Save