aboutsummaryrefslogtreecommitdiffstats
path: root/routers/api
diff options
context:
space:
mode:
authorJason Song <i@wolfogre.com>2023-06-22 21:08:08 +0800
committerGitHub <noreply@github.com>2023-06-22 13:08:08 +0000
commit174213530dc538c124cddc5cc43d9a514c6695b9 (patch)
tree061bdae4a57ed1ca17d1b85bb4c7ab69fe673d71 /routers/api
parent7fb539677b448a9cc554e71afb98da558f3e0631 (diff)
downloadgitea-174213530dc538c124cddc5cc43d9a514c6695b9.tar.gz
gitea-174213530dc538c124cddc5cc43d9a514c6695b9.zip
Fix `Permission` in API returned repository struct (#25388)
The old code generates `structs.Repository.Permissions` with only `access.Permission.AccessMode`, however, it should check the units too, or the value could be incorrect. For example, `structs.Repository.Permissions.Push` could be false even the doer has write access to code unit. Should fix https://github.com/renovatebot/renovate/issues/14059#issuecomment-1047961128 (Not reported by it, I just found it when I was looking into this bug) --- Review tips: The major changes are - `modules/structs/repo.go` https://github.com/go-gitea/gitea/pull/25388/files#diff-870406f6857117f8b03611c43fca0ab9ed6d6e76a2d0069a7c1f17e8fa9092f7 - `services/convert/repository.go` https://github.com/go-gitea/gitea/pull/25388/files#diff-7736f6d2ae894c9edb7729a80ab89aa183b888a26a811a0c1fdebd18726a7101 And other changes are passive.
Diffstat (limited to 'routers/api')
-rw-r--r--routers/api/v1/org/team.go8
-rw-r--r--routers/api/v1/repo/fork.go8
-rw-r--r--routers/api/v1/repo/hook.go3
-rw-r--r--routers/api/v1/repo/key.go5
-rw-r--r--routers/api/v1/repo/migrate.go3
-rw-r--r--routers/api/v1/repo/repo.go20
-rw-r--r--routers/api/v1/repo/status.go2
-rw-r--r--routers/api/v1/repo/transfer.go9
-rw-r--r--routers/api/v1/user/repo.go15
-rw-r--r--routers/api/v1/user/star.go4
-rw-r--r--routers/api/v1/user/watch.go4
11 files changed, 43 insertions, 38 deletions
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index 8b7d7b1951..1aaefacdd5 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -561,12 +561,12 @@ func GetTeamRepos(ctx *context.APIContext) {
}
repos := make([]*api.Repository, len(teamRepos))
for i, repo := range teamRepos {
- access, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
+ permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
return
}
- repos[i] = convert.ToRepo(ctx, repo, access)
+ repos[i] = convert.ToRepo(ctx, repo, permission)
}
ctx.SetTotalCountHeader(int64(team.NumRepos))
ctx.JSON(http.StatusOK, repos)
@@ -612,13 +612,13 @@ func GetTeamRepo(ctx *context.APIContext) {
return
}
- access, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
+ permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err)
return
}
- ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, access))
+ ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, permission))
}
// getRepositoryByParams get repository by a team's organization ID and repo name
diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go
index 4cb3eddf58..f75153ab2d 100644
--- a/routers/api/v1/repo/fork.go
+++ b/routers/api/v1/repo/fork.go
@@ -60,12 +60,12 @@ func ListForks(ctx *context.APIContext) {
}
apiForks := make([]*api.Repository, len(forks))
for i, fork := range forks {
- access, err := access_model.AccessLevel(ctx, ctx.Doer, fork)
+ permission, err := access_model.GetUserRepoPermission(ctx, fork, ctx.Doer)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
+ ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
return
}
- apiForks[i] = convert.ToRepo(ctx, fork, access)
+ apiForks[i] = convert.ToRepo(ctx, fork, permission)
}
ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumForks))
@@ -152,5 +152,5 @@ func CreateFork(ctx *context.APIContext) {
}
// TODO change back to 201
- ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx, fork, perm.AccessModeOwner))
+ ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx, fork, access_model.Permission{AccessMode: perm.AccessModeOwner}))
}
diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go
index 39d83912b0..d0b77b5687 100644
--- a/routers/api/v1/repo/hook.go
+++ b/routers/api/v1/repo/hook.go
@@ -8,6 +8,7 @@ import (
"net/http"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
@@ -185,7 +186,7 @@ func TestHook(ctx *context.APIContext) {
Commits: []*api.PayloadCommit{commit},
TotalCommits: 1,
HeadCommit: commit,
- Repo: convert.ToRepo(ctx, ctx.Repo.Repository, perm.AccessModeNone),
+ Repo: convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeNone}),
Pusher: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone),
Sender: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone),
}); err != nil {
diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go
index d496c4a73c..824880880a 100644
--- a/routers/api/v1/repo/key.go
+++ b/routers/api/v1/repo/key.go
@@ -13,6 +13,7 @@ import (
asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
@@ -27,13 +28,13 @@ import (
func appendPrivateInformation(ctx stdCtx.Context, apiKey *api.DeployKey, key *asymkey_model.DeployKey, repository *repo_model.Repository) (*api.DeployKey, error) {
apiKey.ReadOnly = key.Mode == perm.AccessModeRead
if repository.ID == key.RepoID {
- apiKey.Repository = convert.ToRepo(ctx, repository, key.Mode)
+ apiKey.Repository = convert.ToRepo(ctx, repository, access_model.Permission{AccessMode: key.Mode})
} else {
repo, err := repo_model.GetRepositoryByID(ctx, key.RepoID)
if err != nil {
return apiKey, err
}
- apiKey.Repository = convert.ToRepo(ctx, repo, key.Mode)
+ apiKey.Repository = convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: key.Mode})
}
return apiKey, nil
}
diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go
index b458cd122b..84327de5fb 100644
--- a/routers/api/v1/repo/migrate.go
+++ b/routers/api/v1/repo/migrate.go
@@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
@@ -211,7 +212,7 @@ func Migrate(ctx *context.APIContext) {
}
log.Trace("Repository migrated: %s/%s", repoOwner.Name, form.RepoName)
- ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, perm.AccessModeAdmin))
+ ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeAdmin}))
}
func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, remoteAddr string, err error) {
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 114b93534a..a9f8b5b7e7 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -211,14 +211,14 @@ func Search(ctx *context.APIContext) {
})
return
}
- accessMode, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
+ permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
ctx.JSON(http.StatusInternalServerError, api.SearchError{
OK: false,
Error: err.Error(),
})
}
- results[i] = convert.ToRepo(ctx, repo, accessMode)
+ results[i] = convert.ToRepo(ctx, repo, permission)
}
ctx.SetLinkHeader(int(count), opts.PageSize)
ctx.SetTotalCountHeader(count)
@@ -272,7 +272,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err)
}
- ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, perm.AccessModeOwner))
+ ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner}))
}
// Create one repository of mine
@@ -419,7 +419,7 @@ func Generate(ctx *context.APIContext) {
}
log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
- ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, perm.AccessModeOwner))
+ ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner}))
}
// CreateOrgRepoDeprecated create one repository of the organization
@@ -537,7 +537,7 @@ func Get(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusOK, convert.ToRepo(ctx, ctx.Repo.Repository, ctx.Repo.AccessMode))
+ ctx.JSON(http.StatusOK, convert.ToRepo(ctx, ctx.Repo.Repository, ctx.Repo.Permission))
}
// GetByID returns a single Repository
@@ -568,15 +568,15 @@ func GetByID(ctx *context.APIContext) {
return
}
- perm, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
+ permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
+ ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
return
- } else if !perm.HasAccess() {
+ } else if !permission.HasAccess() {
ctx.NotFound()
return
}
- ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, perm.AccessMode))
+ ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, permission))
}
// Edit edit repository properties
@@ -638,7 +638,7 @@ func Edit(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, ctx.Repo.AccessMode))
+ ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, ctx.Repo.Permission))
}
// updateBasicProperties updates the basic properties of a repo: Name, Description, Website and Visibility
diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go
index c1110ebce5..028e3083c6 100644
--- a/routers/api/v1/repo/status.go
+++ b/routers/api/v1/repo/status.go
@@ -264,7 +264,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
return
}
- combiStatus := convert.ToCombinedStatus(ctx, statuses, convert.ToRepo(ctx, repo, ctx.Repo.AccessMode))
+ combiStatus := convert.ToCombinedStatus(ctx, statuses, convert.ToRepo(ctx, repo, ctx.Repo.Permission))
ctx.SetTotalCountHeader(count)
ctx.JSON(http.StatusOK, combiStatus)
diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go
index ded8edd41c..8ff22a1193 100644
--- a/routers/api/v1/repo/transfer.go
+++ b/routers/api/v1/repo/transfer.go
@@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm"
+ access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
@@ -122,12 +123,12 @@ func Transfer(ctx *context.APIContext) {
if ctx.Repo.Repository.Status == repo_model.RepositoryPendingTransfer {
log.Trace("Repository transfer initiated: %s -> %s", oldFullname, ctx.Repo.Repository.FullName())
- ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, ctx.Repo.Repository, perm.AccessModeAdmin))
+ ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeAdmin}))
return
}
log.Trace("Repository transferred: %s -> %s", oldFullname, ctx.Repo.Repository.FullName())
- ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx, ctx.Repo.Repository, perm.AccessModeAdmin))
+ ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeAdmin}))
}
// AcceptTransfer accept a repo transfer
@@ -165,7 +166,7 @@ func AcceptTransfer(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx, ctx.Repo.Repository, ctx.Repo.AccessMode))
+ ctx.JSON(http.StatusAccepted, convert.ToRepo(ctx, ctx.Repo.Repository, ctx.Repo.Permission))
}
// RejectTransfer reject a repo transfer
@@ -203,7 +204,7 @@ func RejectTransfer(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusOK, convert.ToRepo(ctx, ctx.Repo.Repository, ctx.Repo.AccessMode))
+ ctx.JSON(http.StatusOK, convert.ToRepo(ctx, ctx.Repo.Repository, ctx.Repo.Permission))
}
func acceptOrRejectRepoTransfer(ctx *context.APIContext, accept bool) error {
diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go
index 7a8978cc4e..86af8cb440 100644
--- a/routers/api/v1/user/repo.go
+++ b/routers/api/v1/user/repo.go
@@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
+ unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
@@ -38,13 +39,13 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
apiRepos := make([]*api.Repository, 0, len(repos))
for i := range repos {
- access, err := access_model.AccessLevel(ctx, ctx.Doer, repos[i])
+ permission, err := access_model.GetUserRepoPermission(ctx, repos[i], ctx.Doer)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
+ ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
return
}
- if ctx.IsSigned && ctx.Doer.IsAdmin || access >= perm.AccessModeRead {
- apiRepos = append(apiRepos, convert.ToRepo(ctx, repos[i], access))
+ if ctx.IsSigned && ctx.Doer.IsAdmin || permission.UnitAccessMode(unit_model.TypeCode) >= perm.AccessModeRead {
+ apiRepos = append(apiRepos, convert.ToRepo(ctx, repos[i], permission))
}
}
@@ -123,11 +124,11 @@ func ListMyRepos(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "LoadOwner", err)
return
}
- accessMode, err := access_model.AccessLevel(ctx, ctx.Doer, repo)
+ permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "AccessLevel", err)
+ ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
}
- results[i] = convert.ToRepo(ctx, repo, accessMode)
+ results[i] = convert.ToRepo(ctx, repo, permission)
}
ctx.SetLinkHeader(int(count), opts.ListOptions.PageSize)
diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go
index ad5a8bee33..9399ad2b4d 100644
--- a/routers/api/v1/user/star.go
+++ b/routers/api/v1/user/star.go
@@ -28,11 +28,11 @@ func getStarredRepos(ctx std_context.Context, user *user_model.User, private boo
repos := make([]*api.Repository, len(starredRepos))
for i, starred := range starredRepos {
- access, err := access_model.AccessLevel(ctx, user, starred)
+ permission, err := access_model.GetUserRepoPermission(ctx, starred, user)
if err != nil {
return nil, err
}
- repos[i] = convert.ToRepo(ctx, starred, access)
+ repos[i] = convert.ToRepo(ctx, starred, permission)
}
return repos, nil
}
diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go
index 211f36459a..172d9d5cc5 100644
--- a/routers/api/v1/user/watch.go
+++ b/routers/api/v1/user/watch.go
@@ -26,11 +26,11 @@ func getWatchedRepos(ctx std_context.Context, user *user_model.User, private boo
repos := make([]*api.Repository, len(watchedRepos))
for i, watched := range watchedRepos {
- access, err := access_model.AccessLevel(ctx, user, watched)
+ permission, err := access_model.GetUserRepoPermission(ctx, watched, user)
if err != nil {
return nil, 0, err
}
- repos[i] = convert.ToRepo(ctx, watched, access)
+ repos[i] = convert.ToRepo(ctx, watched, permission)
}
return repos, total, nil
}