Skip to content

Commit 2c1ec90

Browse files
n0tooseearl-warren
authored andcommitted
[GITEA] add option for banning dots in usernames
Refs: https://codeberg.org/forgejo/forgejo/pulls/676 Author: Panagiotis "Ivory" Vasilopoulos <[email protected]> Date: Mon Jun 12 13:57:01 2023 +0200 Co-authored-by: Gusted <[email protected]> (cherry picked from commit fabdda5) (cherry picked from commit d2c7f45621028d37944659db096bc92c031dd8e7) (cherry picked from commit dfdbaba3d6b7abf1c542b0ea41b7812b729cc217) (cherry picked from commit a3cda092b8897e4d669cfcf2cb8b16236e3c9b32) (cherry picked from commit f0fdb5905c3b22bec043530da15d2c52f6bc41c9) (cherry picked from commit 9697e48c1f8b23d3dd1da246b525b63c3756353d) (cherry picked from commit 46e31009a86db18a9b5bd8e2f535b198df90c437) (cherry picked from commit 5bb2c54b6f55499937396339bcacd3b4d8fb6b5e) (cherry picked from commit 682f9d24e13b83d89bd6b86324960f1b4fc72eeb) (cherry picked from commit 18634810057ef88fd01b54cec33bd4bd04c53221) (cherry picked from commit 4f1b7c4ddbc4099aa9b6fda1e0145d37f638e567) (cherry picked from commit 6afe70bbf1290e604fc476ee27901d1722ac1272) (cherry picked from commit 5cec1d9) Conflicts: templates/admin/config.tmpl https://codeberg.org/forgejo/forgejo/pulls/1512 (cherry picked from commit de2d172473217e3437238fd9c691edc8d8524e1a) (cherry picked from commit 37a3172dd9e2646157ec49ca46f94b9b0012b061) (cherry picked from commit 92dfca0c5a8a8d4fd8a93b5468ba593283fc9452) (cherry picked from commit a713d59b0cbeaf2fe023be1daa42165cd0df3b1d) (cherry picked from commit e7bd71a6188ed4abbabf8b64b439e588c1c1f5f7) (cherry picked from commit 69f3e952c495ecf8af5e7fc8cca6f3ba31fd3da2) (cherry picked from commit 83fbb7b566f68f84f56d371bcfbba89bba602e2f) (cherry picked from commit 3196605fa99679d28c51c7faccb8402155d31c49) (cherry picked from commit e37eb8de9c8e9975fd2f33e0ea92d45da4c3835c) (cherry picked from commit 8c99f59e48098b0058c5692f17aa66352ad3ad01) (cherry picked from commit 74aa1ac66f659478b9e6994967a6207d7843b9ae) (cherry picked from commit 622440b3bd32ce4db6305187c854e1f9a8820305)
1 parent 91631d4 commit 2c1ec90

File tree

7 files changed

+57
-5
lines changed

7 files changed

+57
-5
lines changed

custom/conf/app.example.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,11 @@ LEVEL = Info
815815
;; Every new user will have restricted permissions depending on this setting
816816
;DEFAULT_USER_IS_RESTRICTED = false
817817
;;
818+
;; Users will be able to use dots when choosing their username. Disabling this is
819+
;; helpful if your usersare having issues with e.g. RSS feeds or advanced third-party
820+
;; extensions that use strange regex patterns.
821+
; ALLOW_DOTS_IN_USERNAMES = true
822+
;;
818823
;; Either "public", "limited" or "private", default is "public"
819824
;; Limited is for users visible only to signed users
820825
;; Private is for users visible only to members of their organizations

modules/setting/service.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ var Service = struct {
6868
DefaultKeepEmailPrivate bool
6969
DefaultAllowCreateOrganization bool
7070
DefaultUserIsRestricted bool
71+
AllowDotsInUsernames bool
7172
EnableTimetracking bool
7273
DefaultEnableTimetracking bool
7374
DefaultEnableDependencies bool
@@ -180,6 +181,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
180181
Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
181182
Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
182183
Service.DefaultUserIsRestricted = sec.Key("DEFAULT_USER_IS_RESTRICTED").MustBool(false)
184+
Service.AllowDotsInUsernames = sec.Key("ALLOW_DOTS_IN_USERNAMES").MustBool(true)
183185
Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true)
184186
if Service.EnableTimetracking {
185187
Service.DefaultEnableTimetracking = sec.Key("DEFAULT_ENABLE_TIMETRACKING").MustBool(true)

modules/validation/helpers.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,20 @@ func IsValidExternalTrackerURLFormat(uri string) bool {
117117
}
118118

119119
var (
120-
validUsernamePattern = regexp.MustCompile(`^[\da-zA-Z][-.\w]*$`)
121-
invalidUsernamePattern = regexp.MustCompile(`[-._]{2,}|[-._]$`) // No consecutive or trailing non-alphanumeric chars
120+
validUsernamePatternWithDots = regexp.MustCompile(`^[\da-zA-Z][-.\w]*$`)
121+
validUsernamePatternWithoutDots = regexp.MustCompile(`^[\da-zA-Z][-\w]*$`)
122+
123+
// No consecutive or trailing non-alphanumeric chars, catches both cases
124+
invalidUsernamePattern = regexp.MustCompile(`[-._]{2,}|[-._]$`)
122125
)
123126

124127
// IsValidUsername checks if username is valid
125128
func IsValidUsername(name string) bool {
126129
// It is difficult to find a single pattern that is both readable and effective,
127130
// but it's easier to use positive and negative checks.
128-
return validUsernamePattern.MatchString(name) && !invalidUsernamePattern.MatchString(name)
131+
if setting.Service.AllowDotsInUsernames {
132+
return validUsernamePatternWithDots.MatchString(name) && !invalidUsernamePattern.MatchString(name)
133+
}
134+
135+
return validUsernamePatternWithoutDots.MatchString(name) && !invalidUsernamePattern.MatchString(name)
129136
}

modules/validation/helpers_test.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ func Test_IsValidExternalTrackerURLFormat(t *testing.T) {
155155
}
156156
}
157157

158-
func TestIsValidUsername(t *testing.T) {
158+
func TestIsValidUsernameAllowDots(t *testing.T) {
159+
setting.Service.AllowDotsInUsernames = true
159160
tests := []struct {
160161
arg string
161162
want bool
@@ -185,3 +186,31 @@ func TestIsValidUsername(t *testing.T) {
185186
})
186187
}
187188
}
189+
190+
func TestIsValidUsernameBanDots(t *testing.T) {
191+
setting.Service.AllowDotsInUsernames = false
192+
defer func() {
193+
setting.Service.AllowDotsInUsernames = true
194+
}()
195+
196+
tests := []struct {
197+
arg string
198+
want bool
199+
}{
200+
{arg: "a", want: true},
201+
{arg: "abc", want: true},
202+
{arg: "0.b-c", want: false},
203+
{arg: "a.b-c_d", want: false},
204+
{arg: ".abc", want: false},
205+
{arg: "abc.", want: false},
206+
{arg: "a..bc", want: false},
207+
{arg: "a...bc", want: false},
208+
{arg: "a.-bc", want: false},
209+
{arg: "a._bc", want: false},
210+
}
211+
for _, tt := range tests {
212+
t.Run(tt.arg, func(t *testing.T) {
213+
assert.Equalf(t, tt.want, IsValidUsername(tt.arg), "IsValidUsername[AllowDotsInUsernames=false](%v)", tt.arg)
214+
})
215+
}
216+
}

modules/web/middleware/binding.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"reflect"
99
"strings"
1010

11+
"code.gitea.io/gitea/modules/setting"
1112
"code.gitea.io/gitea/modules/translation"
1213
"code.gitea.io/gitea/modules/util"
1314
"code.gitea.io/gitea/modules/validation"
@@ -135,7 +136,11 @@ func Validate(errs binding.Errors, data map[string]any, f Form, l translation.Lo
135136
case validation.ErrRegexPattern:
136137
data["ErrorMsg"] = trName + l.Tr("form.regex_pattern_error", errs[0].Message)
137138
case validation.ErrUsername:
138-
data["ErrorMsg"] = trName + l.Tr("form.username_error")
139+
if setting.Service.AllowDotsInUsernames {
140+
data["ErrorMsg"] = trName + l.Tr("form.username_error")
141+
} else {
142+
data["ErrorMsg"] = trName + l.Tr("form.username_error_no_dots")
143+
}
139144
case validation.ErrInvalidGroupTeamMap:
140145
data["ErrorMsg"] = trName + l.Tr("form.invalid_group_team_map_error", errs[0].Message)
141146
default:

options/locale/locale_en-US.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ default_allow_create_organization = Allow Creation of Organizations by Default
294294
default_allow_create_organization_popup = Allow new user accounts to create organizations by default.
295295
default_enable_timetracking = Enable Time Tracking by Default
296296
default_enable_timetracking_popup = Enable time tracking for new repositories by default.
297+
allow_dots_in_usernames = Allow users to use dots in their usernames. Doesn't affect existing accounts.
297298
no_reply_address = Hidden Email Domain
298299
no_reply_address_helper = Domain name for users with a hidden email address. For example, the username 'joe' will be logged in Git as '[email protected]' if the hidden email domain is set to 'noreply.example.org'.
299300
password_algorithm = Password Hash Algorithm
@@ -533,6 +534,7 @@ include_error = ` must contain substring "%s".`
533534
glob_pattern_error = ` glob pattern is invalid: %s.`
534535
regex_pattern_error = ` regex pattern is invalid: %s.`
535536
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.`
537+
username_error_no_dots = ` can only contain alphanumeric chars ('0-9','a-z','A-Z'), dash ('-') and underscore ('_'). It cannot begin or end with non-alphanumeric chars, and consecutive non-alphanumeric chars are also forbidden.`
536538
invalid_group_team_map_error = ` mapping is invalid: %s`
537539
unknown_error = Unknown error:
538540
captcha_incorrect = The CAPTCHA code is incorrect.

templates/admin/config.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@
157157
<dd>{{if .Service.DefaultKeepEmailPrivate}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
158158
<dt>{{ctx.Locale.Tr "admin.config.default_allow_create_organization"}}</dt>
159159
<dd>{{if .Service.DefaultAllowCreateOrganization}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
160+
<dt>{{ctx.Locale.Tr "admin.config.allow_dots_in_usernames"}}</dt>
161+
<dd>{{if .Service.AllowDotsInUsernames}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
160162
<dt>{{ctx.Locale.Tr "admin.config.enable_timetracking"}}</dt>
161163
<dd>{{if .Service.EnableTimetracking}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</dd>
162164
{{if .Service.EnableTimetracking}}

0 commit comments

Comments
 (0)