Skip to content

Commit afe98af

Browse files
committed
Merge remote-tracking branch 'upstream/release/v1.16' into codeberg-1.16
2 parents 8af36e8 + f460b75 commit afe98af

File tree

28 files changed

+247
-88
lines changed

28 files changed

+247
-88
lines changed

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@ This changelog goes through all the changes that have been made in each release
44
without substantial changes to our git log; to see the highlights of what has
55
been added to each release, please refer to the [blog](https://blog.gitea.io).
66

7+
## [1.16.4](https://github.com/go-gitea/gitea/releases/tag/v1.16.4) - 2022-03-14
8+
9+
* SECURITY
10+
* Restrict email address validation (#17688) (#19085)
11+
* Fix lfs bug (#19072) (#19080)
12+
* ENHANCEMENTS
13+
* Improve SyncMirrors logging (#19045) (#19050)
14+
* BUGFIXES
15+
* Refactor mirror code & fix `StartToMirror` (#18904) (#19075)
16+
* Update the webauthn_credential_id_sequence in Postgres (#19048) (#19060)
17+
* Prevent 500 when there is an error during new auth source post (#19041) (#19059)
18+
* If rendering has failed due to a net.OpError stop rendering (attempt 2) (#19049) (#19056)
19+
* Fix flag validation (#19046) (#19051)
20+
* Add pam account authorization check (#19040) (#19047)
21+
* Ignore missing comment for user notifications (#18954) (#19043)
22+
* Set `rel="nofollow noindex"` on new issue links (#19023) (#19042)
23+
* Upgrading binding package (#19034) (#19035)
24+
* Don't show context cancelled errors in attribute reader (#19006) (#19027)
25+
* Fix update hint bug (#18996) (#19002)
26+
* MISC
27+
* Fix potential assignee query for repo (#18994) (#18999)
28+
729
## [1.16.3](https://github.com/go-gitea/gitea/releases/tag/v1.16.3) - 2022-03-02
830

931
* SECURITY

cmd/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func argsSet(c *cli.Context, args ...string) error {
3131
return errors.New(a + " is not set")
3232
}
3333

34-
if util.IsEmptyString(a) {
34+
if util.IsEmptyString(c.String(a)) {
3535
return errors.New(a + " is required")
3636
}
3737
}

docs/content/doc/developers/guidelines-backend.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ To maintain understandable code and avoid circular dependencies it is important
4242
- `modules/setting`: Store all system configurations read from ini files and has been referenced by everywhere. But they should be used as function parameters when possible.
4343
- `modules/git`: Package to interactive with `Git` command line or Gogit package.
4444
- `public`: Compiled frontend files (javascript, images, css, etc.)
45-
- `routers`: Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) shall not depend on routers.
45+
- `routers`: Handling of server requests. As it uses other Gitea packages to serve the request, other packages (models, modules or services) must not depend on routers.
4646
- `routers/api` Contains routers for `/api/v1` aims to handle RESTful API requests.
4747
- `routers/install` Could only respond when system is in INSTALL mode (INSTALL_LOCK=false).
4848
- `routers/private` will only be invoked by internal sub commands, especially `serv` and `hooks`.
@@ -106,10 +106,20 @@ i.e. `servcies/user`, `models/repository`.
106106
Since there are some packages which use the same package name, it is possible that you find packages like `modules/user`, `models/user`, and `services/user`. When these packages are imported in one Go file, it's difficult to know which package we are using and if it's a variable name or an import name. So, we always recommend to use import aliases. To differ from package variables which are commonly in camelCase, just use **snake_case** for import aliases.
107107
i.e. `import user_service "code.gitea.io/gitea/services/user"`
108108

109+
### Important Gotchas
110+
111+
- Never write `x.Update(exemplar)` without an explicit `WHERE` clause:
112+
- This will cause all rows in the table to be updated with the non-zero values of the exemplar - including IDs.
113+
- You should usually write `x.ID(id).Update(exemplar)`.
114+
- If during a migration you are inserting into a table using `x.Insert(exemplar)` where the ID is preset:
115+
- You will need to ``SET IDENTITY_INSERT `table` ON`` for the MSSQL variant (the migration will fail otherwise)
116+
- However, you will also need to update the id sequence for postgres - the migration will silently pass here but later insertions will fail:
117+
``SELECT setval('table_name_id_seq', COALESCE((SELECT MAX(id)+1 FROM `table_name`), 1), false)``
118+
109119
### Future Tasks
110120

111121
Currently, we are creating some refactors to do the following things:
112122

113123
- Correct that codes which doesn't follow the rules.
114124
- There are too many files in `models`, so we are moving some of them into a sub package `models/xxx`.
115-
- Some `modules` sub packages should be moved to `services` because they depends on `models`.
125+
- Some `modules` sub packages should be moved to `services` because they depend on `models`.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
cloud.google.com/go v0.78.0 // indirect
77
code.gitea.io/gitea-vet v0.2.1
88
code.gitea.io/sdk/gitea v0.15.1
9-
gitea.com/go-chi/binding v0.0.0-20211013065440-d16dc407c2be
9+
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb
1010
gitea.com/go-chi/cache v0.0.0-20211013020926-78790b11abf1
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: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFj
4141
code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M=
4242
code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
4343
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
44-
gitea.com/go-chi/binding v0.0.0-20211013065440-d16dc407c2be h1:IzSwPVzd2hE6e67ujY8ReBCrQ5IFNd0uiBmC7Ux5IaY=
45-
gitea.com/go-chi/binding v0.0.0-20211013065440-d16dc407c2be/go.mod h1:/vR0YjlusOYvosKYW7QKcSnrY0nPLe4RQ/DGi3+i/Do=
44+
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb h1:Yy0Bxzc8R2wxiwXoG/rECGplJUSpXqCsog9PuJFgiHs=
45+
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc=
4646
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0=
4747
gitea.com/go-chi/cache v0.0.0-20211013020926-78790b11abf1 h1:Z7DcvTkxt8ovcENgPsQ7xzrGNSQmmIjGS9fJEb1l8jk=
4848
gitea.com/go-chi/cache v0.0.0-20211013020926-78790b11abf1/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0=
@@ -489,8 +489,9 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
489489
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
490490
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
491491
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
492-
github.com/goccy/go-json v0.7.4 h1:B44qRUFwz/vxPKPISQ1KhvzRi9kZ28RAf6YtjriBZ5k=
493492
github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
493+
github.com/goccy/go-json v0.9.5 h1:ooSMW526ZjK+EaL5elrSyN2EzIfi/3V0m4+HJEDYLik=
494+
github.com/goccy/go-json v0.9.5/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
494495
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
495496
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
496497
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=

models/lfs.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,13 @@ func LFSAutoAssociate(metas []*LFSMetaObject, user *user_model.User, repoID int6
193193
// admin can associate any LFS object to any repository, and we do not care about errors (eg: duplicated unique key),
194194
// even if error occurs, it won't hurt users and won't make things worse
195195
for i := range metas {
196+
p := lfs.Pointer{Oid: metas[i].Oid, Size: metas[i].Size}
196197
_, err = sess.Insert(&LFSMetaObject{
197-
Pointer: lfs.Pointer{Oid: metas[i].Oid, Size: metas[i].Size},
198+
Pointer: p,
198199
RepositoryID: repoID,
199200
})
200201
if err != nil {
201-
log.Warn("failed to insert LFS meta object into database, err=%v", err)
202+
log.Warn("failed to insert LFS meta object %-v for repo_id: %d into database, err=%v", p, repoID, err)
202203
}
203204
}
204205
}

models/migrations/v210.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,5 +174,11 @@ func remigrateU2FCredentials(x *xorm.Engine) error {
174174
regs = regs[:0]
175175
}
176176

177+
if x.Dialect().URI().DBType == schemas.POSTGRES {
178+
if _, err := x.Exec("SELECT setval('webauthn_credential_id_seq', COALESCE((SELECT MAX(id)+1 FROM `webauthn_credential`), 1), false)"); err != nil {
179+
return err
180+
}
181+
}
182+
177183
return nil
178184
}

models/notification.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,15 @@ func (n *Notification) APIURL() string {
498498
type NotificationList []*Notification
499499

500500
// LoadAttributes load Repo Issue User and Comment if not loaded
501-
func (nl NotificationList) LoadAttributes() (err error) {
501+
func (nl NotificationList) LoadAttributes() error {
502+
var err error
502503
for i := 0; i < len(nl); i++ {
503504
err = nl[i].LoadAttributes()
504505
if err != nil && !IsErrCommentNotExist(err) {
505-
return
506+
return err
506507
}
507508
}
508-
return
509+
return nil
509510
}
510511

511512
func (nl NotificationList) getPendingRepoIDs() []int64 {

models/user/email_address.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"errors"
1111
"fmt"
1212
"net/mail"
13+
"regexp"
1314
"strings"
1415

1516
"code.gitea.io/gitea/models/db"
@@ -21,10 +22,23 @@ import (
2122
"xorm.io/builder"
2223
)
2324

24-
var (
25-
// ErrEmailNotActivated e-mail address has not been activated error
26-
ErrEmailNotActivated = errors.New("E-mail address has not been activated")
27-
)
25+
// ErrEmailNotActivated e-mail address has not been activated error
26+
var ErrEmailNotActivated = errors.New("e-mail address has not been activated")
27+
28+
// ErrEmailCharIsNotSupported e-mail address contains unsupported character
29+
type ErrEmailCharIsNotSupported struct {
30+
Email string
31+
}
32+
33+
// IsErrEmailCharIsNotSupported checks if an error is an ErrEmailCharIsNotSupported
34+
func IsErrEmailCharIsNotSupported(err error) bool {
35+
_, ok := err.(ErrEmailCharIsNotSupported)
36+
return ok
37+
}
38+
39+
func (err ErrEmailCharIsNotSupported) Error() string {
40+
return fmt.Sprintf("e-mail address contains unsupported character [email: %s]", err.Email)
41+
}
2842

2943
// ErrEmailInvalid represents an error where the email address does not comply with RFC 5322
3044
type ErrEmailInvalid struct {
@@ -108,12 +122,24 @@ func (email *EmailAddress) BeforeInsert() {
108122
}
109123
}
110124

125+
var emailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
126+
111127
// ValidateEmail check if email is a allowed address
112128
func ValidateEmail(email string) error {
113129
if len(email) == 0 {
114130
return nil
115131
}
116132

133+
if !emailRegexp.MatchString(email) {
134+
return ErrEmailCharIsNotSupported{email}
135+
}
136+
137+
if !(email[0] >= 'a' && email[0] <= 'z') &&
138+
!(email[0] >= 'A' && email[0] <= 'Z') &&
139+
!(email[0] >= '0' && email[0] <= '9') {
140+
return ErrEmailInvalid{email}
141+
}
142+
117143
if _, err := mail.ParseAddress(email); err != nil {
118144
return ErrEmailInvalid{email}
119145
}

models/user/email_address_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,58 @@ func TestListEmails(t *testing.T) {
252252
assert.Len(t, emails, 5)
253253
assert.Greater(t, count, int64(len(emails)))
254254
}
255+
256+
func TestEmailAddressValidate(t *testing.T) {
257+
kases := map[string]error{
258+
259+
260+
261+
262+
263+
264+
265+
`first#[email protected]`: nil,
266+
267+
`first%[email protected]`: nil,
268+
`first&[email protected]`: nil,
269+
`first'[email protected]`: nil,
270+
`first*[email protected]`: nil,
271+
272+
`first/[email protected]`: nil,
273+
274+
275+
`first^[email protected]`: nil,
276+
"first`[email protected]": nil,
277+
`first{[email protected]`: nil,
278+
`first|[email protected]`: nil,
279+
`first}[email protected]`: nil,
280+
281+
`first;[email protected]`: ErrEmailCharIsNotSupported{`first;[email protected]`},
282+
"[email protected]": ErrEmailInvalid{"[email protected]"},
283+
"[email protected]": ErrEmailInvalid{"[email protected]"},
284+
"#[email protected]": ErrEmailInvalid{"#[email protected]"},
285+
"[email protected]": ErrEmailInvalid{"[email protected]"},
286+
"%[email protected]": ErrEmailInvalid{"%[email protected]"},
287+
"&[email protected]": ErrEmailInvalid{"&[email protected]"},
288+
"'[email protected]": ErrEmailInvalid{"'[email protected]"},
289+
"*[email protected]": ErrEmailInvalid{"*[email protected]"},
290+
"[email protected]": ErrEmailInvalid{"[email protected]"},
291+
"/[email protected]": ErrEmailInvalid{"/[email protected]"},
292+
"[email protected]": ErrEmailInvalid{"[email protected]"},
293+
"[email protected]": ErrEmailInvalid{"[email protected]"},
294+
"^[email protected]": ErrEmailInvalid{"^[email protected]"},
295+
"`[email protected]": ErrEmailInvalid{"`[email protected]"},
296+
"{[email protected]": ErrEmailInvalid{"{[email protected]"},
297+
"|[email protected]": ErrEmailInvalid{"|[email protected]"},
298+
"}[email protected]": ErrEmailInvalid{"}[email protected]"},
299+
"[email protected]": ErrEmailInvalid{"[email protected]"},
300+
";[email protected]": ErrEmailCharIsNotSupported{";[email protected]"},
301+
"Foo <[email protected]>": ErrEmailCharIsNotSupported{"Foo <[email protected]>"},
302+
string([]byte{0xE2, 0x84, 0xAA}): ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})},
303+
}
304+
for kase, err := range kases {
305+
t.Run(kase, func(t *testing.T) {
306+
assert.EqualValues(t, err, ValidateEmail(kase))
307+
})
308+
}
309+
}

models/user/user.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,15 @@ func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err e
669669
u.Visibility = overwriteDefault[0].Visibility
670670
}
671671

672+
// validate data
673+
if err := validateUser(u); err != nil {
674+
return err
675+
}
676+
677+
if err := ValidateEmail(u.Email); err != nil {
678+
return err
679+
}
680+
672681
ctx, committer, err := db.TxContext()
673682
if err != nil {
674683
return err
@@ -677,11 +686,6 @@ func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err e
677686

678687
sess := db.GetEngine(ctx)
679688

680-
// validate data
681-
if err := validateUser(u); err != nil {
682-
return err
683-
}
684-
685689
isExist, err := isUserExist(sess, 0, u.Name)
686690
if err != nil {
687691
return err

models/user/user_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ func TestCreateUserInvalidEmail(t *testing.T) {
232232

233233
err := CreateUser(user)
234234
assert.Error(t, err)
235-
assert.True(t, IsErrEmailInvalid(err))
235+
assert.True(t, IsErrEmailCharIsNotSupported(err))
236236
}
237237

238238
func TestCreateUserEmailAlreadyUsed(t *testing.T) {

modules/auth/pam/pam.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ func Auth(serviceName, userName, passwd string) (string, error) {
3535
if err = t.Authenticate(0); err != nil {
3636
return "", err
3737
}
38+
39+
if err = t.AcctMgmt(0); err != nil {
40+
return "", err
41+
}
3842

3943
// PAM login names might suffer transformations in the PAM stack.
4044
// We should take whatever the PAM stack returns for it.

modules/context/context.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ func (ctx *Context) ServerError(logMsg string, logErr error) {
266266
func (ctx *Context) serverErrorInternal(logMsg string, logErr error) {
267267
if logErr != nil {
268268
log.ErrorWithSkip(2, "%s: %v", logMsg, logErr)
269-
if errors.Is(logErr, &net.OpError{}) {
269+
if _, ok := logErr.(*net.OpError); ok || errors.Is(logErr, &net.OpError{}) {
270270
// This is an error within the underlying connection
271271
// and further rendering will not work so just return
272272
return

modules/lfs/pointer.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"regexp"
1515
"strconv"
1616
"strings"
17+
18+
"code.gitea.io/gitea/modules/log"
1719
)
1820

1921
const (
@@ -111,6 +113,17 @@ func (p Pointer) RelativePath() string {
111113
return path.Join(p.Oid[0:2], p.Oid[2:4], p.Oid[4:])
112114
}
113115

116+
// ColorFormat provides a basic color format for a Team
117+
func (p Pointer) ColorFormat(s fmt.State) {
118+
if p.Oid == "" && p.Size == 0 {
119+
log.ColorFprintf(s, "<empty>")
120+
return
121+
}
122+
log.ColorFprintf(s, "%s:%d",
123+
log.NewColoredIDValue(p.Oid),
124+
p.Size)
125+
}
126+
114127
// GeneratePointer generates a pointer for arbitrary content
115128
func GeneratePointer(content io.Reader) (Pointer, error) {
116129
h := sha256.New()

0 commit comments

Comments
 (0)