Browse Source

Merge branch 'feature/change-email' into 'develop'

Add email change endpoint

Closes #1156

See merge request pleroma/pleroma!1580
tags/v1.1.4
Haelwenn 4 years ago
parent
commit
0d9609894f
7 changed files with 176 additions and 2 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +12
    -2
      docs/api/pleroma_api.md
  3. +9
    -0
      lib/pleroma/user.ex
  4. +1
    -0
      lib/pleroma/web/router.ex
  5. +19
    -0
      lib/pleroma/web/twitter_api/controllers/util_controller.ex
  6. +27
    -0
      test/user_test.exs
  7. +107
    -0
      test/web/twitter_api/util_controller_test.exs

+ 1
- 0
CHANGELOG.md View File

@@ -106,6 +106,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- ActivityPub: Optional signing of ActivityPub object fetches.
- Admin API: Endpoint for fetching latest user's statuses
- Pleroma API: Add `/api/v1/pleroma/accounts/confirmation_resend?email=<email>` for resending account confirmation.
- Pleroma API: Email change endpoint.
- Relays: Added a task to list relay subscriptions.
- Mix Tasks: `mix pleroma.database fix_likes_collections`
- Federation: Remove `likes` from objects.


+ 12
- 2
docs/api/pleroma_api.md View File

@@ -252,7 +252,7 @@ See [Admin-API](Admin-API.md)
* Params:
* `email`: email of that needs to be verified
* Authentication: not required
* Response: 204 No Content
* Response: 204 No Content

## `/api/v1/pleroma/mascot`
### Gets user mascot image
@@ -321,11 +321,21 @@ See [Admin-API](Admin-API.md)
}
```

## `/api/pleroma/change_email`
### Change account email
* Method `POST`
* Authentication: required
* Params:
* `password`: user's password
* `email`: new email
* Response: JSON. Returns `{"status": "success"}` if the change was successful, `{"error": "[error message]"}` otherwise
* Note: Currently, Mastodon has no API for changing email. If they add it in future it might be incompatible with Pleroma.

# Pleroma Conversations

Pleroma Conversations have the same general structure that Mastodon Conversations have. The behavior differs in the following ways when using these endpoints:

1. Pleroma Conversations never add or remove recipients, unless explicitly changed by the user.
1. Pleroma Conversations never add or remove recipients, unless explicitly changed by the user.
2. Pleroma Conversations statuses can be requested by Conversation id.
3. Pleroma Conversations can be replied to.



+ 9
- 0
lib/pleroma/user.ex View File

@@ -1624,4 +1624,13 @@ defmodule Pleroma.User do
def is_internal_user?(%User{nickname: nil}), do: true
def is_internal_user?(%User{local: true, nickname: "internal." <> _}), do: true
def is_internal_user?(_), do: false

def change_email(user, email) do
user
|> cast(%{email: email}, [:email])
|> validate_required([:email])
|> unique_constraint(:email)
|> validate_format(:email, @email_regex)
|> update_and_set_cache()
end
end

+ 1
- 0
lib/pleroma/web/router.ex View File

@@ -224,6 +224,7 @@ defmodule Pleroma.Web.Router do
scope [] do
pipe_through(:oauth_write)

post("/change_email", UtilController, :change_email)
post("/change_password", UtilController, :change_password)
post("/delete_account", UtilController, :delete_account)
put("/notification_settings", UtilController, :update_notificaton_settings)


+ 19
- 0
lib/pleroma/web/twitter_api/controllers/util_controller.ex View File

@@ -314,6 +314,25 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
end

def change_email(%{assigns: %{user: user}} = conn, params) do
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
{:ok, user} ->
with {:ok, _user} <- User.change_email(user, params["email"]) do
json(conn, %{status: "success"})
else
{:error, changeset} ->
{_, {error, _}} = Enum.at(changeset.errors, 0)
json(conn, %{error: "Email #{error}."})

_ ->
json(conn, %{error: "Unable to change email."})
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["password"]) do
{:ok, user} ->


+ 27
- 0
test/user_test.exs View File

@@ -1614,4 +1614,31 @@ defmodule Pleroma.UserTest do
assert User.user_info(other_user).following_count == 152
end
end

describe "change_email/2" do
setup do
[user: insert(:user)]
end

test "blank email returns error", %{user: user} do
assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, "")
assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, nil)
end

test "non unique email returns error", %{user: user} do
%{email: email} = insert(:user)

assert {:error, %{errors: [email: {"has already been taken", _}]}} =
User.change_email(user, email)
end

test "invalid email returns error", %{user: user} do
assert {:error, %{errors: [email: {"has invalid format", _}]}} =
User.change_email(user, "cofe")
end

test "changes email", %{user: user} do
assert {:ok, %User{email: "cofe@cofe.party"}} = User.change_email(user, "cofe@cofe.party")
end
end
end

+ 107
- 0
test/web/twitter_api/util_controller_test.exs View File

@@ -662,4 +662,111 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
assert called(Pleroma.Captcha.new())
end
end

defp with_credentials(conn, username, password) do
header_content = "Basic " <> Base.encode64("#{username}:#{password}")
put_req_header(conn, "authorization", header_content)
end

defp valid_user(_context) do
user = insert(:user)
[user: user]
end

describe "POST /api/pleroma/change_email" do
setup [:valid_user]

test "without credentials", %{conn: conn} do
conn = post(conn, "/api/pleroma/change_email")
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_email", %{
"password" => "hi",
"email" => "test@test.com"
})

assert json_response(conn, 200) == %{"error" => "Invalid password."}
end

test "with credentials, valid password and invalid email", %{
conn: conn,
user: current_user
} do
conn =
conn
|> with_credentials(current_user.nickname, "test")
|> post("/api/pleroma/change_email", %{
"password" => "test",
"email" => "foobar"
})

assert json_response(conn, 200) == %{"error" => "Email has invalid format."}
end

test "with credentials, valid password and no email", %{
conn: conn,
user: current_user
} do
conn =
conn
|> with_credentials(current_user.nickname, "test")
|> post("/api/pleroma/change_email", %{
"password" => "test"
})

assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
end

test "with credentials, valid password and blank email", %{
conn: conn,
user: current_user
} do
conn =
conn
|> with_credentials(current_user.nickname, "test")
|> post("/api/pleroma/change_email", %{
"password" => "test",
"email" => ""
})

assert json_response(conn, 200) == %{"error" => "Email can't be blank."}
end

test "with credentials, valid password and non unique email", %{
conn: conn,
user: current_user
} do
user = insert(:user)

conn =
conn
|> with_credentials(current_user.nickname, "test")
|> post("/api/pleroma/change_email", %{
"password" => "test",
"email" => user.email
})

assert json_response(conn, 200) == %{"error" => "Email has already been taken."}
end

test "with credentials, valid password and valid email", %{
conn: conn,
user: current_user
} do
conn =
conn
|> with_credentials(current_user.nickname, "test")
|> post("/api/pleroma/change_email", %{
"password" => "test",
"email" => "cofe@foobar.com"
})

assert json_response(conn, 200) == %{"status" => "success"}
end
end
end

Loading…
Cancel
Save