Added endpoint for changing passwords
authorSyldexia <syldexia@ofthewi.red>
Mon, 21 May 2018 21:17:34 +0000 (22:17 +0100)
committerSyldexia <syldexia@ofthewi.red>
Mon, 21 May 2018 22:06:03 +0000 (23:06 +0100)
lib/pleroma/web/common_api/utils.ex
lib/pleroma/web/router.ex
lib/pleroma/web/twitter_api/controllers/util_controller.ex
test/web/twitter_api/twitter_api_controller_test.exs

index e774743a2736c41d1410e1ada51088b296237506..4ac45b5929a92c851f9e580c14d5981fa208e290 100644 (file)
@@ -187,9 +187,9 @@ defmodule Pleroma.Web.CommonAPI.Utils do
     end
   end
 
-  def confirm_current_password(user, params) do
+  def confirm_current_password(user, password) do
     with %User{local: true} = db_user <- Repo.get(User, user.id),
-         true <- Pbkdf2.checkpw(params["password"], db_user.password_hash) do
+         true <- Pbkdf2.checkpw(password, db_user.password_hash) do
       {:ok, db_user}
     else
       _ -> {:error, "Invalid password."}
index 2b5209b75c768f3413ae351c16c63fbd28657267..9389244b1ed1f864fc4b19ba3f38e5670912a398 100644 (file)
@@ -73,6 +73,7 @@ defmodule Pleroma.Web.Router do
   scope "/api/pleroma", Pleroma.Web.TwitterAPI do
     pipe_through(:authenticated_api)
     post("/follow_import", UtilController, :follow_import)
+    post("/change_password", UtilController, :change_password)
     post("/delete_account", UtilController, :delete_account)
   end
 
index 23e7408a0f8e7b454d0e94095701fc58cb1c9a7a..cc514656610e8e0b8744aae435be872d2e4e9013 100644 (file)
@@ -197,8 +197,31 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
     json(conn, "job started")
   end
 
+  def change_password(%{assigns: %{user: user}} = conn, params) do
+    case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
+      {:ok, user} ->
+        with {:ok, _user} <-
+               User.reset_password(user, %{
+                 password: params["new_password"],
+                 password_confirmation: params["new_password_confirmation"]
+               }) do
+          json(conn, %{status: "success"})
+        else
+          {:error, changeset} ->
+            {_, {error, _}} = Enum.at(changeset.errors, 0)
+            json(conn, %{error: "New password #{error}."})
+
+          _ ->
+            json(conn, %{error: "Unable to change password."})
+        end
+
+      {:error, msg} ->
+        json(conn, %{error: msg})
+    end
+  end
+
   def delete_account(%{assigns: %{user: user}} = conn, params) do
-    case CommonAPI.Utils.confirm_current_password(user, params) do
+    case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
       {:ok, user} ->
         Task.start(fn -> User.delete(user) end)
         json(conn, %{status: "success"})
index 02aba0bc8859ba105ce73d919275667f6b69955a..73443e053a6c7e87c0bf4ca1c234305e30947501 100644 (file)
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
   alias Pleroma.Web.TwitterAPI.NotificationView
   alias Pleroma.Web.CommonAPI
   alias Pleroma.Web.TwitterAPI.TwitterAPI
+  alias Comeonin.Pbkdf2
 
   import Pleroma.Factory
 
@@ -801,6 +802,82 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
     assert user.bio == "Hello,<br>World! I<br> am a test."
   end
 
+  describe "POST /api/pleroma/change_password" do
+    setup [:valid_user]
+
+    test "without credentials", %{conn: conn} do
+      conn = post(conn, "/api/pleroma/change_password")
+      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/pleroma/change_password", %{
+          "password" => "hi",
+          "new_password" => "newpass",
+          "new_password_confirmation" => "newpass"
+        })
+
+      assert json_response(conn, 200) == %{"error" => "Invalid password."}
+    end
+
+    test "with credentials, valid password and new password and confirmation not matching", %{
+      conn: conn,
+      user: current_user
+    } do
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> post("/api/pleroma/change_password", %{
+          "password" => "test",
+          "new_password" => "newpass",
+          "new_password_confirmation" => "notnewpass"
+        })
+
+      assert json_response(conn, 200) == %{
+               "error" => "New password does not match confirmation."
+             }
+    end
+
+    test "with credentials, valid password and invalid new password", %{
+      conn: conn,
+      user: current_user
+    } do
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> post("/api/pleroma/change_password", %{
+          "password" => "test",
+          "new_password" => "",
+          "new_password_confirmation" => ""
+        })
+
+      assert json_response(conn, 200) == %{
+               "error" => "New password can't be blank."
+             }
+    end
+
+    test "with credentials, valid password and matching new password and confirmation", %{
+      conn: conn,
+      user: current_user
+    } do
+      conn =
+        conn
+        |> with_credentials(current_user.nickname, "test")
+        |> post("/api/pleroma/change_password", %{
+          "password" => "test",
+          "new_password" => "newpass",
+          "new_password_confirmation" => "newpass"
+        })
+
+      assert json_response(conn, 200) == %{"status" => "success"}
+      fetched_user = Repo.get(User, current_user.id)
+      assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
+    end
+  end
+
   describe "POST /api/pleroma/delete_account" do
     setup [:valid_user]