0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-02-10 23:58:30 -05:00

fix(api): allow collaborators to read their own permissions (#6856)

- Instead of checking the login name (which is not set in most cases and really the wrong thing to do here just like it is case sensitive) simply check that the requested user has the same ID as the doer.
- Resolves forgejo/forgejo#6837
- Add integration test.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6856
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
Gusted 2025-02-08 15:09:08 +00:00 committed by Gusted
parent ed855e1492
commit 751a3da979
2 changed files with 23 additions and 5 deletions

View file

@ -282,11 +282,6 @@ func GetRepoPermissions(ctx *context.APIContext) {
// "403": // "403":
// "$ref": "#/responses/forbidden" // "$ref": "#/responses/forbidden"
if !ctx.Doer.IsAdmin && ctx.Doer.LoginName != ctx.Params(":collaborator") && !ctx.IsUserRepoAdmin() {
ctx.Error(http.StatusForbidden, "User", "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
return
}
collaborator, err := user_model.GetUserByName(ctx, ctx.Params(":collaborator")) collaborator, err := user_model.GetUserByName(ctx, ctx.Params(":collaborator"))
if err != nil { if err != nil {
if user_model.IsErrUserNotExist(err) { if user_model.IsErrUserNotExist(err) {
@ -297,6 +292,15 @@ func GetRepoPermissions(ctx *context.APIContext) {
return return
} }
// Only allow the request in any of the following situations:
// - The user is the instance admin.
// - The user is the repository admin.
// - The user is querying the permissiosn of themselves.
if !ctx.IsUserSiteAdmin() && ctx.Doer.ID != collaborator.ID && !ctx.IsUserRepoAdmin() {
ctx.Error(http.StatusForbidden, "User", "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
return
}
permission, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator) permission, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator)
if err != nil { if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)

View file

@ -52,6 +52,20 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) {
DecodeJSON(t, resp, &repoPermission) DecodeJSON(t, resp, &repoPermission)
assert.Equal(t, "read", repoPermission.Permission) assert.Equal(t, "read", repoPermission.Permission)
t.Run("CollaboratorCanReadTheirPermission", func(t *testing.T) {
session := loginUser(t, user4.Name)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, user4.Name).
AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusOK)
var repoPermission api.RepoCollaboratorPermission
DecodeJSON(t, resp, &repoPermission)
assert.Equal(t, "read", repoPermission.Permission)
})
}) })
t.Run("CollaboratorWithWriteAccess", func(t *testing.T) { t.Run("CollaboratorWithWriteAccess", func(t *testing.T) {