test_social_pipeline.py 28 KB

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