test_social_pipeline.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  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.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. class AssociateByEmailTests(PipelineTestCase):
  54. def test_skip_if_user_is_already_set(self):
  55. """pipeline step is skipped if user was found by previous step"""
  56. result = associate_by_email(None, {}, GithubOAuth2, self.user)
  57. self.assertIsNone(result)
  58. def test_skip_if_no_email_passed(self):
  59. """pipeline step is skipped if no email was passed"""
  60. result = associate_by_email(None, {}, GithubOAuth2)
  61. self.assertIsNone(result)
  62. def test_skip_if_user_with_email_not_found(self):
  63. """pipeline step is skipped if no email was passed"""
  64. result = associate_by_email(None, {'email': 'not@found.com'}, GithubOAuth2)
  65. self.assertIsNone(result)
  66. def test_raise_if_user_is_inactive(self):
  67. """pipeline raises if user was inactive"""
  68. self.user.is_active = False
  69. self.user.save()
  70. try:
  71. associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  72. self.fail("associate_by_email should raise SocialAuthFailed")
  73. except SocialAuthFailed as e:
  74. self.assertEqual(
  75. e.message,
  76. (
  77. "The e-mail address associated with your GitHub account is not available for "
  78. "use on this site."
  79. ),
  80. )
  81. def test_raise_if_user_needs_admin_activation(self):
  82. """pipeline raises if user needs admin activation"""
  83. self.user.requires_activation = UserModel.ACTIVATION_ADMIN
  84. self.user.save()
  85. try:
  86. associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  87. self.fail("associate_by_email should raise SocialAuthFailed")
  88. except SocialAuthFailed as e:
  89. self.assertEqual(
  90. e.message,
  91. (
  92. "Your account has to be activated by site administrator before you will be "
  93. "able to sign in with GitHub."
  94. ),
  95. )
  96. def test_return_user(self):
  97. """pipeline returns user if email was found"""
  98. result = associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  99. self.assertEqual(result, {'user': self.user, 'is_new': False})
  100. def test_return_user_email_inactive(self):
  101. """pipeline returns user even if they didn't activate their account manually"""
  102. self.user.requires_activation = UserModel.ACTIVATION_USER
  103. self.user.save()
  104. result = associate_by_email(None, {'email': self.user.email}, GithubOAuth2)
  105. self.assertEqual(result, {'user': self.user, 'is_new': False})
  106. class CreateUser(PipelineTestCase):
  107. def test_skip_if_user_is_set(self):
  108. """pipeline step is skipped if user was passed"""
  109. result = create_user(MockStrategy(), {}, GithubOAuth2(), user=self.user)
  110. self.assertIsNone(result)
  111. def test_skip_if_no_email_passed(self):
  112. """pipeline step is skipped if no email was passed"""
  113. result = create_user(
  114. MockStrategy(),
  115. {},
  116. GithubOAuth2(),
  117. clean_username='TestBob',
  118. )
  119. self.assertIsNone(result)
  120. def test_skip_if_no_clean_username_passed(self):
  121. """pipeline step is skipped if cleaned username wasnt passed"""
  122. result = create_user(
  123. MockStrategy(),
  124. {'email': 'hello@example.com'},
  125. GithubOAuth2(),
  126. )
  127. self.assertIsNone(result)
  128. def test_skip_if_email_is_taken(self):
  129. """pipeline step is skipped if email was taken"""
  130. result = create_user(
  131. MockStrategy(),
  132. {'email': self.user.email},
  133. GithubOAuth2(),
  134. clean_username='NewUser',
  135. )
  136. self.assertIsNone(result)
  137. @override_settings(account_activation='none')
  138. def test_user_created_no_activation(self):
  139. """pipeline step creates active user for valid data and disabled activation"""
  140. result = create_user(
  141. MockStrategy(),
  142. {'email': 'new@example.com'},
  143. GithubOAuth2(),
  144. clean_username='NewUser',
  145. )
  146. new_user = UserModel.objects.get(email='new@example.com')
  147. self.assertEqual(result, {
  148. 'user': new_user,
  149. 'is_new': True,
  150. })
  151. self.assertEqual(new_user.username, 'NewUser')
  152. self.assertNewUserIsCorrect(new_user, email_verified=True, activation='none')
  153. @override_settings(account_activation='user')
  154. def test_user_created_activation_by_user(self):
  155. """pipeline step creates active user for valid data and user activation"""
  156. result = create_user(
  157. MockStrategy(),
  158. {'email': 'new@example.com'},
  159. GithubOAuth2(),
  160. clean_username='NewUser',
  161. )
  162. new_user = UserModel.objects.get(email='new@example.com')
  163. self.assertEqual(result, {
  164. 'user': new_user,
  165. 'is_new': True,
  166. })
  167. self.assertEqual(new_user.username, 'NewUser')
  168. self.assertNewUserIsCorrect(new_user, email_verified=True, activation='user')
  169. @override_settings(account_activation='admin')
  170. def test_user_created_activation_by_admin(self):
  171. """pipeline step creates in user for valid data and admin activation"""
  172. result = create_user(
  173. MockStrategy(),
  174. {'email': 'new@example.com'},
  175. GithubOAuth2(),
  176. clean_username='NewUser',
  177. )
  178. new_user = UserModel.objects.get(email='new@example.com')
  179. self.assertEqual(result, {
  180. 'user': new_user,
  181. 'is_new': True,
  182. })
  183. self.assertEqual(new_user.username, 'NewUser')
  184. self.assertNewUserIsCorrect(new_user, email_verified=True, activation='admin')
  185. class CreateUserWithFormTests(PipelineTestCase):
  186. def test_skip_if_user_is_set(self):
  187. """pipeline step is skipped if user was passed"""
  188. request = create_request()
  189. strategy = load_strategy(request=request)
  190. backend = GithubOAuth2(strategy, '/')
  191. result = create_user_with_form(
  192. strategy=strategy,
  193. details={},
  194. backend=backend,
  195. user=self.user,
  196. pipeline_index=1,
  197. )
  198. self.assertEqual(result, {})
  199. def test_renders_form_if_not_post(self):
  200. """pipeline step renders form if not POST"""
  201. request = create_request()
  202. strategy = load_strategy(request=request)
  203. backend = GithubOAuth2(strategy, '/')
  204. response = create_user_with_form(
  205. strategy=strategy,
  206. details={},
  207. backend=backend,
  208. user=None,
  209. pipeline_index=1,
  210. )
  211. self.assertContains(response, "GitHub")
  212. def test_empty_data_rejected(self):
  213. """form rejects empty data"""
  214. request = create_request(data={})
  215. strategy = load_strategy(request=request)
  216. backend = GithubOAuth2(strategy, '/')
  217. response = create_user_with_form(
  218. strategy=strategy,
  219. details={},
  220. backend=backend,
  221. user=None,
  222. pipeline_index=1,
  223. )
  224. self.assertEqual(response.status_code, 400)
  225. self.assertEqual(json.loads(response.content), {
  226. 'email': ["This field is required."],
  227. 'username': ["This field is required."],
  228. })
  229. def test_taken_data_rejected(self):
  230. """form rejects taken data"""
  231. request = create_request(data={
  232. 'email': self.user.email,
  233. 'username': self.user.username,
  234. })
  235. strategy = load_strategy(request=request)
  236. backend = GithubOAuth2(strategy, '/')
  237. response = create_user_with_form(
  238. strategy=strategy,
  239. details={},
  240. backend=backend,
  241. user=None,
  242. pipeline_index=1,
  243. )
  244. self.assertEqual(response.status_code, 400)
  245. self.assertEqual(json.loads(response.content), {
  246. 'email': ["This e-mail address is not available."],
  247. 'username': ["This username is not available."],
  248. })
  249. @override_settings(account_activation='none')
  250. def test_user_created_no_activation_verified_email(self):
  251. """active user is created for verified email and activation disabled"""
  252. form_data = {
  253. 'email': 'social@auth.com',
  254. 'username': 'SocialUser',
  255. }
  256. request = create_request(data=form_data)
  257. strategy = load_strategy(request=request)
  258. backend = GithubOAuth2(strategy, '/')
  259. result = create_user_with_form(
  260. strategy=strategy,
  261. details={'email': form_data['email']},
  262. backend=backend,
  263. user=None,
  264. pipeline_index=1,
  265. )
  266. new_user = UserModel.objects.get(email='social@auth.com')
  267. self.assertEqual(result, {'user': new_user, 'is_new': True})
  268. self.assertNewUserIsCorrect(new_user, form_data, activation='none', email_verified=True)
  269. @override_settings(account_activation='none')
  270. def test_user_created_no_activation_nonverified_email(self):
  271. """active user is created for non-verified email and activation disabled"""
  272. form_data = {
  273. 'email': 'social@auth.com',
  274. 'username': 'SocialUser',
  275. }
  276. request = create_request(data=form_data)
  277. strategy = load_strategy(request=request)
  278. backend = GithubOAuth2(strategy, '/')
  279. result = create_user_with_form(
  280. strategy=strategy,
  281. details={'email': ''},
  282. backend=backend,
  283. user=None,
  284. pipeline_index=1,
  285. )
  286. new_user = UserModel.objects.get(email='social@auth.com')
  287. self.assertEqual(result, {'user': new_user, 'is_new': True})
  288. self.assertNewUserIsCorrect(new_user, form_data, activation='none', email_verified=False)
  289. @override_settings(account_activation='user')
  290. def test_user_created_activation_by_user_verified_email(self):
  291. """active user is created for verified email and activation by user"""
  292. form_data = {
  293. 'email': 'social@auth.com',
  294. 'username': 'SocialUser',
  295. }
  296. request = create_request(data=form_data)
  297. strategy = load_strategy(request=request)
  298. backend = GithubOAuth2(strategy, '/')
  299. result = create_user_with_form(
  300. strategy=strategy,
  301. details={'email': form_data['email']},
  302. backend=backend,
  303. user=None,
  304. pipeline_index=1,
  305. )
  306. new_user = UserModel.objects.get(email='social@auth.com')
  307. self.assertEqual(result, {'user': new_user, 'is_new': True})
  308. self.assertNewUserIsCorrect(new_user, form_data, activation='user', email_verified=True)
  309. @override_settings(account_activation='user')
  310. def test_user_created_activation_by_user_nonverified_email(self):
  311. """inactive user is created for non-verified email and activation by user"""
  312. form_data = {
  313. 'email': 'social@auth.com',
  314. 'username': 'SocialUser',
  315. }
  316. request = create_request(data=form_data)
  317. strategy = load_strategy(request=request)
  318. backend = GithubOAuth2(strategy, '/')
  319. result = create_user_with_form(
  320. strategy=strategy,
  321. details={'email': ''},
  322. backend=backend,
  323. user=None,
  324. pipeline_index=1,
  325. )
  326. new_user = UserModel.objects.get(email='social@auth.com')
  327. self.assertEqual(result, {'user': new_user, 'is_new': True})
  328. self.assertNewUserIsCorrect(new_user, form_data, activation='user', email_verified=False)
  329. @override_settings(account_activation='admin')
  330. def test_user_created_activation_by_admin_verified_email(self):
  331. """inactive user is created for verified email and activation by admin"""
  332. form_data = {
  333. 'email': 'social@auth.com',
  334. 'username': 'SocialUser',
  335. }
  336. request = create_request(data=form_data)
  337. strategy = load_strategy(request=request)
  338. backend = GithubOAuth2(strategy, '/')
  339. result = create_user_with_form(
  340. strategy=strategy,
  341. details={'email': form_data['email']},
  342. backend=backend,
  343. user=None,
  344. pipeline_index=1,
  345. )
  346. new_user = UserModel.objects.get(email='social@auth.com')
  347. self.assertEqual(result, {'user': new_user, 'is_new': True})
  348. self.assertNewUserIsCorrect(new_user, form_data, activation='admin', email_verified=True)
  349. @override_settings(account_activation='admin')
  350. def test_user_created_activation_by_admin_nonverified_email(self):
  351. """inactive user is created for non-verified email and activation by admin"""
  352. form_data = {
  353. 'email': 'social@auth.com',
  354. 'username': 'SocialUser',
  355. }
  356. request = create_request(data=form_data)
  357. strategy = load_strategy(request=request)
  358. backend = GithubOAuth2(strategy, '/')
  359. result = create_user_with_form(
  360. strategy=strategy,
  361. details={'email': ''},
  362. backend=backend,
  363. user=None,
  364. pipeline_index=1,
  365. )
  366. new_user = UserModel.objects.get(email='social@auth.com')
  367. self.assertEqual(result, {'user': new_user, 'is_new': True})
  368. self.assertNewUserIsCorrect(new_user, form_data, activation='admin', email_verified=False)
  369. class GetUsernameTests(PipelineTestCase):
  370. def test_skip_if_user_is_set(self):
  371. """pipeline step is skipped if user was passed"""
  372. result = get_username(None, {}, None, user=self.user)
  373. self.assertIsNone(result)
  374. def test_skip_if_no_names(self):
  375. """pipeline step is skipped if API returned no names"""
  376. result = get_username(None, {}, None)
  377. self.assertIsNone(result)
  378. def test_resolve_to_username(self):
  379. """pipeline step resolves username"""
  380. result = get_username(None, {'username': 'BobBoberson'}, None)
  381. self.assertEqual(result, {'clean_username': 'BobBoberson'})
  382. def test_normalize_username(self):
  383. """pipeline step normalizes username"""
  384. result = get_username(None, {'username': u'Błop Błoperson'}, None)
  385. self.assertEqual(result, {'clean_username': 'BlopBloperson'})
  386. def test_resolve_to_first_name(self):
  387. """pipeline attempts to use first name because username is taken"""
  388. details = {
  389. 'username': self.user.username,
  390. 'first_name': u'Błob',
  391. }
  392. result = get_username(None, details, None)
  393. self.assertEqual(result, {'clean_username': 'Blob'})
  394. def test_dont_resolve_to_last_name(self):
  395. """pipeline will not fallback to last name because username is taken"""
  396. details = {
  397. 'username': self.user.username,
  398. 'last_name': u'Błob',
  399. }
  400. result = get_username(None, details, None)
  401. self.assertIsNone(result)
  402. def test_resolve_to_first_last_name_first_char(self):
  403. """pipeline will construct username from first name and first char of surname"""
  404. details = {
  405. 'first_name': self.user.username,
  406. 'last_name': u'Błob',
  407. }
  408. result = get_username(None, details, None)
  409. self.assertEqual(result, {'clean_username': self.user.username + 'B'})
  410. def test_dont_resolve_to_banned_name(self):
  411. """pipeline will not resolve to banned name"""
  412. Ban.objects.create(banned_value='*Admin*', check_type=Ban.USERNAME)
  413. details = {
  414. 'username': 'Misago Admin',
  415. 'first_name': u'Błob',
  416. }
  417. result = get_username(None, details, None)
  418. self.assertEqual(result, {'clean_username': 'Blob'})
  419. def test_resolve_full_name(self):
  420. """pipeline will resolve to full name"""
  421. Ban.objects.create(banned_value='*Admin*', check_type=Ban.USERNAME)
  422. details = {
  423. 'username': 'Misago Admin',
  424. 'full_name': u'Błob Błopo',
  425. }
  426. result = get_username(None, details, None)
  427. self.assertEqual(result, {'clean_username': 'BlobBlopo'})
  428. def test_resolve_to_cut_name(self):
  429. """pipeline will resolve cut too long name on second pass"""
  430. details = {
  431. 'username': u'Abrakadabrapokuskonstantynopolitańczykowianeczkatrzy',
  432. }
  433. result = get_username(None, details, None)
  434. self.assertEqual(result, {'clean_username': 'Abrakadabrapok'})
  435. class RequireActivationTests(PipelineTestCase):
  436. def setUp(self):
  437. super(RequireActivationTests, self).setUp()
  438. self.user.requires_activation = UserModel.ACTIVATION_ADMIN
  439. self.user.save()
  440. def test_skip_if_user_not_set(self):
  441. """pipeline step is skipped if user is not set"""
  442. request = create_request()
  443. strategy = load_strategy(request=request)
  444. backend = GithubOAuth2(strategy, '/')
  445. result = require_activation(
  446. strategy=strategy,
  447. details={},
  448. backend=backend,
  449. user=None,
  450. pipeline_index=1,
  451. )
  452. self.assertEqual(result, {})
  453. def test_partial_token_if_user_not_set_no_showstopper(self):
  454. """pipeline step handles set session token if user is not set"""
  455. request = create_request()
  456. strategy = load_strategy(request=request)
  457. strategy.request.session['partial_pipeline_token'] = 'test-token'
  458. backend = GithubOAuth2(strategy, '/')
  459. require_activation(
  460. strategy=strategy,
  461. details={},
  462. backend=backend,
  463. user=None,
  464. pipeline_index=1,
  465. )
  466. def test_skip_if_user_is_active(self):
  467. """pipeline step is skipped if user is active"""
  468. self.user.requires_activation = UserModel.ACTIVATION_NONE
  469. self.user.save()
  470. self.assertFalse(self.user.requires_activation)
  471. request = create_request()
  472. strategy = load_strategy(request=request)
  473. backend = GithubOAuth2(strategy, '/')
  474. result = require_activation(
  475. strategy=strategy,
  476. details={},
  477. backend=backend,
  478. user=self.user,
  479. pipeline_index=1,
  480. )
  481. self.assertEqual(result, {})
  482. def test_pipeline_returns_html_responseon_get(self):
  483. """pipeline step renders http response for GET request and inactive user"""
  484. request = create_request()
  485. strategy = load_strategy(request=request)
  486. backend = GithubOAuth2(strategy, '/')
  487. response = require_activation(
  488. strategy=strategy,
  489. details={},
  490. backend=backend,
  491. user=self.user,
  492. pipeline_index=1,
  493. )
  494. self.assertEqual(response.status_code, 200)
  495. self.assertEqual(response['content-type'], 'text/html; charset=utf-8')
  496. def test_pipeline_returns_json_response_on_post(self):
  497. """pipeline step renders json response for POST request and inactive user"""
  498. request = create_request(data={'username': 'anything'})
  499. strategy = load_strategy(request=request)
  500. backend = GithubOAuth2(strategy, '/')
  501. response = require_activation(
  502. strategy=strategy,
  503. details={},
  504. backend=backend,
  505. user=self.user,
  506. pipeline_index=1,
  507. )
  508. self.assertEqual(response.status_code, 200)
  509. self.assertEqual(response['content-type'], 'application/json')
  510. self.assertEqual(json.loads(response.content), {
  511. 'step': 'done',
  512. 'backend_name': 'GitHub',
  513. 'activation': 'admin',
  514. 'email': 'test@user.com',
  515. 'username': 'TestUser',
  516. })
  517. class ValidateIpNotBannedTests(PipelineTestCase):
  518. def test_skip_if_user_not_set(self):
  519. """pipeline step is skipped if no user was passed"""
  520. result = validate_ip_not_banned(None, {}, GithubOAuth2)
  521. self.assertIsNone(result)
  522. def test_raise_if_banned(self):
  523. """pipeline raises if user's IP is banned"""
  524. Ban.objects.create(banned_value='188.*', check_type=Ban.IP)
  525. try:
  526. validate_ip_not_banned(MockStrategy(user_ip='188.1.2.3'), {}, GithubOAuth2, self.user)
  527. self.fail("validate_ip_not_banned should raise SocialAuthBanned")
  528. except SocialAuthBanned as e:
  529. self.assertTrue(isinstance(e.ban, Ban))
  530. def test_exclude_staff(self):
  531. """pipeline excludes staff from bans"""
  532. self.user.is_staff = True
  533. self.user.save()
  534. Ban.objects.create(banned_value='188.*', check_type=Ban.IP)
  535. result = validate_ip_not_banned(
  536. MockStrategy(user_ip='188.1.2.3'), {}, GithubOAuth2, self.user)
  537. self.assertIsNone(result)
  538. class ValidateUserNotBannedTests(PipelineTestCase):
  539. def test_skip_if_user_not_set(self):
  540. """pipeline step is skipped if no user was passed"""
  541. result = validate_user_not_banned(None, {}, GithubOAuth2)
  542. self.assertIsNone(result)
  543. def test_raise_if_banned(self):
  544. """pipeline raises if user's IP is banned"""
  545. Ban.objects.create(banned_value=self.user.username, check_type=Ban.USERNAME)
  546. try:
  547. validate_user_not_banned(MockStrategy(), {}, GithubOAuth2, self.user)
  548. self.fail("validate_ip_not_banned should raise SocialAuthBanned")
  549. except SocialAuthBanned as e:
  550. self.assertEqual(e.ban.user, self.user)
  551. self.assertTrue(isinstance(e.ban, BanCache))
  552. def test_exclude_staff(self):
  553. """pipeline excludes staff from bans"""
  554. self.user.is_staff = True
  555. self.user.save()
  556. Ban.objects.create(banned_value=self.user.username, check_type=Ban.USERNAME)
  557. result = validate_user_not_banned(MockStrategy(), {}, GithubOAuth2, self.user)
  558. self.assertIsNone(result)