You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

user_test.go 10KB

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