Skip to content

Commit af2a835

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Fix typo (go-gitea#21695) Remove template previewer (go-gitea#21701) Revert "[skip ci] Updated translations via Crowdin" (go-gitea#21689) [skip ci] Updated translations via Crowdin Fix docs relref (go-gitea#21685) Add "Copy" button to file view of raw text (go-gitea#21629) Improve valid user name check (go-gitea#20136)
2 parents cc7c2c0 + a0367c2 commit af2a835

File tree

18 files changed

+120
-51
lines changed

18 files changed

+120
-51
lines changed

docs/content/doc/installation/from-source.fr-fr.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ git checkout pr-xyz
5353

5454
## Compilation
5555

56-
Comme nous regroupons déjà toutes les bibliothèques requises pour compiler Gitea, vous pouvez continuer avec le processus de compilation lui-même. Nous fournissons diverses [tâches Make](https://github.com/go-gitea/gitea/blob/master/Makefile) pour rendre le processus de construction aussi simple que possible. [Voyez ici comment obtenir Make]({{< relref "doc/developers/hacking-on-gitea.fr-fr.md" >}}#installing-make). Selon vos besoins, vous pourrez éventuellement ajouter diverses options de compilation, vous pouvez choisir entre ces options :
56+
Comme nous regroupons déjà toutes les bibliothèques requises pour compiler Gitea, vous pouvez continuer avec le processus de compilation lui-même. Nous fournissons diverses [tâches Make](https://github.com/go-gitea/gitea/blob/master/Makefile) pour rendre le processus de construction aussi simple que possible. [Voyez ici comment obtenir Make](/fr-fr/hacking-on-gitea/). Selon vos besoins, vous pourrez éventuellement ajouter diverses options de compilation, vous pouvez choisir entre ces options :
5757

5858
* `bindata`: Intègre toutes les ressources nécessaires à l'exécution d'une instance de Gitea, ce qui rend un déploiement facile car il n'est pas nécessaire de se préoccuper des fichiers supplémentaires.
5959
* `sqlite sqlite_unlock_notify`: Active la prise en charge d'une base de données [SQLite3](https://sqlite.org/), ceci n'est recommandé que pour les petites installations de Gitea.

docs/content/doc/installation/from-source.zh-cn.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ git checkout v{{< version >}}
5454

5555
- `go` {{< min-go-version >}} 或以上版本, 详见[这里](https://golang.google.cn/doc/install)
5656
- `node` {{< min-node-version >}} 或以上版本,并且安装 `npm`, 详见[这里](https://nodejs.org/zh-cn/download/)
57-
- `make`, 详见[这里]({{< relref "doc/developers/hacking-on-gitea.zh-cn.md" >}})</a>
57+
- `make`, 详见[这里](/zh-cn/hacking-on-gitea/)
5858

5959
各种可用的 [make 任务](https://github.com/go-gitea/gitea/blob/main/Makefile)
6060
可以用来使编译过程更方便。

models/user/user.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"code.gitea.io/gitea/modules/structs"
3030
"code.gitea.io/gitea/modules/timeutil"
3131
"code.gitea.io/gitea/modules/util"
32+
"code.gitea.io/gitea/modules/validation"
3233

3334
"golang.org/x/crypto/argon2"
3435
"golang.org/x/crypto/bcrypt"
@@ -621,7 +622,7 @@ var (
621622
// IsUsableUsername returns an error when a username is reserved
622623
func IsUsableUsername(name string) error {
623624
// Validate username make sure it satisfies requirement.
624-
if db.AlphaDashDotPattern.MatchString(name) {
625+
if !validation.IsValidUsername(name) {
625626
// Note: usually this error is normally caught up earlier in the UI
626627
return db.ErrNameCharsNotAllowed{Name: name}
627628
}

modules/structs/admin_user.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ type CreateUserOption struct {
1010
SourceID int64 `json:"source_id"`
1111
LoginName string `json:"login_name"`
1212
// required: true
13-
Username string `json:"username" binding:"Required;AlphaDashDot;MaxSize(40)"`
13+
Username string `json:"username" binding:"Required;Username;MaxSize(40)"`
1414
FullName string `json:"full_name" binding:"MaxSize(100)"`
1515
// required: true
1616
// swagger:strfmt email

modules/validation/binding.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ const (
2424

2525
// ErrRegexPattern is returned when a regex pattern is invalid
2626
ErrRegexPattern = "RegexPattern"
27+
28+
// ErrUsername is username error
29+
ErrUsername = "UsernameError"
2730
)
2831

2932
// AddBindingRules adds additional binding rules
@@ -34,6 +37,7 @@ func AddBindingRules() {
3437
addGlobPatternRule()
3538
addRegexPatternRule()
3639
addGlobOrRegexPatternRule()
40+
addUsernamePatternRule()
3741
}
3842

3943
func addGitRefNameBindingRule() {
@@ -148,6 +152,22 @@ func addGlobOrRegexPatternRule() {
148152
})
149153
}
150154

155+
func addUsernamePatternRule() {
156+
binding.AddRule(&binding.Rule{
157+
IsMatch: func(rule string) bool {
158+
return rule == "Username"
159+
},
160+
IsValid: func(errs binding.Errors, name string, val interface{}) (bool, binding.Errors) {
161+
str := fmt.Sprintf("%v", val)
162+
if !IsValidUsername(str) {
163+
errs.Add([]string{name}, ErrUsername, "invalid username")
164+
return false, errs
165+
}
166+
return true, errs
167+
},
168+
})
169+
}
170+
151171
func portOnly(hostport string) string {
152172
colon := strings.IndexByte(hostport, ':')
153173
if colon == -1 {

modules/validation/helpers.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,15 @@ func IsValidExternalTrackerURLFormat(uri string) bool {
9191

9292
return true
9393
}
94+
95+
var (
96+
validUsernamePattern = regexp.MustCompile(`^[\da-zA-Z][-.\w]*$`)
97+
invalidUsernamePattern = regexp.MustCompile(`[-._]{2,}|[-._]$`) // No consecutive or trailing non-alphanumeric chars
98+
)
99+
100+
// IsValidUsername checks if username is valid
101+
func IsValidUsername(name string) bool {
102+
// It is difficult to find a single pattern that is both readable and effective,
103+
// but it's easier to use positive and negative checks.
104+
return validUsernamePattern.MatchString(name) && !invalidUsernamePattern.MatchString(name)
105+
}

modules/validation/helpers_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,34 @@ func Test_IsValidExternalTrackerURLFormat(t *testing.T) {
155155
})
156156
}
157157
}
158+
159+
func TestIsValidUsername(t *testing.T) {
160+
tests := []struct {
161+
arg string
162+
want bool
163+
}{
164+
{arg: "a", want: true},
165+
{arg: "abc", want: true},
166+
{arg: "0.b-c", want: true},
167+
{arg: "a.b-c_d", want: true},
168+
{arg: "", want: false},
169+
{arg: ".abc", want: false},
170+
{arg: "abc.", want: false},
171+
{arg: "a..bc", want: false},
172+
{arg: "a...bc", want: false},
173+
{arg: "a.-bc", want: false},
174+
{arg: "a._bc", want: false},
175+
{arg: "a_-bc", want: false},
176+
{arg: "a/bc", want: false},
177+
{arg: "☁️", want: false},
178+
{arg: "-", want: false},
179+
{arg: "--diff", want: false},
180+
{arg: "-im-here", want: false},
181+
{arg: "a space", want: false},
182+
}
183+
for _, tt := range tests {
184+
t.Run(tt.arg, func(t *testing.T) {
185+
assert.Equalf(t, tt.want, IsValidUsername(tt.arg), "IsValidUsername(%v)", tt.arg)
186+
})
187+
}
188+
}

modules/web/middleware/binding.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ func Validate(errs binding.Errors, data map[string]interface{}, f Form, l transl
135135
data["ErrorMsg"] = trName + l.Tr("form.glob_pattern_error", errs[0].Message)
136136
case validation.ErrRegexPattern:
137137
data["ErrorMsg"] = trName + l.Tr("form.regex_pattern_error", errs[0].Message)
138+
case validation.ErrUsername:
139+
data["ErrorMsg"] = trName + l.Tr("form.username_error")
138140
default:
139141
msg := errs[0].Classification
140142
if msg != "" && errs[0].Message != "" {

options/locale/locale_en-US.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ edit = Edit
8888

8989
copy = Copy
9090
copy_url = Copy URL
91+
copy_content = Copy content
9192
copy_branch = Copy branch name
9293
copy_success = Copied!
9394
copy_error = Copy failed
@@ -463,6 +464,7 @@ url_error = `'%s' is not a valid URL.`
463464
include_error = ` must contain substring '%s'.`
464465
glob_pattern_error = ` glob pattern is invalid: %s.`
465466
regex_pattern_error = ` regex pattern is invalid: %s.`
467+
username_error = ` can only contain alphanumeric chars ('0-9','a-z','A-Z'), dash ('-'), underscore ('_') and dot ('.'). It cannot begin or end with non-alphanumeric chars, and consecutive non-alphanumeric chars are also forbidden.`
466468
unknown_error = Unknown error:
467469
captcha_incorrect = The CAPTCHA code is incorrect.
468470
password_not_match = The passwords do not match.
@@ -1089,6 +1091,7 @@ editor.cannot_edit_non_text_files = Binary files cannot be edited in the web int
10891091
editor.edit_this_file = Edit File
10901092
editor.this_file_locked = File is locked
10911093
editor.must_be_on_a_branch = You must be on a branch to make or propose changes to this file.
1094+
editor.only_copy_raw = You may only copy raw text files.
10921095
editor.fork_before_edit = You must fork this repository to make or propose changes to this file.
10931096
editor.delete_this_file = Delete File
10941097
editor.must_have_write_access = You must have write access to make or propose changes to this file.

routers/web/dev/template.go

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)