diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index 9ef1a92be4..f648c41adc 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -282,11 +282,6 @@ func GetRepoPermissions(ctx *context.APIContext) { // "403": // "$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")) if err != nil { if user_model.IsErrUserNotExist(err) { @@ -297,6 +292,15 @@ func GetRepoPermissions(ctx *context.APIContext) { 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) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) diff --git a/tests/integration/api_repo_collaborator_test.go b/tests/integration/api_repo_collaborator_test.go index 59cf85fef3..81d7a591f8 100644 --- a/tests/integration/api_repo_collaborator_test.go +++ b/tests/integration/api_repo_collaborator_test.go @@ -52,6 +52,20 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { DecodeJSON(t, resp, &repoPermission) 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) {