Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

user_test.go 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package user_test
  4. import (
  5. "context"
  6. "fmt"
  7. "math/rand"
  8. "strings"
  9. "testing"
  10. "time"
  11. "code.gitea.io/gitea/models/auth"
  12. "code.gitea.io/gitea/models/db"
  13. "code.gitea.io/gitea/models/unittest"
  14. user_model "code.gitea.io/gitea/models/user"
  15. "code.gitea.io/gitea/modules/auth/password/hash"
  16. "code.gitea.io/gitea/modules/setting"
  17. "code.gitea.io/gitea/modules/structs"
  18. "code.gitea.io/gitea/modules/timeutil"
  19. "code.gitea.io/gitea/modules/util"
  20. "github.com/stretchr/testify/assert"
  21. )
  22. func TestOAuth2Application_LoadUser(t *testing.T) {
  23. assert.NoError(t, unittest.PrepareTestDatabase())
  24. app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1})
  25. user, err := user_model.GetUserByID(db.DefaultContext, app.UID)
  26. assert.NoError(t, err)
  27. assert.NotNil(t, user)
  28. }
  29. func TestGetUserEmailsByNames(t *testing.T) {
  30. assert.NoError(t, unittest.PrepareTestDatabase())
  31. // ignore none active user email
  32. assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user9"}))
  33. assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user5"}))
  34. assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "org7"}))
  35. }
  36. func TestCanCreateOrganization(t *testing.T) {
  37. assert.NoError(t, unittest.PrepareTestDatabase())
  38. admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
  39. assert.True(t, admin.CanCreateOrganization())
  40. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  41. assert.True(t, user.CanCreateOrganization())
  42. // Disable user create organization permission.
  43. user.AllowCreateOrganization = false
  44. assert.False(t, user.CanCreateOrganization())
  45. setting.Admin.DisableRegularOrgCreation = true
  46. user.AllowCreateOrganization = true
  47. assert.True(t, admin.CanCreateOrganization())
  48. assert.False(t, user.CanCreateOrganization())
  49. }
  50. func TestSearchUsers(t *testing.T) {
  51. assert.NoError(t, unittest.PrepareTestDatabase())
  52. testSuccess := func(opts *user_model.SearchUserOptions, expectedUserOrOrgIDs []int64) {
  53. users, _, err := user_model.SearchUsers(db.DefaultContext, opts)
  54. assert.NoError(t, err)
  55. cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts)
  56. if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) {
  57. for i, expectedID := range expectedUserOrOrgIDs {
  58. assert.EqualValues(t, expectedID, users[i].ID, "case: %s", cassText)
  59. }
  60. }
  61. }
  62. // test orgs
  63. testOrgSuccess := func(opts *user_model.SearchUserOptions, expectedOrgIDs []int64) {
  64. opts.Type = user_model.UserTypeOrganization
  65. testSuccess(opts, expectedOrgIDs)
  66. }
  67. testOrgSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1, PageSize: 2}},
  68. []int64{3, 6})
  69. testOrgSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 2, PageSize: 2}},
  70. []int64{7, 17})
  71. testOrgSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 3, PageSize: 2}},
  72. []int64{19, 25})
  73. testOrgSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 4, PageSize: 2}},
  74. []int64{26})
  75. testOrgSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 5, PageSize: 2}},
  76. []int64{})
  77. // test users
  78. testUserSuccess := func(opts *user_model.SearchUserOptions, expectedUserIDs []int64) {
  79. opts.Type = user_model.UserTypeIndividual
  80. testSuccess(opts, expectedUserIDs)
  81. }
  82. testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}},
  83. []int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34})
  84. testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolFalse},
  85. []int64{9})
  86. testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
  87. []int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34})
  88. testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
  89. []int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
  90. // order by name asc default
  91. testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
  92. []int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
  93. testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsAdmin: util.OptionalBoolTrue},
  94. []int64{1})
  95. testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsRestricted: util.OptionalBoolTrue},
  96. []int64{29})
  97. testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsProhibitLogin: util.OptionalBoolTrue},
  98. []int64{30})
  99. testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: util.OptionalBoolTrue},
  100. []int64{24})
  101. }
  102. func TestEmailNotificationPreferences(t *testing.T) {
  103. assert.NoError(t, unittest.PrepareTestDatabase())
  104. for _, test := range []struct {
  105. expected string
  106. userID int64
  107. }{
  108. {user_model.EmailNotificationsEnabled, 1},
  109. {user_model.EmailNotificationsEnabled, 2},
  110. {user_model.EmailNotificationsOnMention, 3},
  111. {user_model.EmailNotificationsOnMention, 4},
  112. {user_model.EmailNotificationsEnabled, 5},
  113. {user_model.EmailNotificationsEnabled, 6},
  114. {user_model.EmailNotificationsDisabled, 7},
  115. {user_model.EmailNotificationsEnabled, 8},
  116. {user_model.EmailNotificationsOnMention, 9},
  117. } {
  118. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.userID})
  119. assert.Equal(t, test.expected, user.EmailNotifications())
  120. // Try all possible settings
  121. assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsEnabled))
  122. assert.Equal(t, user_model.EmailNotificationsEnabled, user.EmailNotifications())
  123. assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsOnMention))
  124. assert.Equal(t, user_model.EmailNotificationsOnMention, user.EmailNotifications())
  125. assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsDisabled))
  126. assert.Equal(t, user_model.EmailNotificationsDisabled, user.EmailNotifications())
  127. assert.NoError(t, user_model.SetEmailNotifications(db.DefaultContext, user, user_model.EmailNotificationsAndYourOwn))
  128. assert.Equal(t, user_model.EmailNotificationsAndYourOwn, user.EmailNotifications())
  129. }
  130. }
  131. func TestHashPasswordDeterministic(t *testing.T) {
  132. b := make([]byte, 16)
  133. u := &user_model.User{}
  134. algos := hash.RecommendedHashAlgorithms
  135. for j := 0; j < len(algos); j++ {
  136. u.PasswdHashAlgo = algos[j]
  137. for i := 0; i < 50; i++ {
  138. // generate a random password
  139. rand.Read(b)
  140. pass := string(b)
  141. // save the current password in the user - hash it and store the result
  142. u.SetPassword(pass)
  143. r1 := u.Passwd
  144. // run again
  145. u.SetPassword(pass)
  146. r2 := u.Passwd
  147. assert.NotEqual(t, r1, r2)
  148. assert.True(t, u.ValidatePassword(pass))
  149. }
  150. }
  151. }
  152. func BenchmarkHashPassword(b *testing.B) {
  153. // BenchmarkHashPassword ensures that it takes a reasonable amount of time
  154. // to hash a password - in order to protect from brute-force attacks.
  155. pass := "password1337"
  156. u := &user_model.User{Passwd: pass}
  157. b.ResetTimer()
  158. for i := 0; i < b.N; i++ {
  159. u.SetPassword(pass)
  160. }
  161. }
  162. func TestNewGitSig(t *testing.T) {
  163. users := make([]*user_model.User, 0, 20)
  164. err := db.GetEngine(db.DefaultContext).Find(&users)
  165. assert.NoError(t, err)
  166. for _, user := range users {
  167. sig := user.NewGitSig()
  168. assert.NotContains(t, sig.Name, "<")
  169. assert.NotContains(t, sig.Name, ">")
  170. assert.NotContains(t, sig.Name, "\n")
  171. assert.NotEqual(t, len(strings.TrimSpace(sig.Name)), 0)
  172. }
  173. }
  174. func TestDisplayName(t *testing.T) {
  175. users := make([]*user_model.User, 0, 20)
  176. err := db.GetEngine(db.DefaultContext).Find(&users)
  177. assert.NoError(t, err)
  178. for _, user := range users {
  179. displayName := user.DisplayName()
  180. assert.Equal(t, strings.TrimSpace(displayName), displayName)
  181. if len(strings.TrimSpace(user.FullName)) == 0 {
  182. assert.Equal(t, user.Name, displayName)
  183. }
  184. assert.NotEqual(t, len(strings.TrimSpace(displayName)), 0)
  185. }
  186. }
  187. func TestCreateUserInvalidEmail(t *testing.T) {
  188. user := &user_model.User{
  189. Name: "GiteaBot",
  190. Email: "GiteaBot@gitea.io\r\n",
  191. Passwd: ";p['////..-++']",
  192. IsAdmin: false,
  193. Theme: setting.UI.DefaultTheme,
  194. MustChangePassword: false,
  195. }
  196. err := user_model.CreateUser(db.DefaultContext, user)
  197. assert.Error(t, err)
  198. assert.True(t, user_model.IsErrEmailCharIsNotSupported(err))
  199. }
  200. func TestCreateUserEmailAlreadyUsed(t *testing.T) {
  201. assert.NoError(t, unittest.PrepareTestDatabase())
  202. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  203. // add new user with user2's email
  204. user.Name = "testuser"
  205. user.LowerName = strings.ToLower(user.Name)
  206. user.ID = 0
  207. err := user_model.CreateUser(db.DefaultContext, user)
  208. assert.Error(t, err)
  209. assert.True(t, user_model.IsErrEmailAlreadyUsed(err))
  210. }
  211. func TestCreateUserCustomTimestamps(t *testing.T) {
  212. assert.NoError(t, unittest.PrepareTestDatabase())
  213. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  214. // Add new user with a custom creation timestamp.
  215. var creationTimestamp timeutil.TimeStamp = 12345
  216. user.Name = "testuser"
  217. user.LowerName = strings.ToLower(user.Name)
  218. user.ID = 0
  219. user.Email = "unique@example.com"
  220. user.CreatedUnix = creationTimestamp
  221. err := user_model.CreateUser(db.DefaultContext, user)
  222. assert.NoError(t, err)
  223. fetched, err := user_model.GetUserByID(context.Background(), user.ID)
  224. assert.NoError(t, err)
  225. assert.Equal(t, creationTimestamp, fetched.CreatedUnix)
  226. assert.Equal(t, creationTimestamp, fetched.UpdatedUnix)
  227. }
  228. func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
  229. assert.NoError(t, unittest.PrepareTestDatabase())
  230. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  231. // There is no way to use a mocked time for the XORM auto-time functionality,
  232. // so use the real clock to approximate the expected timestamp.
  233. timestampStart := time.Now().Unix()
  234. // Add new user without a custom creation timestamp.
  235. user.Name = "Testuser"
  236. user.LowerName = strings.ToLower(user.Name)
  237. user.ID = 0
  238. user.Email = "unique@example.com"
  239. user.CreatedUnix = 0
  240. user.UpdatedUnix = 0
  241. err := user_model.CreateUser(db.DefaultContext, user)
  242. assert.NoError(t, err)
  243. timestampEnd := time.Now().Unix()
  244. fetched, err := user_model.GetUserByID(context.Background(), user.ID)
  245. assert.NoError(t, err)
  246. assert.LessOrEqual(t, timestampStart, fetched.CreatedUnix)
  247. assert.LessOrEqual(t, fetched.CreatedUnix, timestampEnd)
  248. assert.LessOrEqual(t, timestampStart, fetched.UpdatedUnix)
  249. assert.LessOrEqual(t, fetched.UpdatedUnix, timestampEnd)
  250. }
  251. func TestGetUserIDsByNames(t *testing.T) {
  252. assert.NoError(t, unittest.PrepareTestDatabase())
  253. // ignore non existing
  254. IDs, err := user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "user2", "none_existing_user"}, true)
  255. assert.NoError(t, err)
  256. assert.Equal(t, []int64{1, 2}, IDs)
  257. // ignore non existing
  258. IDs, err = user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "do_not_exist"}, false)
  259. assert.Error(t, err)
  260. assert.Equal(t, []int64(nil), IDs)
  261. }
  262. func TestGetMaileableUsersByIDs(t *testing.T) {
  263. assert.NoError(t, unittest.PrepareTestDatabase())
  264. results, err := user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, false)
  265. assert.NoError(t, err)
  266. assert.Len(t, results, 1)
  267. if len(results) > 1 {
  268. assert.Equal(t, results[0].ID, 1)
  269. }
  270. results, err = user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, true)
  271. assert.NoError(t, err)
  272. assert.Len(t, results, 2)
  273. if len(results) > 2 {
  274. assert.Equal(t, results[0].ID, 1)
  275. assert.Equal(t, results[1].ID, 4)
  276. }
  277. }
  278. func TestUpdateUser(t *testing.T) {
  279. assert.NoError(t, unittest.PrepareTestDatabase())
  280. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  281. user.KeepActivityPrivate = true
  282. assert.NoError(t, user_model.UpdateUser(db.DefaultContext, user, false))
  283. user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  284. assert.True(t, user.KeepActivityPrivate)
  285. setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false}
  286. user.KeepActivityPrivate = false
  287. user.Visibility = structs.VisibleTypePrivate
  288. assert.Error(t, user_model.UpdateUser(db.DefaultContext, user, false))
  289. user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  290. assert.True(t, user.KeepActivityPrivate)
  291. newEmail := "new_" + user.Email
  292. user.Email = newEmail
  293. assert.NoError(t, user_model.UpdateUser(db.DefaultContext, user, true))
  294. user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  295. assert.Equal(t, newEmail, user.Email)
  296. user.Email = "no mail@mail.org"
  297. assert.Error(t, user_model.UpdateUser(db.DefaultContext, user, true))
  298. }
  299. func TestUpdateUserEmailAlreadyUsed(t *testing.T) {
  300. assert.NoError(t, unittest.PrepareTestDatabase())
  301. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  302. org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
  303. user2.Email = org3.Email
  304. err := user_model.UpdateUser(db.DefaultContext, user2, true)
  305. assert.True(t, user_model.IsErrEmailAlreadyUsed(err))
  306. }
  307. func TestNewUserRedirect(t *testing.T) {
  308. // redirect to a completely new name
  309. assert.NoError(t, unittest.PrepareTestDatabase())
  310. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
  311. assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
  312. unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
  313. LowerName: user.LowerName,
  314. RedirectUserID: user.ID,
  315. })
  316. unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
  317. LowerName: "olduser1",
  318. RedirectUserID: user.ID,
  319. })
  320. }
  321. func TestNewUserRedirect2(t *testing.T) {
  322. // redirect to previously used name
  323. assert.NoError(t, unittest.PrepareTestDatabase())
  324. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
  325. assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "olduser1"))
  326. unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
  327. LowerName: user.LowerName,
  328. RedirectUserID: user.ID,
  329. })
  330. unittest.AssertNotExistsBean(t, &user_model.Redirect{
  331. LowerName: "olduser1",
  332. RedirectUserID: user.ID,
  333. })
  334. }
  335. func TestNewUserRedirect3(t *testing.T) {
  336. // redirect for a previously-unredirected user
  337. assert.NoError(t, unittest.PrepareTestDatabase())
  338. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  339. assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
  340. unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
  341. LowerName: user.LowerName,
  342. RedirectUserID: user.ID,
  343. })
  344. }
  345. func TestGetUserByOpenID(t *testing.T) {
  346. assert.NoError(t, unittest.PrepareTestDatabase())
  347. _, err := user_model.GetUserByOpenID(db.DefaultContext, "https://unknown")
  348. if assert.Error(t, err) {
  349. assert.True(t, user_model.IsErrUserNotExist(err))
  350. }
  351. user, err := user_model.GetUserByOpenID(db.DefaultContext, "https://user1.domain1.tld")
  352. if assert.NoError(t, err) {
  353. assert.Equal(t, int64(1), user.ID)
  354. }
  355. user, err = user_model.GetUserByOpenID(db.DefaultContext, "https://domain1.tld/user2/")
  356. if assert.NoError(t, err) {
  357. assert.Equal(t, int64(2), user.ID)
  358. }
  359. }
  360. func TestFollowUser(t *testing.T) {
  361. assert.NoError(t, unittest.PrepareTestDatabase())
  362. testSuccess := func(followerID, followedID int64) {
  363. assert.NoError(t, user_model.FollowUser(db.DefaultContext, followerID, followedID))
  364. unittest.AssertExistsAndLoadBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID})
  365. }
  366. testSuccess(4, 2)
  367. testSuccess(5, 2)
  368. assert.NoError(t, user_model.FollowUser(db.DefaultContext, 2, 2))
  369. unittest.CheckConsistencyFor(t, &user_model.User{})
  370. }
  371. func TestUnfollowUser(t *testing.T) {
  372. assert.NoError(t, unittest.PrepareTestDatabase())
  373. testSuccess := func(followerID, followedID int64) {
  374. assert.NoError(t, user_model.UnfollowUser(db.DefaultContext, followerID, followedID))
  375. unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID})
  376. }
  377. testSuccess(4, 2)
  378. testSuccess(5, 2)
  379. testSuccess(2, 2)
  380. unittest.CheckConsistencyFor(t, &user_model.User{})
  381. }
  382. func TestIsUserVisibleToViewer(t *testing.T) {
  383. assert.NoError(t, unittest.PrepareTestDatabase())
  384. user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) // admin, public
  385. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // normal, public
  386. user20 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) // public, same team as user31
  387. user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}) // public, is restricted
  388. user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31}) // private, same team as user20
  389. user33 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 33}) // limited, follows 31
  390. test := func(u, viewer *user_model.User, expected bool) {
  391. name := func(u *user_model.User) string {
  392. if u == nil {
  393. return "<nil>"
  394. }
  395. return u.Name
  396. }
  397. assert.Equal(t, expected, user_model.IsUserVisibleToViewer(db.DefaultContext, u, viewer), "user %v should be visible to viewer %v: %v", name(u), name(viewer), expected)
  398. }
  399. // admin viewer
  400. test(user1, user1, true)
  401. test(user20, user1, true)
  402. test(user31, user1, true)
  403. test(user33, user1, true)
  404. // non admin viewer
  405. test(user4, user4, true)
  406. test(user20, user4, true)
  407. test(user31, user4, false)
  408. test(user33, user4, true)
  409. test(user4, nil, true)
  410. // public user
  411. test(user4, user20, true)
  412. test(user4, user31, true)
  413. test(user4, user33, true)
  414. // limited user
  415. test(user33, user33, true)
  416. test(user33, user4, true)
  417. test(user33, user29, false)
  418. test(user33, nil, false)
  419. // private user
  420. test(user31, user31, true)
  421. test(user31, user4, false)
  422. test(user31, user20, true)
  423. test(user31, user29, false)
  424. test(user31, user33, true)
  425. test(user31, nil, false)
  426. }
  427. func Test_ValidateUser(t *testing.T) {
  428. oldSetting := setting.Service.AllowedUserVisibilityModesSlice
  429. defer func() {
  430. setting.Service.AllowedUserVisibilityModesSlice = oldSetting
  431. }()
  432. setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, true}
  433. kases := map[*user_model.User]bool{
  434. {ID: 1, Visibility: structs.VisibleTypePublic}: true,
  435. {ID: 2, Visibility: structs.VisibleTypeLimited}: false,
  436. {ID: 2, Visibility: structs.VisibleTypeLimited, Email: "invalid"}: false,
  437. {ID: 2, Visibility: structs.VisibleTypePrivate, Email: "valid@valid.com"}: true,
  438. }
  439. for kase, expected := range kases {
  440. err := user_model.ValidateUser(kase)
  441. assert.EqualValues(t, expected, err == nil, fmt.Sprintf("case: %+v", kase))
  442. }
  443. }