mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-23 16:44:41 +02:00
fix(feed): hide release notes in tags feed without releases access (#39944)
The tags feed (`tags.rss` / `tags.atom`) lives in the tags route group, which only requires code read access, yet it lists every published release next to the plain tags and includes each release's title and rendered note. The releases page and `releases.rss` require releases read access, and the tags page only shows tag names to users without it, so the feed is the one place that leaks. A team member granted Code but not Releases on a private repo, or anyone on a public repo whose Releases unit is disabled, can read all release notes this way. I noticed it while comparing the feed routes with the tags template. When the doer cannot read releases, the feed now lists releases as plain tags, linking to `/src/tag/` like the tags page does.
This commit is contained in:
1 parent
4bbe1b918a
commit
269b116b1b
2 files changed
+34
-13
No files matched your search
+16
-13
@@ -15,6 +15,7 @@ import (
|
||||
activities_model "gitea.dev/models/activities"
|
||||
"gitea.dev/models/renderhelper"
|
||||
repo_model "gitea.dev/models/repo"
|
||||
"gitea.dev/models/unit"
|
||||
"gitea.dev/modules/markup"
|
||||
"gitea.dev/modules/markup/markdown"
|
||||
"gitea.dev/modules/setting"
|
||||
@@ -276,27 +277,29 @@ func GetFeedType(name string, req *http.Request) (showFeed bool, feedType string
|
||||
|
||||
// feedActionsToFeedItems convert gitea's Repo's Releases to feeds Item
|
||||
func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release) (items []*feeds.Item, err error) {
|
||||
canReadReleases := ctx.Repo.Permission.CanRead(unit.TypeReleases)
|
||||
for _, rel := range releases {
|
||||
err := rel.LoadAttributes(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var title string
|
||||
var content template.HTML
|
||||
|
||||
if rel.IsTag {
|
||||
title = rel.TagName
|
||||
} else {
|
||||
title = rel.Title
|
||||
}
|
||||
|
||||
title := rel.TagName
|
||||
link := &feeds.Link{Href: rel.HTMLURL()}
|
||||
rctx := renderhelper.NewRenderContextRepoComment(ctx, rel.Repo).WithUseAbsoluteLink(true)
|
||||
content, err = markdown.RenderString(rctx,
|
||||
rel.Note)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
if !canReadReleases {
|
||||
// the tags feed only requires code access, so list releases as plain tags like the tags page does
|
||||
link.Href = rel.Repo.HTMLURL() + "/src/tag/" + util.PathEscapeSegments(rel.TagName)
|
||||
} else {
|
||||
if !rel.IsTag {
|
||||
title = rel.Title
|
||||
}
|
||||
rctx := renderhelper.NewRenderContextRepoComment(ctx, rel.Repo).WithUseAbsoluteLink(true)
|
||||
content, err = markdown.RenderString(rctx, rel.Note)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
items = append(items, &feeds.Item{
|
||||
|
||||
@@ -9,9 +9,14 @@ import (
|
||||
"testing"
|
||||
|
||||
auth_model "gitea.dev/models/auth"
|
||||
repo_model "gitea.dev/models/repo"
|
||||
unit_model "gitea.dev/models/unit"
|
||||
"gitea.dev/models/unittest"
|
||||
repo_service "gitea.dev/services/repository"
|
||||
"gitea.dev/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFeedRepo(t *testing.T) {
|
||||
@@ -33,6 +38,19 @@ func TestFeedRepo(t *testing.T) {
|
||||
assert.Equal(t, "issue5", rss.Channel.Items[0].Description)
|
||||
assert.NotEmpty(t, rss.Channel.Items[0].PubDate)
|
||||
})
|
||||
|
||||
t.Run("TagsWithoutReleasesAccess", func(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
require.NoError(t, repo_service.UpdateRepositoryUnits(t.Context(), repo, nil, []unit_model.Type{unit_model.TypeReleases}))
|
||||
|
||||
resp := MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/tags.rss"), http.StatusOK)
|
||||
data := resp.Body.String()
|
||||
assert.Contains(t, data, "/user2/repo1/src/tag/v1.0")
|
||||
assert.NotContains(t, data, "pre-release")
|
||||
assert.NotContains(t, data, "some text for a pre release")
|
||||
})
|
||||
}
|
||||
|
||||
// TestFeedRepoContentTokenScopes ensures repository feed endpoints enforce the
|
||||
|
||||
Reference in new issue
Block a user