diff options
author | Jason Song <i@wolfogre.com> | 2023-06-22 21:08:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-22 13:08:08 +0000 |
commit | 174213530dc538c124cddc5cc43d9a514c6695b9 (patch) | |
tree | 061bdae4a57ed1ca17d1b85bb4c7ab69fe673d71 /routers/api | |
parent | 7fb539677b448a9cc554e71afb98da558f3e0631 (diff) | |
download | gitea-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.go | 8 | ||||
-rw-r--r-- | routers/api/v1/repo/fork.go | 8 | ||||
-rw-r--r-- | routers/api/v1/repo/hook.go | 3 | ||||
-rw-r--r-- | routers/api/v1/repo/key.go | 5 | ||||
-rw-r--r-- | routers/api/v1/repo/migrate.go | 3 | ||||
-rw-r--r-- | routers/api/v1/repo/repo.go | 20 | ||||
-rw-r--r-- | routers/api/v1/repo/status.go | 2 | ||||
-rw-r--r-- | routers/api/v1/repo/transfer.go | 9 | ||||
-rw-r--r-- | routers/api/v1/user/repo.go | 15 | ||||
-rw-r--r-- | routers/api/v1/user/star.go | 4 | ||||
-rw-r--r-- | routers/api/v1/user/watch.go | 4 |
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 } |