From 4e824a735ea9290f75f57d1211d1b7e8c4e9dda2 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 1 Oct 2023 19:54:11 +0800 Subject: [PATCH] Allow get release download files and lfs files with oauth2 token format (#26430) (#27379) Backport #26430 by @lunny Fix #26165 Fix #25257 Co-authored-by: Lunny Xiao --- models/fixtures/attachment.yml | 13 +++++++++++++ models/fixtures/release.yml | 14 ++++++++++++++ routers/web/web.go | 8 +++----- services/auth/oauth2.go | 4 +++- .../user2/repo2.git/refs/tags/v1.1 | 1 + tests/integration/release_test.go | 17 +++++++++++++++++ tests/test_utils.go | 14 ++++++++++++++ .../a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22 | 1 + 8 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 tests/gitea-repositories-meta/user2/repo2.git/refs/tags/v1.1 create mode 100644 tests/testdata/data/attachments/a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22 diff --git a/models/fixtures/attachment.yml b/models/fixtures/attachment.yml index 9ad43fa2b7..7882d8bff2 100644 --- a/models/fixtures/attachment.yml +++ b/models/fixtures/attachment.yml @@ -140,3 +140,16 @@ download_count: 0 size: 0 created_unix: 946684800 + +- + id: 12 + uuid: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22 + repo_id: 2 + issue_id: 0 + release_id: 11 + uploader_id: 2 + comment_id: 0 + name: README.md + download_count: 0 + size: 0 + created_unix: 946684800 diff --git a/models/fixtures/release.yml b/models/fixtures/release.yml index 4ed7df440d..372a79509f 100644 --- a/models/fixtures/release.yml +++ b/models/fixtures/release.yml @@ -136,3 +136,17 @@ is_prerelease: false is_tag: false created_unix: 946684803 + +- id: 11 + repo_id: 2 + publisher_id: 2 + tag_name: "v1.1" + lower_tag_name: "v1.1" + target: "" + title: "v1.1" + sha1: "205ac761f3326a7ebe416e8673760016450b5cec" + num_commits: 2 + is_draft: false + is_prerelease: false + is_tag: false + created_unix: 946684803 diff --git a/routers/web/web.go b/routers/web/web.go index 99862505b4..2154838726 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -978,9 +978,6 @@ func registerRoutes(m *web.Route) { }, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false)) }, ignSignIn, context_service.UserAssignmentWeb(), context.OrgAssignment()) // for "/{username}/-" (packages, projects, code) - // ***** Release Attachment Download without Signin - m.Get("/{username}/{reponame}/releases/download/{vTag}/{fileName}", ignSignIn, context.RepoAssignment, repo.MustBeNotEmpty, repo.RedirectDownload) - m.Group("/{username}/{reponame}", func() { m.Group("/settings", func() { m.Group("", func() { @@ -1240,8 +1237,9 @@ func registerRoutes(m *web.Route) { m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS) m.Get(".atom", feedEnabled, repo.ReleasesFeedAtom) }, ctxDataSet("EnableFeed", setting.Other.EnableFeed), - repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag, true)) - m.Get("/releases/attachments/{uuid}", repo.MustBeNotEmpty, reqRepoReleaseReader, repo.GetAttachment) + repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefTag, true)) + m.Get("/releases/attachments/{uuid}", repo.MustBeNotEmpty, repo.GetAttachment) + m.Get("/releases/download/{vTag}/{fileName}", repo.MustBeNotEmpty, repo.RedirectDownload) m.Group("/releases", func() { m.Get("/new", repo.NewRelease) m.Post("/new", web.Bind(forms.NewReleaseForm{}), repo.NewReleasePost) diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go index 6572d661e8..38b705cc5b 100644 --- a/services/auth/oauth2.go +++ b/services/auth/oauth2.go @@ -125,7 +125,9 @@ func (o *OAuth2) userIDFromToken(ctx context.Context, tokenSHA string, store Dat // If verification is successful returns an existing user object. // Returns nil if verification fails. func (o *OAuth2) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { - if !middleware.IsAPIPath(req) && !isAttachmentDownload(req) && !isAuthenticatedTokenRequest(req) { + // These paths are not API paths, but we still want to check for tokens because they maybe in the API returned URLs + if !middleware.IsAPIPath(req) && !isAttachmentDownload(req) && !isAuthenticatedTokenRequest(req) && + !gitRawReleasePathRe.MatchString(req.URL.Path) { return nil, nil } diff --git a/tests/gitea-repositories-meta/user2/repo2.git/refs/tags/v1.1 b/tests/gitea-repositories-meta/user2/repo2.git/refs/tags/v1.1 new file mode 100644 index 0000000000..334d09ca02 --- /dev/null +++ b/tests/gitea-repositories-meta/user2/repo2.git/refs/tags/v1.1 @@ -0,0 +1 @@ +1032bbf17fbc0d9c95bb5418dabe8f8c99278700 diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go index 8de761ea6c..42d0d00e78 100644 --- a/tests/integration/release_test.go +++ b/tests/integration/release_test.go @@ -239,3 +239,20 @@ func TestViewTagsList(t *testing.T) { assert.EqualValues(t, []string{"v1.0", "delete-tag", "v1.1"}, tagNames) } + +func TestDownloadReleaseAttachment(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + tests.PrepareAttachmentsStorage(t) + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + + url := repo.Link() + "/releases/download/v1.1/README.md" + + req := NewRequest(t, "GET", url) + MakeRequest(t, req, http.StatusNotFound) + + req = NewRequest(t, "GET", url) + session := loginUser(t, "user2") + session.MakeRequest(t, req, http.StatusOK) +} diff --git a/tests/test_utils.go b/tests/test_utils.go index 089b4dce1c..50049e73f0 100644 --- a/tests/test_utils.go +++ b/tests/test_utils.go @@ -179,6 +179,20 @@ func InitTest(requireGitea bool) { routers.InitWebInstalled(graceful.GetManager().HammerContext()) } +func PrepareAttachmentsStorage(t testing.TB) { + // prepare attachments directory and files + assert.NoError(t, storage.Clean(storage.Attachments)) + + s, err := storage.NewStorage(setting.LocalStorageType, &setting.Storage{ + Path: filepath.Join(filepath.Dir(setting.AppPath), "tests", "testdata", "data", "attachments"), + }) + assert.NoError(t, err) + assert.NoError(t, s.IterateObjects("", func(p string, obj storage.Object) error { + _, err = storage.Copy(storage.Attachments, p, s, p) + return err + })) +} + func PrepareTestEnv(t testing.TB, skip ...int) func() { t.Helper() ourSkip := 1 diff --git a/tests/testdata/data/attachments/a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22 b/tests/testdata/data/attachments/a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22 new file mode 100644 index 0000000000..96fc98807f --- /dev/null +++ b/tests/testdata/data/attachments/a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a22 @@ -0,0 +1 @@ +# This is a release README