diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mix/pleroma.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/ecto_enums.ex | 8 | ||||
-rw-r--r-- | lib/pleroma/following_relationship.ex | 51 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 18 | ||||
-rw-r--r-- | lib/pleroma/user/query.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/user_relationship.ex | 29 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/transmogrifier.ex | 13 | ||||
-rw-r--r-- | lib/pleroma/web/common_api/common_api.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/account_view.ex | 6 |
9 files changed, 97 insertions, 39 deletions
diff --git a/lib/mix/pleroma.ex b/lib/mix/pleroma.ex index 4dfcc32e7..3ad6edbfb 100644 --- a/lib/mix/pleroma.ex +++ b/lib/mix/pleroma.ex @@ -5,7 +5,6 @@ defmodule Mix.Pleroma do @doc "Common functions to be reused in mix tasks" def start_pleroma do - Mix.Task.run("app.start") Application.put_env(:phoenix, :serve_endpoints, false, persistent: true) if Pleroma.Config.get(:env) != :test do diff --git a/lib/pleroma/ecto_enums.ex b/lib/pleroma/ecto_enums.ex index d9b601223..6fc47620c 100644 --- a/lib/pleroma/ecto_enums.ex +++ b/lib/pleroma/ecto_enums.ex @@ -4,10 +4,16 @@ import EctoEnum -defenum(UserRelationshipTypeEnum, +defenum(Pleroma.UserRelationship.Type, block: 1, mute: 2, reblog_mute: 3, notification_mute: 4, inverse_subscription: 5 ) + +defenum(Pleroma.FollowingRelationship.State, + follow_pending: 1, + follow_accept: 2, + follow_reject: 3 +) diff --git a/lib/pleroma/following_relationship.ex b/lib/pleroma/following_relationship.ex index a9538ea4e..9ccf40495 100644 --- a/lib/pleroma/following_relationship.ex +++ b/lib/pleroma/following_relationship.ex @@ -8,12 +8,13 @@ defmodule Pleroma.FollowingRelationship do import Ecto.Changeset import Ecto.Query + alias Ecto.Changeset alias FlakeId.Ecto.CompatType alias Pleroma.Repo alias Pleroma.User schema "following_relationships" do - field(:state, :string, default: "accept") + field(:state, Pleroma.FollowingRelationship.State, default: :follow_pending) belongs_to(:follower, User, type: CompatType) belongs_to(:following, User, type: CompatType) @@ -27,6 +28,18 @@ defmodule Pleroma.FollowingRelationship do |> put_assoc(:follower, attrs.follower) |> put_assoc(:following, attrs.following) |> validate_required([:state, :follower, :following]) + |> unique_constraint(:follower_id, + name: :following_relationships_follower_id_following_id_index + ) + |> validate_not_self_relationship() + end + + def state_to_enum(state) when state in ["pending", "accept", "reject"] do + String.to_existing_atom("follow_#{state}") + end + + def state_to_enum(state) do + raise "State is not convertible to Pleroma.FollowingRelationship.State: #{state}" end def get(%User{} = follower, %User{} = following) do @@ -35,7 +48,7 @@ defmodule Pleroma.FollowingRelationship do |> Repo.one() end - def update(follower, following, "reject"), do: unfollow(follower, following) + def update(follower, following, :follow_reject), do: unfollow(follower, following) def update(%User{} = follower, %User{} = following, state) do case get(follower, following) do @@ -50,7 +63,7 @@ defmodule Pleroma.FollowingRelationship do end end - def follow(%User{} = follower, %User{} = following, state \\ "accept") do + def follow(%User{} = follower, %User{} = following, state \\ :follow_accept) do %__MODULE__{} |> changeset(%{follower: follower, following: following, state: state}) |> Repo.insert(on_conflict: :nothing) @@ -80,7 +93,7 @@ defmodule Pleroma.FollowingRelationship do def get_follow_requests(%User{id: id}) do __MODULE__ |> join(:inner, [r], f in assoc(r, :follower)) - |> where([r], r.state == "pending") + |> where([r], r.state == ^:follow_pending) |> where([r], r.following_id == ^id) |> select([r, f], f) |> Repo.all() @@ -88,7 +101,7 @@ defmodule Pleroma.FollowingRelationship do def following?(%User{id: follower_id}, %User{id: followed_id}) do __MODULE__ - |> where(follower_id: ^follower_id, following_id: ^followed_id, state: "accept") + |> where(follower_id: ^follower_id, following_id: ^followed_id, state: ^:follow_accept) |> Repo.exists?() end @@ -97,7 +110,7 @@ defmodule Pleroma.FollowingRelationship do __MODULE__ |> join(:inner, [r], u in User, on: r.following_id == u.id) |> where([r], r.follower_id == ^user.id) - |> where([r], r.state == "accept") + |> where([r], r.state == ^:follow_accept) |> select([r, u], u.follower_address) |> Repo.all() @@ -157,4 +170,30 @@ defmodule Pleroma.FollowingRelationship do fr -> fr.follower_id == follower.id and fr.following_id == following.id end) end + + defp validate_not_self_relationship(%Changeset{} = changeset) do + changeset + |> validate_follower_id_following_id_inequality() + |> validate_following_id_follower_id_inequality() + end + + defp validate_follower_id_following_id_inequality(%Changeset{} = changeset) do + validate_change(changeset, :follower_id, fn _, follower_id -> + if follower_id == get_field(changeset, :following_id) do + [source_id: "can't be equal to following_id"] + else + [] + end + end) + end + + defp validate_following_id_follower_id_inequality(%Changeset{} = changeset) do + validate_change(changeset, :following_id, fn _, following_id -> + if following_id == get_field(changeset, :follower_id) do + [target_id: "can't be equal to follower_id"] + else + [] + end + end) + end end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 71c8c3a4e..670ce397b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -700,7 +700,7 @@ defmodule Pleroma.User do @spec maybe_direct_follow(User.t(), User.t()) :: {:ok, User.t()} | {:error, String.t()} def maybe_direct_follow(%User{} = follower, %User{local: true, locked: true} = followed) do - follow(follower, followed, "pending") + follow(follower, followed, :follow_pending) end def maybe_direct_follow(%User{} = follower, %User{local: true} = followed) do @@ -720,14 +720,14 @@ defmodule Pleroma.User do def follow_all(follower, followeds) do followeds |> Enum.reject(fn followed -> blocks?(follower, followed) || blocks?(followed, follower) end) - |> Enum.each(&follow(follower, &1, "accept")) + |> Enum.each(&follow(follower, &1, :follow_accept)) set_cache(follower) end defdelegate following(user), to: FollowingRelationship - def follow(%User{} = follower, %User{} = followed, state \\ "accept") do + def follow(%User{} = follower, %User{} = followed, state \\ :follow_accept) do deny_follow_blocked = Pleroma.Config.get([:user, :deny_follow_blocked]) cond do @@ -754,7 +754,7 @@ defmodule Pleroma.User do def unfollow(%User{} = follower, %User{} = followed) do case get_follow_state(follower, followed) do - state when state in ["accept", "pending"] -> + state when state in [:follow_pending, :follow_accept] -> FollowingRelationship.unfollow(follower, followed) {:ok, followed} = update_follower_count(followed) @@ -772,6 +772,7 @@ defmodule Pleroma.User do defdelegate following?(follower, followed), to: FollowingRelationship + @doc "Returns follow state as Pleroma.FollowingRelationship.State value" def get_follow_state(%User{} = follower, %User{} = following) do following_relationship = FollowingRelationship.get(follower, following) get_follow_state(follower, following, following_relationship) @@ -785,8 +786,11 @@ defmodule Pleroma.User do case {following_relationship, following.local} do {nil, false} -> case Utils.fetch_latest_follow(follower, following) do - %{data: %{"state" => state}} when state in ["pending", "accept"] -> state - _ -> nil + %Activity{data: %{"state" => state}} when state in ["pending", "accept"] -> + FollowingRelationship.state_to_enum(state) + + _ -> + nil end {%{state: state}, _} -> @@ -1285,7 +1289,7 @@ defmodule Pleroma.User do def blocks?(%User{} = user, %User{} = target) do blocks_user?(user, target) || - (!User.following?(user, target) && blocks_domain?(user, target)) + (blocks_domain?(user, target) and not User.following?(user, target)) end def blocks_user?(%User{} = user, %User{} = target) do diff --git a/lib/pleroma/user/query.ex b/lib/pleroma/user/query.ex index 884e33039..ec88088cf 100644 --- a/lib/pleroma/user/query.ex +++ b/lib/pleroma/user/query.ex @@ -148,7 +148,7 @@ defmodule Pleroma.User.Query do as: :relationships, on: r.following_id == ^id and r.follower_id == u.id ) - |> where([relationships: r], r.state == "accept") + |> where([relationships: r], r.state == ^:follow_accept) end defp compose_query({:friends, %User{id: id}}, query) do @@ -158,7 +158,7 @@ defmodule Pleroma.User.Query do as: :relationships, on: r.following_id == u.id and r.follower_id == ^id ) - |> where([relationships: r], r.state == "accept") + |> where([relationships: r], r.state == ^:follow_accept) end defp compose_query({:recipients_from_activity, to}, query) do @@ -173,7 +173,7 @@ defmodule Pleroma.User.Query do ) |> where( [u, following: f, relationships: r], - u.ap_id in ^to or (f.follower_address in ^to and r.state == "accept") + u.ap_id in ^to or (f.follower_address in ^to and r.state == ^:follow_accept) ) |> distinct(true) end diff --git a/lib/pleroma/user_relationship.ex b/lib/pleroma/user_relationship.ex index 18a5eec72..ad0d303b1 100644 --- a/lib/pleroma/user_relationship.ex +++ b/lib/pleroma/user_relationship.ex @@ -8,6 +8,7 @@ defmodule Pleroma.UserRelationship do import Ecto.Changeset import Ecto.Query + alias Ecto.Changeset alias Pleroma.FollowingRelationship alias Pleroma.Repo alias Pleroma.User @@ -16,12 +17,12 @@ defmodule Pleroma.UserRelationship do schema "user_relationships" do belongs_to(:source, User, type: FlakeId.Ecto.CompatType) belongs_to(:target, User, type: FlakeId.Ecto.CompatType) - field(:relationship_type, UserRelationshipTypeEnum) + field(:relationship_type, Pleroma.UserRelationship.Type) timestamps(updated_at: false) end - for relationship_type <- Keyword.keys(UserRelationshipTypeEnum.__enum_map__()) do + for relationship_type <- Keyword.keys(Pleroma.UserRelationship.Type.__enum_map__()) do # `def create_block/2`, `def create_mute/2`, `def create_reblog_mute/2`, # `def create_notification_mute/2`, `def create_inverse_subscription/2` def unquote(:"create_#{relationship_type}")(source, target), @@ -40,7 +41,7 @@ defmodule Pleroma.UserRelationship do def user_relationship_types, do: Keyword.keys(user_relationship_mappings()) - def user_relationship_mappings, do: UserRelationshipTypeEnum.__enum_map__() + def user_relationship_mappings, do: Pleroma.UserRelationship.Type.__enum_map__() def changeset(%UserRelationship{} = user_relationship, params \\ %{}) do user_relationship @@ -147,18 +148,26 @@ defmodule Pleroma.UserRelationship do %{user_relationships: user_relationships, following_relationships: following_relationships} end - defp validate_not_self_relationship(%Ecto.Changeset{} = changeset) do + defp validate_not_self_relationship(%Changeset{} = changeset) do changeset - |> validate_change(:target_id, fn _, target_id -> - if target_id == get_field(changeset, :source_id) do - [target_id: "can't be equal to source_id"] + |> validate_source_id_target_id_inequality() + |> validate_target_id_source_id_inequality() + end + + defp validate_source_id_target_id_inequality(%Changeset{} = changeset) do + validate_change(changeset, :source_id, fn _, source_id -> + if source_id == get_field(changeset, :target_id) do + [source_id: "can't be equal to target_id"] else [] end end) - |> validate_change(:source_id, fn _, source_id -> - if source_id == get_field(changeset, :target_id) do - [source_id: "can't be equal to target_id"] + end + + defp validate_target_id_source_id_inequality(%Changeset{} = changeset) do + validate_change(changeset, :target_id, fn _, target_id -> + if target_id == get_field(changeset, :source_id) do + [target_id: "can't be equal to source_id"] else [] end diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index f9951cc5d..39feae285 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -524,7 +524,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do {_, {:ok, follower}} <- {:follow, User.follow(follower, followed)}, {_, {:ok, _}} <- {:follow_state_update, Utils.update_follow_state_for_all(activity, "accept")}, - {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do + {:ok, _relationship} <- + FollowingRelationship.update(follower, followed, :follow_accept) do ActivityPub.accept(%{ to: [follower.ap_id], actor: followed, @@ -534,7 +535,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do else {:user_blocked, true} -> {:ok, _} = Utils.update_follow_state_for_all(activity, "reject") - {:ok, _relationship} = FollowingRelationship.update(follower, followed, "reject") + {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject) ActivityPub.reject(%{ to: [follower.ap_id], @@ -545,7 +546,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do {:follow, {:error, _}} -> {:ok, _} = Utils.update_follow_state_for_all(activity, "reject") - {:ok, _relationship} = FollowingRelationship.update(follower, followed, "reject") + {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject) ActivityPub.reject(%{ to: [follower.ap_id], @@ -555,7 +556,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do }) {:user_locked, true} -> - {:ok, _relationship} = FollowingRelationship.update(follower, followed, "pending") + {:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_pending) :noop end @@ -575,7 +576,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do {:ok, follow_activity} <- get_follow_activity(follow_object, followed), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"), %User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]), - {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do + {:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do ActivityPub.accept(%{ to: follow_activity.data["to"], type: "Accept", @@ -598,7 +599,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do {:ok, follow_activity} <- get_follow_activity(follow_object, followed), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"), %User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]), - {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "reject"), + {:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_reject), {:ok, activity} <- ActivityPub.reject(%{ to: follow_activity.data["to"], diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 51447f897..7a8ccf3e5 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -45,7 +45,7 @@ defmodule Pleroma.Web.CommonAPI do with {:ok, follower} <- User.follow(follower, followed), %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"), - {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept"), + {:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept), {:ok, _activity} <- ActivityPub.accept(%{ to: [follower.ap_id], @@ -60,7 +60,7 @@ defmodule Pleroma.Web.CommonAPI do def reject_follow_request(follower, followed) do with %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"), - {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "reject"), + {:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_reject), {:ok, _activity} <- ActivityPub.reject(%{ to: [follower.ap_id], diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 99e62f580..313b2f602 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -73,7 +73,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do followed_by = if following_relationships do case FollowingRelationship.find(following_relationships, target, reading_user) do - %{state: "accept"} -> true + %{state: :follow_accept} -> true _ -> false end else @@ -83,7 +83,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do # NOTE: adjust UserRelationship.view_relationships_option/2 on new relation-related flags %{ id: to_string(target.id), - following: follow_state == "accept", + following: follow_state == :follow_accept, followed_by: followed_by, blocking: UserRelationship.exists?( @@ -125,7 +125,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do reading_user, &User.subscribed_to?(&2, &1) ), - requested: follow_state == "pending", + requested: follow_state == :follow_pending, domain_blocking: User.blocks_domain?(reading_user, target), showing_reblogs: not UserRelationship.exists?( |