Added endpoint for user account deletion
authorSyldexia <syldexia@ofthewi.red>
Fri, 11 May 2018 11:32:59 +0000 (12:32 +0100)
committerSyldexia <syldexia@ofthewi.red>
Sun, 13 May 2018 13:35:48 +0000 (14:35 +0100)
lib/pleroma/web/common_api/utils.ex
lib/pleroma/web/router.ex
lib/pleroma/web/twitter_api/twitter_api_controller.ex
test/web/common_api/common_api_utils_test.exs
test/web/twitter_api/twitter_api_controller_test.exs

index 57f8be89458cc1eff74f68b9683608b121a0c44d..5c2123f2d8675ee47ffdbd20eebe0564ed200e25 100644 (file)
@@ -1,7 +1,9 @@
 defmodule Pleroma.Web.CommonAPI.Utils do
   alias Pleroma.{Repo, Object, Formatter, Activity}
   alias Pleroma.Web.ActivityPub.Utils
+  alias Pleroma.User
   alias Calendar.Strftime
+  alias Comeonin.Pbkdf2
 
   # This is a hack for twidere.
   def get_by_id_or_ap_id(id) do
@@ -184,4 +186,19 @@ defmodule Pleroma.Web.CommonAPI.Utils do
       String.slice(name, 0..30) <> "…"
     end
   end
+
+  def confirm_current_password(user, params) do
+    case user do
+      nil ->
+        {:error, "Invalid credentials."}
+
+      _ ->
+        with %User{local: true} = db_user <- Repo.get(User, user.id),
+             true <- Pbkdf2.checkpw(params["password"], db_user.password_hash) do
+          {:ok, db_user}
+        else
+          _ -> {:error, "Invalid password."}
+        end
+    end
+  end
 end
index c202cb8102bac99a18df9f77a41796f3c928e014..829d9fc7b91683b1c2354fdefdfb5efb01dd90df 100644 (file)
@@ -211,6 +211,8 @@ defmodule Pleroma.Web.Router do
     post("/account/update_profile_banner", TwitterAPI.Controller, :update_banner)
     post("/qvitter/update_background_image", TwitterAPI.Controller, :update_background)
 
+    post("/account/delete_account", TwitterAPI.Controller, :delete_account)
+
     post(
       "/account/most_recent_notification",
       TwitterAPI.Controller,
index a99487738d3ef0785afbd94753f133e45aab0ec0..a51cfa036e95a1355876da9927b0da8870791097 100644 (file)
@@ -364,6 +364,19 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
     end
   end
 
+  def delete_account(%{assigns: %{user: user}} = conn, params) do
+    case CommonAPI.Utils.confirm_current_password(user, params) do
+      {:ok, user} ->
+        case User.delete(user) do
+          :ok -> json(conn, %{status: "success"})
+          :error -> error_json(conn, "Unable to delete user.")
+        end
+
+      {:error, msg} ->
+        forbidden_json_reply(conn, msg)
+    end
+  end
+
   def search(%{assigns: %{user: user}} = conn, %{"q" => _query} = params) do
     activities = TwitterAPI.search(user, params)
 
index 689bdd61eb34fd33d80876f7843fd2e55f45a0fb..d59864c4352152246a280016ee38865e28c8794a 100644 (file)
@@ -1,5 +1,6 @@
 defmodule Pleroma.Web.CommonAPI.UtilsTest do
   alias Pleroma.Web.CommonAPI.Utils
+  alias Pleroma.Builders.{UserBuilder}
   use Pleroma.DataCase
 
   test "it adds attachment links to a given text and attachment set" do
@@ -15,4 +16,23 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
     assert res ==
              "<br><a href=\"#{name}\" class='attachment'>Sakura Mana – Turned on by a Se…</a>"
   end
+
+  describe "it confirms the password given is the current users password" do
+    test "with no credentials" do
+      assert Utils.confirm_current_password(nil, %{"password" => "test"}) ==
+               {:error, "Invalid credentials."}
+    end
+
+    test "with incorrect password given" do
+      {:ok, user} = UserBuilder.insert()
+
+      assert Utils.confirm_current_password(user, %{"password" => ""}) ==
+               {:error, "Invalid password."}
+    end
+
+    test "with correct password given" do
+      {:ok, user} = UserBuilder.insert()
+      assert Utils.confirm_current_password(user, %{"password" => "test"}) == {:ok, user}
+    end
+  end
 end
index 896fe246d0d42c9790be2694bf83bfcc6afc9587..a9350d1897a58abfe132f6858a55c4e132c334e7 100644 (file)
@@ -800,4 +800,40 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
     user = Repo.get!(User, user.id)
     assert user.bio == "Hello,<br>World! I<br> am a test."
   end
+
+  describe "POST /api/account/delete_account" do
+    setup [:valid_user]
+
+    test "without credentials", %{conn: conn} do
+      conn = post(conn, "/api/account/delete_account")
+      assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+    end
+
+    test "with credentials and invalid password", %{conn: conn, user: current_user} do
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> post("/api/account/delete_account", %{
+          "password" => ""
+        })
+
+      assert json_response(conn, 403) == %{
+               "error" => "Invalid password.",
+               "request" => "/api/account/delete_account"
+             }
+    end
+
+    test "with credentials and valid password", %{conn: conn, user: current_user} do
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> post("/api/account/delete_account", %{
+          "password" => "test"
+        })
+
+      assert json_response(conn, 200) == %{"status" => "success"}
+      fetched_user = Repo.get(User, current_user.id)
+      assert fetched_user.info == %{"deactivated" => true}
+    end
+  end
 end