test_change_oauth2_settings.py 18 KB

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