Browse Source

Add User.change_info/2 and User.update_info/2

object-id-column
Egor Kislitsyn 4 years ago
parent
commit
209395c7e6
12 changed files with 147 additions and 308 deletions
  1. +3
    -22
      lib/mix/tasks/pleroma/user.ex
  2. +44
    -129
      lib/pleroma/user.ex
  3. +8
    -16
      lib/pleroma/user/info.ex
  4. +22
    -37
      lib/pleroma/web/admin_api/admin_api_controller.ex
  5. +8
    -20
      lib/pleroma/web/common_api/common_api.ex
  6. +23
    -45
      lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
  7. +3
    -5
      lib/pleroma/web/twitter_api/twitter_api_controller.ex
  8. +1
    -3
      test/tasks/database_test.exs
  9. +18
    -0
      test/user_test.exs
  10. +5
    -12
      test/web/mastodon_api/mastodon_api_controller_test.exs
  11. +3
    -6
      test/web/oauth/oauth_controller_test.exs
  12. +9
    -13
      test/web/ostatus/ostatus_controller_test.exs

+ 3
- 22
lib/mix/tasks/pleroma/user.ex View File

@@ -4,7 +4,6 @@

defmodule Mix.Tasks.Pleroma.User do
use Mix.Task
import Ecto.Changeset
import Mix.Pleroma
alias Pleroma.User
alias Pleroma.UserInviteToken
@@ -443,39 +442,21 @@ defmodule Mix.Tasks.Pleroma.User do
end

defp set_moderator(user, value) do
info_cng = User.Info.admin_api_update(user.info, %{is_moderator: value})

user_cng =
Ecto.Changeset.change(user)
|> put_embed(:info, info_cng)

{:ok, user} = User.update_and_set_cache(user_cng)
{:ok, user} = User.update_info(user, &User.Info.admin_api_update(&1, %{is_moderator: value}))

shell_info("Moderator status of #{user.nickname}: #{user.info.is_moderator}")
user
end

defp set_admin(user, value) do
info_cng = User.Info.admin_api_update(user.info, %{is_admin: value})

user_cng =
Ecto.Changeset.change(user)
|> put_embed(:info, info_cng)

{:ok, user} = User.update_and_set_cache(user_cng)
{:ok, user} = User.update_info(user, &User.Info.admin_api_update(&1, %{is_admin: value}))

shell_info("Admin status of #{user.nickname}: #{user.info.is_admin}")
user
end

defp set_locked(user, value) do
info_cng = User.Info.user_upgrade(user.info, %{locked: value})

user_cng =
Ecto.Changeset.change(user)
|> put_embed(:info, info_cng)

{:ok, user} = User.update_and_set_cache(user_cng)
{:ok, user} = User.update_info(user, &User.Info.user_upgrade(&1, %{locked: value}))

shell_info("Locked status of #{user.nickname}: #{user.info.locked}")
user


+ 44
- 129
lib/pleroma/user.ex View File

@@ -197,8 +197,6 @@ defmodule Pleroma.User do
|> truncate_if_exists(:name, name_limit)
|> truncate_if_exists(:bio, bio_limit)

info_cng = User.Info.remote_user_creation(%User.Info{}, params[:info])

changes =
%User{}
|> cast(params, [:bio, :name, :ap_id, :nickname, :avatar])
@@ -208,7 +206,7 @@ defmodule Pleroma.User do
|> validate_length(:bio, max: bio_limit)
|> validate_length(:name, max: name_limit)
|> put_change(:local, false)
|> put_embed(:info, info_cng)
|> change_info(&User.Info.remote_user_creation(&1, params[:info]))

if changes.valid? do
case info_cng.changes[:source_data] do
@@ -245,7 +243,6 @@ defmodule Pleroma.User do
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)

params = Map.put(params, :last_refreshed_at, NaiveDateTime.utc_now())
info_cng = User.Info.user_upgrade(struct.info, params[:info], remote?)

struct
|> cast(params, [
@@ -260,7 +257,7 @@ defmodule Pleroma.User do
|> validate_format(:nickname, local_nickname_regex())
|> validate_length(:bio, max: bio_limit)
|> validate_length(:name, max: name_limit)
|> put_embed(:info, info_cng)
|> change_info(&User.Info.user_upgrade(&1, params[:info], remote?))
end

def password_update_changeset(struct, params) do
@@ -785,21 +782,15 @@ defmodule Pleroma.User do
end

def update_note_count(%User{} = user) do
note_count_query =
note_count =
from(
a in Object,
where: fragment("?->>'actor' = ? and ?->>'type' = 'Note'", a.data, ^user.ap_id, a.data),
select: count(a.id)
)
|> Repo.one()

note_count = Repo.one(note_count_query)

info_cng = User.Info.set_note_count(user.info, note_count)

user
|> change()
|> put_embed(:info, info_cng)
|> update_and_set_cache()
update_info(user, &User.Info.set_note_count(&1, note_count))
end

@spec maybe_fetch_follow_information(User.t()) :: User.t()
@@ -816,17 +807,7 @@ defmodule Pleroma.User do

def fetch_follow_information(user) do
with {:ok, info} <- ActivityPub.fetch_follow_information_for_user(user) do
info_cng = User.Info.follow_information_update(user.info, info)

changeset =
user
|> change()
|> put_embed(:info, info_cng)

update_and_set_cache(changeset)
else
{:error, _} = e -> e
e -> {:error, e}
update_info(user, &User.Info.follow_information_update(&1, info))
end
end

@@ -900,31 +881,11 @@ defmodule Pleroma.User do

@spec mute(User.t(), User.t(), boolean()) :: {:ok, User.t()} | {:error, String.t()}
def mute(muter, %User{ap_id: ap_id}, notifications? \\ true) do
info = muter.info

info_cng =
User.Info.add_to_mutes(info, ap_id)
|> User.Info.add_to_muted_notifications(info, ap_id, notifications?)

cng =
change(muter)
|> put_embed(:info, info_cng)

update_and_set_cache(cng)
update_info(muter, &User.Info.add_to_mutes(&1, ap_id, notifications?))
end

def unmute(muter, %{ap_id: ap_id}) do
info = muter.info

info_cng =
User.Info.remove_from_mutes(info, ap_id)
|> User.Info.remove_from_muted_notifications(info, ap_id)

cng =
change(muter)
|> put_embed(:info, info_cng)

update_and_set_cache(cng)
update_info(muter, &User.Info.remove_from_mutes(&1, ap_id))
end

def subscribe(subscriber, %{ap_id: ap_id}) do
@@ -936,26 +897,14 @@ defmodule Pleroma.User do
if blocked do
{:error, "Could not subscribe: #{subscribed.nickname} is blocking you"}
else
info_cng =
subscribed.info
|> User.Info.add_to_subscribers(subscriber.ap_id)

change(subscribed)
|> put_embed(:info, info_cng)
|> update_and_set_cache()
update_info(subscribed, &User.Info.add_to_subscribers(&1, subscriber.ap_id))
end
end
end

def unsubscribe(unsubscriber, %{ap_id: ap_id}) do
with %User{} = user <- get_cached_by_ap_id(ap_id) do
info_cng =
user.info
|> User.Info.remove_from_subscribers(unsubscriber.ap_id)

change(user)
|> put_embed(:info, info_cng)
|> update_and_set_cache()
update_info(user, &User.Info.remove_from_subscribers(&1, unsubscriber.ap_id))
end
end

@@ -990,15 +939,7 @@ defmodule Pleroma.User do

{:ok, blocker} = update_follower_count(blocker)

info_cng =
blocker.info
|> User.Info.add_to_block(ap_id)

cng =
change(blocker)
|> put_embed(:info, info_cng)

update_and_set_cache(cng)
update_info(blocker, &User.Info.add_to_block(&1, ap_id))
end

# helper to handle the block given only an actor's AP id
@@ -1007,15 +948,7 @@ defmodule Pleroma.User do
end

def unblock(blocker, %{ap_id: ap_id}) do
info_cng =
blocker.info
|> User.Info.remove_from_block(ap_id)

cng =
change(blocker)
|> put_embed(:info, info_cng)

update_and_set_cache(cng)
update_info(blocker, &User.Info.remove_from_block(&1, ap_id))
end

def mutes?(nil, _), do: false
@@ -1072,27 +1005,11 @@ defmodule Pleroma.User do
end

def block_domain(user, domain) do
info_cng =
user.info
|> User.Info.add_to_domain_block(domain)

cng =
change(user)
|> put_embed(:info, info_cng)

update_and_set_cache(cng)
update_info(user, &User.Info.add_to_domain_block(&1, domain))
end

def unblock_domain(user, domain) do
info_cng =
user.info
|> User.Info.remove_from_domain_block(domain)

cng =
change(user)
|> put_embed(:info, info_cng)

update_and_set_cache(cng)
update_info(user, &User.Info.remove_from_domain_block(&1, domain))
end

def deactivate_async(user, status \\ true) do
@@ -1100,13 +1017,7 @@ defmodule Pleroma.User do
end

def deactivate(%User{} = user, status \\ true) do
info_cng = User.Info.set_activation_status(user.info, status)

with {:ok, user} <-
user
|> change()
|> put_embed(:info, info_cng)
|> update_and_set_cache() do
with {:ok, user} <- update_info(user, &User.Info.set_activation_status(&1, status)) do
Enum.each(get_followers(user), &invalidate_cache/1)
Enum.each(get_friends(user), &update_follower_count/1)

@@ -1115,11 +1026,7 @@ defmodule Pleroma.User do
end

def update_notification_settings(%User{} = user, settings \\ %{}) do
info_changeset = User.Info.update_notification_settings(user.info, settings)

change(user)
|> put_embed(:info, info_changeset)
|> update_and_set_cache()
update_info(user, &User.Info.update_notification_settings(&1, settings))
end

def delete(%User{} = user) do
@@ -1560,11 +1467,7 @@ defmodule Pleroma.User do
@spec switch_email_notifications(t(), String.t(), boolean()) ::
{:ok, t()} | {:error, Ecto.Changeset.t()}
def switch_email_notifications(user, type, status) do
info = Pleroma.User.Info.update_email_notifications(user.info, %{type => status})

change(user)
|> put_embed(:info, info)
|> update_and_set_cache()
update_info(user, &User.Info.update_email_notifications(&1, %{type => status}))
end

@doc """
@@ -1586,13 +1489,8 @@ defmodule Pleroma.User do
def toggle_confirmation(%User{} = user) do
need_confirmation? = !user.info.confirmation_pending

info_changeset =
User.Info.confirmation_changeset(user.info, need_confirmation: need_confirmation?)

user
|> change()
|> put_embed(:info, info_changeset)
|> update_and_set_cache()
|> update_info(&User.Info.confirmation_changeset(&1, need_confirmation: need_confirmation?))
end

def get_mascot(%{info: %{mascot: %{} = mascot}}) when not is_nil(mascot) do
@@ -1615,16 +1513,11 @@ defmodule Pleroma.User do
}
end

def ensure_keys_present(%User{info: info} = user) do
if info.keys do
{:ok, user}
else
{:ok, pem} = Keys.generate_rsa_pem()
def ensure_keys_present(%{info: %{keys: keys}} = user) when not is_nil(keys), do: {:ok, user}

user
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:info, User.Info.set_keys(info, pem))
|> update_and_set_cache()
def ensure_keys_present(%User{} = user) do
with {:ok, pem} <- Keys.generate_rsa_pem() do
update_info(user, &User.Info.set_keys(&1, pem))
end
end

@@ -1670,4 +1563,26 @@ defmodule Pleroma.User do
|> validate_format(:email, @email_regex)
|> update_and_set_cache()
end

@doc """
Changes `user.info` and returns the user changeset.

`fun` is called with the `user.info`.
"""
def change_info(user, fun) do
changeset = change(user)
info = get_field(changeset, :info) || %User.Info{}
put_embed(changeset, :info, fun.(info))
end

@doc """
Updates `user.info` and sets cache.

`fun` is called with the `user.info`.
"""
def update_info(user, fun) do
user
|> change_info(fun)
|> update_and_set_cache()
end
end

+ 8
- 16
lib/pleroma/user/info.ex View File

@@ -187,16 +187,11 @@ defmodule Pleroma.User.Info do
|> validate_required([:subscribers])
end

@spec add_to_mutes(Info.t(), String.t()) :: Changeset.t()
def add_to_mutes(info, muted) do
set_mutes(info, Enum.uniq([muted | info.mutes]))
end

@spec add_to_muted_notifications(Changeset.t(), Info.t(), String.t(), boolean()) ::
Changeset.t()
def add_to_muted_notifications(changeset, info, muted, notifications?) do
set_notification_mutes(
changeset,
@spec add_to_mutes(Info.t(), String.t(), boolean()) :: Changeset.t()
def add_to_mutes(info, muted, notifications?) do
info
|> set_mutes(Enum.uniq([muted | info.mutes]))
|> set_notification_mutes(
Enum.uniq([muted | info.muted_notifications]),
notifications?
)
@@ -204,12 +199,9 @@ defmodule Pleroma.User.Info do

@spec remove_from_mutes(Info.t(), String.t()) :: Changeset.t()
def remove_from_mutes(info, muted) do
set_mutes(info, List.delete(info.mutes, muted))
end

@spec remove_from_muted_notifications(Changeset.t(), Info.t(), String.t()) :: Changeset.t()
def remove_from_muted_notifications(changeset, info, muted) do
set_notification_mutes(changeset, List.delete(info.muted_notifications, muted), true)
info
|> set_mutes(List.delete(info.mutes, muted))
|> set_notification_mutes(List.delete(info.muted_notifications, muted), true)
end

def add_to_block(info, blocked) do


+ 22
- 37
lib/pleroma/web/admin_api/admin_api_controller.ex View File

@@ -254,18 +254,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
"nickname" => nickname
})
when permission_group in ["moderator", "admin"] do
user = User.get_cached_by_nickname(nickname)

info =
%{}
|> Map.put("is_" <> permission_group, true)

info_cng = User.Info.admin_api_update(user.info, info)
info = Map.put(%{}, "is_" <> permission_group, true)

cng =
user
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:info, info_cng)
{:ok, user} =
nickname
|> User.get_cached_by_nickname()
|> User.update_info(&User.Info.admin_api_update(&1, info))

ModerationLog.insert_log(%{
action: "grant",
@@ -274,8 +268,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
permission: permission_group
})

{:ok, _user} = User.update_and_set_cache(cng)

json(conn, info)
end

@@ -293,40 +285,33 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
})
end

def right_delete(%{assigns: %{user: %{nickname: nickname}}} = conn, %{"nickname" => nickname}) do
render_error(conn, :forbidden, "You can't revoke your own admin status.")
end

def right_delete(
%{assigns: %{user: %User{:nickname => admin_nickname} = admin}} = conn,
%{assigns: %{user: admin}} = conn,
%{
"permission_group" => permission_group,
"nickname" => nickname
}
)
when permission_group in ["moderator", "admin"] do
if admin_nickname == nickname do
render_error(conn, :forbidden, "You can't revoke your own admin status.")
else
user = User.get_cached_by_nickname(nickname)

info =
%{}
|> Map.put("is_" <> permission_group, false)

info_cng = User.Info.admin_api_update(user.info, info)
info = Map.put(%{}, "is_" <> permission_group, false)

cng =
Ecto.Changeset.change(user)
|> Ecto.Changeset.put_embed(:info, info_cng)
{:ok, user} =
nickname
|> User.get_cached_by_nickname()
|> User.update_info(&User.Info.admin_api_update(&1, info))

{:ok, _user} = User.update_and_set_cache(cng)

ModerationLog.insert_log(%{
action: "revoke",
actor: admin,
subject: user,
permission: permission_group
})
ModerationLog.insert_log(%{
action: "revoke",
actor: admin,
subject: user,
permission: permission_group
})

json(conn, info)
end
json(conn, info)
end

def right_delete(conn, _) do


+ 8
- 20
lib/pleroma/web/common_api/common_api.ex View File

@@ -302,12 +302,11 @@ defmodule Pleroma.Web.CommonAPI do

# Updates the emojis for a user based on their profile
def update(user) do
emoji = emoji_from_profile(user)
source_data = user.info |> Map.get(:source_data, {}) |> Map.put("tag", emoji)

user =
with emoji <- emoji_from_profile(user),
source_data <- (user.info.source_data || %{}) |> Map.put("tag", emoji),
info_cng <- User.Info.set_source_data(user.info, source_data),
change <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng),
{:ok, user} <- User.update_and_set_cache(change) do
with {:ok, user} <- User.update_info(user, &User.Info.set_source_data(&1, source_data)) do
user
else
_e ->
@@ -336,10 +335,7 @@ defmodule Pleroma.Web.CommonAPI do
}
} = activity <- get_by_id_or_ap_id(id_or_ap_id),
true <- Visibility.is_public?(activity),
%{valid?: true} = info_changeset <- User.Info.add_pinnned_activity(user.info, activity),
changeset <-
Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset),
{:ok, _user} <- User.update_and_set_cache(changeset) do
{:ok, _user} <- User.update_info(user, &User.Info.add_pinnned_activity(&1, activity)) do
{:ok, activity}
else
%{errors: [pinned_activities: {err, _}]} ->
@@ -352,11 +348,7 @@ defmodule Pleroma.Web.CommonAPI do

def unpin(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
%{valid?: true} = info_changeset <-
User.Info.remove_pinnned_activity(user.info, activity),
changeset <-
Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset),
{:ok, _user} <- User.update_and_set_cache(changeset) do
{:ok, _user} <- User.update_info(user, &User.Info.remove_pinnned_activity(&1, activity)) do
{:ok, activity}
else
%{errors: [pinned_activities: {err, _}]} ->
@@ -462,9 +454,7 @@ defmodule Pleroma.Web.CommonAPI do
ap_id = muted.ap_id

if ap_id not in user.info.muted_reblogs do
info_changeset = User.Info.add_reblog_mute(user.info, ap_id)
changeset = Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset)
User.update_and_set_cache(changeset)
User.update_info(user, &User.Info.add_reblog_mute(&1, ap_id))
end
end

@@ -472,9 +462,7 @@ defmodule Pleroma.Web.CommonAPI do
ap_id = muted.ap_id

if ap_id in user.info.muted_reblogs do
info_changeset = User.Info.remove_reblog_mute(user.info, ap_id)
changeset = Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_changeset)
User.update_and_set_cache(changeset)
User.update_info(user, &User.Info.remove_reblog_mute(&1, ap_id))
end
end
end

+ 23
- 45
lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex View File

@@ -188,14 +188,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end)
|> Map.put(:emoji, user_info_emojis)

info_cng = User.Info.profile_update(user.info, info_params)
changeset =
user
|> User.update_changeset(user_params)
|> User.change_info(&User.Info.profile_update(&1, info_params))

with changeset <- User.update_changeset(user, user_params),
changeset <- Changeset.put_embed(changeset, :info, info_cng),
{:ok, user} <- User.update_and_set_cache(changeset) do
if original_user != user do
CommonAPI.update(user)
end
with {:ok, user} <- User.update_and_set_cache(changeset) do
if original_user != user, do: CommonAPI.update(user)

json(
conn,
@@ -225,12 +224,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end

def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
with new_info <- %{"banner" => %{}},
info_cng <- User.Info.profile_update(user.info, new_info),
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng),
{:ok, user} <- User.update_and_set_cache(changeset) do
CommonAPI.update(user)
new_info = %{"banner" => %{}}

with {:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
CommonAPI.update(user)
json(conn, %{url: nil})
end
end
@@ -238,9 +235,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def update_banner(%{assigns: %{user: user}} = conn, params) do
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
new_info <- %{"banner" => object.data},
info_cng <- User.Info.profile_update(user.info, new_info),
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng),
{:ok, user} <- User.update_and_set_cache(changeset) do
{:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
CommonAPI.update(user)
%{"url" => [%{"href" => href} | _]} = object.data

@@ -249,10 +244,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end

def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
with new_info <- %{"background" => %{}},
info_cng <- User.Info.profile_update(user.info, new_info),
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng),
{:ok, _user} <- User.update_and_set_cache(changeset) do
new_info = %{"background" => %{}}

with {:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
json(conn, %{url: nil})
end
end
@@ -260,9 +254,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def update_background(%{assigns: %{user: user}} = conn, params) do
with {:ok, object} <- ActivityPub.upload(params, type: :background),
new_info <- %{"background" => object.data},
info_cng <- User.Info.profile_update(user.info, new_info),
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng),
{:ok, _user} <- User.update_and_set_cache(changeset) do
{:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
%{"url" => [%{"href" => href} | _]} = object.data

json(conn, %{url: href})
@@ -816,26 +808,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def set_mascot(%{assigns: %{user: user}} = conn, %{"file" => file}) do
with {:ok, object} <- ActivityPub.upload(file, actor: User.ap_id(user)),
%{} = attachment_data <- Map.put(object.data, "id", object.id),
%{type: type} = rendered <-
# Reject if not an image
%{type: "image"} = rendered <-
StatusView.render("attachment.json", %{attachment: attachment_data}) do
# Reject if not an image
if type == "image" do
# Sure!
# Save to the user's info
info_changeset = User.Info.mascot_update(user.info, rendered)

user_changeset =
user
|> Changeset.change()
|> Changeset.put_embed(:info, info_changeset)

{:ok, _user} = User.update_and_set_cache(user_changeset)
# Sure!
# Save to the user's info
{:ok, _user} = User.update_info(user, &User.Info.mascot_update(&1, rendered))

conn
|> json(rendered)
else
render_error(conn, :unsupported_media_type, "mascots can only be images")
end
json(conn, rendered)
else
%{type: _} -> render_error(conn, :unsupported_media_type, "mascots can only be images")
end
end

@@ -1366,11 +1348,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end

def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do
info_cng = User.Info.mastodon_settings_update(user.info, settings)

with changeset <- Changeset.change(user),
changeset <- Changeset.put_embed(changeset, :info, info_cng),
{:ok, _user} <- User.update_and_set_cache(changeset) do
with {:ok, _user} <- User.update_info(user, &User.Info.mastodon_settings_update(&1, settings)) do
json(conn, %{})
else
e ->


+ 3
- 5
lib/pleroma/web/twitter_api/twitter_api_controller.ex View File

@@ -5,7 +5,6 @@
defmodule Pleroma.Web.TwitterAPI.Controller do
use Pleroma.Web, :controller

alias Ecto.Changeset
alias Pleroma.Notification
alias Pleroma.User
alias Pleroma.Web.OAuth.Token
@@ -16,15 +15,14 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
action_fallback(:errors)

def confirm_email(conn, %{"user_id" => uid, "token" => token}) do
with %User{} = user <- User.get_cached_by_id(uid),
true <- user.local,
true <- user.info.confirmation_pending,
true <- user.info.confirmation_token == token,
info_change <- User.Info.confirmation_changeset(user.info, need_confirmation: false),
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_change),
{:ok, _} <- User.update_and_set_cache(changeset) do
conn
|> redirect(to: "/")
with %User{info: info} = user <- User.get_cached_by_id(uid),
{:ok, _} <-
User.update_info(user, &User.Info.confirmation_changeset(&1, need_confirmation: false)) do
end
end



+ 1
- 3
test/tasks/database_test.exs View File

@@ -77,12 +77,10 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
assert length(following) == 2
assert info.follower_count == 0

info_cng = Ecto.Changeset.change(info, %{follower_count: 3})

{:ok, user} =
user
|> Ecto.Changeset.change(%{following: following ++ following})
|> Ecto.Changeset.put_embed(:info, info_cng)
|> User.change_info(&Ecto.Changeset.change(&1, %{follower_count: 3}))
|> Repo.update()

assert length(user.following) == 4


+ 18
- 0
test/user_test.exs View File

@@ -1707,4 +1707,22 @@ defmodule Pleroma.UserTest do
assert password_reset_pending
end
end

test "change_info/2" do
user = insert(:user)
assert user.info.hide_follows == false

changeset = User.change_info(user, &User.Info.profile_update(&1, %{hide_follows: true}))
assert changeset.changes.info.changes.hide_follows == true
end

test "update_info/2" do
user = insert(:user)
assert user.info.hide_follows == false

assert {:ok, _} = User.update_info(user, &User.Info.profile_update(&1, %{hide_follows: true}))

assert %{info: %{hide_follows: true}} = Repo.get(User, user.id)
assert {:ok, %{info: %{hide_follows: true}}} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
end
end

+ 5
- 12
test/web/mastodon_api/mastodon_api_controller_test.exs View File

@@ -2613,14 +2613,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
{:ok, _} = CommonAPI.post(user, %{"status" => "cofe"})

# Stats should count users with missing or nil `info.deactivated` value
user = User.get_cached_by_id(user.id)
info_change = Changeset.change(user.info, %{deactivated: nil})

{:ok, _user} =
user
|> Changeset.change()
|> Changeset.put_embed(:info, info_change)
|> User.update_and_set_cache()
user.id
|> User.get_cached_by_id()
|> User.update_info(&Changeset.change(&1, %{deactivated: nil}))

Pleroma.Stats.force_update()

@@ -3953,13 +3950,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do

describe "POST /api/v1/pleroma/accounts/confirmation_resend" do
setup do
user = insert(:user)
info_change = User.Info.confirmation_changeset(user.info, need_confirmation: true)

{:ok, user} =
user
|> Changeset.change()
|> Changeset.put_embed(:info, info_change)
insert(:user)
|> User.change_info(&User.Info.confirmation_changeset(&1, need_confirmation: true))
|> Repo.update()

assert user.info.confirmation_pending


+ 3
- 6
test/web/oauth/oauth_controller_test.exs View File

@@ -7,6 +7,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
import Pleroma.Factory

alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.OAuthController
alias Pleroma.Web.OAuth.Token
@@ -775,15 +776,11 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do

test "rejects token exchange for valid credentials belonging to unconfirmed user and confirmation is required" do
Pleroma.Config.put([:instance, :account_activation_required], true)

password = "testpassword"
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
info_change = Pleroma.User.Info.confirmation_changeset(user.info, need_confirmation: true)

{:ok, user} =
user
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:info, info_change)
insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
|> User.change_info(&User.Info.confirmation_changeset(&1, need_confirmation: true))
|> Repo.update()

refute Pleroma.User.auth_active?(user)


+ 9
- 13
test/web/ostatus/ostatus_controller_test.exs View File

@@ -50,20 +50,16 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
assert response(conn, 200)
end) =~ "[error]"

# Set a wrong magic-key for a user so it has to refetch
salmon_user = User.get_cached_by_ap_id("http://gs.example.org:4040/index.php/user/1")

# Wrong key
info_cng =
User.Info.remote_user_creation(salmon_user.info, %{
magic_key:
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
})

salmon_user
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:info, info_cng)
|> User.update_and_set_cache()
info = %{
magic_key:
"RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
}

# Set a wrong magic-key for a user so it has to refetch
"http://gs.example.org:4040/index.php/user/1"
|> User.get_cached_by_ap_id()
|> User.update_info(&User.Info.remote_user_creation(&1, info))

assert capture_log(fn ->
conn =


Loading…
Cancel
Save