test_change_oauth2_settings.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. from django.urls import reverse
  2. from ...models import Setting
  3. from ....test import ERROR, assert_has_message, assert_contains
  4. def test_oauth2_can_be_enabled(admin_client):
  5. response = admin_client.post(
  6. reverse("misago:admin:settings:oauth2:index"),
  7. {
  8. "enable_oauth2_client": "1",
  9. "oauth2_provider": "Lorem",
  10. "oauth2_client_id": "id",
  11. "oauth2_client_secret": "secret",
  12. "oauth2_scopes": "some scope",
  13. "oauth2_login_url": "https://example.com/login/",
  14. "oauth2_token_url": "https://example.com/token/",
  15. "oauth2_token_method": "POST",
  16. "oauth2_token_extra_headers": "",
  17. "oauth2_json_token_path": "access_token",
  18. "oauth2_user_url": "https://example.com/user/",
  19. "oauth2_user_method": "GET",
  20. "oauth2_user_token_location": "HEADER",
  21. "oauth2_user_token_name": "access_token",
  22. "oauth2_user_extra_headers": "",
  23. "oauth2_send_welcome_email": "",
  24. "oauth2_json_id_path": "id",
  25. "oauth2_json_name_path": "name",
  26. "oauth2_json_email_path": "email",
  27. "oauth2_json_avatar_path": "avatar",
  28. },
  29. )
  30. assert response.status_code == 302
  31. settings = {row.setting: row.value for row in Setting.objects.all()}
  32. assert settings["enable_oauth2_client"] is True
  33. assert settings["oauth2_provider"] == "Lorem"
  34. assert settings["oauth2_client_id"] == "id"
  35. assert settings["oauth2_client_secret"] == "secret"
  36. assert settings["oauth2_scopes"] == "some scope"
  37. assert settings["oauth2_login_url"] == "https://example.com/login/"
  38. assert settings["oauth2_token_url"] == "https://example.com/token/"
  39. assert settings["oauth2_token_method"] == "POST"
  40. assert settings["oauth2_token_extra_headers"] == ""
  41. assert settings["oauth2_json_token_path"] == "access_token"
  42. assert settings["oauth2_user_url"] == "https://example.com/user/"
  43. assert settings["oauth2_user_method"] == "GET"
  44. assert settings["oauth2_user_token_location"] == "HEADER"
  45. assert settings["oauth2_user_token_name"] == "access_token"
  46. assert settings["oauth2_user_extra_headers"] == ""
  47. assert settings["oauth2_send_welcome_email"] is False
  48. assert settings["oauth2_json_id_path"] == "id"
  49. assert settings["oauth2_json_name_path"] == "name"
  50. assert settings["oauth2_json_email_path"] == "email"
  51. assert settings["oauth2_json_avatar_path"] == "avatar"
  52. def test_oauth2_can_be_enabled_without_avatar(admin_client):
  53. response = admin_client.post(
  54. reverse("misago:admin:settings:oauth2:index"),
  55. {
  56. "enable_oauth2_client": "1",
  57. "oauth2_provider": "Lorem",
  58. "oauth2_client_id": "id",
  59. "oauth2_client_secret": "secret",
  60. "oauth2_scopes": "some scope",
  61. "oauth2_login_url": "https://example.com/login/",
  62. "oauth2_token_url": "https://example.com/token/",
  63. "oauth2_token_method": "POST",
  64. "oauth2_token_extra_headers": "",
  65. "oauth2_json_token_path": "access_token",
  66. "oauth2_user_url": "https://example.com/user/",
  67. "oauth2_user_method": "GET",
  68. "oauth2_user_token_location": "HEADER",
  69. "oauth2_user_token_name": "access_token",
  70. "oauth2_user_extra_headers": "",
  71. "oauth2_send_welcome_email": "",
  72. "oauth2_json_id_path": "id",
  73. "oauth2_json_name_path": "name",
  74. "oauth2_json_email_path": "email",
  75. "oauth2_json_avatar_path": "",
  76. },
  77. )
  78. assert response.status_code == 302
  79. settings = {row.setting: row.value for row in Setting.objects.all()}
  80. assert settings["enable_oauth2_client"] is True
  81. assert settings["oauth2_provider"] == "Lorem"
  82. assert settings["oauth2_client_id"] == "id"
  83. assert settings["oauth2_client_secret"] == "secret"
  84. assert settings["oauth2_scopes"] == "some scope"
  85. assert settings["oauth2_login_url"] == "https://example.com/login/"
  86. assert settings["oauth2_token_url"] == "https://example.com/token/"
  87. assert settings["oauth2_token_method"] == "POST"
  88. assert settings["oauth2_token_extra_headers"] == ""
  89. assert settings["oauth2_json_token_path"] == "access_token"
  90. assert settings["oauth2_user_url"] == "https://example.com/user/"
  91. assert settings["oauth2_user_method"] == "GET"
  92. assert settings["oauth2_user_token_location"] == "HEADER"
  93. assert settings["oauth2_user_token_name"] == "access_token"
  94. assert settings["oauth2_user_extra_headers"] == ""
  95. assert settings["oauth2_send_welcome_email"] == False
  96. assert settings["oauth2_json_id_path"] == "id"
  97. assert settings["oauth2_json_name_path"] == "name"
  98. assert settings["oauth2_json_email_path"] == "email"
  99. assert settings["oauth2_json_avatar_path"] == ""
  100. def test_oauth2_cant_be_enabled_with_some_value_missing(admin_client):
  101. data = {
  102. "enable_oauth2_client": "1",
  103. "oauth2_provider": "Lorem",
  104. "oauth2_client_id": "id",
  105. "oauth2_client_secret": "secret",
  106. "oauth2_scopes": "some scope",
  107. "oauth2_login_url": "https://example.com/login/",
  108. "oauth2_token_url": "https://example.com/token/",
  109. "oauth2_token_method": "POST",
  110. "oauth2_token_extra_headers": "",
  111. "oauth2_json_token_path": "access_token",
  112. "oauth2_user_url": "https://example.com/user/",
  113. "oauth2_user_method": "GET",
  114. "oauth2_user_token_location": "HEADER",
  115. "oauth2_user_token_name": "access_token",
  116. "oauth2_user_extra_headers": "",
  117. "oauth2_send_welcome_email": "",
  118. "oauth2_json_id_path": "id",
  119. "oauth2_json_name_path": "name",
  120. "oauth2_json_email_path": "email",
  121. "oauth2_json_avatar_path": "",
  122. }
  123. skip_settings = (
  124. "enable_oauth2_client",
  125. "oauth2_json_avatar_path",
  126. "oauth2_token_method",
  127. "oauth2_token_extra_headers",
  128. "oauth2_user_method",
  129. "oauth2_user_token_location",
  130. "oauth2_user_extra_headers",
  131. "oauth2_send_welcome_email",
  132. )
  133. for setting in data:
  134. if setting in skip_settings:
  135. continue
  136. new_data = data.copy()
  137. new_data[setting] = ""
  138. response = admin_client.post(
  139. reverse("misago:admin:settings:oauth2:index"),
  140. new_data,
  141. )
  142. assert response.status_code == 302
  143. assert_has_message(response, "You need to complete the configuration", ERROR)
  144. settings = {row.setting: row.value for row in Setting.objects.all()}
  145. assert settings["enable_oauth2_client"] is False
  146. if setting != "oauth2_client_id":
  147. assert settings["oauth2_client_id"] == "id"
  148. if setting != "oauth2_client_secret":
  149. assert settings["oauth2_client_secret"] == "secret"
  150. if setting != "oauth2_scopes":
  151. assert settings["oauth2_scopes"] == "some scope"
  152. if setting != "oauth2_login_url":
  153. assert settings["oauth2_login_url"] == "https://example.com/login/"
  154. if setting != "oauth2_token_url":
  155. assert settings["oauth2_token_url"] == "https://example.com/token/"
  156. if setting != "oauth2_json_token_path":
  157. assert settings["oauth2_json_token_path"] == "access_token"
  158. if setting != "oauth2_user_url":
  159. assert settings["oauth2_user_url"] == "https://example.com/user/"
  160. if setting != "oauth2_user_token_name":
  161. assert settings["oauth2_user_token_name"] == "access_token"
  162. if setting != "oauth2_json_id_path":
  163. assert settings["oauth2_json_id_path"] == "id"
  164. if setting != "oauth2_json_name_path":
  165. assert settings["oauth2_json_name_path"] == "name"
  166. if setting != "oauth2_json_email_path":
  167. assert settings["oauth2_json_email_path"] == "email"
  168. def test_oauth2_scopes_are_normalized(admin_client):
  169. response = admin_client.post(
  170. reverse("misago:admin:settings:oauth2:index"),
  171. {
  172. "enable_oauth2_client": "0",
  173. "oauth2_client_id": "id",
  174. "oauth2_client_secret": "secret",
  175. "oauth2_scopes": "some some scope",
  176. "oauth2_login_url": "https://example.com/login/",
  177. "oauth2_token_url": "https://example.com/token/",
  178. "oauth2_token_method": "POST",
  179. "oauth2_token_extra_headers": "",
  180. "oauth2_json_token_path": "access_token",
  181. "oauth2_user_url": "https://example.com/user/",
  182. "oauth2_user_method": "GET",
  183. "oauth2_user_token_location": "HEADER",
  184. "oauth2_user_token_name": "access_token",
  185. "oauth2_user_extra_headers": "",
  186. "oauth2_json_id_path": "id",
  187. "oauth2_json_name_path": "name",
  188. "oauth2_json_email_path": "email",
  189. "oauth2_json_avatar_path": "",
  190. },
  191. )
  192. assert response.status_code == 302
  193. setting = Setting.objects.get(setting="oauth2_scopes")
  194. assert setting.value == "some scope"
  195. def test_oauth2_extra_token_headers_are_normalized(admin_client):
  196. response = admin_client.post(
  197. reverse("misago:admin:settings:oauth2:index"),
  198. {
  199. "enable_oauth2_client": "0",
  200. "oauth2_client_id": "id",
  201. "oauth2_client_secret": "secret",
  202. "oauth2_scopes": "some some scope",
  203. "oauth2_login_url": "https://example.com/login/",
  204. "oauth2_token_url": "https://example.com/token/",
  205. "oauth2_token_method": "POST",
  206. "oauth2_token_extra_headers": ("Lorem: ipsum\n Dolor: Met-elit"),
  207. "oauth2_json_token_path": "access_token",
  208. "oauth2_user_url": "https://example.com/user/",
  209. "oauth2_user_method": "GET",
  210. "oauth2_user_token_location": "HEADER",
  211. "oauth2_user_token_name": "access_token",
  212. "oauth2_user_extra_headers": "",
  213. "oauth2_send_welcome_email": "",
  214. "oauth2_json_id_path": "id",
  215. "oauth2_json_name_path": "name",
  216. "oauth2_json_email_path": "email",
  217. "oauth2_json_avatar_path": "",
  218. },
  219. )
  220. assert response.status_code == 302
  221. setting = Setting.objects.get(setting="oauth2_token_extra_headers")
  222. assert setting.value == "Lorem: ipsum\nDolor: Met-elit"
  223. def test_oauth2_extra_token_headers_are_validated(admin_client):
  224. response = admin_client.post(
  225. reverse("misago:admin:settings:oauth2:index"),
  226. {
  227. "enable_oauth2_client": "0",
  228. "oauth2_client_id": "id",
  229. "oauth2_client_secret": "secret",
  230. "oauth2_scopes": "some some scope",
  231. "oauth2_login_url": "https://example.com/login/",
  232. "oauth2_token_url": "https://example.com/token/",
  233. "oauth2_token_method": "POST",
  234. "oauth2_token_extra_headers": (
  235. "Lorem: ipsum\n Dolor-amet\n Dolor: Met-elit"
  236. ),
  237. "oauth2_json_token_path": "access_token",
  238. "oauth2_user_url": "https://example.com/user/",
  239. "oauth2_user_method": "GET",
  240. "oauth2_user_token_location": "HEADER",
  241. "oauth2_user_token_name": "access_token",
  242. "oauth2_user_extra_headers": "",
  243. "oauth2_send_welcome_email": "",
  244. "oauth2_json_id_path": "id",
  245. "oauth2_json_name_path": "name",
  246. "oauth2_json_email_path": "email",
  247. "oauth2_json_avatar_path": "",
  248. },
  249. )
  250. assert_contains(response, "is not a valid header")
  251. def test_oauth2_extra_user_headers_are_normalized(admin_client):
  252. response = admin_client.post(
  253. reverse("misago:admin:settings:oauth2:index"),
  254. {
  255. "enable_oauth2_client": "0",
  256. "oauth2_client_id": "id",
  257. "oauth2_client_secret": "secret",
  258. "oauth2_scopes": "some some scope",
  259. "oauth2_login_url": "https://example.com/login/",
  260. "oauth2_token_url": "https://example.com/token/",
  261. "oauth2_token_method": "POST",
  262. "oauth2_token_extra_headers": "",
  263. "oauth2_json_token_path": "access_token",
  264. "oauth2_user_url": "https://example.com/user/",
  265. "oauth2_user_method": "GET",
  266. "oauth2_user_token_location": "HEADER",
  267. "oauth2_user_token_name": "access_token",
  268. "oauth2_user_extra_headers": ("Lorem: ipsum\n Dolor: Met-amet"),
  269. "oauth2_send_welcome_email": "",
  270. "oauth2_json_id_path": "id",
  271. "oauth2_json_name_path": "name",
  272. "oauth2_json_email_path": "email",
  273. "oauth2_json_avatar_path": "",
  274. },
  275. )
  276. assert response.status_code == 302
  277. setting = Setting.objects.get(setting="oauth2_user_extra_headers")
  278. assert setting.value == "Lorem: ipsum\nDolor: Met-amet"
  279. def test_oauth2_extra_user_headers_are_validated(admin_client):
  280. response = admin_client.post(
  281. reverse("misago:admin:settings:oauth2:index"),
  282. {
  283. "enable_oauth2_client": "0",
  284. "oauth2_client_id": "id",
  285. "oauth2_client_secret": "secret",
  286. "oauth2_scopes": "some some scope",
  287. "oauth2_login_url": "https://example.com/login/",
  288. "oauth2_token_url": "https://example.com/token/",
  289. "oauth2_token_method": "POST",
  290. "oauth2_token_extra_headers": "",
  291. "oauth2_json_token_path": "access_token",
  292. "oauth2_user_url": "https://example.com/user/",
  293. "oauth2_user_method": "GET",
  294. "oauth2_user_token_location": "HEADER",
  295. "oauth2_user_token_name": "access_token",
  296. "oauth2_user_extra_headers": ("Lorem: ipsum\n Dolor-met"),
  297. "oauth2_send_welcome_email": "",
  298. "oauth2_json_id_path": "id",
  299. "oauth2_json_name_path": "name",
  300. "oauth2_json_email_path": "email",
  301. "oauth2_json_avatar_path": "",
  302. },
  303. )
  304. assert_contains(response, "is not a valid header")
  305. def test_oauth2_extra_headers_are_validated_to_have_colons(admin_client):
  306. response = admin_client.post(
  307. reverse("misago:admin:settings:oauth2:index"),
  308. {
  309. "enable_oauth2_client": "0",
  310. "oauth2_client_id": "id",
  311. "oauth2_client_secret": "secret",
  312. "oauth2_scopes": "some some scope",
  313. "oauth2_login_url": "https://example.com/login/",
  314. "oauth2_token_url": "https://example.com/token/",
  315. "oauth2_token_method": "POST",
  316. "oauth2_token_extra_headers": "",
  317. "oauth2_json_token_path": "access_token",
  318. "oauth2_user_url": "https://example.com/user/",
  319. "oauth2_user_method": "GET",
  320. "oauth2_user_token_location": "HEADER",
  321. "oauth2_user_token_name": "access_token",
  322. "oauth2_user_extra_headers": ("Lorem: ipsum\n Dolor-met"),
  323. "oauth2_send_welcome_email": "",
  324. "oauth2_json_id_path": "id",
  325. "oauth2_json_name_path": "name",
  326. "oauth2_json_email_path": "email",
  327. "oauth2_json_avatar_path": "",
  328. },
  329. )
  330. assert_contains(response, "is not a valid header. It's missing a colon")
  331. def test_oauth2_extra_headers_are_validated_to_have_names(admin_client):
  332. response = admin_client.post(
  333. reverse("misago:admin:settings:oauth2:index"),
  334. {
  335. "enable_oauth2_client": "0",
  336. "oauth2_client_id": "id",
  337. "oauth2_client_secret": "secret",
  338. "oauth2_scopes": "some some scope",
  339. "oauth2_login_url": "https://example.com/login/",
  340. "oauth2_token_url": "https://example.com/token/",
  341. "oauth2_token_method": "POST",
  342. "oauth2_token_extra_headers": "",
  343. "oauth2_json_token_path": "access_token",
  344. "oauth2_user_url": "https://example.com/user/",
  345. "oauth2_user_method": "GET",
  346. "oauth2_user_token_location": "HEADER",
  347. "oauth2_user_token_name": "access_token",
  348. "oauth2_user_extra_headers": ("Lorem: ipsum\n :Dolor-met"),
  349. "oauth2_send_welcome_email": "",
  350. "oauth2_json_id_path": "id",
  351. "oauth2_json_name_path": "name",
  352. "oauth2_json_email_path": "email",
  353. "oauth2_json_avatar_path": "",
  354. },
  355. )
  356. assert_contains(
  357. response,
  358. "is not a valid header. It's missing a header name before the colon",
  359. )
  360. def test_oauth2_extra_headers_are_validated_to_have_values(admin_client):
  361. response = admin_client.post(
  362. reverse("misago:admin:settings:oauth2:index"),
  363. {
  364. "enable_oauth2_client": "0",
  365. "oauth2_client_id": "id",
  366. "oauth2_client_secret": "secret",
  367. "oauth2_scopes": "some some scope",
  368. "oauth2_login_url": "https://example.com/login/",
  369. "oauth2_token_url": "https://example.com/token/",
  370. "oauth2_token_method": "POST",
  371. "oauth2_token_extra_headers": "",
  372. "oauth2_json_token_path": "access_token",
  373. "oauth2_user_url": "https://example.com/user/",
  374. "oauth2_user_method": "GET",
  375. "oauth2_user_token_location": "HEADER",
  376. "oauth2_user_token_name": "access_token",
  377. "oauth2_user_extra_headers": ("Lorem: ipsum\n Dolor-met:"),
  378. "oauth2_send_welcome_email": "",
  379. "oauth2_json_id_path": "id",
  380. "oauth2_json_name_path": "name",
  381. "oauth2_json_email_path": "email",
  382. "oauth2_json_avatar_path": "",
  383. },
  384. )
  385. assert_contains(
  386. response,
  387. "is not a valid header. It's missing a header value after the colon",
  388. )
  389. def test_oauth2_extra_headers_are_validated_to_be_unique(admin_client):
  390. response = admin_client.post(
  391. reverse("misago:admin:settings:oauth2:index"),
  392. {
  393. "enable_oauth2_client": "0",
  394. "oauth2_client_id": "id",
  395. "oauth2_client_secret": "secret",
  396. "oauth2_scopes": "some some scope",
  397. "oauth2_login_url": "https://example.com/login/",
  398. "oauth2_token_url": "https://example.com/token/",
  399. "oauth2_token_method": "POST",
  400. "oauth2_token_extra_headers": "",
  401. "oauth2_json_token_path": "access_token",
  402. "oauth2_user_url": "https://example.com/user/",
  403. "oauth2_user_method": "GET",
  404. "oauth2_user_token_location": "HEADER",
  405. "oauth2_user_token_name": "access_token",
  406. "oauth2_user_extra_headers": ("Accept:b\nLorem: ipsum\n Accept: a"),
  407. "oauth2_send_welcome_email": "",
  408. "oauth2_json_id_path": "id",
  409. "oauth2_json_name_path": "name",
  410. "oauth2_json_email_path": "email",
  411. "oauth2_json_avatar_path": "",
  412. },
  413. )
  414. assert_contains(response, ""Accept" header is entered more than once.")