aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2019-10-17 18:36:52 +0200
committerlain <lain@soykaf.club>2019-10-17 18:36:52 +0200
commit66452f518faa1f079f02006943b0c2cdc830b47f (patch)
tree9caab63611fa4f43f80f4ab6ea02616440b6718b /lib
parent081e8206ab75e336a76b621508b3999170159ec6 (diff)
downloadpleroma-66452f518faa1f079f02006943b0c2cdc830b47f.tar.gz
ObjectValidator: Rewrite LikeValidator with Ecto.
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/web/activity_pub/object_validator.ex42
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/like_validator.ex69
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/types/object.ex25
-rw-r--r--lib/pleroma/web/common_api/common_api.ex10
4 files changed, 102 insertions, 44 deletions
diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex
index 0048cc4ec..adcb53c65 100644
--- a/lib/pleroma/web/activity_pub/object_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validator.ex
@@ -9,50 +9,24 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
the system.
"""
- alias Pleroma.User
- alias Pleroma.Object
- alias Pleroma.Web.ActivityPub.Utils
-
- def validate_id(object, meta) do
- with {_, true} <- {:id_presence, Map.has_key?(object, "id")} do
- {:ok, object, meta}
- else
- e -> {:error, e}
- end
- end
-
- def validate_actor(object, meta) do
- with {_, %User{}} <- {:actor_validation, User.get_cached_by_ap_id(object["actor"])} do
- {:ok, object, meta}
- else
- e -> {:error, e}
- end
- end
-
- def common_validations(object, meta) do
- with {_, {:ok, object, meta}} <- {:validate_id, validate_id(object, meta)},
- {_, {:ok, object, meta}} <- {:validate_actor, validate_actor(object, meta)} do
- {:ok, object, meta}
- else
- e -> {:error, e}
- end
- end
+ alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
@spec validate(map(), keyword()) :: {:ok, map(), keyword()} | {:error, any()}
def validate(object, meta)
def validate(%{"type" => "Like"} = object, meta) do
- with {:ok, object, meta} <- common_validations(object, meta),
- {_, %Object{} = liked_object} <-
- {:find_liked_object, Object.normalize(object["object"])},
- {_, nil} <- {:existing_like, Utils.get_existing_like(object["actor"], liked_object)} do
+ with {_, %{valid?: true, changes: object}} <-
+ {:validate_object, LikeValidator.cast_and_validate(object)} do
+ object = stringify_keys(object)
{:ok, object, meta}
else
e -> {:error, e}
end
end
- def validate(object, meta) do
- common_validations(object, meta)
+ defp stringify_keys(object) do
+ object
+ |> Enum.map(fn {key, val} -> {to_string(key), val} end)
+ |> Enum.into(%{})
end
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/like_validator.ex b/lib/pleroma/web/activity_pub/object_validators/like_validator.ex
new file mode 100644
index 000000000..d5a2f7202
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/object_validators/like_validator.ex
@@ -0,0 +1,69 @@
+defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ alias Pleroma.Web.ActivityPub.ObjectValidators.Types
+ alias Pleroma.Web.ActivityPub.Utils
+ alias Pleroma.User
+ alias Pleroma.Object
+
+ @primary_key false
+
+ embedded_schema do
+ field(:id, :string, primary_key: true)
+ field(:type, :string)
+ field(:object, Types.ObjectID)
+ field(:actor, Types.ObjectID)
+ field(:context, :string)
+ field(:to, {:array, :string})
+ field(:cc, {:array, :string})
+ end
+
+ def cast_and_validate(data) do
+ data
+ |> cast_data()
+ |> validate_data()
+ end
+
+ def cast_data(data) do
+ %__MODULE__{}
+ |> cast(data, [:id, :type, :object, :actor, :context, :to, :cc])
+ end
+
+ def validate_data(data_cng) do
+ data_cng
+ |> validate_inclusion(:type, ["Like"])
+ |> validate_required([:id, :type, :object, :actor, :context])
+ |> validate_change(:actor, &actor_valid?/2)
+ |> validate_change(:object, &object_valid?/2)
+ |> validate_existing_like()
+ end
+
+ def validate_existing_like(%{changes: %{actor: actor, object: object}} = cng) do
+ if Utils.get_existing_like(actor, %{data: %{"id" => object}}) do
+ cng
+ |> add_error(:actor, "already liked this object")
+ |> add_error(:object, "already liked by this actor")
+ else
+ cng
+ end
+ end
+
+ def validate_existing_like(cng), do: cng
+
+ def actor_valid?(field_name, actor) do
+ if User.get_cached_by_ap_id(actor) do
+ []
+ else
+ [{field_name, "can't find user"}]
+ end
+ end
+
+ def object_valid?(field_name, object) do
+ if Object.get_cached_by_ap_id(object) do
+ []
+ else
+ [{field_name, "can't find object"}]
+ end
+ end
+end
diff --git a/lib/pleroma/web/activity_pub/object_validators/types/object.ex b/lib/pleroma/web/activity_pub/object_validators/types/object.ex
new file mode 100644
index 000000000..92fc13ba8
--- /dev/null
+++ b/lib/pleroma/web/activity_pub/object_validators/types/object.ex
@@ -0,0 +1,25 @@
+defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.ObjectID do
+ use Ecto.Type
+
+ def type, do: :string
+
+ def cast(object) when is_binary(object) do
+ {:ok, object}
+ end
+
+ def cast(%{"id" => object}) when is_binary(object) do
+ {:ok, object}
+ end
+
+ def cast(_) do
+ :error
+ end
+
+ def dump(data) do
+ {:ok, data}
+ end
+
+ def load(data) do
+ {:ok, data}
+ end
+end
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 466beb724..e0b22a314 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -115,16 +115,6 @@ defmodule Pleroma.Web.CommonAPI do
end
end
- # def favorite(id_or_ap_id, user) do
- # with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id),
- # object <- Object.normalize(activity),
- # nil <- Utils.get_existing_like(user.ap_id, object) do
- # ActivityPub.like(user, object)
- # else
- # _ -> {:error, dgettext("errors", "Could not favorite")}
- # end
- # end
-
def unfavorite(id_or_ap_id, user) do
with %Activity{} = activity <- get_by_id_or_ap_id(id_or_ap_id) do
object = Object.normalize(activity)