Skip to content

Commit 8ba4b5e

Browse files
authored
Merge branch 'main' into oauth-client-type
2 parents 8290420 + 4eeea7b commit 8ba4b5e

File tree

16 files changed

+204
-54
lines changed

16 files changed

+204
-54
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b
77
code.gitea.io/sdk/gitea v0.15.1
88
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
9-
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb
9+
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681
1010
gitea.com/go-chi/cache v0.2.0
1111
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
1212
gitea.com/go-chi/session v0.0.0-20211218221615-e3605d8b28b8

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcig
8181
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
8282
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
8383
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
84-
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb h1:Yy0Bxzc8R2wxiwXoG/rECGplJUSpXqCsog9PuJFgiHs=
85-
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
84+
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681 h1:MMSPgnVULVwV9kEBgvyEUhC9v/uviZ55hPJEMjpbNR4=
85+
gitea.com/go-chi/binding v0.0.0-20221013104517-b29891619681/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
8686
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0=
8787
gitea.com/go-chi/cache v0.2.0 h1:E0npuTfDW6CT1yD8NMDVc1SK6IeRjfmRL2zlEsCEd7w=
8888
gitea.com/go-chi/cache v0.2.0/go.mod h1:iQlVK2aKTZ/rE9UcHyz9pQWGvdP9i1eI2spOpzgCrtE=

models/packages/container/search.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ type ImageTagsSearchOptions struct {
165165
PackageID int64
166166
Query string
167167
IsTagged bool
168+
Sort packages.VersionSort
168169
db.Paginator
169170
}
170171

@@ -195,12 +196,26 @@ func (opts *ImageTagsSearchOptions) toConds() builder.Cond {
195196
return cond
196197
}
197198

199+
func (opts *ImageTagsSearchOptions) configureOrderBy(e db.Engine) {
200+
switch opts.Sort {
201+
case packages.SortVersionDesc:
202+
e.Desc("package_version.version")
203+
case packages.SortVersionAsc:
204+
e.Asc("package_version.version")
205+
case packages.SortCreatedAsc:
206+
e.Asc("package_version.created_unix")
207+
default:
208+
e.Desc("package_version.created_unix")
209+
}
210+
}
211+
198212
// SearchImageTags gets a sorted list of the tags of an image
199213
func SearchImageTags(ctx context.Context, opts *ImageTagsSearchOptions) ([]*packages.PackageVersion, int64, error) {
200214
sess := db.GetEngine(ctx).
201215
Join("INNER", "package", "package.id = package_version.package_id").
202-
Where(opts.toConds()).
203-
Desc("package_version.created_unix")
216+
Where(opts.toConds())
217+
218+
opts.configureOrderBy(sess)
204219

205220
if opts.Paginator != nil {
206221
sess = db.SetSessionPagination(sess, opts)

models/packages/package_version.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,17 @@ type SearchValue struct {
163163
ExactMatch bool
164164
}
165165

166+
type VersionSort = string
167+
168+
const (
169+
SortNameAsc VersionSort = "name_asc"
170+
SortNameDesc VersionSort = "name_desc"
171+
SortVersionAsc VersionSort = "version_asc"
172+
SortVersionDesc VersionSort = "version_desc"
173+
SortCreatedAsc VersionSort = "created_asc"
174+
SortCreatedDesc VersionSort = "created_desc"
175+
)
176+
166177
// PackageSearchOptions are options for SearchXXX methods
167178
// Besides IsInternal are all fields optional and are not used if they have their default value (nil, "", 0)
168179
type PackageSearchOptions struct {
@@ -176,7 +187,7 @@ type PackageSearchOptions struct {
176187
IsInternal util.OptionalBool
177188
HasFileWithName string // only results are found which are associated with a file with the specific name
178189
HasFiles util.OptionalBool // only results are found which have associated files
179-
Sort string
190+
Sort VersionSort
180191
db.Paginator
181192
}
182193

@@ -254,15 +265,15 @@ func (opts *PackageSearchOptions) toConds() builder.Cond {
254265

255266
func (opts *PackageSearchOptions) configureOrderBy(e db.Engine) {
256267
switch opts.Sort {
257-
case "alphabetically":
268+
case SortNameAsc:
258269
e.Asc("package.name")
259-
case "reversealphabetically":
270+
case SortNameDesc:
260271
e.Desc("package.name")
261-
case "highestversion":
272+
case SortVersionDesc:
262273
e.Desc("package_version.version")
263-
case "lowestversion":
274+
case SortVersionAsc:
264275
e.Asc("package_version.version")
265-
case "oldest":
276+
case SortCreatedAsc:
266277
e.Asc("package_version.created_unix")
267278
default:
268279
e.Desc("package_version.created_unix")

options/locale/locale_en-US.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ never = Never
106106

107107
rss_feed = RSS Feed
108108

109+
[filter]
110+
string.asc = A - Z
111+
string.desc = Z - A
112+
109113
[error]
110114
occurred = An error occurred
111115
report_message = If you are sure this is a Gitea bug, please search for issues on <a href="https://github.com/go-gitea/gitea/issues" target="_blank">GitHub</a> or open a new issue if necessary.

routers/web/auth/oauth.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const (
4848
// TODO move error and responses to SDK or models
4949

5050
// AuthorizeErrorCode represents an error code specified in RFC 6749
51+
// https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2.1
5152
type AuthorizeErrorCode string
5253

5354
const (
@@ -68,6 +69,7 @@ const (
6869
)
6970

7071
// AuthorizeError represents an error type specified in RFC 6749
72+
// https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2.1
7173
type AuthorizeError struct {
7274
ErrorCode AuthorizeErrorCode `json:"error" form:"error"`
7375
ErrorDescription string
@@ -80,6 +82,7 @@ func (err AuthorizeError) Error() string {
8082
}
8183

8284
// AccessTokenErrorCode represents an error code specified in RFC 6749
85+
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
8386
type AccessTokenErrorCode string
8487

8588
const (
@@ -98,6 +101,7 @@ const (
98101
)
99102

100103
// AccessTokenError represents an error response specified in RFC 6749
104+
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
101105
type AccessTokenError struct {
102106
ErrorCode AccessTokenErrorCode `json:"error" form:"error"`
103107
ErrorDescription string `json:"error_description"`
@@ -129,6 +133,7 @@ const (
129133
)
130134

131135
// AccessTokenResponse represents a successful access token response
136+
// https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2
132137
type AccessTokenResponse struct {
133138
AccessToken string `json:"access_token"`
134139
TokenType TokenType `json:"token_type"`
@@ -676,6 +681,30 @@ func AccessTokenOAuth(ctx *context.Context) {
676681
}
677682

678683
func handleRefreshToken(ctx *context.Context, form forms.AccessTokenForm, serverKey, clientKey oauth2.JWTSigningKey) {
684+
app, err := auth.GetOAuth2ApplicationByClientID(ctx, form.ClientID)
685+
if err != nil {
686+
handleAccessTokenError(ctx, AccessTokenError{
687+
ErrorCode: AccessTokenErrorCodeInvalidClient,
688+
ErrorDescription: fmt.Sprintf("cannot load client with client id: %q", form.ClientID),
689+
})
690+
return
691+
}
692+
// "The authorization server MUST ... require client authentication for confidential clients"
693+
// https://datatracker.ietf.org/doc/html/rfc6749#section-6
694+
if !app.ValidateClientSecret([]byte(form.ClientSecret)) {
695+
errorDescription := "invalid client secret"
696+
if form.ClientSecret == "" {
697+
errorDescription = "invalid empty client secret"
698+
}
699+
// "invalid_client ... Client authentication failed"
700+
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
701+
handleAccessTokenError(ctx, AccessTokenError{
702+
ErrorCode: AccessTokenErrorCodeInvalidClient,
703+
ErrorDescription: errorDescription,
704+
})
705+
return
706+
}
707+
679708
token, err := oauth2.ParseToken(form.RefreshToken, serverKey)
680709
if err != nil {
681710
handleAccessTokenError(ctx, AccessTokenError{

routers/web/user/package.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ func ListPackageVersions(ctx *context.Context) {
233233
}
234234

235235
query := ctx.FormTrim("q")
236+
sort := ctx.FormTrim("sort")
236237

237238
ctx.Data["Title"] = ctx.Tr("packages.title")
238239
ctx.Data["IsPackagesPage"] = true
@@ -243,9 +244,11 @@ func ListPackageVersions(ctx *context.Context) {
243244
Owner: ctx.Package.Owner,
244245
}
245246
ctx.Data["Query"] = query
247+
ctx.Data["Sort"] = sort
246248

247249
pagerParams := map[string]string{
248-
"q": query,
250+
"q": query,
251+
"sort": sort,
249252
}
250253

251254
var (
@@ -264,6 +267,7 @@ func ListPackageVersions(ctx *context.Context) {
264267
PackageID: p.ID,
265268
Query: query,
266269
IsTagged: tagged == "" || tagged == "tagged",
270+
Sort: sort,
267271
})
268272
if err != nil {
269273
ctx.ServerError("SearchImageTags", err)
@@ -278,6 +282,7 @@ func ListPackageVersions(ctx *context.Context) {
278282
Value: query,
279283
},
280284
IsInternal: util.OptionalBoolFalse,
285+
Sort: sort,
281286
})
282287
if err != nil {
283288
ctx.ServerError("SearchVersions", err)

services/markup/processorhelper.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,26 @@ import (
88
"context"
99

1010
"code.gitea.io/gitea/models/user"
11-
"code.gitea.io/gitea/modules/log"
11+
gitea_context "code.gitea.io/gitea/modules/context"
1212
"code.gitea.io/gitea/modules/markup"
1313
)
1414

1515
func ProcessorHelper() *markup.ProcessorHelper {
1616
return &markup.ProcessorHelper{
1717
IsUsernameMentionable: func(ctx context.Context, username string) bool {
18-
// TODO: cast ctx to modules/context.Context and use IsUserVisibleToViewer
19-
20-
// Only link if the user actually exists
21-
userExists, err := user.IsUserExist(ctx, 0, username)
18+
mentionedUser, err := user.GetUserByName(ctx, username)
2219
if err != nil {
23-
log.Error("Failed to validate user in mention %q exists, assuming it does", username)
24-
userExists = true
20+
return false
21+
}
22+
23+
giteaCtx, ok := ctx.(*gitea_context.Context)
24+
if !ok {
25+
// when using general context, use user's visibility to check
26+
return mentionedUser.Visibility.IsPublic()
2527
}
26-
return userExists
28+
29+
// when using gitea context (web context), use user's visibility and user's permission to check
30+
return user.IsUserVisibleToViewer(giteaCtx, mentionedUser, giteaCtx.Doer)
2731
},
2832
}
2933
}

services/markup/processorhelper_test.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,48 @@ package markup
66

77
import (
88
"context"
9+
"net/http"
910
"testing"
1011

12+
"code.gitea.io/gitea/models/db"
1113
"code.gitea.io/gitea/models/unittest"
14+
"code.gitea.io/gitea/models/user"
15+
gitea_context "code.gitea.io/gitea/modules/context"
1216

1317
"github.com/stretchr/testify/assert"
1418
)
1519

1620
func TestProcessorHelper(t *testing.T) {
1721
assert.NoError(t, unittest.PrepareTestDatabase())
18-
assert.True(t, ProcessorHelper().IsUsernameMentionable(context.Background(), "user10"))
19-
assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), "no-such-user"))
22+
23+
userPublic := "user1"
24+
userPrivate := "user31"
25+
userLimited := "user33"
26+
userNoSuch := "no-such-user"
27+
28+
unittest.AssertCount(t, &user.User{Name: userPublic}, 1)
29+
unittest.AssertCount(t, &user.User{Name: userPrivate}, 1)
30+
unittest.AssertCount(t, &user.User{Name: userLimited}, 1)
31+
unittest.AssertCount(t, &user.User{Name: userNoSuch}, 0)
32+
33+
// when using general context, use user's visibility to check
34+
assert.True(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userPublic))
35+
assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userLimited))
36+
assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userPrivate))
37+
assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userNoSuch))
38+
39+
// when using web context, use user.IsUserVisibleToViewer to check
40+
var err error
41+
giteaCtx := &gitea_context.Context{}
42+
giteaCtx.Req, err = http.NewRequest("GET", "/", nil)
43+
assert.NoError(t, err)
44+
45+
giteaCtx.Doer = nil
46+
assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPublic))
47+
assert.False(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPrivate))
48+
49+
giteaCtx.Doer, err = user.GetUserByName(db.DefaultContext, userPrivate)
50+
assert.NoError(t, err)
51+
assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPublic))
52+
assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPrivate))
2053
}

templates/admin/packages/list.tmpl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,20 @@
3737
<th>ID</th>
3838
<th>{{.locale.Tr "admin.packages.owner"}}</th>
3939
<th>{{.locale.Tr "admin.packages.type"}}</th>
40-
<th data-sortt-asc="alphabetically" data-sortt-desc="reversealphabetically">
40+
<th data-sortt-asc="name_asc" data-sortt-desc="name_desc">
4141
{{.locale.Tr "admin.packages.name"}}
42-
{{SortArrow "alphabetically" "reversealphabetically" .SortType false}}
42+
{{SortArrow "name_asc" "name_desc" .SortType false}}
4343
</th>
44-
<th data-sortt-asc="highestversion" data-sortt-desc="lowestversion">
44+
<th data-sortt-asc="version_desc" data-sortt-desc="version_asc">
4545
{{.locale.Tr "admin.packages.version"}}
46-
{{SortArrow "highestversion" "lowestversion" .SortType false}}
46+
{{SortArrow "version_desc" "version_asc" .SortType false}}
4747
</th>
4848
<th>{{.locale.Tr "admin.packages.creator"}}</th>
4949
<th>{{.locale.Tr "admin.packages.repository"}}</th>
5050
<th>{{.locale.Tr "admin.packages.size"}}</th>
51-
<th data-sortt-asc="oldest" data-sortt-desc="newest">
51+
<th data-sortt-asc="created_asc" data-sortt-desc="created_desc">
5252
{{.locale.Tr "admin.packages.published"}}
53-
{{SortArrow "oldest" "newest" .SortType true}}
53+
{{SortArrow "created_asc" "created_desc" .SortType true}}
5454
</th>
5555
<th>{{.locale.Tr "admin.notices.op"}}</th>
5656
</tr>

templates/package/shared/versionlist.tmpl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@
33
<form class="ui form ignore-dirty">
44
<div class="ui fluid action input">
55
<input name="q" value="{{.Query}}" placeholder="{{.locale.Tr "explore.search"}}..." autofocus>
6+
<select class="ui dropdown" name="sort">
7+
<option value="version_asc"{{if eq .Sort "version_asc"}} selected="selected"{{end}}>{{.locale.Tr "filter.string.asc"}}</option>
8+
<option value="version_desc"{{if eq .Sort "version_desc"}} selected="selected"{{end}}>{{.locale.Tr "filter.string.desc"}}</option>
9+
<option value="created_asc"{{if eq .Sort "created_asc"}} selected="selected"{{end}}>{{.locale.Tr "repo.issues.filter_sort.oldest"}}</option>
10+
<option value="created_desc"{{if or (eq .Sort "") (eq .Sort "created_desc")}} selected="selected"{{end}}>{{.locale.Tr "repo.issues.filter_sort.latest"}}</option>
11+
</select>
612
{{if eq .PackageDescriptor.Package.Type "container"}}
713
<select class="ui dropdown" name="tagged">
814
{{$isTagged := or (eq .Tagged "") (eq .Tagged "tagged")}}
9-
<option value="tagged" {{if $isTagged}}selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.tagged"}}</option>
10-
<option value="untagged" {{if not $isTagged}}selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.untagged"}}</option>
15+
<option value="tagged"{{if $isTagged}} selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.tagged"}}</option>
16+
<option value="untagged"{{if not $isTagged}} selected="selected"{{end}}>{{.locale.Tr "packages.filter.container.untagged"}}</option>
1117
</select>
1218
{{end}}
1319
<button class="ui primary button">{{.locale.Tr "explore.search"}}</button>

0 commit comments

Comments
 (0)