mirror of
https://github.com/go-gitea/gitea.git
synced 2025-06-21 13:38:00 +02:00
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.
This commit is contained in:
@ -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
|
||||
|
@ -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}))
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/models/webhook"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
@ -685,7 +686,7 @@ func TestWebhook(ctx *context.Context) {
|
||||
Commits: []*api.PayloadCommit{apiCommit},
|
||||
TotalCommits: 1,
|
||||
HeadCommit: apiCommit,
|
||||
Repo: convert.ToRepo(ctx, ctx.Repo.Repository, perm.AccessModeNone),
|
||||
Repo: convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeNone}),
|
||||
Pusher: apiUser,
|
||||
Sender: apiUser,
|
||||
}
|
||||
|
Reference in New Issue
Block a user