validator renaming & add validation for target
This commit is contained in:
parent
17f28c0507
commit
ff612750b1
|
@ -17,6 +17,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
||||||
alias Pleroma.Object.Containment
|
alias Pleroma.Object.Containment
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.AcceptRejectValidator
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectValidators.AddRemoveValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.AnnounceValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.AnswerValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNoteValidator
|
||||||
|
@ -30,7 +31,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.EventValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.EventValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.PinValidator
|
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator
|
||||||
alias Pleroma.Web.ActivityPub.ObjectValidators.UpdateValidator
|
alias Pleroma.Web.ActivityPub.ObjectValidators.UpdateValidator
|
||||||
|
@ -238,7 +238,7 @@ def validate(%{"type" => "Announce"} = object, meta) do
|
||||||
def validate(%{"type" => type} = object, meta) when type in ~w(Add Remove) do
|
def validate(%{"type" => type} = object, meta) when type in ~w(Add Remove) do
|
||||||
with {:ok, object} <-
|
with {:ok, object} <-
|
||||||
object
|
object
|
||||||
|> PinValidator.cast_and_validate()
|
|> AddRemoveValidator.cast_and_validate()
|
||||||
|> Ecto.Changeset.apply_action(:insert) do
|
|> Ecto.Changeset.apply_action(:insert) do
|
||||||
object = stringify_keys(object)
|
object = stringify_keys(object)
|
||||||
{:ok, object, meta}
|
{:ok, object, meta}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.PinValidator do
|
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AddRemoveValidator do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
@ -37,6 +37,17 @@ defp validate_data(changeset) do
|
||||||
|> validate_required([:id, :target, :object, :actor, :type, :to, :cc])
|
|> validate_required([:id, :target, :object, :actor, :type, :to, :cc])
|
||||||
|> validate_inclusion(:type, ~w(Add Remove))
|
|> validate_inclusion(:type, ~w(Add Remove))
|
||||||
|> validate_actor_presence()
|
|> validate_actor_presence()
|
||||||
|
|> validate_collection_belongs_to_actor()
|
||||||
|> validate_object_presence()
|
|> validate_object_presence()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp validate_collection_belongs_to_actor(changeset) do
|
||||||
|
validate_change(changeset, :target, fn :target, target ->
|
||||||
|
if String.starts_with?(target, changeset.changes[:actor]) do
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
[target: "collection doesn't belong to actor"]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations do
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
|
@spec validate_any_presence(Ecto.Changeset.t(), [atom()]) :: Ecto.Changeset.t()
|
||||||
def validate_any_presence(cng, fields) do
|
def validate_any_presence(cng, fields) do
|
||||||
non_empty =
|
non_empty =
|
||||||
fields
|
fields
|
||||||
|
@ -29,6 +30,7 @@ def validate_any_presence(cng, fields) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec validate_actor_presence(Ecto.Changeset.t(), keyword()) :: Ecto.Changeset.t()
|
||||||
def validate_actor_presence(cng, options \\ []) do
|
def validate_actor_presence(cng, options \\ []) do
|
||||||
field_name = Keyword.get(options, :field_name, :actor)
|
field_name = Keyword.get(options, :field_name, :actor)
|
||||||
|
|
||||||
|
@ -47,6 +49,7 @@ def validate_actor_presence(cng, options \\ []) do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec validate_object_presence(Ecto.Changeset.t(), keyword()) :: Ecto.Changeset.t()
|
||||||
def validate_object_presence(cng, options \\ []) do
|
def validate_object_presence(cng, options \\ []) do
|
||||||
field_name = Keyword.get(options, :field_name, :object)
|
field_name = Keyword.get(options, :field_name, :object)
|
||||||
allowed_types = Keyword.get(options, :allowed_types, false)
|
allowed_types = Keyword.get(options, :allowed_types, false)
|
||||||
|
@ -68,6 +71,7 @@ def validate_object_presence(cng, options \\ []) do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec validate_object_or_user_presence(Ecto.Changeset.t(), keyword()) :: Ecto.Changeset.t()
|
||||||
def validate_object_or_user_presence(cng, options \\ []) do
|
def validate_object_or_user_presence(cng, options \\ []) do
|
||||||
field_name = Keyword.get(options, :field_name, :object)
|
field_name = Keyword.get(options, :field_name, :object)
|
||||||
options = Keyword.put(options, :field_name, field_name)
|
options = Keyword.put(options, :field_name, field_name)
|
||||||
|
@ -83,6 +87,7 @@ def validate_object_or_user_presence(cng, options \\ []) do
|
||||||
if actor_cng.valid?, do: actor_cng, else: object_cng
|
if actor_cng.valid?, do: actor_cng, else: object_cng
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec validate_host_match(Ecto.Changeset.t(), [atom()]) :: Ecto.Changeset.t()
|
||||||
def validate_host_match(cng, fields \\ [:id, :actor]) do
|
def validate_host_match(cng, fields \\ [:id, :actor]) do
|
||||||
if same_domain?(cng, fields) do
|
if same_domain?(cng, fields) do
|
||||||
cng
|
cng
|
||||||
|
@ -95,6 +100,7 @@ def validate_host_match(cng, fields \\ [:id, :actor]) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec validate_fields_match(Ecto.Changeset.t(), [atom()]) :: Ecto.Changeset.t()
|
||||||
def validate_fields_match(cng, fields) do
|
def validate_fields_match(cng, fields) do
|
||||||
if map_unique?(cng, fields) do
|
if map_unique?(cng, fields) do
|
||||||
cng
|
cng
|
||||||
|
@ -122,12 +128,14 @@ defp map_unique?(cng, fields, func \\ & &1) do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec same_domain?(Ecto.Changeset.t(), [atom()]) :: boolean()
|
||||||
def same_domain?(cng, fields \\ [:actor, :object]) do
|
def same_domain?(cng, fields \\ [:actor, :object]) do
|
||||||
map_unique?(cng, fields, fn value -> URI.parse(value).host end)
|
map_unique?(cng, fields, fn value -> URI.parse(value).host end)
|
||||||
end
|
end
|
||||||
|
|
||||||
# This figures out if a user is able to create, delete or modify something
|
# This figures out if a user is able to create, delete or modify something
|
||||||
# based on the domain and superuser status
|
# based on the domain and superuser status
|
||||||
|
@spec validate_modification_rights(Ecto.Changeset.t()) :: Ecto.Changeset.t()
|
||||||
def validate_modification_rights(cng) do
|
def validate_modification_rights(cng) do
|
||||||
actor = User.get_cached_by_ap_id(get_field(cng, :actor))
|
actor = User.get_cached_by_ap_id(get_field(cng, :actor))
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,7 @@ test "it accepts Add/Remove activities" do
|
||||||
"id" => "http://localhost:400/objects/d61d6733-e256-4fe1-ab13-1e369789423d",
|
"id" => "http://localhost:400/objects/d61d6733-e256-4fe1-ab13-1e369789423d",
|
||||||
"actor" => actor,
|
"actor" => actor,
|
||||||
"object" => object_url,
|
"object" => object_url,
|
||||||
"target" => "http://example.com/users/lain/collections/featured",
|
"target" => "https://example.com/users/lain/collections/featured",
|
||||||
"type" => "Remove",
|
"type" => "Remove",
|
||||||
"to" => [Pleroma.Constants.as_public()],
|
"to" => [Pleroma.Constants.as_public()],
|
||||||
"cc" => ["https://example.com/users/lain/followers"]
|
"cc" => ["https://example.com/users/lain/followers"]
|
||||||
|
|
|
@ -1209,15 +1209,15 @@ test "returns 404 error for a wrong id", %{conn: conn} do
|
||||||
setup do: clear_config([:instance, :max_pinned_statuses], 1)
|
setup do: clear_config([:instance, :max_pinned_statuses], 1)
|
||||||
|
|
||||||
test "pin status", %{conn: conn, user: user, activity: activity} do
|
test "pin status", %{conn: conn, user: user, activity: activity} do
|
||||||
id_str = to_string(activity.id)
|
id = activity.id
|
||||||
|
|
||||||
assert %{"id" => ^id_str, "pinned" => true} =
|
assert %{"id" => ^id, "pinned" => true} =
|
||||||
conn
|
conn
|
||||||
|> put_req_header("content-type", "application/json")
|
|> put_req_header("content-type", "application/json")
|
||||||
|> post("/api/v1/statuses/#{activity.id}/pin")
|
|> post("/api/v1/statuses/#{activity.id}/pin")
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
||||||
assert [%{"id" => ^id_str, "pinned" => true}] =
|
assert [%{"id" => ^id, "pinned" => true}] =
|
||||||
conn
|
conn
|
||||||
|> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
|
|> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
|
||||||
|> json_response_and_validate_schema(200)
|
|> json_response_and_validate_schema(200)
|
||||||
|
|
|
@ -924,7 +924,8 @@ def get("https://mastodon.social/users/lambadalambda/collections/featured", _, _
|
||||||
body:
|
body:
|
||||||
File.read!("test/fixtures/users_mock/masto_featured.json")
|
File.read!("test/fixtures/users_mock/masto_featured.json")
|
||||||
|> String.replace("{{domain}}", "mastodon.social")
|
|> String.replace("{{domain}}", "mastodon.social")
|
||||||
|> String.replace("{{nickname}}", "lambadalambda")
|
|> String.replace("{{nickname}}", "lambadalambda"),
|
||||||
|
headers: activitypub_object_headers()
|
||||||
}}
|
}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue