test_oauth2_complete_view.py 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. import responses
  2. from django.contrib.auth import get_user_model
  3. from django.urls import reverse
  4. from responses.matchers import header_matcher, urlencoded_params_matcher
  5. from ...conf.test import override_dynamic_settings
  6. from ...test import assert_contains
  7. from ...users.bans import ban_ip, ban_user
  8. from ..client import SESSION_STATE
  9. from ..models import Subject
  10. User = get_user_model()
  11. def test_oauth2_complete_view_returns_404_if_oauth_is_disabled(
  12. client, dynamic_settings
  13. ):
  14. assert dynamic_settings.enable_oauth2_client is False
  15. response = client.get(reverse("misago:oauth2-complete"))
  16. assert response.status_code == 404
  17. def test_oauth2_complete_view_returns_error_404_if_user_ip_is_banned_and_oauth_is_disabled(
  18. client, dynamic_settings
  19. ):
  20. ban_ip("127.*", "Ya got banned!")
  21. assert dynamic_settings.enable_oauth2_client is False
  22. response = client.get(reverse("misago:oauth2-complete"))
  23. assert response.status_code == 404
  24. @override_dynamic_settings(
  25. enable_oauth2_client=True,
  26. oauth2_client_id="clientid123",
  27. oauth2_scopes="scopes",
  28. oauth2_login_url="https://example.com/oauth2/login",
  29. )
  30. def test_oauth2_complete_view_returns_error_403_if_user_ip_is_banned(
  31. client, dynamic_settings
  32. ):
  33. ban_ip("127.*", "Ya got banned!")
  34. assert dynamic_settings.enable_oauth2_client is True
  35. response = client.get(reverse("misago:oauth2-complete"))
  36. assert_contains(response, "Ya got banned", 403)
  37. @override_dynamic_settings(
  38. enable_oauth2_client=True,
  39. oauth2_client_id="clientid123",
  40. oauth2_scopes="scopes",
  41. oauth2_login_url="https://example.com/oauth2/login",
  42. )
  43. def test_oauth2_complete_view_returns_error_400_if_user_canceled_sign_in(
  44. client, dynamic_settings
  45. ):
  46. assert dynamic_settings.enable_oauth2_client is True
  47. response = client.get("%s?error=access_denied" % reverse("misago:oauth2-complete"))
  48. assert_contains(response, "The OAuth2 process was canceled by the provider.", 400)
  49. @override_dynamic_settings(
  50. enable_oauth2_client=True,
  51. oauth2_client_id="clientid123",
  52. oauth2_scopes="scopes",
  53. oauth2_login_url="https://example.com/oauth2/login",
  54. )
  55. def test_oauth2_complete_view_returns_error_400_if_state_is_not_set(
  56. client, dynamic_settings
  57. ):
  58. assert dynamic_settings.enable_oauth2_client is True
  59. response = client.get(reverse("misago:oauth2-complete"))
  60. assert_contains(response, "OAuth2 session is missing state.", 400)
  61. @override_dynamic_settings(
  62. enable_oauth2_client=True,
  63. oauth2_client_id="clientid123",
  64. oauth2_scopes="scopes",
  65. oauth2_login_url="https://example.com/oauth2/login",
  66. )
  67. def test_oauth2_complete_view_returns_error_400_if_state_is_invalid(
  68. client, dynamic_settings
  69. ):
  70. assert dynamic_settings.enable_oauth2_client is True
  71. session = client.session
  72. session[SESSION_STATE] = "state123"
  73. session.save()
  74. response = client.get(
  75. "%s?state=invalid&code=1234" % reverse("misago:oauth2-complete")
  76. )
  77. assert_contains(
  78. response,
  79. "OAuth2 state sent by the provider did not match one in the session.",
  80. 400,
  81. )
  82. @override_dynamic_settings(
  83. enable_oauth2_client=True,
  84. oauth2_client_id="clientid123",
  85. oauth2_scopes="scopes",
  86. oauth2_login_url="https://example.com/oauth2/login",
  87. )
  88. def test_oauth2_complete_view_returns_error_400_if_code_is_missing(
  89. client, dynamic_settings
  90. ):
  91. assert dynamic_settings.enable_oauth2_client is True
  92. session = client.session
  93. session[SESSION_STATE] = "state123"
  94. session.save()
  95. response = client.get("%s?state=state123&code=" % reverse("misago:oauth2-complete"))
  96. assert_contains(
  97. response,
  98. "OAuth2 authorization code was not sent by the provider.",
  99. 400,
  100. )
  101. TEST_SETTINGS = {
  102. "enable_oauth2_client": True,
  103. "oauth2_client_id": "oauth2_client_id",
  104. "oauth2_client_secret": "oauth2_client_secret",
  105. "oauth2_login_url": "https://example.com/oauth2/login",
  106. "oauth2_token_url": "https://example.com/oauth2/token",
  107. "oauth2_token_method": "POST",
  108. "oauth2_json_token_path": "token.bearer",
  109. "oauth2_user_url": "https://example.com/oauth2/user",
  110. "oauth2_user_method": "POST",
  111. "oauth2_user_token_name": "Authorization",
  112. "oauth2_user_token_location": "HEADER_BEARER",
  113. "oauth2_send_welcome_email": True,
  114. "oauth2_json_id_path": "id",
  115. "oauth2_json_name_path": "profile.name",
  116. "oauth2_json_email_path": "profile.email",
  117. }
  118. @responses.activate
  119. @override_dynamic_settings(**TEST_SETTINGS)
  120. def test_oauth2_complete_view_creates_new_user(client, dynamic_settings, mailoutbox):
  121. assert dynamic_settings.enable_oauth2_client is True
  122. code_grant = "12345grant"
  123. session_state = "12345state"
  124. access_token = "12345token"
  125. session = client.session
  126. session[SESSION_STATE] = session_state
  127. session.save()
  128. responses.post(
  129. "https://example.com/oauth2/token",
  130. json={
  131. "token": {
  132. "bearer": access_token,
  133. },
  134. },
  135. match=[
  136. urlencoded_params_matcher(
  137. {
  138. "grant_type": "authorization_code",
  139. "client_id": "oauth2_client_id",
  140. "client_secret": "oauth2_client_secret",
  141. "redirect_uri": "http://testserver/oauth2/complete/",
  142. "code": code_grant,
  143. },
  144. ),
  145. ],
  146. )
  147. responses.post(
  148. "https://example.com/oauth2/user",
  149. json={
  150. "id": 1234,
  151. "profile": {
  152. "name": "John Doe",
  153. "email": "john@example.com",
  154. },
  155. },
  156. match=[
  157. header_matcher({"Authorization": f"Bearer {access_token}"}),
  158. ],
  159. )
  160. response = client.get(
  161. "%s?state=%s&code=%s"
  162. % (
  163. reverse("misago:oauth2-complete"),
  164. session_state,
  165. code_grant,
  166. )
  167. )
  168. assert response.status_code == 302
  169. # User and subject are created
  170. subject = Subject.objects.get(sub="1234")
  171. user = User.objects.get_by_email("john@example.com")
  172. assert subject.user_id == user.id
  173. assert user.username == "John_Doe"
  174. assert user.slug == "john-doe"
  175. assert user.email == "john@example.com"
  176. assert user.requires_activation == User.ACTIVATION_NONE
  177. # User is authenticated
  178. auth_api = client.get(reverse("misago:api:auth")).json()
  179. assert auth_api["id"] == user.id
  180. # User welcome e-mail is sent
  181. assert len(mailoutbox) == 1
  182. assert mailoutbox[0].subject == "Welcome on Misago forums!"
  183. TEST_SETTINGS_EMAIL_DISABLED = TEST_SETTINGS.copy()
  184. TEST_SETTINGS_EMAIL_DISABLED["oauth2_send_welcome_email"] = False
  185. @responses.activate
  186. @override_dynamic_settings(**TEST_SETTINGS_EMAIL_DISABLED)
  187. def test_oauth2_complete_view_doesnt_send_welcome_mail_if_option_is_disabled(
  188. client, dynamic_settings, mailoutbox
  189. ):
  190. assert dynamic_settings.enable_oauth2_client is True
  191. code_grant = "12345grant"
  192. session_state = "12345state"
  193. access_token = "12345token"
  194. session = client.session
  195. session[SESSION_STATE] = session_state
  196. session.save()
  197. responses.post(
  198. "https://example.com/oauth2/token",
  199. json={
  200. "token": {
  201. "bearer": access_token,
  202. },
  203. },
  204. match=[
  205. urlencoded_params_matcher(
  206. {
  207. "grant_type": "authorization_code",
  208. "client_id": "oauth2_client_id",
  209. "client_secret": "oauth2_client_secret",
  210. "redirect_uri": "http://testserver/oauth2/complete/",
  211. "code": code_grant,
  212. },
  213. ),
  214. ],
  215. )
  216. responses.post(
  217. "https://example.com/oauth2/user",
  218. json={
  219. "id": 1234,
  220. "profile": {
  221. "name": "John Doe",
  222. "email": "john@example.com",
  223. },
  224. },
  225. match=[
  226. header_matcher({"Authorization": f"Bearer {access_token}"}),
  227. ],
  228. )
  229. response = client.get(
  230. "%s?state=%s&code=%s"
  231. % (
  232. reverse("misago:oauth2-complete"),
  233. session_state,
  234. code_grant,
  235. )
  236. )
  237. assert response.status_code == 302
  238. # User and subject are created
  239. subject = Subject.objects.get(sub="1234")
  240. user = User.objects.get_by_email("john@example.com")
  241. assert subject.user_id == user.id
  242. # User is authenticated
  243. auth_api = client.get(reverse("misago:api:auth")).json()
  244. assert auth_api["id"] == user.id
  245. # User welcome e-mail is not sent
  246. assert len(mailoutbox) == 0
  247. TEST_SETTINGS_EXTRA_TOKEN_HEADERS = TEST_SETTINGS.copy()
  248. TEST_SETTINGS_EXTRA_TOKEN_HEADERS[
  249. "oauth2_token_extra_headers"
  250. ] = """
  251. Accept: application/json
  252. API-Version: 2.1.3.7
  253. """.strip()
  254. @responses.activate
  255. @override_dynamic_settings(**TEST_SETTINGS_EXTRA_TOKEN_HEADERS)
  256. def test_oauth2_complete_view_includes_extra_headers_in_token_request(
  257. client, dynamic_settings, mailoutbox
  258. ):
  259. assert dynamic_settings.enable_oauth2_client is True
  260. code_grant = "12345grant"
  261. session_state = "12345state"
  262. access_token = "12345token"
  263. session = client.session
  264. session[SESSION_STATE] = session_state
  265. session.save()
  266. responses.post(
  267. "https://example.com/oauth2/token",
  268. json={
  269. "token": {
  270. "bearer": access_token,
  271. },
  272. },
  273. match=[
  274. urlencoded_params_matcher(
  275. {
  276. "grant_type": "authorization_code",
  277. "client_id": "oauth2_client_id",
  278. "client_secret": "oauth2_client_secret",
  279. "redirect_uri": "http://testserver/oauth2/complete/",
  280. "code": code_grant,
  281. },
  282. ),
  283. header_matcher(
  284. {
  285. "Accept": "application/json",
  286. "API-Version": "2.1.3.7",
  287. }
  288. ),
  289. ],
  290. )
  291. responses.post(
  292. "https://example.com/oauth2/user",
  293. json={
  294. "id": 1234,
  295. "profile": {
  296. "name": "John Doe",
  297. "email": "john@example.com",
  298. },
  299. },
  300. match=[
  301. header_matcher({"Authorization": f"Bearer {access_token}"}),
  302. ],
  303. )
  304. response = client.get(
  305. "%s?state=%s&code=%s"
  306. % (
  307. reverse("misago:oauth2-complete"),
  308. session_state,
  309. code_grant,
  310. )
  311. )
  312. assert response.status_code == 302
  313. # User and subject are created
  314. subject = Subject.objects.get(sub="1234")
  315. user = User.objects.get_by_email("john@example.com")
  316. assert subject.user_id == user.id
  317. # User is authenticated
  318. auth_api = client.get(reverse("misago:api:auth")).json()
  319. assert auth_api["id"] == user.id
  320. TEST_SETTINGS_EXTRA_USER_HEADERS = TEST_SETTINGS.copy()
  321. TEST_SETTINGS_EXTRA_USER_HEADERS[
  322. "oauth2_user_extra_headers"
  323. ] = """
  324. X-Header: its-a-test
  325. API-Version: 2.1.3.7
  326. """.strip()
  327. @responses.activate
  328. @override_dynamic_settings(**TEST_SETTINGS_EXTRA_USER_HEADERS)
  329. def test_oauth2_complete_view_includes_extra_headers_in_user_request(
  330. client, dynamic_settings, mailoutbox
  331. ):
  332. assert dynamic_settings.enable_oauth2_client is True
  333. code_grant = "12345grant"
  334. session_state = "12345state"
  335. access_token = "12345token"
  336. session = client.session
  337. session[SESSION_STATE] = session_state
  338. session.save()
  339. responses.post(
  340. "https://example.com/oauth2/token",
  341. json={
  342. "token": {
  343. "bearer": access_token,
  344. },
  345. },
  346. match=[
  347. urlencoded_params_matcher(
  348. {
  349. "grant_type": "authorization_code",
  350. "client_id": "oauth2_client_id",
  351. "client_secret": "oauth2_client_secret",
  352. "redirect_uri": "http://testserver/oauth2/complete/",
  353. "code": code_grant,
  354. },
  355. ),
  356. ],
  357. )
  358. responses.post(
  359. "https://example.com/oauth2/user",
  360. json={
  361. "id": 1234,
  362. "profile": {
  363. "name": "John Doe",
  364. "email": "john@example.com",
  365. },
  366. },
  367. match=[
  368. header_matcher(
  369. {
  370. "Authorization": f"Bearer {access_token}",
  371. "X-Header": "its-a-test",
  372. "API-Version": "2.1.3.7",
  373. }
  374. ),
  375. ],
  376. )
  377. response = client.get(
  378. "%s?state=%s&code=%s"
  379. % (
  380. reverse("misago:oauth2-complete"),
  381. session_state,
  382. code_grant,
  383. )
  384. )
  385. assert response.status_code == 302
  386. # User and subject are created
  387. subject = Subject.objects.get(sub="1234")
  388. user = User.objects.get_by_email("john@example.com")
  389. assert subject.user_id == user.id
  390. # User is authenticated
  391. auth_api = client.get(reverse("misago:api:auth")).json()
  392. assert auth_api["id"] == user.id
  393. @responses.activate
  394. @override_dynamic_settings(**TEST_SETTINGS)
  395. def test_oauth2_complete_view_updates_existing_user(
  396. user, client, dynamic_settings, mailoutbox
  397. ):
  398. assert dynamic_settings.enable_oauth2_client is True
  399. Subject.objects.create(sub="1234", user=user)
  400. code_grant = "12345grant"
  401. session_state = "12345state"
  402. access_token = "12345token"
  403. session = client.session
  404. session[SESSION_STATE] = session_state
  405. session.save()
  406. responses.post(
  407. "https://example.com/oauth2/token",
  408. json={
  409. "token": {
  410. "bearer": access_token,
  411. },
  412. },
  413. match=[
  414. urlencoded_params_matcher(
  415. {
  416. "grant_type": "authorization_code",
  417. "client_id": "oauth2_client_id",
  418. "client_secret": "oauth2_client_secret",
  419. "redirect_uri": "http://testserver/oauth2/complete/",
  420. "code": code_grant,
  421. },
  422. ),
  423. ],
  424. )
  425. responses.post(
  426. "https://example.com/oauth2/user",
  427. json={
  428. "id": 1234,
  429. "profile": {
  430. "name": "John Doe",
  431. "email": "john@example.com",
  432. },
  433. },
  434. match=[
  435. header_matcher({"Authorization": f"Bearer {access_token}"}),
  436. ],
  437. )
  438. response = client.get(
  439. "%s?state=%s&code=%s"
  440. % (
  441. reverse("misago:oauth2-complete"),
  442. session_state,
  443. code_grant,
  444. )
  445. )
  446. assert response.status_code == 302
  447. # User is updated
  448. user.refresh_from_db()
  449. assert user.username == "John_Doe"
  450. assert user.slug == "john-doe"
  451. assert user.email == "john@example.com"
  452. # User is authenticated
  453. auth_api = client.get(reverse("misago:api:auth")).json()
  454. assert auth_api["id"] == user.id
  455. # User welcome e-mail is not sent
  456. assert len(mailoutbox) == 0
  457. @responses.activate
  458. @override_dynamic_settings(**TEST_SETTINGS)
  459. def test_oauth2_complete_view_returns_error_400_if_code_grant_is_rejected(
  460. client, dynamic_settings
  461. ):
  462. assert dynamic_settings.enable_oauth2_client is True
  463. code_grant = "12345grant"
  464. session_state = "12345state"
  465. session = client.session
  466. session[SESSION_STATE] = session_state
  467. session.save()
  468. responses.post(
  469. "https://example.com/oauth2/token",
  470. json={
  471. "error": "Permission denied",
  472. },
  473. status=403,
  474. match=[
  475. urlencoded_params_matcher(
  476. {
  477. "grant_type": "authorization_code",
  478. "client_id": "oauth2_client_id",
  479. "client_secret": "oauth2_client_secret",
  480. "redirect_uri": "http://testserver/oauth2/complete/",
  481. "code": code_grant,
  482. },
  483. ),
  484. ],
  485. )
  486. response = client.get(
  487. "%s?state=%s&code=%s"
  488. % (
  489. reverse("misago:oauth2-complete"),
  490. session_state,
  491. code_grant,
  492. )
  493. )
  494. assert_contains(
  495. response,
  496. "The OAuth2 provider responded with error for an access token request.",
  497. 400,
  498. )
  499. @responses.activate
  500. @override_dynamic_settings(**TEST_SETTINGS)
  501. def test_oauth2_complete_view_returns_error_400_if_access_token_is_rejected(
  502. user, client, dynamic_settings
  503. ):
  504. assert dynamic_settings.enable_oauth2_client is True
  505. Subject.objects.create(sub="1234", user=user)
  506. code_grant = "12345grant"
  507. session_state = "12345state"
  508. access_token = "12345token"
  509. session = client.session
  510. session[SESSION_STATE] = session_state
  511. session.save()
  512. responses.post(
  513. "https://example.com/oauth2/token",
  514. json={
  515. "token": {
  516. "bearer": access_token,
  517. },
  518. },
  519. match=[
  520. urlencoded_params_matcher(
  521. {
  522. "grant_type": "authorization_code",
  523. "client_id": "oauth2_client_id",
  524. "client_secret": "oauth2_client_secret",
  525. "redirect_uri": "http://testserver/oauth2/complete/",
  526. "code": code_grant,
  527. },
  528. ),
  529. ],
  530. )
  531. responses.post(
  532. "https://example.com/oauth2/user",
  533. json={
  534. "error": "Permission denied",
  535. },
  536. status=403,
  537. )
  538. response = client.get(
  539. "%s?state=%s&code=%s"
  540. % (
  541. reverse("misago:oauth2-complete"),
  542. session_state,
  543. code_grant,
  544. )
  545. )
  546. assert_contains(
  547. response,
  548. "The OAuth2 provider responded with error for user profile request.",
  549. 400,
  550. )
  551. @responses.activate
  552. @override_dynamic_settings(**TEST_SETTINGS)
  553. def test_oauth2_complete_view_returns_error_400_if_user_data_didnt_validate(
  554. user, client, dynamic_settings
  555. ):
  556. assert dynamic_settings.enable_oauth2_client is True
  557. Subject.objects.create(sub="1234", user=user)
  558. code_grant = "12345grant"
  559. session_state = "12345state"
  560. access_token = "12345token"
  561. session = client.session
  562. session[SESSION_STATE] = session_state
  563. session.save()
  564. responses.post(
  565. "https://example.com/oauth2/token",
  566. json={
  567. "token": {
  568. "bearer": access_token,
  569. },
  570. },
  571. match=[
  572. urlencoded_params_matcher(
  573. {
  574. "grant_type": "authorization_code",
  575. "client_id": "oauth2_client_id",
  576. "client_secret": "oauth2_client_secret",
  577. "redirect_uri": "http://testserver/oauth2/complete/",
  578. "code": code_grant,
  579. },
  580. ),
  581. ],
  582. )
  583. responses.post(
  584. "https://example.com/oauth2/user",
  585. json={
  586. "id": 1234,
  587. "profile": {
  588. "name": "John Doe",
  589. "email": "",
  590. },
  591. },
  592. match=[
  593. header_matcher({"Authorization": f"Bearer {access_token}"}),
  594. ],
  595. )
  596. response = client.get(
  597. "%s?state=%s&code=%s"
  598. % (
  599. reverse("misago:oauth2-complete"),
  600. session_state,
  601. code_grant,
  602. )
  603. )
  604. assert_contains(response, "Enter a valid email address.", 400)
  605. @responses.activate
  606. @override_dynamic_settings(**TEST_SETTINGS)
  607. def test_oauth2_complete_view_returns_error_400_if_user_data_causes_integrity_error(
  608. user, client, dynamic_settings
  609. ):
  610. assert dynamic_settings.enable_oauth2_client is True
  611. code_grant = "12345grant"
  612. session_state = "12345state"
  613. access_token = "12345token"
  614. session = client.session
  615. session[SESSION_STATE] = session_state
  616. session.save()
  617. responses.post(
  618. "https://example.com/oauth2/token",
  619. json={
  620. "token": {
  621. "bearer": access_token,
  622. },
  623. },
  624. match=[
  625. urlencoded_params_matcher(
  626. {
  627. "grant_type": "authorization_code",
  628. "client_id": "oauth2_client_id",
  629. "client_secret": "oauth2_client_secret",
  630. "redirect_uri": "http://testserver/oauth2/complete/",
  631. "code": code_grant,
  632. },
  633. ),
  634. ],
  635. )
  636. responses.post(
  637. "https://example.com/oauth2/user",
  638. json={
  639. "id": 1234,
  640. "profile": {
  641. "name": "John Doe",
  642. "email": user.email,
  643. },
  644. },
  645. match=[
  646. header_matcher({"Authorization": f"Bearer {access_token}"}),
  647. ],
  648. )
  649. response = client.get(
  650. "%s?state=%s&code=%s"
  651. % (
  652. reverse("misago:oauth2-complete"),
  653. session_state,
  654. code_grant,
  655. )
  656. )
  657. assert_contains(response, "This e-mail address is not available.", 400)
  658. @responses.activate
  659. @override_dynamic_settings(**TEST_SETTINGS)
  660. def test_oauth2_complete_view_updates_deactivated_user_but_returns_error_400(
  661. user, client, dynamic_settings, mailoutbox
  662. ):
  663. assert dynamic_settings.enable_oauth2_client is True
  664. Subject.objects.create(sub="1234", user=user)
  665. user.is_active = False
  666. user.save()
  667. code_grant = "12345grant"
  668. session_state = "12345state"
  669. access_token = "12345token"
  670. session = client.session
  671. session[SESSION_STATE] = session_state
  672. session.save()
  673. responses.post(
  674. "https://example.com/oauth2/token",
  675. json={
  676. "token": {
  677. "bearer": access_token,
  678. },
  679. },
  680. match=[
  681. urlencoded_params_matcher(
  682. {
  683. "grant_type": "authorization_code",
  684. "client_id": "oauth2_client_id",
  685. "client_secret": "oauth2_client_secret",
  686. "redirect_uri": "http://testserver/oauth2/complete/",
  687. "code": code_grant,
  688. },
  689. ),
  690. ],
  691. )
  692. responses.post(
  693. "https://example.com/oauth2/user",
  694. json={
  695. "id": 1234,
  696. "profile": {
  697. "name": "John Doe",
  698. "email": "john@example.com",
  699. },
  700. },
  701. match=[
  702. header_matcher({"Authorization": f"Bearer {access_token}"}),
  703. ],
  704. )
  705. response = client.get(
  706. "%s?state=%s&code=%s"
  707. % (
  708. reverse("misago:oauth2-complete"),
  709. session_state,
  710. code_grant,
  711. )
  712. )
  713. assert_contains(
  714. response,
  715. (
  716. "User account associated with the profile from the OAuth2 provider "
  717. "was deactivated by the site administrator."
  718. ),
  719. 400,
  720. )
  721. # User is updated but still deactivated
  722. user.refresh_from_db()
  723. assert user.username == "John_Doe"
  724. assert user.slug == "john-doe"
  725. assert user.email == "john@example.com"
  726. assert user.is_active is False
  727. # User is not authenticated
  728. auth_api = client.get(reverse("misago:api:auth")).json()
  729. assert auth_api["id"] is None
  730. # User welcome e-mail is not sent
  731. assert len(mailoutbox) == 0
  732. @responses.activate
  733. @override_dynamic_settings(**TEST_SETTINGS)
  734. def test_oauth2_complete_view_creates_banned_user_but_returns_error_403(
  735. user, client, dynamic_settings, mailoutbox
  736. ):
  737. assert dynamic_settings.enable_oauth2_client is True
  738. user.username = "John_Doe"
  739. ban_user(user, "Banned for a test.")
  740. user.refresh_from_db()
  741. code_grant = "12345grant"
  742. session_state = "12345state"
  743. access_token = "12345token"
  744. session = client.session
  745. session[SESSION_STATE] = session_state
  746. session.save()
  747. responses.post(
  748. "https://example.com/oauth2/token",
  749. json={
  750. "token": {
  751. "bearer": access_token,
  752. },
  753. },
  754. match=[
  755. urlencoded_params_matcher(
  756. {
  757. "grant_type": "authorization_code",
  758. "client_id": "oauth2_client_id",
  759. "client_secret": "oauth2_client_secret",
  760. "redirect_uri": "http://testserver/oauth2/complete/",
  761. "code": code_grant,
  762. },
  763. ),
  764. ],
  765. )
  766. responses.post(
  767. "https://example.com/oauth2/user",
  768. json={
  769. "id": 1234,
  770. "profile": {
  771. "name": "John Doe",
  772. "email": "john@example.com",
  773. },
  774. },
  775. match=[
  776. header_matcher({"Authorization": f"Bearer {access_token}"}),
  777. ],
  778. )
  779. response = client.get(
  780. "%s?state=%s&code=%s"
  781. % (
  782. reverse("misago:oauth2-complete"),
  783. session_state,
  784. code_grant,
  785. )
  786. )
  787. assert_contains(response, "Banned for a test.", 403)
  788. # User is created
  789. new_user = User.objects.get_by_email("john@example.com")
  790. assert new_user
  791. assert new_user.id != user.id
  792. assert new_user.username == "John_Doe"
  793. assert new_user.slug == "john-doe"
  794. assert new_user.email == "john@example.com"
  795. # User is not authenticated
  796. auth_api = client.get(reverse("misago:api:auth")).json()
  797. assert auth_api["id"] is None
  798. # User welcome e-mail is not sent
  799. assert len(mailoutbox) == 0
  800. @responses.activate
  801. @override_dynamic_settings(**TEST_SETTINGS)
  802. def test_oauth2_complete_view_updates_banned_user_but_returns_error_403(
  803. user, client, dynamic_settings, mailoutbox
  804. ):
  805. assert dynamic_settings.enable_oauth2_client is True
  806. Subject.objects.create(sub="1234", user=user)
  807. user.username = "John_Doe"
  808. ban_user(user, "Banned for a test.")
  809. user.refresh_from_db()
  810. code_grant = "12345grant"
  811. session_state = "12345state"
  812. access_token = "12345token"
  813. session = client.session
  814. session[SESSION_STATE] = session_state
  815. session.save()
  816. responses.post(
  817. "https://example.com/oauth2/token",
  818. json={
  819. "token": {
  820. "bearer": access_token,
  821. },
  822. },
  823. match=[
  824. urlencoded_params_matcher(
  825. {
  826. "grant_type": "authorization_code",
  827. "client_id": "oauth2_client_id",
  828. "client_secret": "oauth2_client_secret",
  829. "redirect_uri": "http://testserver/oauth2/complete/",
  830. "code": code_grant,
  831. },
  832. ),
  833. ],
  834. )
  835. responses.post(
  836. "https://example.com/oauth2/user",
  837. json={
  838. "id": 1234,
  839. "profile": {
  840. "name": "John Doe",
  841. "email": "john@example.com",
  842. },
  843. },
  844. match=[
  845. header_matcher({"Authorization": f"Bearer {access_token}"}),
  846. ],
  847. )
  848. response = client.get(
  849. "%s?state=%s&code=%s"
  850. % (
  851. reverse("misago:oauth2-complete"),
  852. session_state,
  853. code_grant,
  854. )
  855. )
  856. assert_contains(response, "Banned for a test.", 403)
  857. # User is updated
  858. user.refresh_from_db()
  859. assert user.username == "John_Doe"
  860. assert user.slug == "john-doe"
  861. assert user.email == "john@example.com"
  862. # User is not authenticated
  863. auth_api = client.get(reverse("misago:api:auth")).json()
  864. assert auth_api["id"] is None
  865. # User welcome e-mail is not sent
  866. assert len(mailoutbox) == 0