code.gitea.io/gitea@v1.21.7/tests/integration/api_repo_get_contents_test.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "io" 8 "net/http" 9 "net/url" 10 "testing" 11 12 auth_model "code.gitea.io/gitea/models/auth" 13 repo_model "code.gitea.io/gitea/models/repo" 14 "code.gitea.io/gitea/models/unittest" 15 user_model "code.gitea.io/gitea/models/user" 16 "code.gitea.io/gitea/modules/git" 17 "code.gitea.io/gitea/modules/setting" 18 api "code.gitea.io/gitea/modules/structs" 19 repo_service "code.gitea.io/gitea/services/repository" 20 21 "github.com/stretchr/testify/assert" 22 ) 23 24 func getExpectedContentsResponseForContents(ref, refType, lastCommitSHA string) *api.ContentsResponse { 25 treePath := "README.md" 26 sha := "4b4851ad51df6a7d9f25c979345979eaeb5b349f" 27 encoding := "base64" 28 content := "IyByZXBvMQoKRGVzY3JpcHRpb24gZm9yIHJlcG8x" 29 selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=" + ref 30 htmlURL := setting.AppURL + "user2/repo1/src/" + refType + "/" + ref + "/" + treePath 31 gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha 32 downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath 33 return &api.ContentsResponse{ 34 Name: treePath, 35 Path: treePath, 36 SHA: sha, 37 LastCommitSHA: lastCommitSHA, 38 Type: "file", 39 Size: 30, 40 Encoding: &encoding, 41 Content: &content, 42 URL: &selfURL, 43 HTMLURL: &htmlURL, 44 GitURL: &gitURL, 45 DownloadURL: &downloadURL, 46 Links: &api.FileLinksResponse{ 47 Self: &selfURL, 48 GitURL: &gitURL, 49 HTMLURL: &htmlURL, 50 }, 51 } 52 } 53 54 func TestAPIGetContents(t *testing.T) { 55 onGiteaRun(t, testAPIGetContents) 56 } 57 58 func testAPIGetContents(t *testing.T, u *url.URL) { 59 /*** SETUP ***/ 60 user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 61 org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org 62 user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos 63 repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo 64 repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo 65 repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo 66 treePath := "README.md" 67 68 // Get user2's token 69 session := loginUser(t, user2.Name) 70 token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 71 // Get user4's token 72 session = loginUser(t, user4.Name) 73 token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) 74 75 // Get the commit ID of the default branch 76 gitRepo, err := git.OpenRepository(git.DefaultContext, repo1.RepoPath()) 77 assert.NoError(t, err) 78 defer gitRepo.Close() 79 80 // Make a new branch in repo1 81 newBranch := "test_branch" 82 err = repo_service.CreateNewBranch(git.DefaultContext, user2, repo1, gitRepo, repo1.DefaultBranch, newBranch) 83 assert.NoError(t, err) 84 85 commitID, err := gitRepo.GetBranchCommitID(repo1.DefaultBranch) 86 assert.NoError(t, err) 87 // Make a new tag in repo1 88 newTag := "test_tag" 89 err = gitRepo.CreateTag(newTag, commitID) 90 assert.NoError(t, err) 91 /*** END SETUP ***/ 92 93 // ref is default ref 94 ref := repo1.DefaultBranch 95 refType := "branch" 96 req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref) 97 resp := MakeRequest(t, req, http.StatusOK) 98 var contentsResponse api.ContentsResponse 99 DecodeJSON(t, resp, &contentsResponse) 100 assert.NotNil(t, contentsResponse) 101 lastCommit, _ := gitRepo.GetCommitByPath("README.md") 102 expectedContentsResponse := getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) 103 assert.EqualValues(t, *expectedContentsResponse, contentsResponse) 104 105 // No ref 106 refType = "branch" 107 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath) 108 resp = MakeRequest(t, req, http.StatusOK) 109 DecodeJSON(t, resp, &contentsResponse) 110 assert.NotNil(t, contentsResponse) 111 expectedContentsResponse = getExpectedContentsResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String()) 112 assert.EqualValues(t, *expectedContentsResponse, contentsResponse) 113 114 // ref is the branch we created above in setup 115 ref = newBranch 116 refType = "branch" 117 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref) 118 resp = MakeRequest(t, req, http.StatusOK) 119 DecodeJSON(t, resp, &contentsResponse) 120 assert.NotNil(t, contentsResponse) 121 branchCommit, _ := gitRepo.GetBranchCommit(ref) 122 lastCommit, _ = branchCommit.GetCommitByPath("README.md") 123 expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) 124 assert.EqualValues(t, *expectedContentsResponse, contentsResponse) 125 126 // ref is the new tag we created above in setup 127 ref = newTag 128 refType = "tag" 129 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref) 130 resp = MakeRequest(t, req, http.StatusOK) 131 DecodeJSON(t, resp, &contentsResponse) 132 assert.NotNil(t, contentsResponse) 133 tagCommit, _ := gitRepo.GetTagCommit(ref) 134 lastCommit, _ = tagCommit.GetCommitByPath("README.md") 135 expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) 136 assert.EqualValues(t, *expectedContentsResponse, contentsResponse) 137 138 // ref is a commit 139 ref = commitID 140 refType = "commit" 141 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref) 142 resp = MakeRequest(t, req, http.StatusOK) 143 DecodeJSON(t, resp, &contentsResponse) 144 assert.NotNil(t, contentsResponse) 145 expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, commitID) 146 assert.EqualValues(t, *expectedContentsResponse, contentsResponse) 147 148 // Test file contents a file with a bad ref 149 ref = "badref" 150 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?ref=%s", user2.Name, repo1.Name, treePath, ref) 151 MakeRequest(t, req, http.StatusNotFound) 152 153 // Test accessing private ref with user token that does not have access - should fail 154 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token4) 155 MakeRequest(t, req, http.StatusNotFound) 156 157 // Test access private ref of owner of token 158 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md?token=%s", user2.Name, repo16.Name, token2) 159 MakeRequest(t, req, http.StatusOK) 160 161 // Test access of org org3 private repo file by owner user2 162 req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", org3.Name, repo3.Name, treePath, token2) 163 MakeRequest(t, req, http.StatusOK) 164 } 165 166 func TestAPIGetContentsRefFormats(t *testing.T) { 167 onGiteaRun(t, func(t *testing.T, u *url.URL) { 168 file := "README.md" 169 sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d" 170 content := "# repo1\n\nDescription for repo1" 171 172 noRef := setting.AppURL + "api/v1/repos/user2/repo1/raw/" + file 173 refInPath := setting.AppURL + "api/v1/repos/user2/repo1/raw/" + sha + "/" + file 174 refInQuery := setting.AppURL + "api/v1/repos/user2/repo1/raw/" + file + "?ref=" + sha 175 176 resp := MakeRequest(t, NewRequest(t, http.MethodGet, noRef), http.StatusOK) 177 raw, err := io.ReadAll(resp.Body) 178 assert.NoError(t, err) 179 assert.EqualValues(t, content, string(raw)) 180 181 resp = MakeRequest(t, NewRequest(t, http.MethodGet, refInPath), http.StatusOK) 182 raw, err = io.ReadAll(resp.Body) 183 assert.NoError(t, err) 184 assert.EqualValues(t, content, string(raw)) 185 186 resp = MakeRequest(t, NewRequest(t, http.MethodGet, refInQuery), http.StatusOK) 187 raw, err = io.ReadAll(resp.Body) 188 assert.NoError(t, err) 189 assert.EqualValues(t, content, string(raw)) 190 }) 191 }