logo

pleroma

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

remote_follow_controller_test.exs (10651B)


  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.TwitterAPI.RemoteFollowControllerTest do
  5. use Pleroma.Web.ConnCase
  6. alias Pleroma.Config
  7. alias Pleroma.MFA
  8. alias Pleroma.MFA.TOTP
  9. alias Pleroma.User
  10. alias Pleroma.Web.CommonAPI
  11. import ExUnit.CaptureLog
  12. import Pleroma.Factory
  13. import Ecto.Query
  14. setup do
  15. Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
  16. :ok
  17. end
  18. setup_all do: clear_config([:instance, :federating], true)
  19. setup do: clear_config([:instance])
  20. setup do: clear_config([:frontend_configurations, :pleroma_fe])
  21. setup do: clear_config([:user, :deny_follow_blocked])
  22. describe "GET /ostatus_subscribe - remote_follow/2" do
  23. test "adds status to pleroma instance if the `acct` is a status", %{conn: conn} do
  24. assert conn
  25. |> get(
  26. remote_follow_path(conn, :follow, %{
  27. acct: "https://mastodon.social/users/emelie/statuses/101849165031453009"
  28. })
  29. )
  30. |> redirected_to() =~ "/notice/"
  31. end
  32. test "show follow account page if the `acct` is a account link", %{conn: conn} do
  33. response =
  34. conn
  35. |> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}))
  36. |> html_response(200)
  37. assert response =~ "Log in to follow"
  38. end
  39. test "show follow page if the `acct` is a account link", %{conn: conn} do
  40. user = insert(:user)
  41. response =
  42. conn
  43. |> assign(:user, user)
  44. |> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"}))
  45. |> html_response(200)
  46. assert response =~ "Remote follow"
  47. end
  48. test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do
  49. user = insert(:user)
  50. assert capture_log(fn ->
  51. response =
  52. conn
  53. |> assign(:user, user)
  54. |> get(
  55. remote_follow_path(conn, :follow, %{
  56. acct: "https://mastodon.social/users/not_found"
  57. })
  58. )
  59. |> html_response(200)
  60. assert response =~ "Error fetching user"
  61. end) =~ "Object has been deleted"
  62. end
  63. end
  64. describe "POST /ostatus_subscribe - do_follow/2 with assigned user " do
  65. test "required `follow | write:follows` scope", %{conn: conn} do
  66. user = insert(:user)
  67. user2 = insert(:user)
  68. read_token = insert(:oauth_token, user: user, scopes: ["read"])
  69. assert capture_log(fn ->
  70. response =
  71. conn
  72. |> assign(:user, user)
  73. |> assign(:token, read_token)
  74. |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
  75. |> response(200)
  76. assert response =~ "Error following account"
  77. end) =~ "Insufficient permissions: follow | write:follows."
  78. end
  79. test "follows user", %{conn: conn} do
  80. user = insert(:user)
  81. user2 = insert(:user)
  82. conn =
  83. conn
  84. |> assign(:user, user)
  85. |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
  86. |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
  87. assert redirected_to(conn) == "/users/#{user2.id}"
  88. end
  89. test "returns error when user is deactivated", %{conn: conn} do
  90. user = insert(:user, deactivated: true)
  91. user2 = insert(:user)
  92. response =
  93. conn
  94. |> assign(:user, user)
  95. |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
  96. |> response(200)
  97. assert response =~ "Error following account"
  98. end
  99. test "returns error when user is blocked", %{conn: conn} do
  100. Pleroma.Config.put([:user, :deny_follow_blocked], true)
  101. user = insert(:user)
  102. user2 = insert(:user)
  103. {:ok, _user_block} = Pleroma.User.block(user2, user)
  104. response =
  105. conn
  106. |> assign(:user, user)
  107. |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
  108. |> response(200)
  109. assert response =~ "Error following account"
  110. end
  111. test "returns error when followee not found", %{conn: conn} do
  112. user = insert(:user)
  113. response =
  114. conn
  115. |> assign(:user, user)
  116. |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => "jimm"}})
  117. |> response(200)
  118. assert response =~ "Error following account"
  119. end
  120. test "returns success result when user already in followers", %{conn: conn} do
  121. user = insert(:user)
  122. user2 = insert(:user)
  123. {:ok, _, _, _} = CommonAPI.follow(user, user2)
  124. conn =
  125. conn
  126. |> assign(:user, refresh_record(user))
  127. |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"]))
  128. |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}})
  129. assert redirected_to(conn) == "/users/#{user2.id}"
  130. end
  131. end
  132. describe "POST /ostatus_subscribe - follow/2 with enabled Two-Factor Auth " do
  133. test "render the MFA login form", %{conn: conn} do
  134. otp_secret = TOTP.generate_secret()
  135. user =
  136. insert(:user,
  137. multi_factor_authentication_settings: %MFA.Settings{
  138. enabled: true,
  139. totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
  140. }
  141. )
  142. user2 = insert(:user)
  143. response =
  144. conn
  145. |> post(remote_follow_path(conn, :do_follow), %{
  146. "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
  147. })
  148. |> response(200)
  149. mfa_token = Pleroma.Repo.one(from(q in Pleroma.MFA.Token, where: q.user_id == ^user.id))
  150. assert response =~ "Two-factor authentication"
  151. assert response =~ "Authentication code"
  152. assert response =~ mfa_token.token
  153. refute user2.follower_address in User.following(user)
  154. end
  155. test "returns error when password is incorrect", %{conn: conn} do
  156. otp_secret = TOTP.generate_secret()
  157. user =
  158. insert(:user,
  159. multi_factor_authentication_settings: %MFA.Settings{
  160. enabled: true,
  161. totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
  162. }
  163. )
  164. user2 = insert(:user)
  165. response =
  166. conn
  167. |> post(remote_follow_path(conn, :do_follow), %{
  168. "authorization" => %{"name" => user.nickname, "password" => "test1", "id" => user2.id}
  169. })
  170. |> response(200)
  171. assert response =~ "Wrong username or password"
  172. refute user2.follower_address in User.following(user)
  173. end
  174. test "follows", %{conn: conn} do
  175. otp_secret = TOTP.generate_secret()
  176. user =
  177. insert(:user,
  178. multi_factor_authentication_settings: %MFA.Settings{
  179. enabled: true,
  180. totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
  181. }
  182. )
  183. {:ok, %{token: token}} = MFA.Token.create(user)
  184. user2 = insert(:user)
  185. otp_token = TOTP.generate_token(otp_secret)
  186. conn =
  187. conn
  188. |> post(
  189. remote_follow_path(conn, :do_follow),
  190. %{
  191. "mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id}
  192. }
  193. )
  194. assert redirected_to(conn) == "/users/#{user2.id}"
  195. assert user2.follower_address in User.following(user)
  196. end
  197. test "returns error when auth code is incorrect", %{conn: conn} do
  198. otp_secret = TOTP.generate_secret()
  199. user =
  200. insert(:user,
  201. multi_factor_authentication_settings: %MFA.Settings{
  202. enabled: true,
  203. totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
  204. }
  205. )
  206. {:ok, %{token: token}} = MFA.Token.create(user)
  207. user2 = insert(:user)
  208. otp_token = TOTP.generate_token(TOTP.generate_secret())
  209. response =
  210. conn
  211. |> post(
  212. remote_follow_path(conn, :do_follow),
  213. %{
  214. "mfa" => %{"code" => otp_token, "token" => token, "id" => user2.id}
  215. }
  216. )
  217. |> response(200)
  218. assert response =~ "Wrong authentication code"
  219. refute user2.follower_address in User.following(user)
  220. end
  221. end
  222. describe "POST /ostatus_subscribe - follow/2 without assigned user " do
  223. test "follows", %{conn: conn} do
  224. user = insert(:user)
  225. user2 = insert(:user)
  226. conn =
  227. conn
  228. |> post(remote_follow_path(conn, :do_follow), %{
  229. "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
  230. })
  231. assert redirected_to(conn) == "/users/#{user2.id}"
  232. assert user2.follower_address in User.following(user)
  233. end
  234. test "returns error when followee not found", %{conn: conn} do
  235. user = insert(:user)
  236. response =
  237. conn
  238. |> post(remote_follow_path(conn, :do_follow), %{
  239. "authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"}
  240. })
  241. |> response(200)
  242. assert response =~ "Error following account"
  243. end
  244. test "returns error when login invalid", %{conn: conn} do
  245. user = insert(:user)
  246. response =
  247. conn
  248. |> post(remote_follow_path(conn, :do_follow), %{
  249. "authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id}
  250. })
  251. |> response(200)
  252. assert response =~ "Wrong username or password"
  253. end
  254. test "returns error when password invalid", %{conn: conn} do
  255. user = insert(:user)
  256. user2 = insert(:user)
  257. response =
  258. conn
  259. |> post(remote_follow_path(conn, :do_follow), %{
  260. "authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id}
  261. })
  262. |> response(200)
  263. assert response =~ "Wrong username or password"
  264. end
  265. test "returns error when user is blocked", %{conn: conn} do
  266. Pleroma.Config.put([:user, :deny_follow_blocked], true)
  267. user = insert(:user)
  268. user2 = insert(:user)
  269. {:ok, _user_block} = Pleroma.User.block(user2, user)
  270. response =
  271. conn
  272. |> post(remote_follow_path(conn, :do_follow), %{
  273. "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id}
  274. })
  275. |> response(200)
  276. assert response =~ "Error following account"
  277. end
  278. end
  279. end