Skip to content

Commit 5fdcb5d

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Fix get reviewers' bug (go-gitea#32415) Fix issues with inconsistent spacing in areas (go-gitea#32607) Refactor markup render system (go-gitea#32589) Style unification for the issue_management area (go-gitea#32605) Enhancing Gitea OAuth2 Provider with Granular Scopes for Resource Access (go-gitea#32573)
2 parents 40de404 + fe49cb0 commit 5fdcb5d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1254
-808
lines changed

models/issues/comment_code.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,12 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
112112
}
113113

114114
var err error
115-
if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
116-
Ctx: ctx,
117-
Repo: issue.Repo,
118-
Links: markup.Links{
119-
Base: issue.Repo.Link(),
120-
},
121-
Metas: issue.Repo.ComposeMetas(ctx),
122-
}, comment.Content); err != nil {
115+
rctx := markup.NewRenderContext(ctx).
116+
WithRepoFacade(issue.Repo).
117+
WithLinks(markup.Links{Base: issue.Repo.Link()}).
118+
WithMetas(issue.Repo.ComposeMetas(ctx))
119+
if comment.RenderedContent, err = markdown.RenderString(rctx,
120+
comment.Content); err != nil {
123121
return nil, err
124122
}
125123
}

models/organization/team_repo.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"code.gitea.io/gitea/models/db"
1010
"code.gitea.io/gitea/models/perm"
1111
repo_model "code.gitea.io/gitea/models/repo"
12+
"code.gitea.io/gitea/models/unit"
1213

1314
"xorm.io/builder"
1415
)
@@ -83,3 +84,16 @@ func GetTeamsWithAccessToRepo(ctx context.Context, orgID, repoID int64, mode per
8384
OrderBy("name").
8485
Find(&teams)
8586
}
87+
88+
// GetTeamsWithAccessToRepoUnit returns all teams in an organization that have given access level to the repository special unit.
89+
func GetTeamsWithAccessToRepoUnit(ctx context.Context, orgID, repoID int64, mode perm.AccessMode, unitType unit.Type) ([]*Team, error) {
90+
teams := make([]*Team, 0, 5)
91+
return teams, db.GetEngine(ctx).Where("team_unit.access_mode >= ?", mode).
92+
Join("INNER", "team_repo", "team_repo.team_id = team.id").
93+
Join("INNER", "team_unit", "team_unit.team_id = team.id").
94+
And("team_repo.org_id = ?", orgID).
95+
And("team_repo.repo_id = ?", repoID).
96+
And("team_unit.type = ?", unitType).
97+
OrderBy("name").
98+
Find(&teams)
99+
}

models/organization/team_repo_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package organization_test
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/models/db"
10+
"code.gitea.io/gitea/models/organization"
11+
"code.gitea.io/gitea/models/perm"
12+
"code.gitea.io/gitea/models/repo"
13+
"code.gitea.io/gitea/models/unit"
14+
"code.gitea.io/gitea/models/unittest"
15+
16+
"github.com/stretchr/testify/assert"
17+
)
18+
19+
func TestGetTeamsWithAccessToRepoUnit(t *testing.T) {
20+
assert.NoError(t, unittest.PrepareTestDatabase())
21+
22+
org41 := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 41})
23+
repo61 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 61})
24+
25+
teams, err := organization.GetTeamsWithAccessToRepoUnit(db.DefaultContext, org41.ID, repo61.ID, perm.AccessModeRead, unit.TypePullRequests)
26+
assert.NoError(t, err)
27+
if assert.Len(t, teams, 2) {
28+
assert.EqualValues(t, 21, teams[0].ID)
29+
assert.EqualValues(t, 22, teams[1].ID)
30+
}
31+
}

models/repo/repo.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -617,10 +617,7 @@ func (repo *Repository) CanEnableEditor() bool {
617617

618618
// DescriptionHTML does special handles to description and return HTML string.
619619
func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML {
620-
desc, err := markup.RenderDescriptionHTML(&markup.RenderContext{
621-
Ctx: ctx,
622-
// Don't use Metas to speedup requests
623-
}, repo.Description)
620+
desc, err := markup.RenderDescriptionHTML(markup.NewRenderContext(ctx), repo.Description)
624621
if err != nil {
625622
log.Error("Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err)
626623
return template.HTML(markup.SanitizeDescription(repo.Description))

models/repo/user_repo.go

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"code.gitea.io/gitea/models/unit"
1212
user_model "code.gitea.io/gitea/models/user"
1313
"code.gitea.io/gitea/modules/container"
14-
api "code.gitea.io/gitea/modules/structs"
1514

1615
"xorm.io/builder"
1716
)
@@ -146,57 +145,6 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
146145
return users, nil
147146
}
148147

149-
// GetReviewers get all users can be requested to review:
150-
// * for private repositories this returns all users that have read access or higher to the repository.
151-
// * for public repositories this returns all users that have read access or higher to the repository,
152-
// all repo watchers and all organization members.
153-
// TODO: may be we should have a busy choice for users to block review request to them.
154-
func GetReviewers(ctx context.Context, repo *Repository, doerID, posterID int64) ([]*user_model.User, error) {
155-
// Get the owner of the repository - this often already pre-cached and if so saves complexity for the following queries
156-
if err := repo.LoadOwner(ctx); err != nil {
157-
return nil, err
158-
}
159-
160-
cond := builder.And(builder.Neq{"`user`.id": posterID}).
161-
And(builder.Eq{"`user`.is_active": true})
162-
163-
if repo.IsPrivate || repo.Owner.Visibility == api.VisibleTypePrivate {
164-
// This a private repository:
165-
// Anyone who can read the repository is a requestable reviewer
166-
167-
cond = cond.And(builder.In("`user`.id",
168-
builder.Select("user_id").From("access").Where(
169-
builder.Eq{"repo_id": repo.ID}.
170-
And(builder.Gte{"mode": perm.AccessModeRead}),
171-
),
172-
))
173-
174-
if repo.Owner.Type == user_model.UserTypeIndividual && repo.Owner.ID != posterID {
175-
// as private *user* repos don't generate an entry in the `access` table,
176-
// the owner of a private repo needs to be explicitly added.
177-
cond = cond.Or(builder.Eq{"`user`.id": repo.Owner.ID})
178-
}
179-
} else {
180-
// This is a "public" repository:
181-
// Any user that has read access, is a watcher or organization member can be requested to review
182-
cond = cond.And(builder.And(builder.In("`user`.id",
183-
builder.Select("user_id").From("access").
184-
Where(builder.Eq{"repo_id": repo.ID}.
185-
And(builder.Gte{"mode": perm.AccessModeRead})),
186-
).Or(builder.In("`user`.id",
187-
builder.Select("user_id").From("watch").
188-
Where(builder.Eq{"repo_id": repo.ID}.
189-
And(builder.In("mode", WatchModeNormal, WatchModeAuto))),
190-
).Or(builder.In("`user`.id",
191-
builder.Select("uid").From("org_user").
192-
Where(builder.Eq{"org_id": repo.OwnerID}),
193-
)))))
194-
}
195-
196-
users := make([]*user_model.User, 0, 8)
197-
return users, db.GetEngine(ctx).Where(cond).OrderBy(user_model.GetOrderByName()).Find(&users)
198-
}
199-
200148
// GetIssuePostersWithSearch returns users with limit of 30 whose username started with prefix that have authored an issue/pull request for the given repository
201149
// If isShowFullName is set to true, also include full name prefix search
202150
func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull bool, search string, isShowFullName bool) ([]*user_model.User, error) {

models/repo/user_repo_test.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,46 +38,3 @@ func TestRepoAssignees(t *testing.T) {
3838
assert.NotContains(t, []int64{users[0].ID, users[1].ID, users[2].ID}, 15)
3939
}
4040
}
41-
42-
func TestRepoGetReviewers(t *testing.T) {
43-
assert.NoError(t, unittest.PrepareTestDatabase())
44-
45-
// test public repo
46-
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
47-
48-
ctx := db.DefaultContext
49-
reviewers, err := repo_model.GetReviewers(ctx, repo1, 2, 2)
50-
assert.NoError(t, err)
51-
if assert.Len(t, reviewers, 3) {
52-
assert.ElementsMatch(t, []int64{1, 4, 11}, []int64{reviewers[0].ID, reviewers[1].ID, reviewers[2].ID})
53-
}
54-
55-
// should include doer if doer is not PR poster.
56-
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 2)
57-
assert.NoError(t, err)
58-
assert.Len(t, reviewers, 3)
59-
60-
// should not include PR poster, if PR poster would be otherwise eligible
61-
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 4)
62-
assert.NoError(t, err)
63-
assert.Len(t, reviewers, 2)
64-
65-
// test private user repo
66-
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
67-
68-
reviewers, err = repo_model.GetReviewers(ctx, repo2, 2, 4)
69-
assert.NoError(t, err)
70-
assert.Len(t, reviewers, 1)
71-
assert.EqualValues(t, reviewers[0].ID, 2)
72-
73-
// test private org repo
74-
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
75-
76-
reviewers, err = repo_model.GetReviewers(ctx, repo3, 2, 1)
77-
assert.NoError(t, err)
78-
assert.Len(t, reviewers, 2)
79-
80-
reviewers, err = repo_model.GetReviewers(ctx, repo3, 2, 2)
81-
assert.NoError(t, err)
82-
assert.Len(t, reviewers, 1)
83-
}

modules/csv/csv.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"bytes"
88
stdcsv "encoding/csv"
99
"io"
10-
"path/filepath"
10+
"path"
1111
"regexp"
1212
"strings"
1313

@@ -53,7 +53,7 @@ func CreateReaderAndDetermineDelimiter(ctx *markup.RenderContext, rd io.Reader)
5353
func determineDelimiter(ctx *markup.RenderContext, data []byte) rune {
5454
extension := ".csv"
5555
if ctx != nil {
56-
extension = strings.ToLower(filepath.Ext(ctx.RelativePath))
56+
extension = strings.ToLower(path.Ext(ctx.RenderOptions.RelativePath))
5757
}
5858

5959
var delimiter rune

modules/csv/csv_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ package csv
55

66
import (
77
"bytes"
8+
"context"
89
"encoding/csv"
910
"io"
1011
"strconv"
1112
"strings"
1213
"testing"
1314

14-
"code.gitea.io/gitea/modules/git"
1515
"code.gitea.io/gitea/modules/markup"
1616
"code.gitea.io/gitea/modules/translation"
1717

@@ -231,10 +231,7 @@ John Doe [email protected] This,note,had,a,lot,of,commas,to,test,delimiters`,
231231
}
232232

233233
for n, c := range cases {
234-
delimiter := determineDelimiter(&markup.RenderContext{
235-
Ctx: git.DefaultContext,
236-
RelativePath: c.filename,
237-
}, []byte(decodeSlashes(t, c.csv)))
234+
delimiter := determineDelimiter(markup.NewRenderContext(context.Background()).WithRelativePath(c.filename), []byte(decodeSlashes(t, c.csv)))
238235
assert.EqualValues(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter)
239236
}
240237
}

modules/markup/asciicast/asciicast.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
4444
func (Renderer) Render(ctx *markup.RenderContext, _ io.Reader, output io.Writer) error {
4545
rawURL := fmt.Sprintf("%s/%s/%s/raw/%s/%s",
4646
setting.AppSubURL,
47-
url.PathEscape(ctx.Metas["user"]),
48-
url.PathEscape(ctx.Metas["repo"]),
49-
ctx.Metas["BranchNameSubURL"],
50-
url.PathEscape(ctx.RelativePath),
47+
url.PathEscape(ctx.RenderOptions.Metas["user"]),
48+
url.PathEscape(ctx.RenderOptions.Metas["repo"]),
49+
ctx.RenderOptions.Metas["BranchNameSubURL"],
50+
url.PathEscape(ctx.RenderOptions.RelativePath),
5151
)
5252
return ctx.RenderInternal.FormatWithSafeAttrs(output, `<div class="%s" %s="%s"></div>`, playerClassName, playerSrcAttr, rawURL)
5353
}

modules/markup/console/console_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
package console
55

66
import (
7+
"context"
78
"strings"
89
"testing"
910

10-
"code.gitea.io/gitea/modules/git"
1111
"code.gitea.io/gitea/modules/markup"
1212

1313
"github.com/stretchr/testify/assert"
@@ -24,8 +24,7 @@ func TestRenderConsole(t *testing.T) {
2424
canRender := render.CanRender("test", strings.NewReader(k))
2525
assert.True(t, canRender)
2626

27-
err := render.Render(&markup.RenderContext{Ctx: git.DefaultContext},
28-
strings.NewReader(k), &buf)
27+
err := render.Render(markup.NewRenderContext(context.Background()), strings.NewReader(k), &buf)
2928
assert.NoError(t, err)
3029
assert.EqualValues(t, v, buf.String())
3130
}

modules/markup/csv/csv.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,10 @@ func (r Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.W
133133
// Check if maxRows or maxSize is reached, and if true, warn.
134134
if (row >= maxRows && maxRows != 0) || (rd.InputOffset() >= maxSize && maxSize != 0) {
135135
warn := `<table class="data-table"><tr><td>`
136-
rawLink := ` <a href="` + ctx.Links.RawLink() + `/` + util.PathEscapeSegments(ctx.RelativePath) + `">`
136+
rawLink := ` <a href="` + ctx.RenderOptions.Links.RawLink() + `/` + util.PathEscapeSegments(ctx.RenderOptions.RelativePath) + `">`
137137

138138
// Try to get the user translation
139-
if locale, ok := ctx.Ctx.Value(translation.ContextKey).(translation.Locale); ok {
139+
if locale, ok := ctx.Value(translation.ContextKey).(translation.Locale); ok {
140140
warn += locale.TrString("repo.file_too_large")
141141
rawLink += locale.TrString("repo.file_view_raw")
142142
} else {

modules/markup/csv/csv_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
package markup
55

66
import (
7+
"context"
78
"strings"
89
"testing"
910

10-
"code.gitea.io/gitea/modules/git"
1111
"code.gitea.io/gitea/modules/markup"
1212

1313
"github.com/stretchr/testify/assert"
@@ -24,8 +24,7 @@ func TestRenderCSV(t *testing.T) {
2424

2525
for k, v := range kases {
2626
var buf strings.Builder
27-
err := render.Render(&markup.RenderContext{Ctx: git.DefaultContext},
28-
strings.NewReader(k), &buf)
27+
err := render.Render(markup.NewRenderContext(context.Background()), strings.NewReader(k), &buf)
2928
assert.NoError(t, err)
3029
assert.EqualValues(t, v, buf.String())
3130
}

modules/markup/external/external.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"runtime"
1313
"strings"
1414

15-
"code.gitea.io/gitea/modules/graceful"
1615
"code.gitea.io/gitea/modules/log"
1716
"code.gitea.io/gitea/modules/markup"
1817
"code.gitea.io/gitea/modules/process"
@@ -80,8 +79,8 @@ func envMark(envName string) string {
8079
func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
8180
var (
8281
command = strings.NewReplacer(
83-
envMark("GITEA_PREFIX_SRC"), ctx.Links.SrcLink(),
84-
envMark("GITEA_PREFIX_RAW"), ctx.Links.RawLink(),
82+
envMark("GITEA_PREFIX_SRC"), ctx.RenderOptions.Links.SrcLink(),
83+
envMark("GITEA_PREFIX_RAW"), ctx.RenderOptions.Links.RawLink(),
8584
).Replace(p.Command)
8685
commands = strings.Fields(command)
8786
args = commands[1:]
@@ -113,22 +112,14 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
113112
args = append(args, f.Name())
114113
}
115114

116-
if ctx.Ctx == nil {
117-
if !setting.IsProd || setting.IsInTesting {
118-
panic("RenderContext did not provide context")
119-
}
120-
log.Warn("RenderContext did not provide context, defaulting to Shutdown context")
121-
ctx.Ctx = graceful.GetManager().ShutdownContext()
122-
}
123-
124-
processCtx, _, finished := process.GetManager().AddContext(ctx.Ctx, fmt.Sprintf("Render [%s] for %s", commands[0], ctx.Links.SrcLink()))
115+
processCtx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("Render [%s] for %s", commands[0], ctx.RenderOptions.Links.SrcLink()))
125116
defer finished()
126117

127118
cmd := exec.CommandContext(processCtx, commands[0], args...)
128119
cmd.Env = append(
129120
os.Environ(),
130-
"GITEA_PREFIX_SRC="+ctx.Links.SrcLink(),
131-
"GITEA_PREFIX_RAW="+ctx.Links.RawLink(),
121+
"GITEA_PREFIX_SRC="+ctx.RenderOptions.Links.SrcLink(),
122+
"GITEA_PREFIX_RAW="+ctx.RenderOptions.Links.RawLink(),
132123
)
133124
if !p.IsInputFile {
134125
cmd.Stdin = input

modules/markup/html_codepreview.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func renderCodeBlock(ctx *RenderContext, node *html.Node) (urlPosStart, urlPosSt
3838
CommitID: node.Data[m[6]:m[7]],
3939
FilePath: node.Data[m[8]:m[9]],
4040
}
41-
if !httplib.IsCurrentGiteaSiteURL(ctx.Ctx, opts.FullURL) {
41+
if !httplib.IsCurrentGiteaSiteURL(ctx, opts.FullURL) {
4242
return 0, 0, "", nil
4343
}
4444
u, err := url.Parse(opts.FilePath)
@@ -51,7 +51,7 @@ func renderCodeBlock(ctx *RenderContext, node *html.Node) (urlPosStart, urlPosSt
5151
lineStart, _ := strconv.Atoi(strings.TrimPrefix(lineStartStr, "L"))
5252
lineStop, _ := strconv.Atoi(strings.TrimPrefix(lineStopStr, "L"))
5353
opts.LineStart, opts.LineStop = lineStart, lineStop
54-
h, err := DefaultProcessorHelper.RenderRepoFileCodePreview(ctx.Ctx, opts)
54+
h, err := DefaultProcessorHelper.RenderRepoFileCodePreview(ctx, opts)
5555
return m[0], m[1], h, err
5656
}
5757

0 commit comments

Comments
 (0)