code.gitea.io/gitea@v1.21.7/tests/integration/user_test.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "net/http" 8 "testing" 9 10 auth_model "code.gitea.io/gitea/models/auth" 11 issues_model "code.gitea.io/gitea/models/issues" 12 repo_model "code.gitea.io/gitea/models/repo" 13 "code.gitea.io/gitea/models/unittest" 14 user_model "code.gitea.io/gitea/models/user" 15 "code.gitea.io/gitea/modules/setting" 16 api "code.gitea.io/gitea/modules/structs" 17 "code.gitea.io/gitea/modules/test" 18 "code.gitea.io/gitea/modules/translation" 19 "code.gitea.io/gitea/tests" 20 21 "github.com/stretchr/testify/assert" 22 ) 23 24 func TestViewUser(t *testing.T) { 25 defer tests.PrepareTestEnv(t)() 26 27 req := NewRequest(t, "GET", "/user2") 28 MakeRequest(t, req, http.StatusOK) 29 } 30 31 func TestRenameUsername(t *testing.T) { 32 defer tests.PrepareTestEnv(t)() 33 34 session := loginUser(t, "user2") 35 req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ 36 "_csrf": GetCSRF(t, session, "/user/settings"), 37 "name": "newUsername", 38 "email": "user2@example.com", 39 "language": "en-US", 40 }) 41 session.MakeRequest(t, req, http.StatusSeeOther) 42 43 unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "newUsername"}) 44 unittest.AssertNotExistsBean(t, &user_model.User{Name: "user2"}) 45 } 46 47 func TestRenameInvalidUsername(t *testing.T) { 48 defer tests.PrepareTestEnv(t)() 49 50 invalidUsernames := []string{ 51 "%2f*", 52 "%2f.", 53 "%2f..", 54 "%00", 55 "thisHas ASpace", 56 "p<A>tho>lo<gical", 57 ".", 58 "..", 59 ".well-known", 60 ".abc", 61 "abc.", 62 "a..bc", 63 "a...bc", 64 "a.-bc", 65 "a._bc", 66 "a_-bc", 67 "a/bc", 68 "☁️", 69 "-", 70 "--diff", 71 "-im-here", 72 "a space", 73 } 74 75 session := loginUser(t, "user2") 76 for _, invalidUsername := range invalidUsernames { 77 t.Logf("Testing username %s", invalidUsername) 78 79 req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ 80 "_csrf": GetCSRF(t, session, "/user/settings"), 81 "name": invalidUsername, 82 "email": "user2@example.com", 83 }) 84 resp := session.MakeRequest(t, req, http.StatusOK) 85 htmlDoc := NewHTMLParser(t, resp.Body) 86 assert.Contains(t, 87 htmlDoc.doc.Find(".ui.negative.message").Text(), 88 translation.NewLocale("en-US").Tr("form.username_error"), 89 ) 90 91 unittest.AssertNotExistsBean(t, &user_model.User{Name: invalidUsername}) 92 } 93 } 94 95 func TestRenameReservedUsername(t *testing.T) { 96 defer tests.PrepareTestEnv(t)() 97 98 reservedUsernames := []string{ 99 // ".", "..", ".well-known", // The names are not only reserved but also invalid 100 "admin", 101 "api", 102 "assets", 103 "attachments", 104 "avatar", 105 "avatars", 106 "captcha", 107 "commits", 108 "debug", 109 "error", 110 "explore", 111 "favicon.ico", 112 "ghost", 113 "issues", 114 "login", 115 "manifest.json", 116 "metrics", 117 "milestones", 118 "new", 119 "notifications", 120 "org", 121 "pulls", 122 "raw", 123 "repo", 124 "repo-avatars", 125 "robots.txt", 126 "search", 127 "serviceworker.js", 128 "ssh_info", 129 "swagger.v1.json", 130 "user", 131 "v2", 132 } 133 134 session := loginUser(t, "user2") 135 for _, reservedUsername := range reservedUsernames { 136 t.Logf("Testing username %s", reservedUsername) 137 req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ 138 "_csrf": GetCSRF(t, session, "/user/settings"), 139 "name": reservedUsername, 140 "email": "user2@example.com", 141 "language": "en-US", 142 }) 143 resp := session.MakeRequest(t, req, http.StatusSeeOther) 144 145 req = NewRequest(t, "GET", test.RedirectURL(resp)) 146 resp = session.MakeRequest(t, req, http.StatusOK) 147 htmlDoc := NewHTMLParser(t, resp.Body) 148 assert.Contains(t, 149 htmlDoc.doc.Find(".ui.negative.message").Text(), 150 translation.NewLocale("en-US").Tr("user.form.name_reserved", reservedUsername), 151 ) 152 153 unittest.AssertNotExistsBean(t, &user_model.User{Name: reservedUsername}) 154 } 155 } 156 157 func TestExportUserGPGKeys(t *testing.T) { 158 defer tests.PrepareTestEnv(t)() 159 // Export empty key list 160 testExportUserGPGKeys(t, "user1", `-----BEGIN PGP PUBLIC KEY BLOCK----- 161 Note: This user hasn't uploaded any GPG keys. 162 163 164 =twTO 165 -----END PGP PUBLIC KEY BLOCK----- 166 `) 167 // Import key 168 // User1 <user1@example.com> 169 session := loginUser(t, "user1") 170 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) 171 testCreateGPGKey(t, session.MakeRequest, token, http.StatusCreated, `-----BEGIN PGP PUBLIC KEY BLOCK----- 172 173 mQENBFyy/VUBCADJ7zbM20Z1RWmFoVgp5WkQfI2rU1Vj9cQHes9i42wVLLtcbPeo 174 QzubgzvMPITDy7nfWxgSf83E23DoHQ1ACFbQh/6eFSRrjsusp3YQ/08NSfPPbcu8 175 0M5G+VGwSfzS5uEcwBVQmHyKdcOZIERTNMtYZx1C3bjLD1XVJHvWz9D72Uq4qeO3 176 8SR+lzp5n6ppUakcmRnxt3nGRBj1+hEGkdgzyPo93iy+WioegY2lwCA9xMEo5dah 177 BmYxWx51zyiXYlReTaxlyb3/nuSUt8IcW3Q8zjdtJj4Nu8U1SpV8EdaA1I9IPbHW 178 510OSLmD3XhqHH5m6mIxL1YoWxk3V7gpDROtABEBAAG0GVVzZXIxIDx1c2VyMUBl 179 eGFtcGxlLmNvbT6JAU4EEwEIADgWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9 180 VQIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD9+v0I6RSEH22YCACFqL5+ 181 6M0m18AMC/pumcpnnmvAS1GrrKTF8nOROA1augZwp1WCNuKw2R6uOJIHANrYECSn 182 u7+j6GBP2gbIW8mSAzS6HWCs7GGiPpVtT4wcu8wljUI6BxjpyZtoEkriyBjt6HfK 183 rkegbkuySoJvjq4IcO5D1LB1JWgsUjMYQJj/ZpBIzVtjG9QtFSOiT1Hct4PoZHdC 184 nsdSgyCkwRZXG+u3kT/wP9F663ba4o16vYlz3dCGo66lF2tyoG3qcyZ1OUzUrnuv 185 96ytAzT6XIhrE0nVoBprMxFF5zExotJD3bHjcGBFNLf944bhjKee3U6t9+OsfJVC 186 l7N5xxIawCuTQdbfuQENBFyy/VUBCADe61yGEoTwKfsOKIhxLaNoRmD883O0tiWt 187 soO/HPj9dPQLTOiwXgSgSCd8C+LNxGKct87wgFozpah4tDLC6c0nALuHJ0SLbkfz 188 55aRhLeOOcrAydatDp72GroXzqpZ0xZBk5wjIWdgEol2GmVRM8QGbeuakU/HVz5y 189 lPzxUUocgdbSi3GE3zbzijQzVJdyL/kw/KP7pKT/PPKKJ2C5NQDLy0XGKEHddXGR 190 EWKkVlRalxq/TjfaMR0bi3MpezBsQmp99ATPO/d7trayZUxQHRtXzGFiOXfDHATr 191 qN730sODjqvU+mpc/SHCRwh9qWDjZRHSuKU5YDBjb5jIQJivZsQ/ABEBAAGJATYE 192 GAEIACAWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9VQIbDAAKCRD9+v0I6RSE 193 H7WoB/4tXl+97rQ6owPCGSVp1Xbwt2521V7COgsOFRVTRTryEWxRW8mm0S7wQvax 194 C0TLXKur6NVYQMn01iyL+FZzRpEWNuYF3f9QeeLJ/+l2DafESNhNTy17+RPmacK6 195 21dccpqchByVw/UMDeHSyjQLiG2lxzt8Gfx2gHmSbrq3aWovTGyz6JTffZvfy/n2 196 0Hm437OBPazO0gZyXhdV2PE5RSUfvAgm44235tcV5EV0d32TJDfv61+Vr2GUbah6 197 7XhJ1v6JYuh8kaYaEz8OpZDeh7f6Ho6PzJrsy/TKTKhGgZNINj1iaPFyOkQgKR5M 198 GrE0MHOxUbc9tbtyk0F1SuzREUBH 199 =DDXw 200 -----END PGP PUBLIC KEY BLOCK----- 201 `) 202 // Export new key 203 testExportUserGPGKeys(t, "user1", `-----BEGIN PGP PUBLIC KEY BLOCK----- 204 205 xsBNBFyy/VUBCADJ7zbM20Z1RWmFoVgp5WkQfI2rU1Vj9cQHes9i42wVLLtcbPeo 206 QzubgzvMPITDy7nfWxgSf83E23DoHQ1ACFbQh/6eFSRrjsusp3YQ/08NSfPPbcu8 207 0M5G+VGwSfzS5uEcwBVQmHyKdcOZIERTNMtYZx1C3bjLD1XVJHvWz9D72Uq4qeO3 208 8SR+lzp5n6ppUakcmRnxt3nGRBj1+hEGkdgzyPo93iy+WioegY2lwCA9xMEo5dah 209 BmYxWx51zyiXYlReTaxlyb3/nuSUt8IcW3Q8zjdtJj4Nu8U1SpV8EdaA1I9IPbHW 210 510OSLmD3XhqHH5m6mIxL1YoWxk3V7gpDROtABEBAAHNGVVzZXIxIDx1c2VyMUBl 211 eGFtcGxlLmNvbT7CwI4EEwEIADgWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9 212 VQIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD9+v0I6RSEH22YCACFqL5+ 213 6M0m18AMC/pumcpnnmvAS1GrrKTF8nOROA1augZwp1WCNuKw2R6uOJIHANrYECSn 214 u7+j6GBP2gbIW8mSAzS6HWCs7GGiPpVtT4wcu8wljUI6BxjpyZtoEkriyBjt6HfK 215 rkegbkuySoJvjq4IcO5D1LB1JWgsUjMYQJj/ZpBIzVtjG9QtFSOiT1Hct4PoZHdC 216 nsdSgyCkwRZXG+u3kT/wP9F663ba4o16vYlz3dCGo66lF2tyoG3qcyZ1OUzUrnuv 217 96ytAzT6XIhrE0nVoBprMxFF5zExotJD3bHjcGBFNLf944bhjKee3U6t9+OsfJVC 218 l7N5xxIawCuTQdbfzsBNBFyy/VUBCADe61yGEoTwKfsOKIhxLaNoRmD883O0tiWt 219 soO/HPj9dPQLTOiwXgSgSCd8C+LNxGKct87wgFozpah4tDLC6c0nALuHJ0SLbkfz 220 55aRhLeOOcrAydatDp72GroXzqpZ0xZBk5wjIWdgEol2GmVRM8QGbeuakU/HVz5y 221 lPzxUUocgdbSi3GE3zbzijQzVJdyL/kw/KP7pKT/PPKKJ2C5NQDLy0XGKEHddXGR 222 EWKkVlRalxq/TjfaMR0bi3MpezBsQmp99ATPO/d7trayZUxQHRtXzGFiOXfDHATr 223 qN730sODjqvU+mpc/SHCRwh9qWDjZRHSuKU5YDBjb5jIQJivZsQ/ABEBAAHCwHYE 224 GAEIACAWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9VQIbDAAKCRD9+v0I6RSE 225 H7WoB/4tXl+97rQ6owPCGSVp1Xbwt2521V7COgsOFRVTRTryEWxRW8mm0S7wQvax 226 C0TLXKur6NVYQMn01iyL+FZzRpEWNuYF3f9QeeLJ/+l2DafESNhNTy17+RPmacK6 227 21dccpqchByVw/UMDeHSyjQLiG2lxzt8Gfx2gHmSbrq3aWovTGyz6JTffZvfy/n2 228 0Hm437OBPazO0gZyXhdV2PE5RSUfvAgm44235tcV5EV0d32TJDfv61+Vr2GUbah6 229 7XhJ1v6JYuh8kaYaEz8OpZDeh7f6Ho6PzJrsy/TKTKhGgZNINj1iaPFyOkQgKR5M 230 GrE0MHOxUbc9tbtyk0F1SuzREUBH 231 =WFf5 232 -----END PGP PUBLIC KEY BLOCK----- 233 `) 234 } 235 236 func testExportUserGPGKeys(t *testing.T, user, expected string) { 237 session := loginUser(t, user) 238 t.Logf("Testing username %s export gpg keys", user) 239 req := NewRequest(t, "GET", "/"+user+".gpg") 240 resp := session.MakeRequest(t, req, http.StatusOK) 241 // t.Log(resp.Body.String()) 242 assert.Equal(t, expected, resp.Body.String()) 243 } 244 245 func TestGetUserRss(t *testing.T) { 246 user34 := "the_34-user.with.all.allowedChars" 247 req := NewRequestf(t, "GET", "/%s.rss", user34) 248 resp := MakeRequest(t, req, http.StatusOK) 249 if assert.EqualValues(t, "application/rss+xml;charset=utf-8", resp.Header().Get("Content-Type")) { 250 rssDoc := NewHTMLParser(t, resp.Body).Find("channel") 251 title, _ := rssDoc.ChildrenFiltered("title").Html() 252 assert.EqualValues(t, "Feed of "the_1-user.with.all.allowedChars"", title) 253 description, _ := rssDoc.ChildrenFiltered("description").Html() 254 assert.EqualValues(t, "<p dir="auto">some <a href="https://commonmark.org/" rel="nofollow">commonmark</a>!</p>\n", description) 255 } 256 } 257 258 func TestListStopWatches(t *testing.T) { 259 defer tests.PrepareTestEnv(t)() 260 261 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 262 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 263 264 session := loginUser(t, owner.Name) 265 req := NewRequestf(t, "GET", "/user/stopwatches") 266 resp := session.MakeRequest(t, req, http.StatusOK) 267 var apiWatches []*api.StopWatch 268 DecodeJSON(t, resp, &apiWatches) 269 stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}) 270 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}) 271 if assert.Len(t, apiWatches, 1) { 272 assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) 273 assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex) 274 assert.EqualValues(t, issue.Title, apiWatches[0].IssueTitle) 275 assert.EqualValues(t, repo.Name, apiWatches[0].RepoName) 276 assert.EqualValues(t, repo.OwnerName, apiWatches[0].RepoOwnerName) 277 assert.Greater(t, apiWatches[0].Seconds, int64(0)) 278 } 279 } 280 281 func TestUserLocationMapLink(t *testing.T) { 282 setting.Service.UserLocationMapURL = "https://example/foo/" 283 defer tests.PrepareTestEnv(t)() 284 285 session := loginUser(t, "user2") 286 req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{ 287 "_csrf": GetCSRF(t, session, "/user/settings"), 288 "name": "user2", 289 "email": "user@example.com", 290 "language": "en-US", 291 "location": "A/b", 292 }) 293 session.MakeRequest(t, req, http.StatusSeeOther) 294 295 req = NewRequest(t, "GET", "/user2/") 296 resp := session.MakeRequest(t, req, http.StatusOK) 297 htmlDoc := NewHTMLParser(t, resp.Body) 298 htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true) 299 }