Skip to content

Commit 6029d78

Browse files
authored
Improve the maintainblity of the reserved username list (#32229)
1 parent c221767 commit 6029d78

File tree

3 files changed

+41
-68
lines changed

3 files changed

+41
-68
lines changed

models/user/user.go

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -565,41 +565,43 @@ var (
565565
".",
566566
"..",
567567
".well-known",
568-
"api",
569-
"assets",
570-
"attachments",
571-
"avatar",
572-
"avatars",
568+
569+
"api", // gitea api
570+
"metrics", // prometheus metrics api
571+
"v2", // container registry api
572+
573+
"assets", // static asset files
574+
"attachments", // issue attachments
575+
576+
"avatar", // avatar by email hash
577+
"avatars", // user avatars by file name
578+
"repo-avatars",
579+
573580
"captcha",
574-
"commits",
575-
"debug",
576-
"error",
581+
"login", // oauth2 login
582+
"org", // org create/manage, or "/org/{org}", BUT if an org is named as "invite" then it goes wrong
583+
"repo", // repo create/migrate, etc
584+
"user", // user login/activate/settings, etc
585+
577586
"explore",
578-
"favicon.ico",
579-
"ghost",
580587
"issues",
581-
"login",
582-
"manifest.json",
583-
"metrics",
588+
"pulls",
584589
"milestones",
585-
"new",
586590
"notifications",
587-
"org",
588-
"pulls",
589-
"raw",
590-
"repo",
591-
"repo-avatars",
592-
"robots.txt",
593-
"search",
594-
"serviceworker.js",
595-
"ssh_info",
591+
592+
"favicon.ico",
593+
"manifest.json", // web app manifests
594+
"robots.txt", // search engine robots
595+
"sitemap.xml", // search engine sitemap
596+
"ssh_info", // agit info
596597
"swagger.v1.json",
597-
"user",
598-
"v2",
599-
"gitea-actions",
598+
599+
"ghost", // reserved name for deleted users (id: -1)
600+
"gitea-actions", // gitea builtin user (id: -2)
600601
}
601602

602-
// DON'T ADD ANY NEW STUFF, WE SOLVE THIS WITH `/user/{obj}` PATHS!
603+
// These names are reserved for user accounts: user's keys, user's rss feed, user's avatar, etc.
604+
// DO NOT add any new stuff! The paths with these names are processed by `/{username}` handler (UsernameSubRoute) manually.
603605
reservedUserPatterns = []string{"*.keys", "*.gpg", "*.rss", "*.atom", "*.png"}
604606
)
605607

services/user/user_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,10 @@ func TestRenameUser(t *testing.T) {
114114
})
115115

116116
t.Run("Non usable username", func(t *testing.T) {
117-
usernames := []string{"--diff", "aa.png", ".well-known", "search", "aaa.atom"}
117+
usernames := []string{"--diff", ".well-known", "gitea-actions", "aaa.atom", "aa.png"}
118118
for _, username := range usernames {
119-
t.Run(username, func(t *testing.T) {
120-
assert.Error(t, user_model.IsUsableUsername(username))
121-
assert.Error(t, RenameUser(db.DefaultContext, user, username))
122-
})
119+
assert.Error(t, user_model.IsUsableUsername(username), "non-usable username: %s", username)
120+
assert.Error(t, RenameUser(db.DefaultContext, user, username), "non-usable username: %s", username)
123121
}
124122
})
125123

tests/integration/user_test.go

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package integration
55

66
import (
77
"net/http"
8+
"strings"
89
"testing"
910

1011
auth_model "code.gitea.io/gitea/models/auth"
@@ -98,41 +99,12 @@ func TestRenameReservedUsername(t *testing.T) {
9899
reservedUsernames := []string{
99100
// ".", "..", ".well-known", // The names are not only reserved but also invalid
100101
"api",
101-
"assets",
102-
"attachments",
103-
"avatar",
104-
"avatars",
105-
"captcha",
106-
"commits",
107-
"debug",
108-
"error",
109-
"explore",
110-
"favicon.ico",
111-
"ghost",
112-
"issues",
113-
"login",
114-
"manifest.json",
115-
"metrics",
116-
"milestones",
117-
"new",
118-
"notifications",
119-
"org",
120-
"pulls",
121-
"raw",
122-
"repo",
123-
"repo-avatars",
124-
"robots.txt",
125-
"search",
126-
"serviceworker.js",
127-
"ssh_info",
128-
"swagger.v1.json",
129-
"user",
130-
"v2",
102+
"name.keys",
131103
}
132104

133105
session := loginUser(t, "user2")
106+
locale := translation.NewLocale("en-US")
134107
for _, reservedUsername := range reservedUsernames {
135-
t.Logf("Testing username %s", reservedUsername)
136108
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
137109
"_csrf": GetUserCSRFToken(t, session),
138110
"name": reservedUsername,
@@ -144,11 +116,12 @@ func TestRenameReservedUsername(t *testing.T) {
144116
req = NewRequest(t, "GET", test.RedirectURL(resp))
145117
resp = session.MakeRequest(t, req, http.StatusOK)
146118
htmlDoc := NewHTMLParser(t, resp.Body)
147-
assert.Contains(t,
148-
htmlDoc.doc.Find(".ui.negative.message").Text(),
149-
translation.NewLocale("en-US").TrString("user.form.name_reserved", reservedUsername),
150-
)
151-
119+
actualMsg := strings.TrimSpace(htmlDoc.doc.Find(".ui.negative.message").Text())
120+
expectedMsg := locale.TrString("user.form.name_reserved", reservedUsername)
121+
if strings.Contains(reservedUsername, ".") {
122+
expectedMsg = locale.TrString("user.form.name_pattern_not_allowed", reservedUsername)
123+
}
124+
assert.Equal(t, expectedMsg, actualMsg)
152125
unittest.AssertNotExistsBean(t, &user_model.User{Name: reservedUsername})
153126
}
154127
}

0 commit comments

Comments
 (0)