From eb84de01439c4ee25f59390e5be4ffa7f36e01b8 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 4 Mar 2019 19:55:11 +0700 Subject: allow users to disable their own account --- lib/mix/tasks/pleroma/user.ex | 20 ++++++- lib/pleroma/activity.ex | 16 +++++- lib/pleroma/gopher/server.ex | 3 +- lib/pleroma/notification.ex | 32 +++++------ lib/pleroma/user.ex | 64 +++++++++++++++++----- lib/pleroma/user/info.ex | 9 +++ lib/pleroma/web/activity_pub/activity_pub.ex | 1 + lib/pleroma/web/admin_api/admin_api_controller.ex | 10 ++++ lib/pleroma/web/common_api/utils.ex | 4 +- .../web/mastodon_api/mastodon_api_controller.ex | 12 ++-- lib/pleroma/web/router.ex | 2 + .../web/twitter_api/controllers/util_controller.ex | 11 ++++ lib/pleroma/web/twitter_api/twitter_api.ex | 20 ++++--- .../web/twitter_api/twitter_api_controller.ex | 4 +- 14 files changed, 158 insertions(+), 50 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index 037e44716..297332bc4 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -23,7 +23,7 @@ defmodule Mix.Tasks.Pleroma.User do - `--password PASSWORD` - the user's password - `--moderator`/`--no-moderator` - whether the user is a moderator - `--admin`/`--no-admin` - whether the user is an admin - - `-y`, `--assume-yes`/`--no-assume-yes` - whether to assume yes to all questions + - `-y`, `--assume-yes`/`--no-assume-yes` - whether to assume yes to all questions ## Generate an invite link. @@ -37,6 +37,10 @@ defmodule Mix.Tasks.Pleroma.User do mix pleroma.user toggle_activated NICKNAME + ## Disable or enable the user's account. + + mix pleroma.user toggle_disabled NICKNAME + ## Unsubscribe local users from user's account and deactivate it mix pleroma.user unsubscribe NICKNAME @@ -170,6 +174,20 @@ defmodule Mix.Tasks.Pleroma.User do end end + def run(["toggle_disabled", nickname]) do + Common.start_pleroma() + + case User.get_by_nickname(nickname) do + %User{} = user -> + {:ok, user} = User.disable(user, !user.info.disabled) + status = if(user.info.disabled, do: "ON", else: "OFF") + Mix.shell().info("Disabled status of #{nickname}: #{status}") + + _ -> + Mix.shell().error("No user #{nickname}") + end + end + def run(["reset_password", nickname]) do Common.start_pleroma() diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 66854dc2d..c466bff7f 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -42,7 +42,10 @@ defmodule Pleroma.Activity do end def get_by_id(id) do - Repo.get(Activity, id) + Activity + |> where([a], a.id == ^id) + |> restrict_disabled_users() + |> Repo.one() end def by_object_ap_id(ap_id) do @@ -92,6 +95,7 @@ defmodule Pleroma.Activity do def get_create_by_object_ap_id(ap_id) when is_binary(ap_id) do create_by_object_ap_id(ap_id) + |> restrict_disabled_users() |> Repo.one() end @@ -123,4 +127,14 @@ defmodule Pleroma.Activity do |> where([s], s.actor == ^actor) |> Repo.all() end + + def restrict_disabled_users(query) do + from(activity in query, + where: + fragment( + "? not in (SELECT ap_id FROM users WHERE info->'disabled' @> 'true')", + activity.actor + ) + ) + end end diff --git a/lib/pleroma/gopher/server.ex b/lib/pleroma/gopher/server.ex index ba9614029..24190574e 100644 --- a/lib/pleroma/gopher/server.ex +++ b/lib/pleroma/gopher/server.ex @@ -41,7 +41,6 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do alias Pleroma.Activity alias Pleroma.HTML alias Pleroma.User - alias Pleroma.Repo def start_link(ref, socket, transport, opts) do pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts]) @@ -110,7 +109,7 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do end def response("/notices/" <> id) do - with %Activity{} = activity <- Repo.get(Activity, id), + with %Activity{} = activity <- Activity.get_by_id(id), true <- Visibility.is_public?(activity) do activities = ActivityPub.fetch_activities_for_context(activity.data["context"]) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index c88512567..0f9f74b1e 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -36,22 +36,22 @@ defmodule Pleroma.Notification do defp restrict_since(query, _), do: query def for_user(user, opts \\ %{}) do - query = - from( - n in Notification, - where: n.user_id == ^user.id, - order_by: [desc: n.id], - join: activity in assoc(n, :activity), - preload: [activity: activity], - limit: 20 - ) - - query = - query - |> restrict_since(opts) - |> restrict_max(opts) - - Repo.all(query) + from( + n in Notification, + where: n.user_id == ^user.id, + order_by: [desc: n.id], + join: activity in assoc(n, :activity), + preload: [activity: activity], + limit: 20, + where: + fragment( + "? not in (SELECT ap_id FROM users WHERE info->'disabled' @> 'true')", + activity.actor + ) + ) + |> restrict_since(opts) + |> restrict_max(opts) + |> Repo.all() end def set_read_up_to(%{id: user_id} = _user, id) do diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 50e7e7ccd..f02051174 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -108,10 +108,8 @@ defmodule Pleroma.User do end def user_info(%User{} = user) do - oneself = if user.local, do: 1, else: 0 - %{ - following_count: length(user.following) - oneself, + following_count: following_count(user), note_count: user.info.note_count, follower_count: user.info.follower_count, locked: user.info.locked, @@ -120,6 +118,23 @@ defmodule Pleroma.User do } end + defp restrict_disabled(query) do + from(u in query, + where: not fragment("? \\? 'disabled' AND ?->'disabled' @> 'true'", u.info, u.info) + ) + end + + def following_count(%User{following: []}), do: 0 + + def following_count(%User{following: following, id: id}) do + from(u in User, + where: u.follower_address in ^following, + where: u.id != ^id + ) + |> restrict_disabled() + |> Repo.aggregate(:count, :id) + end + def remote_user_creation(params) do params = params @@ -545,6 +560,7 @@ defmodule Pleroma.User do where: fragment("? <@ ?", ^[follower_address], u.following), where: u.id != ^id ) + |> restrict_disabled() end def get_followers_query(user, page) do @@ -572,6 +588,7 @@ defmodule Pleroma.User do where: u.follower_address in ^following, where: u.id != ^id ) + |> restrict_disabled() end def get_friends_query(user, page) do @@ -681,11 +698,10 @@ defmodule Pleroma.User do info_cng = User.Info.set_note_count(user.info, note_count) - cng = - change(user) - |> put_embed(:info, info_cng) - - update_and_set_cache(cng) + user + |> change() + |> put_embed(:info, info_cng) + |> update_and_set_cache() end def update_follower_count(%User{} = user) do @@ -694,6 +710,7 @@ defmodule Pleroma.User do |> where([u], ^user.follower_address in u.following) |> where([u], u.id != ^user.id) |> select([u], %{count: count(u.id)}) + |> restrict_disabled() User |> where(id: ^user.id) @@ -860,6 +877,7 @@ defmodule Pleroma.User do ^processed_query ) ) + |> restrict_disabled() end defp trigram_search_subquery(term) do @@ -876,6 +894,7 @@ defmodule Pleroma.User do }, where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^term) ) + |> restrict_disabled() end defp boost_search_results(results, nil), do: results @@ -1062,11 +1081,10 @@ defmodule Pleroma.User do def deactivate(%User{} = user, status \\ true) do info_cng = User.Info.set_activation_status(user.info, status) - cng = - change(user) - |> put_embed(:info, info_cng) - - update_and_set_cache(cng) + user + |> change() + |> put_embed(:info, info_cng) + |> update_and_set_cache() end def delete(%User{} = user) do @@ -1100,6 +1118,26 @@ defmodule Pleroma.User do {:ok, user} end + def disable_async(user, status \\ true) do + Pleroma.Jobs.enqueue(:user, __MODULE__, [:disable_async, user, status]) + end + + def disable(%User{} = user, status \\ true) do + with {:ok, user} <- User.deactivate(user, status), + info_cng <- User.Info.set_disabled_status(user.info, status), + {:ok, user} <- + user + |> change() + |> put_embed(:info, info_cng) + |> update_and_set_cache(), + {:ok, friends} <- User.get_friends(user) do + Enum.each(friends, &update_follower_count(&1)) + {:ok, user} + end + end + + def perform(:disable_async, user, status), do: disable(user, status) + def html_filter_policy(%User{info: %{no_rich_text: true}}) do Pleroma.HTML.Scrubber.TwitterText end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 818b64645..1ec356ba9 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -36,6 +36,7 @@ defmodule Pleroma.User.Info do field(:hide_follows, :boolean, default: false) field(:pinned_activities, {:array, :string}, default: []) field(:flavour, :string, default: nil) + field(:disabled, :boolean, default: false) # Found in the wild # ap_id -> Where is this used? @@ -54,6 +55,14 @@ defmodule Pleroma.User.Info do |> validate_required([:deactivated]) end + def set_disabled_status(info, disabled) do + params = %{disabled: disabled} + + info + |> cast(params, [:disabled]) + |> validate_required([:disabled]) + end + def add_to_note_count(info, number) do set_note_count(info, info.note_count + number) end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 783491b67..aa20990f3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -703,6 +703,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_replies(opts) |> restrict_reblogs(opts) |> restrict_pinned(opts) + |> Activity.restrict_disabled_users() end def fetch_activities(recipients, opts \\ %{}) do diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index aae02cab8..1b94f0609 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -44,6 +44,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do |> json(user.nickname) end + def user_toggle_disabled(conn, %{"nickname" => nickname}) do + user = User.get_by_nickname(nickname) + + {:ok, updated_user} = User.disable(user, !user.info.disabled) + + conn + |> put_view(AccountView) + |> render("show.json", %{user: updated_user}) + end + def user_toggle_activation(conn, %{"nickname" => nickname}) do user = User.get_by_nickname(nickname) diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index e4b9102c5..60d1185d3 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -17,7 +17,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do # This is a hack for twidere. def get_by_id_or_ap_id(id) do - activity = Repo.get(Activity, id) || Activity.get_create_by_object_ap_id(id) + activity = Activity.get_by_id(id) || Activity.get_create_by_object_ap_id(id) activity && if activity.data["type"] == "Create" do @@ -30,7 +30,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do def get_replied_to_activity(""), do: nil def get_replied_to_activity(id) when not is_nil(id) do - Repo.get(Activity, id) + Activity.get_by_id(id) end def get_replied_to_activity(_), do: nil diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 056be49b0..00a0f1351 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -307,7 +307,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with %Activity{} = activity <- Repo.get(Activity, id), + with %Activity{} = activity <- Activity.get_by_id(id), true <- Visibility.visible_for_user?(activity, user) do conn |> put_view(StatusView) @@ -316,7 +316,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def get_context(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with %Activity{} = activity <- Repo.get(Activity, id), + with %Activity{} = activity <- Activity.get_by_id(id), activities <- ActivityPub.fetch_activities_for_context(activity.data["context"], %{ "blocking_user" => user, @@ -448,7 +448,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with %Activity{} = activity <- Repo.get(Activity, id), + with %Activity{} = activity <- Activity.get_by_id(id), %User{} = user <- User.get_by_nickname(user.nickname), true <- Visibility.visible_for_user?(activity, user), {:ok, user} <- User.bookmark(user, activity.data["object"]["id"]) do @@ -459,7 +459,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with %Activity{} = activity <- Repo.get(Activity, id), + with %Activity{} = activity <- Activity.get_by_id(id), %User{} = user <- User.get_by_nickname(user.nickname), true <- Visibility.visible_for_user?(activity, user), {:ok, user} <- User.unbookmark(user, activity.data["object"]["id"]) do @@ -583,7 +583,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def favourited_by(conn, %{"id" => id}) do - with %Activity{data: %{"object" => %{"likes" => likes}}} <- Repo.get(Activity, id) do + with %Activity{data: %{"object" => %{"likes" => likes}}} <- Activity.get_by_id(id) do q = from(u in User, where: u.ap_id in ^likes) users = Repo.all(q) @@ -596,7 +596,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do end def reblogged_by(conn, %{"id" => id}) do - with %Activity{data: %{"object" => %{"announcements" => announces}}} <- Repo.get(Activity, id) do + with %Activity{data: %{"object" => %{"announcements" => announces}}} <- Activity.get_by_id(id) do q = from(u in User, where: u.ap_id in ^announces) users = Repo.all(q) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 6fcb46878..5033b5446 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -143,6 +143,7 @@ defmodule Pleroma.Web.Router do get("/users/search", AdminAPIController, :search_users) delete("/user", AdminAPIController, :user_delete) patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation) + patch("/users/:nickname/toggle_disabled", AdminAPIController, :user_toggle_disabled) post("/user", AdminAPIController, :user_create) put("/users/tag", AdminAPIController, :tag_users) delete("/users/tag", AdminAPIController, :untag_users) @@ -183,6 +184,7 @@ defmodule Pleroma.Web.Router do post("/change_password", UtilController, :change_password) post("/delete_account", UtilController, :delete_account) + post("/disable_account", UtilController, :disable_account) end scope [] do diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index e2fdedb25..0006d53e8 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -311,6 +311,17 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end end + def disable_account(%{assigns: %{user: user}} = conn, params) do + case CommonAPI.Utils.confirm_current_password(user, params["password"]) do + {:ok, user} -> + User.disable_async(user) + json(conn, %{status: "success"}) + + {:error, msg} -> + json(conn, %{error: msg}) + end + end + def captcha(conn, _params) do json(conn, Pleroma.Captcha.new()) end diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index ab6470d78..615a34be9 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -21,7 +21,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end def delete(%User{} = user, id) do - with %Activity{data: %{"type" => _type}} <- Repo.get(Activity, id), + with %Activity{data: %{"type" => _type}} <- Activity.get_by_id(id), {:ok, activity} <- CommonAPI.delete(id, user) do {:ok, activity} end @@ -232,21 +232,27 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do def get_user(user \\ nil, params) do case params do %{"user_id" => user_id} -> - case target = User.get_cached_by_nickname_or_id(user_id) do + case User.get_cached_by_nickname_or_id(user_id) do nil -> {:error, "No user with such user_id"} - _ -> - {:ok, target} + %User{info: %{disabled: true}} -> + {:error, "User has been disabled"} + + user -> + {:ok, user} end %{"screen_name" => nickname} -> - case target = Repo.get_by(User, nickname: nickname) do + case User.get_by_nickname(nickname) do nil -> {:error, "No user with such screen_name"} - _ -> - {:ok, target} + %User{info: %{disabled: true}} -> + {:error, "User has been disabled"} + + user -> + {:ok, user} end _ -> diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index de7b9f24c..0769f8698 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -269,7 +269,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do - with %Activity{} = activity <- Repo.get(Activity, id), + with %Activity{} = activity <- Activity.get_by_id(id), true <- Visibility.visible_for_user?(activity, user) do conn |> put_view(ActivityView) @@ -341,7 +341,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do end def get_by_id_or_ap_id(id) do - activity = Repo.get(Activity, id) || Activity.get_create_by_object_ap_id(id) + activity = Activity.get_by_id(id) || Activity.get_create_by_object_ap_id(id) if activity.data["type"] == "Create" do activity -- cgit v1.2.3 From db4badc6aa71df4cb9372ef4aff699399516ffb2 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Thu, 11 Apr 2019 17:22:42 +0700 Subject: move user disable into deactivation --- lib/mix/tasks/pleroma/user.ex | 18 -------- lib/pleroma/activity.ex | 8 ++-- lib/pleroma/notification.ex | 2 +- lib/pleroma/user.ex | 51 +++++++++------------- lib/pleroma/user/info.ex | 9 ---- lib/pleroma/web/activity_pub/activity_pub.ex | 2 +- lib/pleroma/web/admin_api/admin_api_controller.ex | 10 ----- lib/pleroma/web/router.ex | 1 - .../web/twitter_api/controllers/util_controller.ex | 2 +- lib/pleroma/web/twitter_api/twitter_api.ex | 2 +- 10 files changed, 29 insertions(+), 76 deletions(-) (limited to 'lib') diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index 78493231c..441168df2 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -53,10 +53,6 @@ defmodule Mix.Tasks.Pleroma.User do mix pleroma.user toggle_activated NICKNAME - ## Disable or enable the user's account. - - mix pleroma.user toggle_disabled NICKNAME - ## Unsubscribe local users from user's account and deactivate it mix pleroma.user unsubscribe NICKNAME @@ -190,20 +186,6 @@ defmodule Mix.Tasks.Pleroma.User do end end - def run(["toggle_disabled", nickname]) do - Common.start_pleroma() - - case User.get_by_nickname(nickname) do - %User{} = user -> - {:ok, user} = User.disable(user, !user.info.disabled) - status = if(user.info.disabled, do: "ON", else: "OFF") - Mix.shell().info("Disabled status of #{nickname}: #{status}") - - _ -> - Mix.shell().error("No user #{nickname}") - end - end - def run(["reset_password", nickname]) do Common.start_pleroma() diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index c8c7f0d04..d06fd917d 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -100,7 +100,7 @@ defmodule Pleroma.Activity do def get_by_id(id) do Activity |> where([a], a.id == ^id) - |> restrict_disabled_users() + |> restrict_deactivated_users() |> Repo.one() end @@ -169,7 +169,7 @@ defmodule Pleroma.Activity do def get_create_by_object_ap_id(ap_id) when is_binary(ap_id) do create_by_object_ap_id(ap_id) - |> restrict_disabled_users() + |> restrict_deactivated_users() |> Repo.one() end @@ -296,11 +296,11 @@ defmodule Pleroma.Activity do end end - def restrict_disabled_users(query) do + def restrict_deactivated_users(query) do from(activity in query, where: fragment( - "? not in (SELECT ap_id FROM users WHERE info->'disabled' @> 'true')", + "? not in (SELECT ap_id FROM users WHERE info->'deactivated' @> 'true')", activity.actor ) ) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 7de2d4c18..941218eea 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -36,7 +36,7 @@ defmodule Pleroma.Notification do |> where( [n, a], fragment( - "? not in (SELECT ap_id FROM users WHERE info->'disabled' @> 'true')", + "? not in (SELECT ap_id FROM users WHERE info->'deactivated' @> 'true')", a.actor ) ) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1f2aca235..c08d3a171 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -117,9 +117,9 @@ defmodule Pleroma.User do } end - defp restrict_disabled(query) do + defp restrict_deactivated(query) do from(u in query, - where: not fragment("? \\? 'disabled' AND ?->'disabled' @> 'true'", u.info, u.info) + where: not fragment("? \\? 'deactivated' AND ?->'deactivated' @> 'true'", u.info, u.info) ) end @@ -130,7 +130,7 @@ defmodule Pleroma.User do where: u.follower_address in ^following, where: u.id != ^id ) - |> restrict_disabled() + |> restrict_deactivated() |> Repo.aggregate(:count, :id) end @@ -584,7 +584,7 @@ defmodule Pleroma.User do where: fragment("? <@ ?", ^[follower_address], u.following), where: u.id != ^id ) - |> restrict_disabled() + |> restrict_deactivated() end def get_followers_query(user, page) do @@ -612,7 +612,7 @@ defmodule Pleroma.User do where: u.follower_address in ^following, where: u.id != ^id ) - |> restrict_disabled() + |> restrict_deactivated() end def get_friends_query(user, page) do @@ -736,7 +736,7 @@ defmodule Pleroma.User do |> where([u], ^user.follower_address in u.following) |> where([u], u.id != ^user.id) |> select([u], %{count: count(u.id)}) - |> restrict_disabled() + |> restrict_deactivated() User |> where(id: ^user.id) @@ -887,7 +887,7 @@ defmodule Pleroma.User do ^processed_query ) ) - |> restrict_disabled() + |> restrict_deactivated() end defp trigram_search_subquery(term) do @@ -906,7 +906,7 @@ defmodule Pleroma.User do }, where: fragment("trim(? || ' ' || coalesce(?, '')) % ?", u.nickname, u.name, ^term) ) - |> restrict_disabled() + |> restrict_deactivated() end def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do @@ -1150,13 +1150,24 @@ defmodule Pleroma.User do ) end + + def deactivate_async(user, status \\ true) do + PleromaJobQueue.enqueue(:user, __MODULE__, [:deactivate_async, user, status]) + end + + def perform(:deactivate_async, user, status), do: deactivate(user, status) + def deactivate(%User{} = user, status \\ true) do info_cng = User.Info.set_activation_status(user.info, status) - user + with {:ok, user} <- user |> change() |> put_embed(:info, info_cng) - |> update_and_set_cache() + |> update_and_set_cache(), + {:ok, friends} <- User.get_friends(user) do + Enum.each(friends, &update_follower_count(&1)) + {:ok, user} + end end def update_notification_settings(%User{} = user, settings \\ %{}) do @@ -1199,26 +1210,6 @@ defmodule Pleroma.User do {:ok, user} end - def disable_async(user, status \\ true) do - PleromaJobQueue.enqueue(:user, __MODULE__, [:disable_async, user, status]) - end - - def disable(%User{} = user, status \\ true) do - with {:ok, user} <- User.deactivate(user, status), - info_cng <- User.Info.set_disabled_status(user.info, status), - {:ok, user} <- - user - |> change() - |> put_embed(:info, info_cng) - |> update_and_set_cache(), - {:ok, friends} <- User.get_friends(user) do - Enum.each(friends, &update_follower_count(&1)) - {:ok, user} - end - end - - def perform(:disable_async, user, status), do: disable(user, status) - def html_filter_policy(%User{info: %{no_rich_text: true}}) do Pleroma.HTML.Scrubber.TwitterText end diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 07825a1c4..5afa7988c 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -40,7 +40,6 @@ defmodule Pleroma.User.Info do field(:hide_follows, :boolean, default: false) field(:pinned_activities, {:array, :string}, default: []) field(:flavour, :string, default: nil) - field(:disabled, :boolean, default: false) field(:notification_settings, :map, default: %{"remote" => true, "local" => true, "followers" => true, "follows" => true} @@ -76,14 +75,6 @@ defmodule Pleroma.User.Info do |> validate_required([:notification_settings]) end - def set_disabled_status(info, disabled) do - params = %{disabled: disabled} - - info - |> cast(params, [:disabled]) - |> validate_required([:disabled]) - end - def add_to_note_count(info, number) do set_note_count(info, info.note_count + number) end diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index dd51d63c8..e749a80aa 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -804,7 +804,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do |> restrict_reblogs(opts) |> restrict_pinned(opts) |> restrict_muted_reblogs(opts) - |> Activity.restrict_disabled_users() + |> Activity.restrict_deactivated_users() end def fetch_activities(recipients, opts \\ %{}) do diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index fb43d0b01..70a5b5c5d 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -75,16 +75,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do end end - def user_toggle_disabled(conn, %{"nickname" => nickname}) do - user = User.get_by_nickname(nickname) - - {:ok, updated_user} = User.disable(user, !user.info.disabled) - - conn - |> put_view(AccountView) - |> render("show.json", %{user: updated_user}) - end - def user_toggle_activation(conn, %{"nickname" => nickname}) do user = User.get_by_nickname(nickname) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index dd23d7fd5..c331098b4 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -153,7 +153,6 @@ defmodule Pleroma.Web.Router do delete("/user", AdminAPIController, :user_delete) patch("/users/:nickname/toggle_activation", AdminAPIController, :user_toggle_activation) - patch("/users/:nickname/toggle_disabled", AdminAPIController, :user_toggle_disabled) post("/user", AdminAPIController, :user_create) put("/users/tag", AdminAPIController, :tag_users) delete("/users/tag", AdminAPIController, :untag_users) diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 317f2b0ff..44f4b183b 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -358,7 +358,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do def disable_account(%{assigns: %{user: user}} = conn, params) do case CommonAPI.Utils.confirm_current_password(user, params["password"]) do {:ok, user} -> - User.disable_async(user) + User.deactivate_async(user) json(conn, %{status: "success"}) {:error, msg} -> diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index 156f5d40f..bf1051afd 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -235,7 +235,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do nil -> {:error, "No user with such user_id"} - %User{info: %{disabled: true}} -> + %User{info: %{deactivated: true}} -> {:error, "User has been disabled"} user -> -- cgit v1.2.3 From 46bd5c1d875934370621375957fa33a10e2d3507 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Thu, 11 Apr 2019 17:28:12 +0700 Subject: fix format --- lib/pleroma/user.ex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index c08d3a171..a8e902bf3 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1150,7 +1150,6 @@ defmodule Pleroma.User do ) end - def deactivate_async(user, status \\ true) do PleromaJobQueue.enqueue(:user, __MODULE__, [:deactivate_async, user, status]) end @@ -1160,11 +1159,12 @@ defmodule Pleroma.User do 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(), - {:ok, friends} <- User.get_friends(user) do + with {:ok, user} <- + user + |> change() + |> put_embed(:info, info_cng) + |> update_and_set_cache(), + {:ok, friends} <- User.get_friends(user) do Enum.each(friends, &update_follower_count(&1)) {:ok, user} end -- cgit v1.2.3 From dd097a406baf15e983454ab8f13635b4af2a8de4 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Fri, 12 Apr 2019 16:38:32 +0700 Subject: add tests --- lib/pleroma/user.ex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index a8e902bf3..95f5c6d21 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1159,13 +1159,16 @@ defmodule Pleroma.User do def deactivate(%User{} = user, status \\ true) do info_cng = User.Info.set_activation_status(user.info, status) - with {:ok, user} <- + with {:ok, friends} <- User.get_friends(user), + {:ok, followers} <- User.get_followers(user), + {:ok, user} <- user |> change() |> put_embed(:info, info_cng) - |> update_and_set_cache(), - {:ok, friends} <- User.get_friends(user) do + |> update_and_set_cache() do + Enum.each(followers, &invalidate_cache(&1)) Enum.each(friends, &update_follower_count(&1)) + {:ok, user} end end -- cgit v1.2.3 From 32d4630c9ca1c89e655b37b3b939d728f569dc9f Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 13 May 2019 01:58:30 +0000 Subject: user: move initial post fetching to job queue --- lib/pleroma/user.ex | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 474de9ba5..a79da4dd8 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -552,8 +552,7 @@ defmodule Pleroma.User do with [_nick, _domain] <- String.split(nickname, "@"), {:ok, user} <- fetch_by_nickname(nickname) do if Pleroma.Config.get([:fetch_initial_posts, :enabled]) do - # TODO turn into job - {:ok, _} = Task.start(__MODULE__, :fetch_initial_posts, [user]) + fetch_initial_posts(user) end {:ok, user} @@ -564,15 +563,8 @@ defmodule Pleroma.User do end @doc "Fetch some posts when the user has just been federated with" - def fetch_initial_posts(user) do - pages = Pleroma.Config.get!([:fetch_initial_posts, :pages]) - - Enum.each( - # Insert all the posts in reverse order, so they're in the right order on the timeline - Enum.reverse(Utils.fetch_ordered_collection(user.info.source_data["outbox"], pages)), - &Pleroma.Web.Federator.incoming_ap_doc/1 - ) - end + def fetch_initial_posts(user), + do: PleromaJobQueue.enqueue(:background, __MODULE__, [:fetch_initial_posts, user]) @spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t() def get_followers_query(%User{} = user, nil) do @@ -1077,6 +1069,19 @@ defmodule Pleroma.User do delete_user_activities(user) end + @spec perform(atom(), User.t()) :: {:ok, User.t()} + def perform(:fetch_initial_posts, %User{} = user) do + pages = Pleroma.Config.get!([:fetch_initial_posts, :pages]) + + Enum.each( + # Insert all the posts in reverse order, so they're in the right order on the timeline + Enum.reverse(Utils.fetch_ordered_collection(user.info.source_data["outbox"], pages)), + &Pleroma.Web.Federator.incoming_ap_doc/1 + ) + + {:ok, user} + end + def delete_user_activities(%User{ap_id: ap_id} = user) do stream = ap_id @@ -1130,8 +1135,8 @@ defmodule Pleroma.User do resp = fetch_by_ap_id(ap_id) if should_fetch_initial do - with {:ok, %User{} = user} = resp do - {:ok, _} = Task.start(__MODULE__, :fetch_initial_posts, [user]) + with {:ok, %User{} = user} <- resp do + fetch_initial_posts(user) end end -- cgit v1.2.3 From 57d11ac9dbe4f3befd288cb0f59f368968474f93 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 13 May 2019 02:02:00 +0000 Subject: activitypub: move post rich media fetching to job queue --- lib/pleroma/web/activity_pub/activity_pub.ex | 4 +--- lib/pleroma/web/rich_media/helpers.ex | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index 11777c220..d7c0ab4d3 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -133,9 +133,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do activity end - Task.start(fn -> - Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) - end) + PleromaJobQueue.enqueue(:background, Pleroma.Web.RichMedia.Helpers, [:fetch, activity]) Notification.create_notifications(activity) diff --git a/lib/pleroma/web/rich_media/helpers.ex b/lib/pleroma/web/rich_media/helpers.ex index f67aaf58b..0162a5be9 100644 --- a/lib/pleroma/web/rich_media/helpers.ex +++ b/lib/pleroma/web/rich_media/helpers.ex @@ -34,4 +34,6 @@ defmodule Pleroma.Web.RichMedia.Helpers do end def fetch_data_for_activity(_), do: %{} + + def perform(:fetch, %Activity{} = activity), do: fetch_data_for_activity(activity) end -- cgit v1.2.3 From 69a9e0563cc441a772c4884d747bb755ddf58c45 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Mon, 13 May 2019 02:09:28 +0000 Subject: user: migrate follow/blocks import to job queue --- lib/pleroma/user.ex | 73 +++++++++++----------- .../web/twitter_api/controllers/util_controller.ex | 14 ++++- 2 files changed, 50 insertions(+), 37 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index a79da4dd8..c94660de4 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -413,24 +413,6 @@ defmodule Pleroma.User do Enum.member?(follower.following, followed.follower_address) end - def follow_import(%User{} = follower, followed_identifiers) - when is_list(followed_identifiers) do - Enum.map( - followed_identifiers, - fn followed_identifier -> - with {:ok, %User{} = followed} <- get_or_fetch(followed_identifier), - {:ok, follower} <- maybe_direct_follow(follower, followed), - {:ok, _} <- ActivityPub.follow(follower, followed) do - followed - else - err -> - Logger.debug("follow_import failed for #{followed_identifier} with: #{inspect(err)}") - err - end - end - ) - end - def locked?(%User{} = user) do user.info.locked || false end @@ -844,23 +826,6 @@ defmodule Pleroma.User do ) end - def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do - Enum.map( - blocked_identifiers, - fn blocked_identifier -> - with {:ok, %User{} = blocked} <- get_or_fetch(blocked_identifier), - {:ok, blocker} <- block(blocker, blocked), - {:ok, _} <- ActivityPub.block(blocker, blocked) do - blocked - else - err -> - Logger.debug("blocks_import failed for #{blocked_identifier} with: #{inspect(err)}") - err - end - end - ) - end - def mute(muter, %User{ap_id: ap_id}) do info_cng = muter.info @@ -1082,6 +1047,44 @@ defmodule Pleroma.User do {:ok, user} end + @spec perform(atom(), User.t(), list()) :: list() | {:error, any()} + def perform(:blocks_import, %User{} = blocker, blocked_identifiers) + when is_list(blocked_identifiers) do + Enum.map( + blocked_identifiers, + fn blocked_identifier -> + with {:ok, %User{} = blocked} <- get_or_fetch(blocked_identifier), + {:ok, blocker} <- block(blocker, blocked), + {:ok, _} <- ActivityPub.block(blocker, blocked) do + blocked + else + err -> + Logger.debug("blocks_import failed for #{blocked_identifier} with: #{inspect(err)}") + err + end + end + ) + end + + @spec perform(atom(), User.t(), list()) :: list() | {:error, any()} + def perform(:follow_import, %User{} = follower, followed_identifiers) + when is_list(followed_identifiers) do + Enum.map( + followed_identifiers, + fn followed_identifier -> + with {:ok, %User{} = followed} <- get_or_fetch(followed_identifier), + {:ok, follower} <- maybe_direct_follow(follower, followed), + {:ok, _} <- ActivityPub.follow(follower, followed) do + followed + else + err -> + Logger.debug("follow_import failed for #{followed_identifier} with: #{inspect(err)}") + err + end + end + ) + end + def delete_user_activities(%User{ap_id: ap_id} = user) do stream = ap_id diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index c03f8ab3a..143960206 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -310,7 +310,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do String.split(line, ",") |> List.first() end) |> List.delete("Account address"), - {:ok, _} = Task.start(fn -> User.follow_import(follower, followed_identifiers) end) do + :ok <- + PleromaJobQueue.enqueue(:background, User, [ + :follow_import, + follower, + followed_identifiers + ]) do json(conn, "job started") end end @@ -321,7 +326,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do def blocks_import(%{assigns: %{user: blocker}} = conn, %{"list" => list}) do with blocked_identifiers <- String.split(list), - {:ok, _} = Task.start(fn -> User.blocks_import(blocker, blocked_identifiers) end) do + :ok <- + PleromaJobQueue.enqueue(:background, User, [ + :blocks_import, + blocker, + blocked_identifiers + ]) do json(conn, "job started") end end -- cgit v1.2.3 From a18b2c0b12b413c9a8d0aa0d4fd3b15e0e843cdf Mon Sep 17 00:00:00 2001 From: Aaron Tinio Date: Tue, 14 May 2019 06:40:59 +0800 Subject: Fix Pleroma.Config.get!/1 raising an error when value is false --- lib/pleroma/config.ex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex index 189faa15f..71a47b9fb 100644 --- a/lib/pleroma/config.ex +++ b/lib/pleroma/config.ex @@ -12,8 +12,12 @@ defmodule Pleroma.Config do def get([key], default), do: get(key, default) def get([parent_key | keys], default) do - Application.get_env(:pleroma, parent_key) - |> get_in(keys) || default + case :pleroma + |> Application.get_env(parent_key) + |> get_in(keys) do + nil -> default + any -> any + end end def get(key, default) do -- cgit v1.2.3 From b92c004ea8a9ecd066b8eddf755a07a175338416 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Tue, 14 May 2019 18:29:10 +0700 Subject: Reuse query from User.restrict_deactivated/1 --- lib/pleroma/user.ex | 2 +- lib/pleroma/user/query.ex | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index cf378d467..3eb684c3a 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -115,7 +115,7 @@ defmodule Pleroma.User do } end - defp restrict_deactivated(query) do + def restrict_deactivated(query) do from(u in query, where: not fragment("? \\? 'deactivated' AND ?->'deactivated' @> 'true'", u.info, u.info) ) diff --git a/lib/pleroma/user/query.ex b/lib/pleroma/user/query.ex index 3873ef80c..ace9c05f2 100644 --- a/lib/pleroma/user/query.ex +++ b/lib/pleroma/user/query.ex @@ -119,9 +119,7 @@ defmodule Pleroma.User.Query do end defp compose_query({:deactivated, false}, query) do - from(u in query, - where: not fragment("? \\? 'deactivated' AND ?->'deactivated' @> 'true'", u.info, u.info) - ) + User.restrict_deactivated(query) end defp compose_query({:deactivated, true}, query) do -- cgit v1.2.3 From 52297920e74ad7f51bcd3b118522e5e3a8e1c794 Mon Sep 17 00:00:00 2001 From: Maksim Date: Tue, 14 May 2019 14:49:45 +0000 Subject: Refactoring oauth response. --- lib/pleroma/web/oauth/oauth_controller.ex | 77 ++++++------------------------- lib/pleroma/web/oauth/token/response.ex | 32 +++++++++++++ lib/pleroma/web/oauth/token/utils.ex | 38 +++++++++++++++ 3 files changed, 83 insertions(+), 64 deletions(-) create mode 100644 lib/pleroma/web/oauth/token/response.ex (limited to 'lib') diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 4ee8339e2..ae2b80d95 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -19,8 +19,6 @@ defmodule Pleroma.Web.OAuth.OAuthController do if Pleroma.Config.oauth_consumer_enabled?(), do: plug(Ueberauth) - @expires_in Pleroma.Config.get([:oauth2, :token_expires_in], 600) - plug(:fetch_session) plug(:fetch_flash) @@ -144,14 +142,14 @@ defmodule Pleroma.Web.OAuth.OAuthController do @doc "Renew access_token with refresh_token" def token_exchange( conn, - %{"grant_type" => "refresh_token", "refresh_token" => token} = params + %{"grant_type" => "refresh_token", "refresh_token" => token} = _params ) do - with %App{} = app <- get_app_from_request(conn, params), + with {:ok, app} <- Token.Utils.fetch_app(conn), {:ok, %{user: user} = token} <- Token.get_by_refresh_token(app, token), {:ok, token} <- RefreshToken.grant(token) do response_attrs = %{created_at: Token.Utils.format_created_at(token)} - json(conn, response_token(user, token, response_attrs)) + json(conn, Token.Response.build(user, token, response_attrs)) else _error -> put_status(conn, 400) @@ -160,14 +158,14 @@ defmodule Pleroma.Web.OAuth.OAuthController do end def token_exchange(conn, %{"grant_type" => "authorization_code"} = params) do - with %App{} = app <- get_app_from_request(conn, params), + with {:ok, app} <- Token.Utils.fetch_app(conn), fixed_token = Token.Utils.fix_padding(params["code"]), {:ok, auth} <- Authorization.get_by_token(app, fixed_token), %User{} = user <- User.get_cached_by_id(auth.user_id), {:ok, token} <- Token.exchange_token(app, auth) do response_attrs = %{created_at: Token.Utils.format_created_at(token)} - json(conn, response_token(user, token, response_attrs)) + json(conn, Token.Response.build(user, token, response_attrs)) else _error -> put_status(conn, 400) @@ -179,14 +177,14 @@ defmodule Pleroma.Web.OAuth.OAuthController do conn, %{"grant_type" => "password"} = params ) do - with {_, {:ok, %User{} = user}} <- {:get_user, Authenticator.get_user(conn)}, - %App{} = app <- get_app_from_request(conn, params), + with {:ok, %User{} = user} <- Authenticator.get_user(conn), + {:ok, app} <- Token.Utils.fetch_app(conn), {:auth_active, true} <- {:auth_active, User.auth_active?(user)}, {:user_active, true} <- {:user_active, !user.info.deactivated}, {:ok, scopes} <- validate_scopes(app, params), {:ok, auth} <- Authorization.create_authorization(app, user, scopes), {:ok, token} <- Token.exchange_token(app, auth) do - json(conn, response_token(user, token)) + json(conn, Token.Response.build(user, token)) else {:auth_active, false} -> # Per https://github.com/tootsuite/mastodon/blob/ @@ -218,21 +216,11 @@ defmodule Pleroma.Web.OAuth.OAuthController do token_exchange(conn, params) end - def token_exchange(conn, %{"grant_type" => "client_credentials"} = params) do - with %App{} = app <- get_app_from_request(conn, params), + def token_exchange(conn, %{"grant_type" => "client_credentials"} = _params) do + with {:ok, app} <- Token.Utils.fetch_app(conn), {:ok, auth} <- Authorization.create_authorization(app, %User{}), - {:ok, token} <- Token.exchange_token(app, auth), - {:ok, inserted_at} <- DateTime.from_naive(token.inserted_at, "Etc/UTC") do - response = %{ - token_type: "Bearer", - access_token: token.token, - refresh_token: token.refresh_token, - created_at: DateTime.to_unix(inserted_at), - expires_in: 60 * 10, - scope: Enum.join(token.scopes, " ") - } - - json(conn, response) + {:ok, token} <- Token.exchange_token(app, auth) do + json(conn, Token.Response.build_for_client_credentials(token)) else _error -> put_status(conn, 400) @@ -244,7 +232,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do def token_exchange(conn, params), do: bad_request(conn, params) def token_revoke(conn, %{"token" => _token} = params) do - with %App{} = app <- get_app_from_request(conn, params), + with {:ok, app} <- Token.Utils.fetch_app(conn), {:ok, _token} <- RevokeToken.revoke(app, params) do json(conn, %{}) else @@ -427,33 +415,6 @@ defmodule Pleroma.Web.OAuth.OAuthController do end end - defp get_app_from_request(conn, params) do - conn - |> fetch_client_credentials(params) - |> fetch_client - end - - defp fetch_client({id, secret}) when is_binary(id) and is_binary(secret) do - Repo.get_by(App, client_id: id, client_secret: secret) - end - - defp fetch_client({_id, _secret}), do: nil - - defp fetch_client_credentials(conn, params) do - # Per RFC 6749, HTTP Basic is preferred to body params - with ["Basic " <> encoded] <- get_req_header(conn, "authorization"), - {:ok, decoded} <- Base.decode64(encoded), - [id, secret] <- - Enum.map( - String.split(decoded, ":"), - fn s -> URI.decode_www_form(s) end - ) do - {id, secret} - else - _ -> {params["client_id"], params["client_secret"]} - end - end - # Special case: Local MastodonFE defp redirect_uri(conn, "."), do: mastodon_api_url(conn, :login) @@ -464,18 +425,6 @@ defmodule Pleroma.Web.OAuth.OAuthController do defp put_session_registration_id(conn, registration_id), do: put_session(conn, :registration_id, registration_id) - defp response_token(%User{} = user, token, opts \\ %{}) do - %{ - token_type: "Bearer", - access_token: token.token, - refresh_token: token.refresh_token, - expires_in: @expires_in, - scope: Enum.join(token.scopes, " "), - me: user.ap_id - } - |> Map.merge(opts) - end - @spec validate_scopes(App.t(), map()) :: {:ok, list()} | {:error, :missing_scopes | :unsupported_scopes} defp validate_scopes(app, params) do diff --git a/lib/pleroma/web/oauth/token/response.ex b/lib/pleroma/web/oauth/token/response.ex new file mode 100644 index 000000000..64e78b183 --- /dev/null +++ b/lib/pleroma/web/oauth/token/response.ex @@ -0,0 +1,32 @@ +defmodule Pleroma.Web.OAuth.Token.Response do + @moduledoc false + + alias Pleroma.User + alias Pleroma.Web.OAuth.Token.Utils + + @expires_in Pleroma.Config.get([:oauth2, :token_expires_in], 600) + + @doc false + def build(%User{} = user, token, opts \\ %{}) do + %{ + token_type: "Bearer", + access_token: token.token, + refresh_token: token.refresh_token, + expires_in: @expires_in, + scope: Enum.join(token.scopes, " "), + me: user.ap_id + } + |> Map.merge(opts) + end + + def build_for_client_credentials(token) do + %{ + token_type: "Bearer", + access_token: token.token, + refresh_token: token.refresh_token, + created_at: Utils.format_created_at(token), + expires_in: @expires_in, + scope: Enum.join(token.scopes, " ") + } + end +end diff --git a/lib/pleroma/web/oauth/token/utils.ex b/lib/pleroma/web/oauth/token/utils.ex index a81560a1c..7a4fddafd 100644 --- a/lib/pleroma/web/oauth/token/utils.ex +++ b/lib/pleroma/web/oauth/token/utils.ex @@ -3,6 +3,44 @@ defmodule Pleroma.Web.OAuth.Token.Utils do Auxiliary functions for dealing with tokens. """ + alias Pleroma.Repo + alias Pleroma.Web.OAuth.App + + @doc "Fetch app by client credentials from request" + @spec fetch_app(Plug.Conn.t()) :: {:ok, App.t()} | {:error, :not_found} + def fetch_app(conn) do + res = + conn + |> fetch_client_credentials() + |> fetch_client + + case res do + %App{} = app -> {:ok, app} + _ -> {:error, :not_found} + end + end + + defp fetch_client({id, secret}) when is_binary(id) and is_binary(secret) do + Repo.get_by(App, client_id: id, client_secret: secret) + end + + defp fetch_client({_id, _secret}), do: nil + + defp fetch_client_credentials(conn) do + # Per RFC 6749, HTTP Basic is preferred to body params + with ["Basic " <> encoded] <- Plug.Conn.get_req_header(conn, "authorization"), + {:ok, decoded} <- Base.decode64(encoded), + [id, secret] <- + Enum.map( + String.split(decoded, ":"), + fn s -> URI.decode_www_form(s) end + ) do + {id, secret} + else + _ -> {conn.params["client_id"], conn.params["client_secret"]} + end + end + @doc "convert token inserted_at to unix timestamp" def format_created_at(%{inserted_at: inserted_at} = _token) do inserted_at -- cgit v1.2.3 From ac3a3abf6bfae5a6217e0a212abd6be0b4a17309 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 14 May 2019 15:07:38 +0000 Subject: clean up follow/block imports a little --- lib/pleroma/user.ex | 16 +++++++++++++ .../web/twitter_api/controllers/util_controller.ex | 28 +++++++++++----------- 2 files changed, 30 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index c94660de4..417d57d72 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1085,6 +1085,22 @@ defmodule Pleroma.User do ) end + def blocks_import(%User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers), + do: + PleromaJobQueue.enqueue(:background, __MODULE__, [ + :blocks_import, + blocker, + blocked_identifiers + ]) + + def follow_import(%User{} = follower, followed_identifiers) when is_list(followed_identifiers), + do: + PleromaJobQueue.enqueue(:background, __MODULE__, [ + :follow_import, + follower, + followed_identifiers + ]) + def delete_user_activities(%User{ap_id: ap_id} = user) do stream = ap_id diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 143960206..deaacd946 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -309,13 +309,13 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do Enum.map(lines, fn line -> String.split(line, ",") |> List.first() end) - |> List.delete("Account address"), - :ok <- - PleromaJobQueue.enqueue(:background, User, [ - :follow_import, - follower, - followed_identifiers - ]) do + |> List.delete("Account address") do + PleromaJobQueue.enqueue(:background, User, [ + :follow_import, + follower, + followed_identifiers + ]) + json(conn, "job started") end end @@ -325,13 +325,13 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do end def blocks_import(%{assigns: %{user: blocker}} = conn, %{"list" => list}) do - with blocked_identifiers <- String.split(list), - :ok <- - PleromaJobQueue.enqueue(:background, User, [ - :blocks_import, - blocker, - blocked_identifiers - ]) do + with blocked_identifiers <- String.split(list) do + PleromaJobQueue.enqueue(:background, User, [ + :blocks_import, + blocker, + blocked_identifiers + ]) + json(conn, "job started") end end -- cgit v1.2.3 From 51325fd60cf96e2ae99e09f53264f2ca1e69781b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Tue, 14 May 2019 15:35:06 +0000 Subject: gopher: fix rendering of post content (closes #895) --- lib/pleroma/gopher/server.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/gopher/server.ex b/lib/pleroma/gopher/server.ex index 1d2e0785c..b3319e137 100644 --- a/lib/pleroma/gopher/server.ex +++ b/lib/pleroma/gopher/server.ex @@ -77,13 +77,13 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do user = User.get_cached_by_ap_id(activity.data["actor"]) object = Object.normalize(activity) - like_count = object["like_count"] || 0 - announcement_count = object["announcement_count"] || 0 + like_count = object.data["like_count"] || 0 + announcement_count = object.data["announcement_count"] || 0 link("Post ##{activity.id} by #{user.nickname}", "/notices/#{activity.id}") <> info("#{like_count} likes, #{announcement_count} repeats") <> "i\tfake\t(NULL)\t0\r\n" <> - info(HTML.strip_tags(String.replace(object["content"], "
", "\r"))) + info(HTML.strip_tags(String.replace(object.data["content"], "
", "\r"))) end) |> Enum.join("i\tfake\t(NULL)\t0\r\n") end -- cgit v1.2.3 From 1caa6331eaba71db5a04b2097ef06fd6e4a54739 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Tue, 14 May 2019 12:33:03 -0500 Subject: Group def perform() together to fix the build --- lib/pleroma/user.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 19f91d63c..c6a562a61 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1014,8 +1014,6 @@ defmodule Pleroma.User do PleromaJobQueue.enqueue(:background, __MODULE__, [:deactivate_async, user, status]) end - def perform(:deactivate_async, user, status), do: deactivate(user, status) - def deactivate(%User{} = user, status \\ true) do info_cng = User.Info.set_activation_status(user.info, status) @@ -1074,6 +1072,8 @@ defmodule Pleroma.User do {:ok, user} end + def perform(:deactivate_async, user, status), do: deactivate(user, status) + @spec perform(atom(), User.t(), list()) :: list() | {:error, any()} def perform(:blocks_import, %User{} = blocker, blocked_identifiers) when is_list(blocked_identifiers) do -- cgit v1.2.3