test_auth_api.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. import json
  2. from django.contrib.auth import get_user_model
  3. from django.core import mail
  4. from django.test import TestCase
  5. from misago.users.models import Ban, BAN_USERNAME
  6. from misago.users.tokens import (make_activation_token,
  7. make_password_change_token)
  8. class GatewayTests(TestCase):
  9. def test_api_invalid_credentials(self):
  10. """login api returns 400 on invalid POST"""
  11. response = self.client.post(
  12. '/api/auth/',
  13. data={'username': 'nope', 'password': 'nope'})
  14. self.assertEqual(response.status_code, 400)
  15. self.assertIn("Login or password is incorrect.", response.content)
  16. response = self.client.get('/api/auth/')
  17. self.assertEqual(response.status_code, 200)
  18. user_json = json.loads(response.content)
  19. self.assertIsNone(user_json['id'])
  20. def test_login(self):
  21. """api signs user in"""
  22. User = get_user_model()
  23. user = User.objects.create_user('Bob', 'bob@test.com', 'Pass.123')
  24. response = self.client.post(
  25. '/api/auth/',
  26. data={'username': 'Bob', 'password': 'Pass.123'})
  27. self.assertEqual(response.status_code, 200)
  28. response = self.client.get('/api/auth/')
  29. self.assertEqual(response.status_code, 200)
  30. user_json = json.loads(response.content)
  31. self.assertEqual(user_json['id'], user.id)
  32. self.assertEqual(user_json['username'], user.username)
  33. def test_submit_empty(self):
  34. """login api errors for no body"""
  35. response = self.client.post('/api/auth/')
  36. self.assertEqual(response.status_code, 400)
  37. self.assertIn('empty_data', response.content)
  38. def test_login_banned(self):
  39. """login api fails to sign banned user in"""
  40. User = get_user_model()
  41. User.objects.create_user('Bob', 'bob@test.com', 'Pass.123')
  42. ban = Ban.objects.create(check_type=BAN_USERNAME,
  43. banned_value='bob',
  44. user_message='You are tragically banned.')
  45. response = self.client.post(
  46. '/api/auth/',
  47. data={'username': 'Bob', 'password': 'Pass.123'})
  48. self.assertEqual(response.status_code, 400)
  49. response_json = json.loads(response.content)
  50. self.assertEqual(response_json['code'], 'banned')
  51. self.assertEqual(response_json['detail']['message']['plain'],
  52. ban.user_message)
  53. self.assertEqual(response_json['detail']['message']['html'],
  54. '<p>%s</p>' % ban.user_message)
  55. response = self.client.get('/api/auth/')
  56. self.assertEqual(response.status_code, 200)
  57. user_json = json.loads(response.content)
  58. self.assertIsNone(user_json['id'])
  59. def test_login_inactive_admin(self):
  60. """login api fails to sign admin-activated user in"""
  61. User = get_user_model()
  62. User.objects.create_user('Bob', 'bob@test.com', 'Pass.123',
  63. requires_activation=1)
  64. response = self.client.post(
  65. '/api/auth/',
  66. data={'username': 'Bob', 'password': 'Pass.123'})
  67. self.assertEqual(response.status_code, 400)
  68. response_json = json.loads(response.content)
  69. self.assertEqual(response_json['code'], 'inactive_user')
  70. response = self.client.get('/api/auth/')
  71. self.assertEqual(response.status_code, 200)
  72. user_json = json.loads(response.content)
  73. self.assertIsNone(user_json['id'])
  74. def test_login_inactive_user(self):
  75. """login api fails to sign user-activated user in"""
  76. User = get_user_model()
  77. User.objects.create_user('Bob', 'bob@test.com', 'Pass.123',
  78. requires_activation=2)
  79. response = self.client.post(
  80. '/api/auth/',
  81. data={'username': 'Bob', 'password': 'Pass.123'})
  82. self.assertEqual(response.status_code, 400)
  83. response_json = json.loads(response.content)
  84. self.assertEqual(response_json['code'], 'inactive_admin')
  85. response = self.client.get('/api/auth/')
  86. self.assertEqual(response.status_code, 200)
  87. user_json = json.loads(response.content)
  88. self.assertIsNone(user_json['id'])
  89. class SendActivationAPITests(TestCase):
  90. def setUp(self):
  91. User = get_user_model()
  92. self.user = User.objects.create_user('Bob', 'bob@test.com', 'Pass.123')
  93. self.user.requires_activation = 1
  94. self.user.save()
  95. self.link = '/api/auth/send-activation/'
  96. def test_submit_valid(self):
  97. """request activation link api sends reset link mail"""
  98. response = self.client.post(self.link, data={'email': self.user.email})
  99. self.assertEqual(response.status_code, 200)
  100. self.assertIn('Activate Bob', mail.outbox[0].subject)
  101. def test_submit_empty(self):
  102. """request activation link api errors for no body"""
  103. response = self.client.post(self.link)
  104. self.assertEqual(response.status_code, 400)
  105. self.assertIn('empty_email', response.content)
  106. self.assertTrue(not mail.outbox)
  107. def test_submit_invalid(self):
  108. """request activation link api errors for invalid email"""
  109. response = self.client.post(self.link, data={'email': 'fake@mail.com'})
  110. self.assertEqual(response.status_code, 400)
  111. self.assertIn('not_found', response.content)
  112. self.assertTrue(not mail.outbox)
  113. def test_submit_banned(self):
  114. """request activation link api errors for banned users"""
  115. Ban.objects.create(check_type=BAN_USERNAME,
  116. banned_value=self.user.username,
  117. user_message='Nope!')
  118. response = self.client.post(self.link, data={'email': self.user.email})
  119. self.assertEqual(response.status_code, 400)
  120. self.assertIn('Nope!', response.content)
  121. self.assertTrue(not mail.outbox)
  122. def test_submit_active_user(self):
  123. """request activation link api errors for active user"""
  124. self.user.requires_activation = 0
  125. self.user.save()
  126. response = self.client.post(self.link, data={'email': self.user.email})
  127. self.assertEqual(response.status_code, 400)
  128. self.assertIn('Bob, your account is already active.',
  129. response.content)
  130. def test_submit_inactive_user(self):
  131. """request activation link api errors for admin-activated users"""
  132. self.user.requires_activation = 2
  133. self.user.save()
  134. response = self.client.post(self.link, data={'email': self.user.email})
  135. self.assertEqual(response.status_code, 400)
  136. self.assertIn('inactive_admin', response.content)
  137. self.assertTrue(not mail.outbox)
  138. # but succeed for user-activated
  139. self.user.requires_activation = 1
  140. self.user.save()
  141. response = self.client.post(self.link, data={'email': self.user.email})
  142. self.assertEqual(response.status_code, 200)
  143. self.assertTrue(mail.outbox)
  144. class ActivateAccountAPITests(TestCase):
  145. def setUp(self):
  146. User = get_user_model()
  147. self.user = User.objects.create_user('Bob', 'bob@test.com', 'Pass.123')
  148. self.user.requires_activation = 1
  149. self.user.save()
  150. self.link = '/api/auth/activate-account/%s/%s/'
  151. def test_submit_valid(self):
  152. """activate user api returns success and activates user"""
  153. response = self.client.post(self.link % (
  154. self.user.id,
  155. make_activation_token(self.user)
  156. ))
  157. self.assertEqual(response.status_code, 200)
  158. self.assertIn(self.user.username, response.content)
  159. user = get_user_model().objects.get(id=self.user.id)
  160. self.assertFalse(user.requires_activation)
  161. def test_submit_invalid_token(self):
  162. """activate user api errors for invalid token"""
  163. response = self.client.post(self.link % (
  164. self.user.id,
  165. 'sadsadsadsdsassdsa'
  166. ))
  167. self.assertEqual(response.status_code, 400)
  168. self.assertIn('Activation link is invalid.', response.content)
  169. def test_submit_invalid_user(self):
  170. """activate user api errors for invalid user"""
  171. response = self.client.post(self.link % (
  172. 123,
  173. 'sadsadsadsdsassdsa'
  174. ))
  175. self.assertEqual(response.status_code, 400)
  176. self.assertIn('Activation link is invalid.', response.content)
  177. def test_submit_banned(self):
  178. """activate user api errors for banned user"""
  179. Ban.objects.create(check_type=BAN_USERNAME,
  180. banned_value=self.user.username,
  181. user_message='Nope!')
  182. response = self.client.post(self.link % (
  183. self.user.id,
  184. make_activation_token(self.user)
  185. ))
  186. self.assertEqual(response.status_code, 400)
  187. self.assertIn('Activation link has expired.', response.content)
  188. def test_submit_active_user(self):
  189. """validate link api errors for active user"""
  190. self.user.requires_activation = 0
  191. self.user.save()
  192. response = self.client.post(self.link % (
  193. self.user.id,
  194. make_activation_token(self.user)
  195. ))
  196. self.assertEqual(response.status_code, 400)
  197. self.assertIn('Bob, your account is already active.',
  198. response.content)
  199. def test_submit_inactive_user(self):
  200. """validate link api errors for inactive user"""
  201. self.user.requires_activation = 1
  202. self.user.save()
  203. response = self.client.post(self.link % (
  204. self.user.id,
  205. make_activation_token(self.user)
  206. ))
  207. self.assertEqual(response.status_code, 200)
  208. self.user.requires_activation = 2
  209. self.user.save()
  210. response = self.client.post(self.link % (
  211. self.user.id,
  212. make_activation_token(self.user)
  213. ))
  214. self.assertEqual(response.status_code, 400)
  215. self.assertIn('Bob, only administrator may activate your account.',
  216. response.content)
  217. class SendPasswordFormAPITests(TestCase):
  218. def setUp(self):
  219. User = get_user_model()
  220. self.user = User.objects.create_user('Bob', 'bob@test.com', 'Pass.123')
  221. self.link = '/api/auth/send-password-form/'
  222. def test_submit_valid(self):
  223. """request change password form link api sends reset link mail"""
  224. response = self.client.post(self.link, data={'email': self.user.email})
  225. self.assertEqual(response.status_code, 200)
  226. self.assertIn('Change Bob password', mail.outbox[0].subject)
  227. def test_submit_empty(self):
  228. """request change password form link api errors for no body"""
  229. response = self.client.post(self.link)
  230. self.assertEqual(response.status_code, 400)
  231. self.assertIn('empty_email', response.content)
  232. self.assertTrue(not mail.outbox)
  233. def test_submit_invalid(self):
  234. """request change password form link api errors for invalid email"""
  235. response = self.client.post(self.link, data={'email': 'fake@mail.com'})
  236. self.assertEqual(response.status_code, 400)
  237. self.assertIn('not_found', response.content)
  238. self.assertTrue(not mail.outbox)
  239. def test_submit_banned(self):
  240. """request change password form link api errors for banned users"""
  241. Ban.objects.create(check_type=BAN_USERNAME,
  242. banned_value=self.user.username,
  243. user_message='Nope!')
  244. response = self.client.post(self.link, data={'email': self.user.email})
  245. self.assertEqual(response.status_code, 400)
  246. self.assertIn('Nope!', response.content)
  247. self.assertTrue(not mail.outbox)
  248. def test_submit_inactive_user(self):
  249. """request change password form link api errors for inactive users"""
  250. self.user.requires_activation = 1
  251. self.user.save()
  252. response = self.client.post(self.link, data={'email': self.user.email})
  253. self.assertEqual(response.status_code, 400)
  254. self.assertIn('inactive_user', response.content)
  255. self.user.requires_activation = 2
  256. self.user.save()
  257. response = self.client.post(self.link, data={'email': self.user.email})
  258. self.assertEqual(response.status_code, 400)
  259. self.assertIn('inactive_admin', response.content)
  260. self.assertTrue(not mail.outbox)
  261. class ChangePasswordAPITests(TestCase):
  262. def setUp(self):
  263. User = get_user_model()
  264. self.user = User.objects.create_user('Bob', 'bob@test.com', 'Pass.123')
  265. self.link = '/api/auth/change-password/%s/%s/'
  266. def test_valid_link(self):
  267. """get validates link"""
  268. response = self.client.get(self.link % (
  269. self.user.id,
  270. make_password_change_token(self.user)
  271. ))
  272. self.assertEqual(response.status_code, 200)
  273. self.assertIn(self.user.username, response.content)
  274. def test_invalid_user_id_link(self):
  275. """get errors on invalid user id link"""
  276. response = self.client.get(self.link % (
  277. 123,
  278. make_password_change_token(self.user)
  279. ))
  280. self.assertEqual(response.status_code, 400)
  281. self.assertIn('Form link is invalid.', response.content)
  282. def test_invalid_token_link(self):
  283. """get errors on invalid user id link"""
  284. response = self.client.get(self.link % (
  285. self.user.id,
  286. 'asda7ad89sa7d9s789as'
  287. ))
  288. self.assertEqual(response.status_code, 400)
  289. self.assertIn('Form link is invalid.', response.content)
  290. def test_banned_user_link(self):
  291. """get errors because user is banned"""
  292. Ban.objects.create(check_type=BAN_USERNAME,
  293. banned_value=self.user.username,
  294. user_message='Nope!')
  295. response = self.client.get(self.link % (
  296. self.user.id,
  297. make_password_change_token(self.user)
  298. ))
  299. self.assertEqual(response.status_code, 400)
  300. self.assertIn('Your link has expired.', response.content)
  301. def test_inactive_user(self):
  302. """request change password form link api errors for inactive users"""
  303. self.user.requires_activation = 1
  304. self.user.save()
  305. response = self.client.get(self.link % (
  306. self.user.id,
  307. make_password_change_token(self.user)
  308. ))
  309. self.assertEqual(response.status_code, 400)
  310. self.assertIn('Your link has expired.', response.content)
  311. self.user.requires_activation = 2
  312. self.user.save()
  313. response = self.client.get(self.link % (
  314. self.user.id,
  315. make_password_change_token(self.user)
  316. ))
  317. self.assertEqual(response.status_code, 400)
  318. self.assertIn('Your link has expired.', response.content)
  319. def test_submit_empty(self):
  320. """submit change password form api errors for empty body"""
  321. response = self.client.post(self.link % (
  322. self.user.id,
  323. make_password_change_token(self.user)
  324. ))
  325. self.assertEqual(response.status_code, 400)
  326. self.assertIn('Valid password must', response.content)
  327. def test_submit_valid(self):
  328. """submit change password form api errors for empty body"""
  329. response = self.client.post(self.link % (
  330. self.user.id,
  331. make_password_change_token(self.user)
  332. ), data={'password': 'n3wp4ss!'})
  333. self.assertEqual(response.status_code, 200)
  334. user = get_user_model().objects.get(id=self.user.id)
  335. self.assertTrue(user.check_password('n3wp4ss!'))