test_social_pipeline.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. import json
  2. from django.contrib.auth import get_user_model
  3. from django.core import mail
  4. from django.test import RequestFactory, override_settings
  5. from social_core.backends.github import GithubOAuth2
  6. from social_django.utils import load_strategy
  7. from misago.core.exceptions import SocialAuthFailed, SocialAuthBanned
  8. from misago.legal.models import Agreement
  9. from misago.users.models import AnonymousUser, Ban, BanCache
  10. from misago.users.social.pipeline import (
  11. associate_by_email, create_user, create_user_with_form, get_username, require_activation,
  12. validate_ip_not_banned, validate_user_not_banned
  13. )
  14. from misago.users.testutils import UserTestCase
  15. UserModel = get_user_model()
  16. def create_request(user_ip='0.0.0.0', data=None):
  17. factory = RequestFactory()
  18. if data is None:
  19. request = factory.get('/')
  20. else:
  21. request = factory.post('/', data=json.dumps(data), content_type='application/json')
  22. request.include_frontend_context = True
  23. request.frontend_context = {}
  24. request.session = {}
  25. request.user = AnonymousUser()
  26. request.user_ip = user_ip
  27. return request
  28. class MockStrategy(object):
  29. def __init__(self, user_ip='0.0.0.0'):
  30. self.cleaned_partial_token = None
  31. self.request = create_request(user_ip)
  32. def clean_partial_pipeline(self, token):
  33. self.cleaned_partial_token = token
  34. class PipelineTestCase(UserTestCase):
  35. def get_initial_user(self):
  36. self.user = self.get_authenticated_user()
  37. def assertNewUserIsCorrect(
  38. self, new_user, form_data=None, activation=None, email_verified=False):
  39. self.assertFalse(new_user.has_usable_password())
  40. self.assertIn('Welcome', mail.outbox[0].subject)
  41. if form_data:
  42. self.assertEqual(new_user.email, form_data['email'])
  43. self.assertEqual(new_user.username, form_data['username'])
  44. if activation == 'none':
  45. self.assertEqual(new_user.requires_activation, UserModel.ACTIVATION_NONE)
  46. if activation == 'user':
  47. if email_verified:
  48. self.assertEqual(new_user.requires_activation, UserModel.ACTIVATION_NONE)
  49. else:
  50. self.assertEqual(new_user.requires_activation, UserModel.ACTIVATION_USER)
  51. if activation == 'admin':
  52. self.assertEqual(new_user.requires_activation, UserModel.ACTIVATION_ADMIN)
  53. self.assertEqual(new_user.audittrail_set.count(), 1)
  54. def assertJsonResponseEquals(self, response, value):
  55. response_content = response.content.decode("utf-8")
  56. response_json = json.loads(response_content)
  57. self.assertEqual(response_json, value)
  58. class AssociateByEmailTests(PipelineTestCase):
  59. def test_skip_if_user_is_already_set(self):
  60. """pipeline step is skipped if user was found by previous step"""
  61. result = associate_by_email(None, {}, GithubOAuth2, self.user)
  62. self.assertIsNone(result)
  63. def test_skip_if_no_email_passed(self):
  64. """pipeline step is skipped if no email was passed"""
  65. result = associate_by_email(None, {}, GithubOAuth2)
  66. self.assertIsNone(result)
  67. def test_skip_if_user_with_email_not_found(self):
  68. """pipeline step is skipped if no email was passed"""
  69. result = associate_by_email(None, {'email': 'not@found.com'}, GithubOAuth2)
  70. self.assertIsNone(result)
  71. def test_raise_if_user_is_inactive(self):
  72. """pipeline raises if user was inactive"""
  73. self.user.is_active = False
  74. self.user.save()
  75. try:
  76. associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  77. self.fail("associate_by_email should raise SocialAuthFailed")
  78. except SocialAuthFailed as e:
  79. self.assertEqual(
  80. e.message,
  81. (
  82. "The e-mail address associated with your GitHub account is not available for "
  83. "use on this site."
  84. ),
  85. )
  86. def test_raise_if_user_needs_admin_activation(self):
  87. """pipeline raises if user needs admin activation"""
  88. self.user.requires_activation = UserModel.ACTIVATION_ADMIN
  89. self.user.save()
  90. try:
  91. associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  92. self.fail("associate_by_email should raise SocialAuthFailed")
  93. except SocialAuthFailed as e:
  94. self.assertEqual(
  95. e.message,
  96. (
  97. "Your account has to be activated by site administrator before you will be "
  98. "able to sign in with GitHub."
  99. ),
  100. )
  101. def test_return_user(self):
  102. """pipeline returns user if email was found"""
  103. result = associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  104. self.assertEqual(result, {'user': self.user, 'is_new': False})
  105. def test_return_user_email_inactive(self):
  106. """pipeline returns user even if they didn't activate their account manually"""
  107. self.user.requires_activation = UserModel.ACTIVATION_USER
  108. self.user.save()
  109. result = associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  110. self.assertEqual(result, {'user': self.user, 'is_new': False})
  111. class CreateUser(PipelineTestCase):
  112. def test_skip_if_user_is_set(self):
  113. """pipeline step is skipped if user was passed"""
  114. result = create_user(MockStrategy(), {}, GithubOAuth2(), user=self.user)
  115. self.assertIsNone(result)
  116. def test_skip_if_no_email_passed(self):
  117. """pipeline step is skipped if no email was passed"""
  118. result = create_user(
  119. MockStrategy(),
  120. {},
  121. GithubOAuth2(),
  122. clean_username='TestBob',
  123. )
  124. self.assertIsNone(result)
  125. def test_skip_if_no_clean_username_passed(self):
  126. """pipeline step is skipped if cleaned username wasnt passed"""
  127. result = create_user(
  128. MockStrategy(),
  129. {'email': 'hello@example.com'},
  130. GithubOAuth2(),
  131. )
  132. self.assertIsNone(result)
  133. def test_skip_if_email_is_taken(self):
  134. """pipeline step is skipped if email was taken"""
  135. result = create_user(
  136. MockStrategy(),
  137. {'email': self.user.email},
  138. GithubOAuth2(),
  139. clean_username='NewUser',
  140. )
  141. self.assertIsNone(result)
  142. @override_settings(account_activation='none')
  143. def test_user_created_no_activation(self):
  144. """pipeline step creates active user for valid data and disabled activation"""
  145. result = create_user(
  146. MockStrategy(),
  147. {'email': 'new@example.com'},
  148. GithubOAuth2(),
  149. clean_username='NewUser',
  150. )
  151. new_user = UserModel.objects.get(email='new@example.com')
  152. self.assertEqual(result, {
  153. 'user': new_user,
  154. 'is_new': True,
  155. })
  156. self.assertEqual(new_user.username, 'NewUser')
  157. self.assertNewUserIsCorrect(new_user, email_verified=True, activation='none')
  158. @override_settings(account_activation='user')
  159. def test_user_created_activation_by_user(self):
  160. """pipeline step creates active user for valid data and user activation"""
  161. result = create_user(
  162. MockStrategy(),
  163. {'email': 'new@example.com'},
  164. GithubOAuth2(),
  165. clean_username='NewUser',
  166. )
  167. new_user = UserModel.objects.get(email='new@example.com')
  168. self.assertEqual(result, {
  169. 'user': new_user,
  170. 'is_new': True,
  171. })
  172. self.assertEqual(new_user.username, 'NewUser')
  173. self.assertNewUserIsCorrect(new_user, email_verified=True, activation='user')
  174. @override_settings(account_activation='admin')
  175. def test_user_created_activation_by_admin(self):
  176. """pipeline step creates in user for valid data and admin activation"""
  177. result = create_user(
  178. MockStrategy(),
  179. {'email': 'new@example.com'},
  180. GithubOAuth2(),
  181. clean_username='NewUser',
  182. )
  183. new_user = UserModel.objects.get(email='new@example.com')
  184. self.assertEqual(result, {
  185. 'user': new_user,
  186. 'is_new': True,
  187. })
  188. self.assertEqual(new_user.username, 'NewUser')
  189. self.assertNewUserIsCorrect(new_user, email_verified=True, activation='admin')
  190. class CreateUserWithFormTests(PipelineTestCase):
  191. def setUp(self):
  192. super().setUp()
  193. Agreement.objects.invalidate_cache()
  194. def tearDown(self):
  195. super().tearDown()
  196. Agreement.objects.invalidate_cache()
  197. def test_skip_if_user_is_set(self):
  198. """pipeline step is skipped if user was passed"""
  199. request = create_request()
  200. strategy = load_strategy(request=request)
  201. backend = GithubOAuth2(strategy, '/')
  202. result = create_user_with_form(
  203. strategy=strategy,
  204. details={},
  205. backend=backend,
  206. user=self.user,
  207. pipeline_index=1,
  208. )
  209. self.assertEqual(result, {})
  210. def test_renders_form_if_not_post(self):
  211. """pipeline step renders form if not POST"""
  212. request = create_request()
  213. strategy = load_strategy(request=request)
  214. backend = GithubOAuth2(strategy, '/')
  215. response = create_user_with_form(
  216. strategy=strategy,
  217. details={},
  218. backend=backend,
  219. user=None,
  220. pipeline_index=1,
  221. )
  222. self.assertContains(response, "GitHub")
  223. def test_empty_data_rejected(self):
  224. """form rejects empty data"""
  225. request = create_request(data={})
  226. strategy = load_strategy(request=request)
  227. backend = GithubOAuth2(strategy, '/')
  228. response = create_user_with_form(
  229. strategy=strategy,
  230. details={},
  231. backend=backend,
  232. user=None,
  233. pipeline_index=1,
  234. )
  235. self.assertEqual(response.status_code, 400)
  236. self.assertJsonResponseEquals(response, {
  237. 'email': ["This field is required."],
  238. 'username': ["This field is required."],
  239. })
  240. def test_taken_data_rejected(self):
  241. """form rejects taken data"""
  242. request = create_request(data={
  243. 'email': self.user.email,
  244. 'username': self.user.username,
  245. })
  246. strategy = load_strategy(request=request)
  247. backend = GithubOAuth2(strategy, '/')
  248. response = create_user_with_form(
  249. strategy=strategy,
  250. details={},
  251. backend=backend,
  252. user=None,
  253. pipeline_index=1,
  254. )
  255. self.assertEqual(response.status_code, 400)
  256. self.assertJsonResponseEquals(response, {
  257. 'email': ["This e-mail address is not available."],
  258. 'username': ["This username is not available."],
  259. })
  260. @override_settings(account_activation='none')
  261. def test_user_created_no_activation_verified_email(self):
  262. """active user is created for verified email and activation disabled"""
  263. form_data = {
  264. 'email': 'social@auth.com',
  265. 'username': 'SocialUser',
  266. }
  267. request = create_request(data=form_data)
  268. strategy = load_strategy(request=request)
  269. backend = GithubOAuth2(strategy, '/')
  270. result = create_user_with_form(
  271. strategy=strategy,
  272. details={'email': form_data['email']},
  273. backend=backend,
  274. user=None,
  275. pipeline_index=1,
  276. )
  277. new_user = UserModel.objects.get(email='social@auth.com')
  278. self.assertEqual(result, {'user': new_user, 'is_new': True})
  279. self.assertNewUserIsCorrect(new_user, form_data, activation='none', email_verified=True)
  280. @override_settings(account_activation='none')
  281. def test_user_created_no_activation_nonverified_email(self):
  282. """active user is created for non-verified email and activation disabled"""
  283. form_data = {
  284. 'email': 'social@auth.com',
  285. 'username': 'SocialUser',
  286. }
  287. request = create_request(data=form_data)
  288. strategy = load_strategy(request=request)
  289. backend = GithubOAuth2(strategy, '/')
  290. result = create_user_with_form(
  291. strategy=strategy,
  292. details={'email': ''},
  293. backend=backend,
  294. user=None,
  295. pipeline_index=1,
  296. )
  297. new_user = UserModel.objects.get(email='social@auth.com')
  298. self.assertEqual(result, {'user': new_user, 'is_new': True})
  299. self.assertNewUserIsCorrect(new_user, form_data, activation='none', email_verified=False)
  300. @override_settings(account_activation='user')
  301. def test_user_created_activation_by_user_verified_email(self):
  302. """active user is created for verified email and activation by user"""
  303. form_data = {
  304. 'email': 'social@auth.com',
  305. 'username': 'SocialUser',
  306. }
  307. request = create_request(data=form_data)
  308. strategy = load_strategy(request=request)
  309. backend = GithubOAuth2(strategy, '/')
  310. result = create_user_with_form(
  311. strategy=strategy,
  312. details={'email': form_data['email']},
  313. backend=backend,
  314. user=None,
  315. pipeline_index=1,
  316. )
  317. new_user = UserModel.objects.get(email='social@auth.com')
  318. self.assertEqual(result, {'user': new_user, 'is_new': True})
  319. self.assertNewUserIsCorrect(new_user, form_data, activation='user', email_verified=True)
  320. @override_settings(account_activation='user')
  321. def test_user_created_activation_by_user_nonverified_email(self):
  322. """inactive user is created for non-verified email and activation by user"""
  323. form_data = {
  324. 'email': 'social@auth.com',
  325. 'username': 'SocialUser',
  326. }
  327. request = create_request(data=form_data)
  328. strategy = load_strategy(request=request)
  329. backend = GithubOAuth2(strategy, '/')
  330. result = create_user_with_form(
  331. strategy=strategy,
  332. details={'email': ''},
  333. backend=backend,
  334. user=None,
  335. pipeline_index=1,
  336. )
  337. new_user = UserModel.objects.get(email='social@auth.com')
  338. self.assertEqual(result, {'user': new_user, 'is_new': True})
  339. self.assertNewUserIsCorrect(new_user, form_data, activation='user', email_verified=False)
  340. @override_settings(account_activation='admin')
  341. def test_user_created_activation_by_admin_verified_email(self):
  342. """inactive user is created for verified email and activation by admin"""
  343. form_data = {
  344. 'email': 'social@auth.com',
  345. 'username': 'SocialUser',
  346. }
  347. request = create_request(data=form_data)
  348. strategy = load_strategy(request=request)
  349. backend = GithubOAuth2(strategy, '/')
  350. result = create_user_with_form(
  351. strategy=strategy,
  352. details={'email': form_data['email']},
  353. backend=backend,
  354. user=None,
  355. pipeline_index=1,
  356. )
  357. new_user = UserModel.objects.get(email='social@auth.com')
  358. self.assertEqual(result, {'user': new_user, 'is_new': True})
  359. self.assertNewUserIsCorrect(new_user, form_data, activation='admin', email_verified=True)
  360. @override_settings(account_activation='admin')
  361. def test_user_created_activation_by_admin_nonverified_email(self):
  362. """inactive user is created for non-verified email and activation by admin"""
  363. form_data = {
  364. 'email': 'social@auth.com',
  365. 'username': 'SocialUser',
  366. }
  367. request = create_request(data=form_data)
  368. strategy = load_strategy(request=request)
  369. backend = GithubOAuth2(strategy, '/')
  370. result = create_user_with_form(
  371. strategy=strategy,
  372. details={'email': ''},
  373. backend=backend,
  374. user=None,
  375. pipeline_index=1,
  376. )
  377. new_user = UserModel.objects.get(email='social@auth.com')
  378. self.assertEqual(result, {'user': new_user, 'is_new': True})
  379. self.assertNewUserIsCorrect(new_user, form_data, activation='admin', email_verified=False)
  380. def test_form_check_agreement(self):
  381. """social register checks agreement"""
  382. form_data = {
  383. 'email': 'social@auth.com',
  384. 'username': 'SocialUser',
  385. }
  386. request = create_request(data=form_data)
  387. strategy = load_strategy(request=request)
  388. backend = GithubOAuth2(strategy, '/')
  389. agreement = Agreement.objects.create(
  390. type=Agreement.TYPE_TOS,
  391. text="Lorem ipsum",
  392. is_active=True,
  393. )
  394. response = create_user_with_form(
  395. strategy=strategy,
  396. details={'email': form_data['email']},
  397. backend=backend,
  398. user=None,
  399. pipeline_index=1,
  400. )
  401. self.assertEqual(response.status_code, 400)
  402. self.assertJsonResponseEquals(response, {
  403. 'terms_of_service': ['This agreement is required.'],
  404. })
  405. # invalid agreement id
  406. form_data = {
  407. 'email': 'social@auth.com',
  408. 'username': 'SocialUser',
  409. 'terms_of_service': agreement.id + 1,
  410. }
  411. request = create_request(data=form_data)
  412. strategy = load_strategy(request=request)
  413. backend = GithubOAuth2(strategy, '/')
  414. response = create_user_with_form(
  415. strategy=strategy,
  416. details={'email': form_data['email']},
  417. backend=backend,
  418. user=None,
  419. pipeline_index=1,
  420. )
  421. self.assertEqual(response.status_code, 400)
  422. self.assertJsonResponseEquals(response, {
  423. 'terms_of_service': ['This agreement is required.'],
  424. })
  425. # valid agreement id
  426. form_data = {
  427. 'email': 'social@auth.com',
  428. 'username': 'SocialUser',
  429. 'terms_of_service': agreement.id,
  430. }
  431. request = create_request(data=form_data)
  432. strategy = load_strategy(request=request)
  433. backend = GithubOAuth2(strategy, '/')
  434. result = create_user_with_form(
  435. strategy=strategy,
  436. details={'email': form_data['email']},
  437. backend=backend,
  438. user=None,
  439. pipeline_index=1,
  440. )
  441. new_user = UserModel.objects.get(email='social@auth.com')
  442. self.assertEqual(result, {'user': new_user, 'is_new': True})
  443. self.assertEqual(new_user.agreements, [agreement.id])
  444. self.assertEqual(new_user.useragreement_set.count(), 1)
  445. def test_form_ignore_inactive_agreement(self):
  446. """social register ignores inactive agreement"""
  447. form_data = {
  448. 'email': 'social@auth.com',
  449. 'username': 'SocialUser',
  450. 'terms_of_service': None,
  451. }
  452. request = create_request(data=form_data)
  453. strategy = load_strategy(request=request)
  454. backend = GithubOAuth2(strategy, '/')
  455. Agreement.objects.create(
  456. type=Agreement.TYPE_TOS,
  457. text="Lorem ipsum",
  458. is_active=False,
  459. )
  460. result = create_user_with_form(
  461. strategy=strategy,
  462. details={'email': form_data['email']},
  463. backend=backend,
  464. user=None,
  465. pipeline_index=1,
  466. )
  467. new_user = UserModel.objects.get(email='social@auth.com')
  468. self.assertEqual(result, {'user': new_user, 'is_new': True})
  469. self.assertEqual(new_user.agreements, [])
  470. self.assertEqual(new_user.useragreement_set.count(), 0)
  471. class GetUsernameTests(PipelineTestCase):
  472. def test_skip_if_user_is_set(self):
  473. """pipeline step is skipped if user was passed"""
  474. result = get_username(None, {}, None, user=self.user)
  475. self.assertIsNone(result)
  476. def test_skip_if_no_names(self):
  477. """pipeline step is skipped if API returned no names"""
  478. result = get_username(None, {}, None)
  479. self.assertIsNone(result)
  480. def test_resolve_to_username(self):
  481. """pipeline step resolves username"""
  482. result = get_username(None, {'username': 'BobBoberson'}, None)
  483. self.assertEqual(result, {'clean_username': 'BobBoberson'})
  484. def test_normalize_username(self):
  485. """pipeline step normalizes username"""
  486. result = get_username(None, {'username': 'Błop Błoperson'}, None)
  487. self.assertEqual(result, {'clean_username': 'BlopBloperson'})
  488. def test_resolve_to_first_name(self):
  489. """pipeline attempts to use first name because username is taken"""
  490. details = {
  491. 'username': self.user.username,
  492. 'first_name': 'Błob',
  493. }
  494. result = get_username(None, details, None)
  495. self.assertEqual(result, {'clean_username': 'Blob'})
  496. def test_dont_resolve_to_last_name(self):
  497. """pipeline will not fallback to last name because username is taken"""
  498. details = {
  499. 'username': self.user.username,
  500. 'last_name': 'Błob',
  501. }
  502. result = get_username(None, details, None)
  503. self.assertIsNone(result)
  504. def test_resolve_to_first_last_name_first_char(self):
  505. """pipeline will construct username from first name and first char of surname"""
  506. details = {
  507. 'first_name': self.user.username,
  508. 'last_name': 'Błob',
  509. }
  510. result = get_username(None, details, None)
  511. self.assertEqual(result, {'clean_username': self.user.username + 'B'})
  512. def test_dont_resolve_to_banned_name(self):
  513. """pipeline will not resolve to banned name"""
  514. Ban.objects.create(banned_value='*Admin*', check_type=Ban.USERNAME)
  515. details = {
  516. 'username': 'Misago Admin',
  517. 'first_name': 'Błob',
  518. }
  519. result = get_username(None, details, None)
  520. self.assertEqual(result, {'clean_username': 'Blob'})
  521. def test_resolve_full_name(self):
  522. """pipeline will resolve to full name"""
  523. Ban.objects.create(banned_value='*Admin*', check_type=Ban.USERNAME)
  524. details = {
  525. 'username': 'Misago Admin',
  526. 'full_name': 'Błob Błopo',
  527. }
  528. result = get_username(None, details, None)
  529. self.assertEqual(result, {'clean_username': 'BlobBlopo'})
  530. def test_resolve_to_cut_name(self):
  531. """pipeline will resolve cut too long name on second pass"""
  532. details = {
  533. 'username': 'Abrakadabrapokuskonstantynopolitańczykowianeczkatrzy',
  534. }
  535. result = get_username(None, details, None)
  536. self.assertEqual(result, {'clean_username': 'Abrakadabrapok'})
  537. class RequireActivationTests(PipelineTestCase):
  538. def setUp(self):
  539. super().setUp()
  540. self.user.requires_activation = UserModel.ACTIVATION_ADMIN
  541. self.user.save()
  542. def test_skip_if_user_not_set(self):
  543. """pipeline step is skipped if user is not set"""
  544. request = create_request()
  545. strategy = load_strategy(request=request)
  546. backend = GithubOAuth2(strategy, '/')
  547. result = require_activation(
  548. strategy=strategy,
  549. details={},
  550. backend=backend,
  551. user=None,
  552. pipeline_index=1,
  553. )
  554. self.assertEqual(result, {})
  555. def test_partial_token_if_user_not_set_no_showstopper(self):
  556. """pipeline step handles set session token if user is not set"""
  557. request = create_request()
  558. strategy = load_strategy(request=request)
  559. strategy.request.session['partial_pipeline_token'] = 'test-token'
  560. backend = GithubOAuth2(strategy, '/')
  561. require_activation(
  562. strategy=strategy,
  563. details={},
  564. backend=backend,
  565. user=None,
  566. pipeline_index=1,
  567. )
  568. def test_skip_if_user_is_active(self):
  569. """pipeline step is skipped if user is active"""
  570. self.user.requires_activation = UserModel.ACTIVATION_NONE
  571. self.user.save()
  572. self.assertFalse(self.user.requires_activation)
  573. request = create_request()
  574. strategy = load_strategy(request=request)
  575. backend = GithubOAuth2(strategy, '/')
  576. result = require_activation(
  577. strategy=strategy,
  578. details={},
  579. backend=backend,
  580. user=self.user,
  581. pipeline_index=1,
  582. )
  583. self.assertEqual(result, {})
  584. def test_pipeline_returns_html_responseon_get(self):
  585. """pipeline step renders http response for GET request and inactive user"""
  586. request = create_request()
  587. strategy = load_strategy(request=request)
  588. backend = GithubOAuth2(strategy, '/')
  589. response = require_activation(
  590. strategy=strategy,
  591. details={},
  592. backend=backend,
  593. user=self.user,
  594. pipeline_index=1,
  595. )
  596. self.assertEqual(response.status_code, 200)
  597. self.assertEqual(response['content-type'], 'text/html; charset=utf-8')
  598. def test_pipeline_returns_json_response_on_post(self):
  599. """pipeline step renders json response for POST request and inactive user"""
  600. request = create_request(data={'username': 'anything'})
  601. strategy = load_strategy(request=request)
  602. backend = GithubOAuth2(strategy, '/')
  603. response = require_activation(
  604. strategy=strategy,
  605. details={},
  606. backend=backend,
  607. user=self.user,
  608. pipeline_index=1,
  609. )
  610. self.assertEqual(response.status_code, 200)
  611. self.assertEqual(response['content-type'], 'application/json')
  612. self.assertJsonResponseEquals(response, {
  613. 'step': 'done',
  614. 'backend_name': 'GitHub',
  615. 'activation': 'admin',
  616. 'email': 'test@user.com',
  617. 'username': 'TestUser',
  618. })
  619. class ValidateIpNotBannedTests(PipelineTestCase):
  620. def test_skip_if_user_not_set(self):
  621. """pipeline step is skipped if no user was passed"""
  622. result = validate_ip_not_banned(None, {}, GithubOAuth2)
  623. self.assertIsNone(result)
  624. def test_raise_if_banned(self):
  625. """pipeline raises if user's IP is banned"""
  626. Ban.objects.create(banned_value='188.*', check_type=Ban.IP)
  627. try:
  628. validate_ip_not_banned(MockStrategy(user_ip='188.1.2.3'), {}, GithubOAuth2, self.user)
  629. self.fail("validate_ip_not_banned should raise SocialAuthBanned")
  630. except SocialAuthBanned as e:
  631. self.assertTrue(isinstance(e.ban, Ban))
  632. def test_exclude_staff(self):
  633. """pipeline excludes staff from bans"""
  634. self.user.is_staff = True
  635. self.user.save()
  636. Ban.objects.create(banned_value='188.*', check_type=Ban.IP)
  637. result = validate_ip_not_banned(
  638. MockStrategy(user_ip='188.1.2.3'), {}, GithubOAuth2, self.user)
  639. self.assertIsNone(result)
  640. class ValidateUserNotBannedTests(PipelineTestCase):
  641. def test_skip_if_user_not_set(self):
  642. """pipeline step is skipped if no user was passed"""
  643. result = validate_user_not_banned(None, {}, GithubOAuth2)
  644. self.assertIsNone(result)
  645. def test_raise_if_banned(self):
  646. """pipeline raises if user's IP is banned"""
  647. Ban.objects.create(banned_value=self.user.username, check_type=Ban.USERNAME)
  648. try:
  649. validate_user_not_banned(MockStrategy(), {}, GithubOAuth2, self.user)
  650. self.fail("validate_ip_not_banned should raise SocialAuthBanned")
  651. except SocialAuthBanned as e:
  652. self.assertEqual(e.ban.user, self.user)
  653. self.assertTrue(isinstance(e.ban, BanCache))
  654. def test_exclude_staff(self):
  655. """pipeline excludes staff from bans"""
  656. self.user.is_staff = True
  657. self.user.save()
  658. Ban.objects.create(banned_value=self.user.username, check_type=Ban.USERNAME)
  659. result = validate_user_not_banned(MockStrategy(), {}, GithubOAuth2, self.user)
  660. self.assertIsNone(result)