Improve the maintainblity of the reserved username list (#32229)

pull/32236/head
wxiaoguang 1 month ago committed by GitHub
parent c2217670dd
commit 6029d78ab5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 56
      models/user/user.go
  2. 8
      services/user/user_test.go
  3. 45
      tests/integration/user_test.go

@ -565,41 +565,43 @@ var (
".", ".",
"..", "..",
".well-known", ".well-known",
"api",
"assets", "api", // gitea api
"attachments", "metrics", // prometheus metrics api
"avatar", "v2", // container registry api
"avatars",
"assets", // static asset files
"attachments", // issue attachments
"avatar", // avatar by email hash
"avatars", // user avatars by file name
"repo-avatars",
"captcha", "captcha",
"commits", "login", // oauth2 login
"debug", "org", // org create/manage, or "/org/{org}", BUT if an org is named as "invite" then it goes wrong
"error", "repo", // repo create/migrate, etc
"user", // user login/activate/settings, etc
"explore", "explore",
"favicon.ico",
"ghost",
"issues", "issues",
"login", "pulls",
"manifest.json",
"metrics",
"milestones", "milestones",
"new",
"notifications", "notifications",
"org",
"pulls", "favicon.ico",
"raw", "manifest.json", // web app manifests
"repo", "robots.txt", // search engine robots
"repo-avatars", "sitemap.xml", // search engine sitemap
"robots.txt", "ssh_info", // agit info
"search",
"serviceworker.js",
"ssh_info",
"swagger.v1.json", "swagger.v1.json",
"user",
"v2", "ghost", // reserved name for deleted users (id: -1)
"gitea-actions", "gitea-actions", // gitea builtin user (id: -2)
} }
// DON'T ADD ANY NEW STUFF, WE SOLVE THIS WITH `/user/{obj}` PATHS! // These names are reserved for user accounts: user's keys, user's rss feed, user's avatar, etc.
// DO NOT add any new stuff! The paths with these names are processed by `/{username}` handler (UsernameSubRoute) manually.
reservedUserPatterns = []string{"*.keys", "*.gpg", "*.rss", "*.atom", "*.png"} reservedUserPatterns = []string{"*.keys", "*.gpg", "*.rss", "*.atom", "*.png"}
) )

@ -114,12 +114,10 @@ func TestRenameUser(t *testing.T) {
}) })
t.Run("Non usable username", func(t *testing.T) { t.Run("Non usable username", func(t *testing.T) {
usernames := []string{"--diff", "aa.png", ".well-known", "search", "aaa.atom"} usernames := []string{"--diff", ".well-known", "gitea-actions", "aaa.atom", "aa.png"}
for _, username := range usernames { for _, username := range usernames {
t.Run(username, func(t *testing.T) { assert.Error(t, user_model.IsUsableUsername(username), "non-usable username: %s", username)
assert.Error(t, user_model.IsUsableUsername(username)) assert.Error(t, RenameUser(db.DefaultContext, user, username), "non-usable username: %s", username)
assert.Error(t, RenameUser(db.DefaultContext, user, username))
})
} }
}) })

@ -5,6 +5,7 @@ package integration
import ( import (
"net/http" "net/http"
"strings"
"testing" "testing"
auth_model "code.gitea.io/gitea/models/auth" auth_model "code.gitea.io/gitea/models/auth"
@ -98,41 +99,12 @@ func TestRenameReservedUsername(t *testing.T) {
reservedUsernames := []string{ reservedUsernames := []string{
// ".", "..", ".well-known", // The names are not only reserved but also invalid // ".", "..", ".well-known", // The names are not only reserved but also invalid
"api", "api",
"assets", "name.keys",
"attachments",
"avatar",
"avatars",
"captcha",
"commits",
"debug",
"error",
"explore",
"favicon.ico",
"ghost",
"issues",
"login",
"manifest.json",
"metrics",
"milestones",
"new",
"notifications",
"org",
"pulls",
"raw",
"repo",
"repo-avatars",
"robots.txt",
"search",
"serviceworker.js",
"ssh_info",
"swagger.v1.json",
"user",
"v2",
} }
session := loginUser(t, "user2") session := loginUser(t, "user2")
locale := translation.NewLocale("en-US")
for _, reservedUsername := range reservedUsernames { for _, reservedUsername := range reservedUsernames {
t.Logf("Testing username %s", reservedUsername)
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
"_csrf": GetUserCSRFToken(t, session), "_csrf": GetUserCSRFToken(t, session),
"name": reservedUsername, "name": reservedUsername,
@ -144,11 +116,12 @@ func TestRenameReservedUsername(t *testing.T) {
req = NewRequest(t, "GET", test.RedirectURL(resp)) req = NewRequest(t, "GET", test.RedirectURL(resp))
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
assert.Contains(t, actualMsg := strings.TrimSpace(htmlDoc.doc.Find(".ui.negative.message").Text())
htmlDoc.doc.Find(".ui.negative.message").Text(), expectedMsg := locale.TrString("user.form.name_reserved", reservedUsername)
translation.NewLocale("en-US").TrString("user.form.name_reserved", reservedUsername), if strings.Contains(reservedUsername, ".") {
) expectedMsg = locale.TrString("user.form.name_pattern_not_allowed", reservedUsername)
}
assert.Equal(t, expectedMsg, actualMsg)
unittest.AssertNotExistsBean(t, &user_model.User{Name: reservedUsername}) unittest.AssertNotExistsBean(t, &user_model.User{Name: reservedUsername})
} }
} }

Loading…
Cancel
Save