logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma

update_credentials_test.exs (18520B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
  5. alias Pleroma.Repo
  6. alias Pleroma.User
  7. use Pleroma.Web.ConnCase
  8. import Mock
  9. import Pleroma.Factory
  10. setup do: clear_config([:instance, :max_account_fields])
  11. describe "updating credentials" do
  12. setup do: oauth_access(["write:accounts"])
  13. setup :request_content_type
  14. test "sets user settings in a generic way", %{conn: conn} do
  15. res_conn =
  16. patch(conn, "/api/v1/accounts/update_credentials", %{
  17. "pleroma_settings_store" => %{
  18. pleroma_fe: %{
  19. theme: "bla"
  20. }
  21. }
  22. })
  23. assert user_data = json_response_and_validate_schema(res_conn, 200)
  24. assert user_data["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}}
  25. user = Repo.get(User, user_data["id"])
  26. res_conn =
  27. conn
  28. |> assign(:user, user)
  29. |> patch("/api/v1/accounts/update_credentials", %{
  30. "pleroma_settings_store" => %{
  31. masto_fe: %{
  32. theme: "bla"
  33. }
  34. }
  35. })
  36. assert user_data = json_response_and_validate_schema(res_conn, 200)
  37. assert user_data["pleroma"]["settings_store"] ==
  38. %{
  39. "pleroma_fe" => %{"theme" => "bla"},
  40. "masto_fe" => %{"theme" => "bla"}
  41. }
  42. user = Repo.get(User, user_data["id"])
  43. clear_config([:instance, :federating], true)
  44. with_mock Pleroma.Web.Federator,
  45. publish: fn _activity -> :ok end do
  46. res_conn =
  47. conn
  48. |> assign(:user, user)
  49. |> patch("/api/v1/accounts/update_credentials", %{
  50. "pleroma_settings_store" => %{
  51. masto_fe: %{
  52. theme: "blub"
  53. }
  54. }
  55. })
  56. assert user_data = json_response_and_validate_schema(res_conn, 200)
  57. assert user_data["pleroma"]["settings_store"] ==
  58. %{
  59. "pleroma_fe" => %{"theme" => "bla"},
  60. "masto_fe" => %{"theme" => "blub"}
  61. }
  62. assert_called(Pleroma.Web.Federator.publish(:_))
  63. end
  64. end
  65. test "updates the user's bio", %{conn: conn} do
  66. user2 = insert(:user)
  67. raw_bio = "I drink #cofe with @#{user2.nickname}\n\nsuya.."
  68. conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
  69. assert user_data = json_response_and_validate_schema(conn, 200)
  70. assert user_data["note"] ==
  71. ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a class="u-url mention" data-user="#{
  72. user2.id
  73. }" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..)
  74. assert user_data["source"]["note"] == raw_bio
  75. user = Repo.get(User, user_data["id"])
  76. assert user.raw_bio == raw_bio
  77. end
  78. test "updates the user's locking status", %{conn: conn} do
  79. conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"})
  80. assert user_data = json_response_and_validate_schema(conn, 200)
  81. assert user_data["locked"] == true
  82. end
  83. test "updates the user's chat acceptance status", %{conn: conn} do
  84. conn = patch(conn, "/api/v1/accounts/update_credentials", %{accepts_chat_messages: "false"})
  85. assert user_data = json_response_and_validate_schema(conn, 200)
  86. assert user_data["pleroma"]["accepts_chat_messages"] == false
  87. end
  88. test "updates the user's allow_following_move", %{user: user, conn: conn} do
  89. assert user.allow_following_move == true
  90. conn = patch(conn, "/api/v1/accounts/update_credentials", %{allow_following_move: "false"})
  91. assert refresh_record(user).allow_following_move == false
  92. assert user_data = json_response_and_validate_schema(conn, 200)
  93. assert user_data["pleroma"]["allow_following_move"] == false
  94. end
  95. test "updates the user's default scope", %{conn: conn} do
  96. conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "unlisted"})
  97. assert user_data = json_response_and_validate_schema(conn, 200)
  98. assert user_data["source"]["privacy"] == "unlisted"
  99. end
  100. test "updates the user's privacy", %{conn: conn} do
  101. conn = patch(conn, "/api/v1/accounts/update_credentials", %{source: %{privacy: "unlisted"}})
  102. assert user_data = json_response_and_validate_schema(conn, 200)
  103. assert user_data["source"]["privacy"] == "unlisted"
  104. end
  105. test "updates the user's hide_followers status", %{conn: conn} do
  106. conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"})
  107. assert user_data = json_response_and_validate_schema(conn, 200)
  108. assert user_data["pleroma"]["hide_followers"] == true
  109. end
  110. test "updates the user's discoverable status", %{conn: conn} do
  111. assert %{"source" => %{"pleroma" => %{"discoverable" => true}}} =
  112. conn
  113. |> patch("/api/v1/accounts/update_credentials", %{discoverable: "true"})
  114. |> json_response_and_validate_schema(:ok)
  115. assert %{"source" => %{"pleroma" => %{"discoverable" => false}}} =
  116. conn
  117. |> patch("/api/v1/accounts/update_credentials", %{discoverable: "false"})
  118. |> json_response_and_validate_schema(:ok)
  119. end
  120. test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do
  121. conn =
  122. patch(conn, "/api/v1/accounts/update_credentials", %{
  123. hide_followers_count: "true",
  124. hide_follows_count: "true"
  125. })
  126. assert user_data = json_response_and_validate_schema(conn, 200)
  127. assert user_data["pleroma"]["hide_followers_count"] == true
  128. assert user_data["pleroma"]["hide_follows_count"] == true
  129. end
  130. test "updates the user's skip_thread_containment option", %{user: user, conn: conn} do
  131. response =
  132. conn
  133. |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"})
  134. |> json_response_and_validate_schema(200)
  135. assert response["pleroma"]["skip_thread_containment"] == true
  136. assert refresh_record(user).skip_thread_containment
  137. end
  138. test "updates the user's hide_follows status", %{conn: conn} do
  139. conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_follows: "true"})
  140. assert user_data = json_response_and_validate_schema(conn, 200)
  141. assert user_data["pleroma"]["hide_follows"] == true
  142. end
  143. test "updates the user's hide_favorites status", %{conn: conn} do
  144. conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_favorites: "true"})
  145. assert user_data = json_response_and_validate_schema(conn, 200)
  146. assert user_data["pleroma"]["hide_favorites"] == true
  147. end
  148. test "updates the user's show_role status", %{conn: conn} do
  149. conn = patch(conn, "/api/v1/accounts/update_credentials", %{show_role: "false"})
  150. assert user_data = json_response_and_validate_schema(conn, 200)
  151. assert user_data["source"]["pleroma"]["show_role"] == false
  152. end
  153. test "updates the user's no_rich_text status", %{conn: conn} do
  154. conn = patch(conn, "/api/v1/accounts/update_credentials", %{no_rich_text: "true"})
  155. assert user_data = json_response_and_validate_schema(conn, 200)
  156. assert user_data["source"]["pleroma"]["no_rich_text"] == true
  157. end
  158. test "updates the user's name", %{conn: conn} do
  159. conn =
  160. patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"})
  161. assert user_data = json_response_and_validate_schema(conn, 200)
  162. assert user_data["display_name"] == "markorepairs"
  163. update_activity = Repo.one(Pleroma.Activity)
  164. assert update_activity.data["type"] == "Update"
  165. assert update_activity.data["object"]["name"] == "markorepairs"
  166. end
  167. test "updates the user's avatar", %{user: user, conn: conn} do
  168. new_avatar = %Plug.Upload{
  169. content_type: "image/jpg",
  170. path: Path.absname("test/fixtures/image.jpg"),
  171. filename: "an_image.jpg"
  172. }
  173. assert user.avatar == %{}
  174. res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
  175. assert user_response = json_response_and_validate_schema(res, 200)
  176. assert user_response["avatar"] != User.avatar_url(user)
  177. user = User.get_by_id(user.id)
  178. refute user.avatar == %{}
  179. # Also resets it
  180. _res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => ""})
  181. user = User.get_by_id(user.id)
  182. assert user.avatar == nil
  183. end
  184. test "updates the user's banner", %{user: user, conn: conn} do
  185. new_header = %Plug.Upload{
  186. content_type: "image/jpg",
  187. path: Path.absname("test/fixtures/image.jpg"),
  188. filename: "an_image.jpg"
  189. }
  190. res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
  191. assert user_response = json_response_and_validate_schema(res, 200)
  192. assert user_response["header"] != User.banner_url(user)
  193. # Also resets it
  194. _res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => ""})
  195. user = User.get_by_id(user.id)
  196. assert user.banner == nil
  197. end
  198. test "updates the user's background", %{conn: conn, user: user} do
  199. new_header = %Plug.Upload{
  200. content_type: "image/jpg",
  201. path: Path.absname("test/fixtures/image.jpg"),
  202. filename: "an_image.jpg"
  203. }
  204. res =
  205. patch(conn, "/api/v1/accounts/update_credentials", %{
  206. "pleroma_background_image" => new_header
  207. })
  208. assert user_response = json_response_and_validate_schema(res, 200)
  209. assert user_response["pleroma"]["background_image"]
  210. #
  211. # Also resets it
  212. _res =
  213. patch(conn, "/api/v1/accounts/update_credentials", %{"pleroma_background_image" => ""})
  214. user = User.get_by_id(user.id)
  215. assert user.background == nil
  216. end
  217. test "requires 'write:accounts' permission" do
  218. token1 = insert(:oauth_token, scopes: ["read"])
  219. token2 = insert(:oauth_token, scopes: ["write", "follow"])
  220. for token <- [token1, token2] do
  221. conn =
  222. build_conn()
  223. |> put_req_header("content-type", "multipart/form-data")
  224. |> put_req_header("authorization", "Bearer #{token.token}")
  225. |> patch("/api/v1/accounts/update_credentials", %{})
  226. if token == token1 do
  227. assert %{"error" => "Insufficient permissions: write:accounts."} ==
  228. json_response_and_validate_schema(conn, 403)
  229. else
  230. assert json_response_and_validate_schema(conn, 200)
  231. end
  232. end
  233. end
  234. test "updates profile emojos", %{user: user, conn: conn} do
  235. note = "*sips :blank:*"
  236. name = "I am :firefox:"
  237. ret_conn =
  238. patch(conn, "/api/v1/accounts/update_credentials", %{
  239. "note" => note,
  240. "display_name" => name
  241. })
  242. assert json_response_and_validate_schema(ret_conn, 200)
  243. conn = get(conn, "/api/v1/accounts/#{user.id}")
  244. assert user_data = json_response_and_validate_schema(conn, 200)
  245. assert user_data["note"] == note
  246. assert user_data["display_name"] == name
  247. assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user_data["emojis"]
  248. end
  249. test "update fields", %{conn: conn} do
  250. fields = [
  251. %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>"},
  252. %{"name" => "link.io", "value" => "http://cofe.io"}
  253. ]
  254. account_data =
  255. conn
  256. |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
  257. |> json_response_and_validate_schema(200)
  258. assert account_data["fields"] == [
  259. %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"},
  260. %{
  261. "name" => "link.io",
  262. "value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>)
  263. }
  264. ]
  265. assert account_data["source"]["fields"] == [
  266. %{
  267. "name" => "<a href=\"http://google.com\">foo</a>",
  268. "value" => "<script>bar</script>"
  269. },
  270. %{"name" => "link.io", "value" => "http://cofe.io"}
  271. ]
  272. end
  273. test "emojis in fields labels", %{conn: conn} do
  274. fields = [
  275. %{"name" => ":firefox:", "value" => "is best 2hu"},
  276. %{"name" => "they wins", "value" => ":blank:"}
  277. ]
  278. account_data =
  279. conn
  280. |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
  281. |> json_response_and_validate_schema(200)
  282. assert account_data["fields"] == [
  283. %{"name" => ":firefox:", "value" => "is best 2hu"},
  284. %{"name" => "they wins", "value" => ":blank:"}
  285. ]
  286. assert account_data["source"]["fields"] == [
  287. %{"name" => ":firefox:", "value" => "is best 2hu"},
  288. %{"name" => "they wins", "value" => ":blank:"}
  289. ]
  290. assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = account_data["emojis"]
  291. end
  292. test "update fields via x-www-form-urlencoded", %{conn: conn} do
  293. fields =
  294. [
  295. "fields_attributes[1][name]=link",
  296. "fields_attributes[1][value]=http://cofe.io",
  297. "fields_attributes[0][name]=foo",
  298. "fields_attributes[0][value]=bar"
  299. ]
  300. |> Enum.join("&")
  301. account =
  302. conn
  303. |> put_req_header("content-type", "application/x-www-form-urlencoded")
  304. |> patch("/api/v1/accounts/update_credentials", fields)
  305. |> json_response_and_validate_schema(200)
  306. assert account["fields"] == [
  307. %{"name" => "foo", "value" => "bar"},
  308. %{
  309. "name" => "link",
  310. "value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>)
  311. }
  312. ]
  313. assert account["source"]["fields"] == [
  314. %{"name" => "foo", "value" => "bar"},
  315. %{"name" => "link", "value" => "http://cofe.io"}
  316. ]
  317. end
  318. test "update fields with empty name", %{conn: conn} do
  319. fields = [
  320. %{"name" => "foo", "value" => ""},
  321. %{"name" => "", "value" => "bar"}
  322. ]
  323. account =
  324. conn
  325. |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
  326. |> json_response_and_validate_schema(200)
  327. assert account["fields"] == [
  328. %{"name" => "foo", "value" => ""}
  329. ]
  330. end
  331. test "update fields when invalid request", %{conn: conn} do
  332. name_limit = Pleroma.Config.get([:instance, :account_field_name_length])
  333. value_limit = Pleroma.Config.get([:instance, :account_field_value_length])
  334. long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join()
  335. long_value = Enum.map(0..value_limit, fn _ -> "x" end) |> Enum.join()
  336. fields = [%{"name" => "foo", "value" => long_value}]
  337. assert %{"error" => "Invalid request"} ==
  338. conn
  339. |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
  340. |> json_response_and_validate_schema(403)
  341. fields = [%{"name" => long_name, "value" => "bar"}]
  342. assert %{"error" => "Invalid request"} ==
  343. conn
  344. |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
  345. |> json_response_and_validate_schema(403)
  346. Pleroma.Config.put([:instance, :max_account_fields], 1)
  347. fields = [
  348. %{"name" => "foo", "value" => "bar"},
  349. %{"name" => "link", "value" => "http://cofe.io"}
  350. ]
  351. assert %{"error" => "Invalid request"} ==
  352. conn
  353. |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
  354. |> json_response_and_validate_schema(403)
  355. end
  356. end
  357. describe "Mark account as bot" do
  358. setup do: oauth_access(["write:accounts"])
  359. setup :request_content_type
  360. test "changing actor_type to Service makes account a bot", %{conn: conn} do
  361. account =
  362. conn
  363. |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Service"})
  364. |> json_response_and_validate_schema(200)
  365. assert account["bot"]
  366. assert account["source"]["pleroma"]["actor_type"] == "Service"
  367. end
  368. test "changing actor_type to Person makes account a human", %{conn: conn} do
  369. account =
  370. conn
  371. |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Person"})
  372. |> json_response_and_validate_schema(200)
  373. refute account["bot"]
  374. assert account["source"]["pleroma"]["actor_type"] == "Person"
  375. end
  376. test "changing actor_type to Application causes error", %{conn: conn} do
  377. response =
  378. conn
  379. |> patch("/api/v1/accounts/update_credentials", %{actor_type: "Application"})
  380. |> json_response_and_validate_schema(403)
  381. assert %{"error" => "Invalid request"} == response
  382. end
  383. test "changing bot field to true changes actor_type to Service", %{conn: conn} do
  384. account =
  385. conn
  386. |> patch("/api/v1/accounts/update_credentials", %{bot: "true"})
  387. |> json_response_and_validate_schema(200)
  388. assert account["bot"]
  389. assert account["source"]["pleroma"]["actor_type"] == "Service"
  390. end
  391. test "changing bot field to false changes actor_type to Person", %{conn: conn} do
  392. account =
  393. conn
  394. |> patch("/api/v1/accounts/update_credentials", %{bot: "false"})
  395. |> json_response_and_validate_schema(200)
  396. refute account["bot"]
  397. assert account["source"]["pleroma"]["actor_type"] == "Person"
  398. end
  399. test "actor_type field has a higher priority than bot", %{conn: conn} do
  400. account =
  401. conn
  402. |> patch("/api/v1/accounts/update_credentials", %{
  403. actor_type: "Person",
  404. bot: "true"
  405. })
  406. |> json_response_and_validate_schema(200)
  407. refute account["bot"]
  408. assert account["source"]["pleroma"]["actor_type"] == "Person"
  409. end
  410. end
  411. end