Extract auth actions from `MastodonAPIController` to `AuthController`
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 1 Oct 2019 08:54:45 +0000 (15:54 +0700)
committerEgor Kislitsyn <egor@kislitsyn.com>
Tue, 1 Oct 2019 08:54:45 +0000 (15:54 +0700)
lib/pleroma/web/mastodon_api/controllers/auth_controller.ex [new file with mode: 0644]
lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
lib/pleroma/web/router.ex
test/web/mastodon_api/controllers/auth_controller_test.exs [new file with mode: 0644]
test/web/mastodon_api/mastodon_api_controller_test.exs

diff --git a/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex b/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex
new file mode 100644 (file)
index 0000000..0dee670
--- /dev/null
@@ -0,0 +1,91 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.AuthController do
+  use Pleroma.Web, :controller
+
+  alias Pleroma.User
+  alias Pleroma.Web.OAuth.App
+  alias Pleroma.Web.OAuth.Authorization
+  alias Pleroma.Web.OAuth.Token
+  alias Pleroma.Web.TwitterAPI.TwitterAPI
+
+  action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
+
+  @local_mastodon_name "Mastodon-Local"
+
+  plug(Pleroma.Plugs.RateLimiter, :password_reset when action == :password_reset)
+
+  @doc "GET /web/login"
+  def login(%{assigns: %{user: %User{}}} = conn, _params) do
+    redirect(conn, to: local_mastodon_root_path(conn))
+  end
+
+  @doc "Local Mastodon FE login init action"
+  def login(conn, %{"code" => auth_token}) do
+    with {:ok, app} <- get_or_make_app(),
+         {:ok, auth} <- Authorization.get_by_token(app, auth_token),
+         {:ok, token} <- Token.exchange_token(app, auth) do
+      conn
+      |> put_session(:oauth_token, token.token)
+      |> redirect(to: local_mastodon_root_path(conn))
+    end
+  end
+
+  @doc "Local Mastodon FE callback action"
+  def login(conn, _) do
+    with {:ok, app} <- get_or_make_app() do
+      path =
+        o_auth_path(conn, :authorize,
+          response_type: "code",
+          client_id: app.client_id,
+          redirect_uri: ".",
+          scope: Enum.join(app.scopes, " ")
+        )
+
+      redirect(conn, to: path)
+    end
+  end
+
+  @doc "DELETE /auth/sign_out"
+  def logout(conn, _) do
+    conn
+    |> clear_session
+    |> redirect(to: "/")
+  end
+
+  @doc "POST /auth/password"
+  def password_reset(conn, params) do
+    nickname_or_email = params["email"] || params["nickname"]
+
+    with {:ok, _} <- TwitterAPI.password_reset(nickname_or_email) do
+      conn
+      |> put_status(:no_content)
+      |> json("")
+    else
+      {:error, "unknown user"} ->
+        send_resp(conn, :not_found, "")
+
+      {:error, _} ->
+        send_resp(conn, :bad_request, "")
+    end
+  end
+
+  defp local_mastodon_root_path(conn) do
+    case get_session(conn, :return_to) do
+      nil ->
+        mastodon_api_path(conn, :index, ["getting-started"])
+
+      return_to ->
+        delete_session(conn, :return_to)
+        return_to
+    end
+  end
+
+  @spec get_or_make_app() :: {:ok, App.t()} | {:error, Ecto.Changeset.t()}
+  defp get_or_make_app do
+    %{client_name: @local_mastodon_name, redirect_uris: "."}
+    |> App.get_or_make(["read", "write", "follow", "push"])
+  end
+end
index 80a7b5bef78f86b780276dd99a127552ca672002..4fa0e1bcc1f64a593f7677c4a0604a34bdc3c1ac 100644 (file)
@@ -10,7 +10,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   alias Pleroma.Bookmark
   alias Pleroma.Config
   alias Pleroma.Pagination
-  alias Pleroma.Plugs.RateLimiter
   alias Pleroma.Stats
   alias Pleroma.User
   alias Pleroma.Web
@@ -19,18 +18,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
   alias Pleroma.Web.MastodonAPI.AccountView
   alias Pleroma.Web.MastodonAPI.MastodonView
   alias Pleroma.Web.MastodonAPI.StatusView
-  alias Pleroma.Web.OAuth.App
-  alias Pleroma.Web.OAuth.Authorization
-  alias Pleroma.Web.OAuth.Token
-  alias Pleroma.Web.TwitterAPI.TwitterAPI
 
   require Logger
 
-  plug(RateLimiter, :password_reset when action == :password_reset)
-
   action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
 
-  @local_mastodon_name "Mastodon-Local"
   @mastodon_api_level "2.7.2"
 
   def masto_instance(conn, _params) do
@@ -264,61 +256,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     end
   end
 
-  def login(%{assigns: %{user: %User{}}} = conn, _params) do
-    redirect(conn, to: local_mastodon_root_path(conn))
-  end
-
-  @doc "Local Mastodon FE login init action"
-  def login(conn, %{"code" => auth_token}) do
-    with {:ok, app} <- get_or_make_app(),
-         {:ok, auth} <- Authorization.get_by_token(app, auth_token),
-         {:ok, token} <- Token.exchange_token(app, auth) do
-      conn
-      |> put_session(:oauth_token, token.token)
-      |> redirect(to: local_mastodon_root_path(conn))
-    end
-  end
-
-  @doc "Local Mastodon FE callback action"
-  def login(conn, _) do
-    with {:ok, app} <- get_or_make_app() do
-      path =
-        o_auth_path(conn, :authorize,
-          response_type: "code",
-          client_id: app.client_id,
-          redirect_uri: ".",
-          scope: Enum.join(app.scopes, " ")
-        )
-
-      redirect(conn, to: path)
-    end
-  end
-
-  defp local_mastodon_root_path(conn) do
-    case get_session(conn, :return_to) do
-      nil ->
-        mastodon_api_path(conn, :index, ["getting-started"])
-
-      return_to ->
-        delete_session(conn, :return_to)
-        return_to
-    end
-  end
-
-  @spec get_or_make_app() :: {:ok, App.t()} | {:error, Ecto.Changeset.t()}
-  defp get_or_make_app do
-    App.get_or_make(
-      %{client_name: @local_mastodon_name, redirect_uris: "."},
-      ["read", "write", "follow", "push"]
-    )
-  end
-
-  def logout(conn, _) do
-    conn
-    |> clear_session
-    |> redirect(to: "/")
-  end
-
   # Stubs for unimplemented mastodon api
   #
   def empty_array(conn, _) do
@@ -331,22 +268,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
     json(conn, %{})
   end
 
-  def password_reset(conn, params) do
-    nickname_or_email = params["email"] || params["nickname"]
-
-    with {:ok, _} <- TwitterAPI.password_reset(nickname_or_email) do
-      conn
-      |> put_status(:no_content)
-      |> json("")
-    else
-      {:error, "unknown user"} ->
-        send_resp(conn, :not_found, "")
-
-      {:error, _} ->
-        send_resp(conn, :bad_request, "")
-    end
-  end
-
   defp present?(nil), do: false
   defp present?(false), do: false
   defp present?(_), do: true
index 29f53108c05deef998b37b8dab2bb39f38e9f4a0..50197899496a34120d5301d6696d4435ea649925 100644 (file)
@@ -661,10 +661,10 @@ defmodule Pleroma.Web.Router do
   scope "/", Pleroma.Web.MastodonAPI do
     pipe_through(:mastodon_html)
 
-    get("/web/login", MastodonAPIController, :login)
-    delete("/auth/sign_out", MastodonAPIController, :logout)
+    get("/web/login", AuthController, :login)
+    delete("/auth/sign_out", AuthController, :logout)
 
-    post("/auth/password", MastodonAPIController, :password_reset)
+    post("/auth/password", AuthController, :password_reset)
 
     scope [] do
       pipe_through(:oauth_read)
diff --git a/test/web/mastodon_api/controllers/auth_controller_test.exs b/test/web/mastodon_api/controllers/auth_controller_test.exs
new file mode 100644 (file)
index 0000000..98b2a82
--- /dev/null
@@ -0,0 +1,121 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.AuthControllerTest do
+  use Pleroma.Web.ConnCase
+
+  alias Pleroma.Config
+  alias Pleroma.Repo
+  alias Pleroma.Tests.ObanHelpers
+
+  import Pleroma.Factory
+  import Swoosh.TestAssertions
+
+  describe "GET /web/login" do
+    setup %{conn: conn} do
+      session_opts = [
+        store: :cookie,
+        key: "_test",
+        signing_salt: "cooldude"
+      ]
+
+      conn =
+        conn
+        |> Plug.Session.call(Plug.Session.init(session_opts))
+        |> fetch_session()
+
+      test_path = "/web/statuses/test"
+      %{conn: conn, path: test_path}
+    end
+
+    test "redirects to the saved path after log in", %{conn: conn, path: path} do
+      app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".")
+      auth = insert(:oauth_authorization, app: app)
+
+      conn =
+        conn
+        |> put_session(:return_to, path)
+        |> get("/web/login", %{code: auth.token})
+
+      assert conn.status == 302
+      assert redirected_to(conn) == path
+    end
+
+    test "redirects to the getting-started page when referer is not present", %{conn: conn} do
+      app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".")
+      auth = insert(:oauth_authorization, app: app)
+
+      conn = get(conn, "/web/login", %{code: auth.token})
+
+      assert conn.status == 302
+      assert redirected_to(conn) == "/web/getting-started"
+    end
+  end
+
+  describe "POST /auth/password, with valid parameters" do
+    setup %{conn: conn} do
+      user = insert(:user)
+      conn = post(conn, "/auth/password?email=#{user.email}")
+      %{conn: conn, user: user}
+    end
+
+    test "it returns 204", %{conn: conn} do
+      assert json_response(conn, :no_content)
+    end
+
+    test "it creates a PasswordResetToken record for user", %{user: user} do
+      token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
+      assert token_record
+    end
+
+    test "it sends an email to user", %{user: user} do
+      ObanHelpers.perform_all()
+      token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
+
+      email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token)
+      notify_email = Config.get([:instance, :notify_email])
+      instance_name = Config.get([:instance, :name])
+
+      assert_email_sent(
+        from: {instance_name, notify_email},
+        to: {user.name, user.email},
+        html_body: email.html_body
+      )
+    end
+  end
+
+  describe "POST /auth/password, with invalid parameters" do
+    setup do
+      user = insert(:user)
+      {:ok, user: user}
+    end
+
+    test "it returns 404 when user is not found", %{conn: conn, user: user} do
+      conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
+      assert conn.status == 404
+      assert conn.resp_body == ""
+    end
+
+    test "it returns 400 when user is not local", %{conn: conn, user: user} do
+      {:ok, user} = Repo.update(Ecto.Changeset.change(user, local: false))
+      conn = post(conn, "/auth/password?email=#{user.email}")
+      assert conn.status == 400
+      assert conn.resp_body == ""
+    end
+  end
+
+  describe "DELETE /auth/sign_out" do
+    test "redirect to root page", %{conn: conn} do
+      user = insert(:user)
+
+      conn =
+        conn
+        |> assign(:user, user)
+        |> delete("/auth/sign_out")
+
+      assert conn.status == 302
+      assert redirected_to(conn) == "/"
+    end
+  end
+end
index 68fe751e7d58a20207dcc733717cbfadd39540db..2ec5ad2bed6e99b24cac5c651552edf41b9437aa 100644 (file)
@@ -9,12 +9,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
   alias Pleroma.Config
   alias Pleroma.Notification
   alias Pleroma.Repo
-  alias Pleroma.Tests.ObanHelpers
   alias Pleroma.User
   alias Pleroma.Web.CommonAPI
 
   import Pleroma.Factory
-  import Swoosh.TestAssertions
   import Tesla.Mock
 
   setup do
@@ -303,95 +301,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 
       assert return_to == path
     end
-
-    test "redirects to the saved path after log in", %{conn: conn, path: path} do
-      app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".")
-      auth = insert(:oauth_authorization, app: app)
-
-      conn =
-        conn
-        |> put_session(:return_to, path)
-        |> get("/web/login", %{code: auth.token})
-
-      assert conn.status == 302
-      assert redirected_to(conn) == path
-    end
-
-    test "redirects to the getting-started page when referer is not present", %{conn: conn} do
-      app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".")
-      auth = insert(:oauth_authorization, app: app)
-
-      conn = get(conn, "/web/login", %{code: auth.token})
-
-      assert conn.status == 302
-      assert redirected_to(conn) == "/web/getting-started"
-    end
-  end
-
-  describe "POST /auth/password, with valid parameters" do
-    setup %{conn: conn} do
-      user = insert(:user)
-      conn = post(conn, "/auth/password?email=#{user.email}")
-      %{conn: conn, user: user}
-    end
-
-    test "it returns 204", %{conn: conn} do
-      assert json_response(conn, :no_content)
-    end
-
-    test "it creates a PasswordResetToken record for user", %{user: user} do
-      token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
-      assert token_record
-    end
-
-    test "it sends an email to user", %{user: user} do
-      ObanHelpers.perform_all()
-      token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
-
-      email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token)
-      notify_email = Config.get([:instance, :notify_email])
-      instance_name = Config.get([:instance, :name])
-
-      assert_email_sent(
-        from: {instance_name, notify_email},
-        to: {user.name, user.email},
-        html_body: email.html_body
-      )
-    end
-  end
-
-  describe "POST /auth/password, with invalid parameters" do
-    setup do
-      user = insert(:user)
-      {:ok, user: user}
-    end
-
-    test "it returns 404 when user is not found", %{conn: conn, user: user} do
-      conn = post(conn, "/auth/password?email=nonexisting_#{user.email}")
-      assert conn.status == 404
-      assert conn.resp_body == ""
-    end
-
-    test "it returns 400 when user is not local", %{conn: conn, user: user} do
-      {:ok, user} = Repo.update(Changeset.change(user, local: false))
-      conn = post(conn, "/auth/password?email=#{user.email}")
-      assert conn.status == 400
-      assert conn.resp_body == ""
-    end
-  end
-
-  describe "DELETE /auth/sign_out" do
-    test "redirect to root page", %{conn: conn} do
-      user = insert(:user)
-
-      conn =
-        conn
-        |> assign(:user, user)
-        |> delete("/auth/sign_out")
-
-      assert conn.status == 302
-      assert redirected_to(conn) == "/"
-    end
   end
 
   describe "empty_array, stubs for mastodon api" do