Skip to content

Commit cd96dee

Browse files
richmahntechknowlogick
authored andcommitted
Fixes #7292 - API File Contents bug (#7301)
1 parent 738285a commit cd96dee

17 files changed

+961
-333
lines changed

integrations/api_repo_file_content_test.go

Lines changed: 0 additions & 117 deletions
This file was deleted.

integrations/api_repo_file_create_test.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,29 @@ func getCreateFileOptions() api.CreateFileOptions {
4444

4545
func getExpectedFileResponseForCreate(commitID, treePath string) *api.FileResponse {
4646
sha := "a635aa942442ddfdba07468cf9661c08fbdf0ebf"
47+
encoding := "base64"
48+
content := "VGhpcyBpcyBuZXcgdGV4dA=="
49+
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=master"
50+
htmlURL := setting.AppURL + "user2/repo1/src/branch/master/" + treePath
51+
gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha
52+
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
4753
return &api.FileResponse{
48-
Content: &api.FileContentResponse{
54+
Content: &api.ContentsResponse{
4955
Name: filepath.Base(treePath),
5056
Path: treePath,
5157
SHA: sha,
5258
Size: 16,
53-
URL: setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath,
54-
HTMLURL: setting.AppURL + "user2/repo1/blob/master/" + treePath,
55-
GitURL: setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha,
56-
DownloadURL: setting.AppURL + "user2/repo1/raw/branch/master/" + treePath,
57-
Type: "blob",
59+
Type: "file",
60+
Encoding: &encoding,
61+
Content: &content,
62+
URL: &selfURL,
63+
HTMLURL: &htmlURL,
64+
GitURL: &gitURL,
65+
DownloadURL: &downloadURL,
5866
Links: &api.FileLinksResponse{
59-
Self: setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath,
60-
GitURL: setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha,
61-
HTMLURL: setting.AppURL + "user2/repo1/blob/master/" + treePath,
67+
Self: &selfURL,
68+
GitURL: &gitURL,
69+
HTMLURL: &htmlURL,
6270
},
6371
},
6472
Commit: &api.FileCommitResponse{
@@ -145,11 +153,11 @@ func TestAPICreateFile(t *testing.T) {
145153
var fileResponse api.FileResponse
146154
DecodeJSON(t, resp, &fileResponse)
147155
expectedSHA := "a635aa942442ddfdba07468cf9661c08fbdf0ebf"
148-
expectedHTMLURL := fmt.Sprintf(setting.AppURL+"user2/repo1/blob/new_branch/new/file%d.txt", fileID)
156+
expectedHTMLURL := fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/new_branch/new/file%d.txt", fileID)
149157
expectedDownloadURL := fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/new_branch/new/file%d.txt", fileID)
150158
assert.EqualValues(t, expectedSHA, fileResponse.Content.SHA)
151-
assert.EqualValues(t, expectedHTMLURL, fileResponse.Content.HTMLURL)
152-
assert.EqualValues(t, expectedDownloadURL, fileResponse.Content.DownloadURL)
159+
assert.EqualValues(t, expectedHTMLURL, *fileResponse.Content.HTMLURL)
160+
assert.EqualValues(t, expectedDownloadURL, *fileResponse.Content.DownloadURL)
153161
assert.EqualValues(t, createFileOptions.Message+"\n", fileResponse.Commit.Message)
154162

155163
// Test creating a file without a message

integrations/api_repo_file_update_test.go

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,29 @@ func getUpdateFileOptions() *api.UpdateFileOptions {
4747

4848
func getExpectedFileResponseForUpdate(commitID, treePath string) *api.FileResponse {
4949
sha := "08bd14b2e2852529157324de9c226b3364e76136"
50+
encoding := "base64"
51+
content := "VGhpcyBpcyB1cGRhdGVkIHRleHQ="
52+
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=master"
53+
htmlURL := setting.AppURL + "user2/repo1/src/branch/master/" + treePath
54+
gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha
55+
downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath
5056
return &api.FileResponse{
51-
Content: &api.FileContentResponse{
57+
Content: &api.ContentsResponse{
5258
Name: filepath.Base(treePath),
5359
Path: treePath,
5460
SHA: sha,
61+
Type: "file",
5562
Size: 20,
56-
URL: setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath,
57-
HTMLURL: setting.AppURL + "user2/repo1/blob/master/" + treePath,
58-
GitURL: setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha,
59-
DownloadURL: setting.AppURL + "user2/repo1/raw/branch/master/" + treePath,
60-
Type: "blob",
63+
Encoding: &encoding,
64+
Content: &content,
65+
URL: &selfURL,
66+
HTMLURL: &htmlURL,
67+
GitURL: &gitURL,
68+
DownloadURL: &downloadURL,
6169
Links: &api.FileLinksResponse{
62-
Self: setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath,
63-
GitURL: setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha,
64-
HTMLURL: setting.AppURL + "user2/repo1/blob/master/" + treePath,
70+
Self: &selfURL,
71+
GitURL: &gitURL,
72+
HTMLURL: &htmlURL,
6573
},
6674
},
6775
Commit: &api.FileCommitResponse{
@@ -150,11 +158,11 @@ func TestAPIUpdateFile(t *testing.T) {
150158
var fileResponse api.FileResponse
151159
DecodeJSON(t, resp, &fileResponse)
152160
expectedSHA := "08bd14b2e2852529157324de9c226b3364e76136"
153-
expectedHTMLURL := fmt.Sprintf(setting.AppURL+"user2/repo1/blob/new_branch/update/file%d.txt", fileID)
161+
expectedHTMLURL := fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/new_branch/update/file%d.txt", fileID)
154162
expectedDownloadURL := fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/new_branch/update/file%d.txt", fileID)
155163
assert.EqualValues(t, expectedSHA, fileResponse.Content.SHA)
156-
assert.EqualValues(t, expectedHTMLURL, fileResponse.Content.HTMLURL)
157-
assert.EqualValues(t, expectedDownloadURL, fileResponse.Content.DownloadURL)
164+
assert.EqualValues(t, expectedHTMLURL, *fileResponse.Content.HTMLURL)
165+
assert.EqualValues(t, expectedDownloadURL, *fileResponse.Content.DownloadURL)
158166
assert.EqualValues(t, updateFileOptions.Message+"\n", fileResponse.Commit.Message)
159167

160168
// Test updating a file and renaming it
@@ -170,11 +178,11 @@ func TestAPIUpdateFile(t *testing.T) {
170178
resp = session.MakeRequest(t, req, http.StatusOK)
171179
DecodeJSON(t, resp, &fileResponse)
172180
expectedSHA = "08bd14b2e2852529157324de9c226b3364e76136"
173-
expectedHTMLURL = fmt.Sprintf(setting.AppURL+"user2/repo1/blob/master/rename/update/file%d.txt", fileID)
181+
expectedHTMLURL = fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/master/rename/update/file%d.txt", fileID)
174182
expectedDownloadURL = fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/master/rename/update/file%d.txt", fileID)
175183
assert.EqualValues(t, expectedSHA, fileResponse.Content.SHA)
176-
assert.EqualValues(t, expectedHTMLURL, fileResponse.Content.HTMLURL)
177-
assert.EqualValues(t, expectedDownloadURL, fileResponse.Content.DownloadURL)
184+
assert.EqualValues(t, expectedHTMLURL, *fileResponse.Content.HTMLURL)
185+
assert.EqualValues(t, expectedDownloadURL, *fileResponse.Content.DownloadURL)
178186

179187
// Test updating a file without a message
180188
updateFileOptions = getUpdateFileOptions()
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package integrations
6+
7+
import (
8+
"net/http"
9+
"net/url"
10+
"path/filepath"
11+
"testing"
12+
13+
"code.gitea.io/gitea/models"
14+
"code.gitea.io/gitea/modules/context"
15+
"code.gitea.io/gitea/modules/git"
16+
"code.gitea.io/gitea/modules/setting"
17+
api "code.gitea.io/gitea/modules/structs"
18+
19+
"github.com/stretchr/testify/assert"
20+
)
21+
22+
func getExpectedContentsListResponseForContents(ref, refType string) []*api.ContentsResponse {
23+
treePath := "README.md"
24+
sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f"
25+
selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=" + ref
26+
htmlURL := setting.AppURL + "user2/repo1/src/" + refType + "/" + ref + "/" + treePath
27+
gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha
28+
downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath
29+
return []*api.ContentsResponse{
30+
{
31+
Name: filepath.Base(treePath),
32+
Path: treePath,
33+
SHA: sha,
34+
Type: "file",
35+
Size: 30,
36+
URL: &selfURL,
37+
HTMLURL: &htmlURL,
38+
GitURL: &gitURL,
39+
DownloadURL: &downloadURL,
40+
Links: &api.FileLinksResponse{
41+
Self: &selfURL,
42+
GitURL: &gitURL,
43+
HTMLURL: &htmlURL,
44+
},
45+
},
46+
}
47+
}
48+
49+
func TestAPIGetContentsList(t *testing.T) {
50+
onGiteaRun(t, testAPIGetContentsList)
51+
}
52+
53+
func testAPIGetContentsList(t *testing.T, u *url.URL) {
54+
/*** SETUP ***/
55+
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) // owner of the repo1 & repo16
56+
user3 := models.AssertExistsAndLoadBean(t, &models.User{ID: 3}).(*models.User) // owner of the repo3, is an org
57+
user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 4}).(*models.User) // owner of neither repos
58+
repo1 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) // public repo
59+
repo3 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository) // public repo
60+
repo16 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository) // private repo
61+
treePath := "" // root dir
62+
63+
// Get user2's token
64+
session := loginUser(t, user2.Name)
65+
token2 := getTokenForLoggedInUser(t, session)
66+
session = emptyTestSession(t)
67+
// Get user4's token
68+
session = loginUser(t, user4.Name)
69+
token4 := getTokenForLoggedInUser(t, session)
70+
session = emptyTestSession(t)
71+
72+
// Make a new branch in repo1
73+
newBranch := "test_branch"
74+
repo1.CreateNewBranch(user2, repo1.DefaultBranch, newBranch)
75+
// Get the commit ID of the default branch
76+
gitRepo, _ := git.OpenRepository(repo1.RepoPath())
77+
commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch)
78+
// Make a new tag in repo1
79+
newTag := "test_tag"
80+
gitRepo.CreateTag(newTag, commitID)
81+
/*** END SETUP ***/
82+
83+
// ref is default ref
84+
ref := repo1.DefaultBranch
85+
refType := "branch"
86+
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
87+
resp := session.MakeRequest(t, req, http.StatusOK)
88+
var contentsListResponse []*api.ContentsResponse
89+
DecodeJSON(t, resp, &contentsListResponse)
90+
assert.NotNil(t, contentsListResponse)
91+
expectedContentsListResponse := getExpectedContentsListResponseForContents(ref, refType)
92+
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
93+
94+
// No ref
95+
refType = "branch"
96+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath)
97+
resp = session.MakeRequest(t, req, http.StatusOK)
98+
DecodeJSON(t, resp, &contentsListResponse)
99+
assert.NotNil(t, contentsListResponse)
100+
expectedContentsListResponse = getExpectedContentsListResponseForContents(repo1.DefaultBranch, refType)
101+
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
102+
103+
// ref is the branch we created above in setup
104+
ref = newBranch
105+
refType = "branch"
106+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
107+
resp = session.MakeRequest(t, req, http.StatusOK)
108+
DecodeJSON(t, resp, &contentsListResponse)
109+
assert.NotNil(t, contentsListResponse)
110+
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType)
111+
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
112+
113+
// ref is the new tag we created above in setup
114+
ref = newTag
115+
refType = "tag"
116+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
117+
resp = session.MakeRequest(t, req, http.StatusOK)
118+
DecodeJSON(t, resp, &contentsListResponse)
119+
assert.NotNil(t, contentsListResponse)
120+
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType)
121+
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
122+
123+
// ref is a commit
124+
ref = commitID
125+
refType = "commit"
126+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
127+
resp = session.MakeRequest(t, req, http.StatusOK)
128+
DecodeJSON(t, resp, &contentsListResponse)
129+
assert.NotNil(t, contentsListResponse)
130+
expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType)
131+
assert.EqualValues(t, expectedContentsListResponse, contentsListResponse)
132+
133+
// Test file contents a file with a bad ref
134+
ref = "badref"
135+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref)
136+
resp = session.MakeRequest(t, req, http.StatusInternalServerError)
137+
expectedAPIError := context.APIError{
138+
Message: "object does not exist [id: " + ref + ", rel_path: ]",
139+
URL: setting.API.SwaggerURL,
140+
}
141+
var apiError context.APIError
142+
DecodeJSON(t, resp, &apiError)
143+
assert.Equal(t, expectedAPIError, apiError)
144+
145+
// Test accessing private ref with user token that does not have access - should fail
146+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token4)
147+
session.MakeRequest(t, req, http.StatusNotFound)
148+
149+
// Test access private ref of owner of token
150+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md?token=%s", user2.Name, repo16.Name, token2)
151+
session.MakeRequest(t, req, http.StatusOK)
152+
153+
// Test access of org user3 private repo file by owner user2
154+
req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", user3.Name, repo3.Name, treePath, token2)
155+
session.MakeRequest(t, req, http.StatusOK)
156+
}

0 commit comments

Comments
 (0)