test_user_create_api.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. from django.contrib.auth import get_user_model
  2. from django.core import mail
  3. from django.test import override_settings
  4. from django.urls import reverse
  5. from misago.conf import settings
  6. from misago.users.models import Ban, Online
  7. from misago.users.testutils import UserTestCase
  8. UserModel = get_user_model()
  9. class UserCreateTests(UserTestCase):
  10. """tests for new user registration (POST to /api/users/)"""
  11. def setUp(self):
  12. super(UserCreateTests, self).setUp()
  13. self.api_link = '/api/users/'
  14. def test_empty_request(self):
  15. """empty request errors with code 400"""
  16. response = self.client.post(self.api_link)
  17. self.assertEqual(response.status_code, 400)
  18. def test_invalid_data(self):
  19. """invalid request data errors with code 400"""
  20. response = self.client.post(
  21. self.api_link,
  22. 'false',
  23. content_type="application/json",
  24. )
  25. self.assertEqual(response.status_code, 400)
  26. def test_authenticated_request(self):
  27. """authentiated user request errors with code 403"""
  28. self.login_user(self.get_authenticated_user())
  29. response = self.client.post(self.api_link)
  30. self.assertEqual(response.status_code, 403)
  31. def test_registration_off_request(self):
  32. """registrations off request errors with code 403"""
  33. settings.override_setting('account_activation', 'closed')
  34. response = self.client.post(self.api_link)
  35. self.assertContains(response, 'closed', status_code=403)
  36. def test_registration_validates_ip_ban(self):
  37. """api validates ip ban"""
  38. Ban.objects.create(
  39. check_type=Ban.IP,
  40. banned_value='127.*',
  41. user_message="You can't register account like this.",
  42. )
  43. response = self.client.post(
  44. self.api_link,
  45. data={
  46. 'username': 'totallyNew',
  47. 'email': 'loremipsum@dolor.met',
  48. 'password': 'LoremP4ssword',
  49. },
  50. )
  51. self.assertEqual(response.status_code, 403)
  52. def test_registration_validates_ip_registration_ban(self):
  53. """api validates ip registration-only ban"""
  54. Ban.objects.create(
  55. check_type=Ban.IP,
  56. banned_value='127.*',
  57. user_message="You can't register account like this.",
  58. registration_only=True,
  59. )
  60. response = self.client.post(
  61. self.api_link,
  62. data={
  63. 'username': 'totallyNew',
  64. 'email': 'loremipsum@dolor.met',
  65. 'password': 'LoremP4ssword',
  66. },
  67. )
  68. self.assertEqual(response.status_code, 400)
  69. self.assertEqual(
  70. response.json(), {
  71. '__all__': ["You can't register account like this."],
  72. }
  73. )
  74. def test_registration_validates_username(self):
  75. """api validates usernames"""
  76. user = self.get_authenticated_user()
  77. response = self.client.post(
  78. self.api_link,
  79. data={
  80. 'username': user.username,
  81. 'email': 'loremipsum@dolor.met',
  82. 'password': 'LoremP4ssword',
  83. },
  84. )
  85. self.assertEqual(response.status_code, 400)
  86. self.assertEqual(response.json(), {
  87. 'username': ["This username is not available."],
  88. })
  89. def test_registration_validates_username_ban(self):
  90. """api validates username ban"""
  91. Ban.objects.create(
  92. banned_value='totally*',
  93. user_message="You can't register account like this.",
  94. )
  95. response = self.client.post(
  96. self.api_link,
  97. data={
  98. 'username': 'totallyNew',
  99. 'email': 'loremipsum@dolor.met',
  100. 'password': 'LoremP4ssword',
  101. },
  102. )
  103. self.assertEqual(response.status_code, 400)
  104. self.assertEqual(
  105. response.json(), {
  106. 'username': ["You can't register account like this."],
  107. }
  108. )
  109. def test_registration_validates_username_registration_ban(self):
  110. """api validates username registration-only ban"""
  111. Ban.objects.create(
  112. banned_value='totally*',
  113. user_message="You can't register account like this.",
  114. registration_only=True,
  115. )
  116. response = self.client.post(
  117. self.api_link,
  118. data={
  119. 'username': 'totallyNew',
  120. 'email': 'loremipsum@dolor.met',
  121. 'password': 'LoremP4ssword',
  122. },
  123. )
  124. self.assertEqual(response.status_code, 400)
  125. self.assertEqual(
  126. response.json(), {
  127. 'username': ["You can't register account like this."],
  128. }
  129. )
  130. def test_registration_validates_email(self):
  131. """api validates usernames"""
  132. user = self.get_authenticated_user()
  133. response = self.client.post(
  134. self.api_link,
  135. data={
  136. 'username': 'totallyNew',
  137. 'email': user.email,
  138. 'password': 'LoremP4ssword',
  139. },
  140. )
  141. self.assertEqual(response.status_code, 400)
  142. self.assertEqual(response.json(), {
  143. 'email': ["This e-mail address is not available."],
  144. })
  145. def test_registration_validates_email_ban(self):
  146. """api validates email ban"""
  147. Ban.objects.create(
  148. check_type=Ban.EMAIL,
  149. banned_value='lorem*',
  150. user_message="You can't register account like this.",
  151. )
  152. response = self.client.post(
  153. self.api_link,
  154. data={
  155. 'username': 'totallyNew',
  156. 'email': 'loremipsum@dolor.met',
  157. 'password': 'LoremP4ssword',
  158. },
  159. )
  160. self.assertEqual(response.status_code, 400)
  161. self.assertEqual(response.json(), {
  162. 'email': ["You can't register account like this."],
  163. })
  164. def test_registration_validates_email_registration_ban(self):
  165. """api validates email registration-only ban"""
  166. Ban.objects.create(
  167. check_type=Ban.EMAIL,
  168. banned_value='lorem*',
  169. user_message="You can't register account like this.",
  170. registration_only=True,
  171. )
  172. response = self.client.post(
  173. self.api_link,
  174. data={
  175. 'username': 'totallyNew',
  176. 'email': 'loremipsum@dolor.met',
  177. 'password': 'LoremP4ssword',
  178. },
  179. )
  180. self.assertEqual(response.status_code, 400)
  181. self.assertEqual(response.json(), {
  182. 'email': ["You can't register account like this."],
  183. })
  184. def test_registration_validates_password(self):
  185. """api uses django's validate_password to validate registrations"""
  186. response = self.client.post(
  187. self.api_link,
  188. data={
  189. 'username': 'Bob',
  190. 'email': 'l.o.r.e.m.i.p.s.u.m@gmail.com',
  191. 'password': '123',
  192. },
  193. )
  194. self.assertContains(response, "password is too short", status_code=400)
  195. self.assertContains(response, "password is entirely numeric", status_code=400)
  196. self.assertContains(response, "email is not allowed", status_code=400)
  197. def test_registration_validates_password_similiarity(self):
  198. """api uses validate_password to validate registrations"""
  199. response = self.client.post(
  200. self.api_link,
  201. data={
  202. 'username': 'BobBoberson',
  203. 'email': 'l.o.r.e.m.i.p.s.u.m@gmail.com',
  204. 'password': 'BobBoberson',
  205. },
  206. )
  207. self.assertContains(response, "password is too similar to the username", status_code=400)
  208. @override_settings(captcha_type='qa', qa_question='Test', qa_answers='Lorem\nIpsum')
  209. def test_registration_validates_captcha(self):
  210. """api validates captcha"""
  211. response = self.client.post(
  212. self.api_link,
  213. data={
  214. 'username': 'totallyNew',
  215. 'email': 'loremipsum@dolor.met',
  216. 'password': 'LoremP4ssword',
  217. 'captcha': 'dolor'
  218. },
  219. )
  220. self.assertEqual(response.status_code, 400)
  221. self.assertEqual(
  222. response.json(), {
  223. 'captcha': ['Entered answer is incorrect.'],
  224. }
  225. )
  226. # valid captcha
  227. response = self.client.post(
  228. self.api_link,
  229. data={
  230. 'username': 'totallyNew',
  231. 'email': 'loremipsum@dolor.met',
  232. 'password': 'LoremP4ssword',
  233. 'captcha': 'ipSUM'
  234. },
  235. )
  236. self.assertEqual(response.status_code, 200)
  237. def test_registration_calls_validate_new_registration(self):
  238. """api uses validate_new_registration to validate registrations"""
  239. response = self.client.post(
  240. self.api_link,
  241. data={
  242. 'username': 'Bob',
  243. 'email': 'l.o.r.e.m.i.p.s.u.m@gmail.com',
  244. 'password': 'pas123',
  245. },
  246. )
  247. self.assertContains(response, "email is not allowed", status_code=400)
  248. def test_registration_creates_active_user(self):
  249. """api creates active and signed in user on POST"""
  250. settings.override_setting('account_activation', 'none')
  251. response = self.client.post(
  252. self.api_link,
  253. data={
  254. 'username': 'Bob',
  255. 'email': 'bob@bob.com',
  256. 'password': 'pass123',
  257. },
  258. )
  259. self.assertContains(response, 'active')
  260. self.assertContains(response, 'Bob')
  261. self.assertContains(response, 'bob@bob.com')
  262. UserModel.objects.get_by_username('Bob')
  263. test_user = UserModel.objects.get_by_email('bob@bob.com')
  264. self.assertEqual(Online.objects.filter(user=test_user).count(), 1)
  265. self.assertTrue(test_user.check_password('pass123'))
  266. auth_json = self.client.get(reverse('misago:api:auth')).json()
  267. self.assertTrue(auth_json['is_authenticated'])
  268. self.assertEqual(auth_json['username'], 'Bob')
  269. self.assertIn('Welcome', mail.outbox[0].subject)
  270. def test_registration_creates_inactive_user(self):
  271. """api creates inactive user on POST"""
  272. settings.override_setting('account_activation', 'user')
  273. response = self.client.post(
  274. self.api_link,
  275. data={
  276. 'username': 'Bob',
  277. 'email': 'bob@bob.com',
  278. 'password': 'pass123',
  279. },
  280. )
  281. self.assertContains(response, 'user')
  282. self.assertContains(response, 'Bob')
  283. self.assertContains(response, 'bob@bob.com')
  284. auth_json = self.client.get(reverse('misago:api:auth')).json()
  285. self.assertFalse(auth_json['is_authenticated'])
  286. UserModel.objects.get_by_username('Bob')
  287. UserModel.objects.get_by_email('bob@bob.com')
  288. self.assertIn('Welcome', mail.outbox[0].subject)
  289. def test_registration_creates_admin_activated_user(self):
  290. """api creates admin activated user on POST"""
  291. settings.override_setting('account_activation', 'admin')
  292. response = self.client.post(
  293. self.api_link,
  294. data={
  295. 'username': 'Bob',
  296. 'email': 'bob@bob.com',
  297. 'password': 'pass123',
  298. },
  299. )
  300. self.assertContains(response, 'admin')
  301. self.assertContains(response, 'Bob')
  302. self.assertContains(response, 'bob@bob.com')
  303. auth_json = self.client.get(reverse('misago:api:auth')).json()
  304. self.assertFalse(auth_json['is_authenticated'])
  305. UserModel.objects.get_by_username('Bob')
  306. UserModel.objects.get_by_email('bob@bob.com')
  307. self.assertIn('Welcome', mail.outbox[0].subject)
  308. def test_registration_creates_user_with_whitespace_password(self):
  309. """api creates user with spaces around password"""
  310. settings.override_setting('account_activation', 'none')
  311. response = self.client.post(
  312. self.api_link,
  313. data={
  314. 'username': 'Bob',
  315. 'email': 'bob@bob.com',
  316. 'password': ' pass123 ',
  317. },
  318. )
  319. self.assertContains(response, 'active')
  320. self.assertContains(response, 'Bob')
  321. self.assertContains(response, 'bob@bob.com')
  322. UserModel.objects.get_by_username('Bob')
  323. test_user = UserModel.objects.get_by_email('bob@bob.com')
  324. self.assertEqual(Online.objects.filter(user=test_user).count(), 1)
  325. self.assertTrue(test_user.check_password(' pass123 '))
  326. self.assertIn('Welcome', mail.outbox[0].subject)