mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-08 22:13:26 +09:00
fix(api): accept fully-qualified refs in contents API (#38650)
`GET/POST` repository contents endpoints resolve the `ref` query parameter through `ResolveRefCommit`, which previously only accepted short branch/tag names or commit IDs. Clients that pass fully-qualified Git refs (GitHub-compatible), e.g. `ref=refs%2Fheads%2Fmain` or `ref=refs%2Ftags%2Fv1.0`, received 404 "object does not exist". This change accepts fully-qualified **`refs/heads/*`** and **`refs/tags/*`** only, then falls back to the existing short-name and SHA logic. Other `refs/*` prefixes (e.g. `refs/pull/`, `refs/for/`) are rejected. Fixes #38197 --------- Co-authored-by: roman s <roman.sukach@dust-labs.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
co-authored by
roman s
wxiaoguang
parent
4da9b59414
commit
cebdc90ed9
+40
-12
@@ -5,6 +5,7 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
git_model "gitea.dev/models/git"
|
git_model "gitea.dev/models/git"
|
||||||
repo_model "gitea.dev/models/repo"
|
repo_model "gitea.dev/models/repo"
|
||||||
@@ -20,23 +21,50 @@ type RefCommit struct {
|
|||||||
CommitID string
|
CommitID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveRefCommit resolve ref to a commit if exist
|
// ResolveRefCommit resolve ref to a commit if it exists.
|
||||||
|
// inputRef may be a short branch/tag name, a commit ID, or a fully-qualified
|
||||||
|
// git ref (e.g. refs/heads/main, refs/tags/v1.0) for GitHub client compatibility.
|
||||||
func ResolveRefCommit(ctx reqctx.RequestContext, repo *repo_model.Repository, inputRef string, minCommitIDLen ...int) (_ *RefCommit, err error) {
|
func ResolveRefCommit(ctx reqctx.RequestContext, repo *repo_model.Repository, inputRef string, minCommitIDLen ...int) (_ *RefCommit, err error) {
|
||||||
|
refCommit := RefCommit{InputRef: inputRef}
|
||||||
|
|
||||||
|
var testRefBranch, testRefTag git.RefName
|
||||||
|
if strings.HasPrefix(inputRef, "refs/") {
|
||||||
|
// Fully-qualified refs first so clients can pass unambiguous names.
|
||||||
|
testRef := git.RefName(inputRef)
|
||||||
|
if testRef.IsBranch() {
|
||||||
|
testRefBranch = testRef
|
||||||
|
} else if testRef.IsTag() {
|
||||||
|
testRefTag = testRef
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
testRefBranch, testRefTag = git.RefNameFromBranch(inputRef), git.RefNameFromTag(inputRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
if testRefBranch != "" {
|
||||||
|
if exist, _ := git_model.IsBranchExist(ctx, repo.ID, testRefBranch.ShortName()); exist {
|
||||||
|
refCommit.RefName = testRefBranch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if testRefTag != "" {
|
||||||
|
// TODO: use git model instead of git command in the future? Model seems to be faster.
|
||||||
|
if git.IsTagExist(ctx, repo, testRefTag.ShortName()) {
|
||||||
|
refCommit.RefName = testRefTag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if refCommit.RefName == "" {
|
||||||
|
if git.IsStringLikelyCommitID(git.ObjectFormatFromName(repo.ObjectFormatName), inputRef, minCommitIDLen...) {
|
||||||
|
refCommit.RefName = git.RefNameFromCommit(inputRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if refCommit.RefName == "" {
|
||||||
|
return nil, git.ErrNotExist{ID: inputRef}
|
||||||
|
}
|
||||||
|
|
||||||
gitRepo, err := git.RepositoryFromRequestContextOrOpen(ctx, repo)
|
gitRepo, err := git.RepositoryFromRequestContextOrOpen(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
refCommit := RefCommit{InputRef: inputRef}
|
|
||||||
if exist, _ := git_model.IsBranchExist(ctx, repo.ID, inputRef); exist {
|
|
||||||
refCommit.RefName = git.RefNameFromBranch(inputRef)
|
|
||||||
} else if git.IsTagExist(ctx, repo, inputRef) {
|
|
||||||
refCommit.RefName = git.RefNameFromTag(inputRef)
|
|
||||||
} else if git.IsStringLikelyCommitID(git.ObjectFormatFromName(repo.ObjectFormatName), inputRef, minCommitIDLen...) {
|
|
||||||
refCommit.RefName = git.RefNameFromCommit(inputRef)
|
|
||||||
}
|
|
||||||
if refCommit.RefName == "" {
|
|
||||||
return nil, git.ErrNotExist{ID: inputRef}
|
|
||||||
}
|
|
||||||
if refCommit.Commit, err = gitRepo.GetCommit(ctx, refCommit.RefName.String()); err != nil {
|
if refCommit.Commit, err = gitRepo.GetCommit(ctx, refCommit.RefName.String()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,33 +63,50 @@ func TestAPIGetRequestedFiles(t *testing.T) {
|
|||||||
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/file-contents?body="+url.QueryEscape(string(reqBodyParam)))
|
req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/file-contents?body="+url.QueryEscape(string(reqBodyParam)))
|
||||||
resp := MakeRequest(t, req, http.StatusOK)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
ret := DecodeJSON(t, resp, []*api.ContentsResponse{})
|
ret := DecodeJSON(t, resp, []*api.ContentsResponse{})
|
||||||
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents(repo1.DefaultBranch, "branch", lastCommit.ID.String())}
|
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("master", "refs/heads/master", lastCommit.ID.String())}
|
||||||
assert.Equal(t, expected, ret)
|
assert.Equal(t, expected, ret)
|
||||||
})
|
})
|
||||||
t.Run("User2NoRef", func(t *testing.T) {
|
t.Run("User2NoRef", func(t *testing.T) {
|
||||||
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents", []string{"README.md"})
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents", []string{"README.md"})
|
||||||
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents(repo1.DefaultBranch, "branch", lastCommit.ID.String())}
|
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("master", "refs/heads/master", lastCommit.ID.String())}
|
||||||
assert.Equal(t, expected, ret)
|
assert.Equal(t, expected, ret)
|
||||||
})
|
})
|
||||||
t.Run("User2RefBranch", func(t *testing.T) {
|
t.Run("User2RefBranch", func(t *testing.T) {
|
||||||
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=master", []string{"README.md"})
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=master", []string{"README.md"})
|
||||||
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents(repo1.DefaultBranch, "branch", lastCommit.ID.String())}
|
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("master", "refs/heads/master", lastCommit.ID.String())}
|
||||||
assert.Equal(t, expected, ret)
|
assert.Equal(t, expected, ret)
|
||||||
})
|
})
|
||||||
t.Run("User2RefTag", func(t *testing.T) {
|
t.Run("User2RefTag", func(t *testing.T) {
|
||||||
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=v1.1", []string{"README.md"})
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=v1.1", []string{"README.md"})
|
||||||
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("v1.1", "tag", lastCommit.ID.String())}
|
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("v1.1", "refs/tags/v1.1", lastCommit.ID.String())}
|
||||||
assert.Equal(t, expected, ret)
|
assert.Equal(t, expected, ret)
|
||||||
})
|
})
|
||||||
t.Run("User2RefCommit", func(t *testing.T) {
|
t.Run("User2RefCommit", func(t *testing.T) {
|
||||||
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=65f1bf27bc3bf70f64657658635e66094edbcb4d", []string{"README.md"})
|
commitID := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
|
||||||
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("65f1bf27bc3bf70f64657658635e66094edbcb4d", "commit", lastCommit.ID.String())}
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref="+commitID, []string{"README.md"})
|
||||||
|
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents(commitID, git.RefNameFromCommit(commitID), lastCommit.ID.String())}
|
||||||
assert.Equal(t, expected, ret)
|
assert.Equal(t, expected, ret)
|
||||||
})
|
})
|
||||||
t.Run("User2RefNotExist", func(t *testing.T) {
|
t.Run("User2RefNotExist", func(t *testing.T) {
|
||||||
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=not-exist", []string{"README.md"}, http.StatusNotFound)
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=not-exist", []string{"README.md"}, http.StatusNotFound)
|
||||||
assert.Empty(t, ret)
|
assert.Empty(t, ret)
|
||||||
})
|
})
|
||||||
|
t.Run("User2RefFullBranch", func(t *testing.T) {
|
||||||
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=refs/heads/master", []string{"README.md"})
|
||||||
|
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("refs/heads/master", "refs/heads/master", lastCommit.ID.String())}
|
||||||
|
assert.Equal(t, expected, ret)
|
||||||
|
})
|
||||||
|
t.Run("User2RefFullTag", func(t *testing.T) {
|
||||||
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref=refs/tags/v1.1", []string{"README.md"})
|
||||||
|
expected := []*api.ContentsResponse{getExpectedContentsResponseForContents("refs/tags/v1.1", "refs/tags/v1.1", lastCommit.ID.String())}
|
||||||
|
assert.Equal(t, expected, ret)
|
||||||
|
})
|
||||||
|
t.Run("User2RefInternalPullRejected", func(t *testing.T) {
|
||||||
|
// repo1 has refs/pull/2/head in fixtures; contents API must not resolve it
|
||||||
|
assert.True(t, git.IsReferenceExist(t.Context(), gitRepo, "refs/pull/2/head"))
|
||||||
|
ret := requestFiles(t, "/api/v1/repos/user2/repo1/file-contents?ref="+url.QueryEscape("refs/pull/2/head"), []string{"README.md"}, http.StatusNotFound)
|
||||||
|
assert.Empty(t, ret)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("PermissionCheck", func(t *testing.T) {
|
t.Run("PermissionCheck", func(t *testing.T) {
|
||||||
filesOptions := &api.GetFilesOptions{Files: []string{"README.md"}}
|
filesOptions := &api.GetFilesOptions{Files: []string{"README.md"}}
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getExpectedContentsResponseForContents(ref, refType, lastCommitSHA string) *api.ContentsResponse {
|
func getExpectedContentsResponseForContents(inputRef string, expectedRef git.RefName, lastCommitSHA string) *api.ContentsResponse {
|
||||||
treePath := "README.md"
|
treePath := "README.md"
|
||||||
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=" + ref
|
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=" + url.QueryEscape(inputRef)
|
||||||
htmlURL := setting.AppURL + "user2/repo1/src/" + refType + "/" + ref + "/" + treePath
|
htmlURL := setting.AppURL + "user2/repo1/src/" + expectedRef.RefWebLinkPath() + "/" + treePath
|
||||||
gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/4b4851ad51df6a7d9f25c979345979eaeb5b349f"
|
gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/4b4851ad51df6a7d9f25c979345979eaeb5b349f"
|
||||||
return &api.ContentsResponse{
|
return &api.ContentsResponse{
|
||||||
Name: treePath,
|
Name: treePath,
|
||||||
@@ -43,7 +43,7 @@ func getExpectedContentsResponseForContents(ref, refType, lastCommitSHA string)
|
|||||||
URL: &selfURL,
|
URL: &selfURL,
|
||||||
HTMLURL: &htmlURL,
|
HTMLURL: &htmlURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
DownloadURL: new(setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath),
|
DownloadURL: new(setting.AppURL + "user2/repo1/raw/" + expectedRef.RefWebLinkPath() + "/" + treePath),
|
||||||
Links: &api.FileLinksResponse{
|
Links: &api.FileLinksResponse{
|
||||||
Self: &selfURL,
|
Self: &selfURL,
|
||||||
GitURL: &gitURL,
|
GitURL: &gitURL,
|
||||||
@@ -82,92 +82,91 @@ func testAPIGetContents(t *testing.T, _ *url.URL) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer gitRepo.Close()
|
defer gitRepo.Close()
|
||||||
|
|
||||||
// Make a new branch in repo1
|
defaultBranchCommitID, err := gitRepo.GetBranchCommitID(t.Context(), repo1.DefaultBranch)
|
||||||
newBranch := "test_branch"
|
|
||||||
err = repo_service.CreateNewBranch(t.Context(), user2, repo1, gitRepo, repo1.DefaultBranch, newBranch)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
commitID, err := gitRepo.GetBranchCommitID(t.Context(), repo1.DefaultBranch)
|
t.Run("FileNotFound", func(t *testing.T) {
|
||||||
require.NoError(t, err)
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/no-such/file.md", user2.Name, repo1.Name)
|
||||||
// Make a new tag in repo1
|
resp := MakeRequest(t, req, http.StatusNotFound)
|
||||||
newTag := "test_tag"
|
assert.Contains(t, resp.Body.String(), "object does not exist [id: , rel_path: no-such]")
|
||||||
err = gitRepo.CreateTag(t.Context(), newTag, commitID)
|
})
|
||||||
require.NoError(t, err)
|
|
||||||
/*** END SETUP ***/
|
|
||||||
|
|
||||||
// not found
|
t.Run("NoRef", func(t *testing.T) {
|
||||||
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/no-such/file.md", user2.Name, repo1.Name)
|
ref := git.RefNameFromBranch(repo1.DefaultBranch)
|
||||||
resp := MakeRequest(t, req, http.StatusNotFound)
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath)
|
||||||
assert.Contains(t, resp.Body.String(), "object does not exist [id: , rel_path: no-such]")
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
contentsResponse := DecodeJSON(t, resp, &api.ContentsResponse{})
|
||||||
|
expectedContentsResponse := getExpectedContentsResponseForContents("master", ref, defaultBranchCommitID)
|
||||||
|
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
||||||
|
})
|
||||||
|
|
||||||
// ref is default ref
|
t.Run("NewlyCreatedBranchSynced", func(t *testing.T) {
|
||||||
ref := repo1.DefaultBranch
|
newBranch := "test_branch"
|
||||||
refType := "branch"
|
err = repo_service.CreateNewBranch(t.Context(), user2, repo1, gitRepo, repo1.DefaultBranch, newBranch)
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
|
require.NoError(t, err)
|
||||||
resp = MakeRequest(t, req, http.StatusOK)
|
|
||||||
contentsResponse := DecodeJSON(t, resp, &api.ContentsResponse{})
|
|
||||||
lastCommit, _ := gitRepo.GetCommitByPath(t.Context(), "README.md")
|
|
||||||
expectedContentsResponse := getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String())
|
|
||||||
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
|
||||||
|
|
||||||
// No ref
|
ref := git.RefNameFromBranch(newBranch)
|
||||||
refType = "branch"
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref.ShortName())
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
resp = MakeRequest(t, req, http.StatusOK)
|
contentsResponse := DecodeJSON(t, resp, &api.ContentsResponse{})
|
||||||
contentsResponse = DecodeJSON(t, resp, &api.ContentsResponse{})
|
branchCommit, _ := gitRepo.GetBranchCommit(t.Context(), ref.ShortName())
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String())
|
lastCommit, _ := branchCommit.GetCommitByPath(t.Context(), gitRepo, "README.md")
|
||||||
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
expectedContentsResponse := getExpectedContentsResponseForContents(ref.ShortName(), ref, lastCommit.ID.String())
|
||||||
|
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
||||||
|
})
|
||||||
|
|
||||||
// ref is the branch we created above in setup
|
t.Run("NewlyCreatedTagSynced", func(t *testing.T) {
|
||||||
ref = newBranch
|
newTag := "test_tag"
|
||||||
refType = "branch"
|
err = gitRepo.CreateTag(t.Context(), newTag, defaultBranchCommitID)
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
|
require.NoError(t, err)
|
||||||
resp = MakeRequest(t, req, http.StatusOK)
|
ref := git.RefNameFromTag(newTag)
|
||||||
contentsResponse = DecodeJSON(t, resp, &api.ContentsResponse{})
|
tagCommit, _ := gitRepo.GetTagCommit(t.Context(), ref.ShortName())
|
||||||
branchCommit, _ := gitRepo.GetBranchCommit(t.Context(), ref)
|
lastCommit, _ := tagCommit.GetCommitByPath(t.Context(), gitRepo, "README.md")
|
||||||
lastCommit, _ = branchCommit.GetCommitByPath(t.Context(), gitRepo, "README.md")
|
expectedContentsResponse := getExpectedContentsResponseForContents(ref.ShortName(), ref, lastCommit.ID.String())
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String())
|
|
||||||
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
|
||||||
|
|
||||||
// ref is the new tag we created above in setup
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref.ShortName())
|
||||||
ref = newTag
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
refType = "tag"
|
contentsResponse := DecodeJSON(t, resp, &api.ContentsResponse{})
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
|
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
||||||
resp = MakeRequest(t, req, http.StatusOK)
|
})
|
||||||
contentsResponse = DecodeJSON(t, resp, &api.ContentsResponse{})
|
|
||||||
tagCommit, _ := gitRepo.GetTagCommit(t.Context(), ref)
|
|
||||||
lastCommit, _ = tagCommit.GetCommitByPath(t.Context(), gitRepo, "README.md")
|
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String())
|
|
||||||
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
|
||||||
|
|
||||||
// ref is a commit
|
t.Run("CommitRef", func(t *testing.T) {
|
||||||
ref = commitID
|
ref := git.RefNameFromCommit(defaultBranchCommitID)
|
||||||
refType = "commit"
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref.ShortName())
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
resp = MakeRequest(t, req, http.StatusOK)
|
contentsResponse := DecodeJSON(t, resp, &api.ContentsResponse{})
|
||||||
contentsResponse = DecodeJSON(t, resp, &api.ContentsResponse{})
|
expectedContentsResponse := getExpectedContentsResponseForContents(ref.ShortName(), ref, defaultBranchCommitID)
|
||||||
expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, commitID)
|
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
||||||
assert.Equal(t, *expectedContentsResponse, *contentsResponse)
|
})
|
||||||
|
|
||||||
// Test file contents a file with a bad ref
|
t.Run("NotExistingRef", func(t *testing.T) {
|
||||||
ref = "badref"
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=not-existing", user2.Name, repo1.Name, treePath)
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
})
|
||||||
|
|
||||||
// Test accessing private ref with user token that does not have access - should fail
|
t.Run("InternalRef", func(t *testing.T) {
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath).
|
// Internal pull ref exists in the test repo but must not be accepted via contents API
|
||||||
AddTokenAuth(token4)
|
assert.True(t, git.IsReferenceExist(t.Context(), gitRepo, "refs/pull/2/head"))
|
||||||
MakeRequest(t, req, http.StatusNotFound)
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, url.QueryEscape("refs/pull/2/head"))
|
||||||
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
})
|
||||||
|
|
||||||
// Test access private ref of owner of token
|
t.Run("Permission", func(t *testing.T) {
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md", user2.Name, repo16.Name).
|
// Test accessing private ref with user token that does not have access - should fail
|
||||||
AddTokenAuth(token2)
|
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath).
|
||||||
MakeRequest(t, req, http.StatusOK)
|
AddTokenAuth(token4)
|
||||||
|
MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
// Test access of org org3 private repo file by owner user2
|
// Test access private ref of owner of token
|
||||||
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath).
|
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md", user2.Name, repo16.Name).
|
||||||
AddTokenAuth(token2)
|
AddTokenAuth(token2)
|
||||||
MakeRequest(t, req, http.StatusOK)
|
MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
// Test access of org org3 private repo file by owner user2
|
||||||
|
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath).
|
||||||
|
AddTokenAuth(token2)
|
||||||
|
MakeRequest(t, req, http.StatusOK)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAPIGetContentsRefFormats(t *testing.T) {
|
func testAPIGetContentsRefFormats(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user