diff options
author | Lain Soykaf <lain@soykaf.club> | 2021-01-28 09:33:30 +0100 |
---|---|---|
committer | Lain Soykaf <lain@soykaf.club> | 2021-01-28 09:33:30 +0100 |
commit | d18ba133b2db3d6af05cce191c5ea0c200b57346 (patch) | |
tree | aac2e5fa108474fc8b2e369647075ab1a506b9b4 /lib/pleroma | |
parent | 633d0286b3cecc5140490b3a27e2732f98e012c5 (diff) | |
download | pleroma-groups.tar.gz |
Groups: Basic group validation.groups
Diffstat (limited to 'lib/pleroma')
-rw-r--r-- | lib/pleroma/group.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 4 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/builder.ex | 25 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/object_validator.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/object_validators/group_validator.ex | 40 | ||||
-rw-r--r-- | lib/pleroma/web/common_api.ex | 7 |
6 files changed, 98 insertions, 0 deletions
diff --git a/lib/pleroma/group.ex b/lib/pleroma/group.ex index 732791ec2..880cd52c6 100644 --- a/lib/pleroma/group.ex +++ b/lib/pleroma/group.ex @@ -92,4 +92,15 @@ defmodule Pleroma.Group do {:ok, group} end end + + @spec get_for_object(map()) :: t() | nil + def get_for_object(%{"type" => "Group", "id" => id}) do + with %User{} = user <- User.get_cached_by_ap_id(id), + group <- Repo.preload(user, :group).group do + group + end + end + + def get_for_object(%{"type" => "Create", "object" => object}), do: get_for_object(object) + def get_for_object(_), do: nil end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 1e5c87403..5d9016e96 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -18,6 +18,7 @@ defmodule Pleroma.User do alias Pleroma.Emoji alias Pleroma.FollowingRelationship alias Pleroma.Formatter + alias Pleroma.Group alias Pleroma.HTML alias Pleroma.Keys alias Pleroma.MFA @@ -209,6 +210,9 @@ defmodule Pleroma.User do on_replace: :delete ) + # Some `users` are actually groups. In this case, they can have a corresponding `Group` + has_one(:group, Group) + timestamps() end diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex index f56bfc600..08f017a51 100644 --- a/lib/pleroma/web/activity_pub/builder.ex +++ b/lib/pleroma/web/activity_pub/builder.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Web.ActivityPub.Builder do alias Pleroma.Emoji alias Pleroma.Object alias Pleroma.User + alias Pleroma.Web alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Visibility @@ -105,6 +106,30 @@ defmodule Pleroma.Web.ActivityPub.Builder do }, []} end + def group(owner, name \\ nil, description \\ nil) do + id = Ecto.UUID.generate() + ap_id = "#{Web.base_url()}/groups/#{id}" + + {:ok, + %{ + "id" => ap_id, + "type" => "Group", + "name" => name, + "summary" => description, + "following" => "#{ap_id}/following", + "followers" => "#{ap_id}/followers", + "members" => "#{ap_id}/members", + # attributedTo? owner? admin? + "attributedTo" => owner.ap_id + }, []} + end + + def create_group(owner, params \\ %{}) do + with {:ok, group, _} <- group(owner, params[:name], params[:description]) do + create(owner, group, []) + end + end + def create(actor, object, recipients) do context = if is_map(object) do diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index 297c19cc0..264ae5831 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -29,6 +29,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do alias Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator alias Pleroma.Web.ActivityPub.ObjectValidators.EventValidator alias Pleroma.Web.ActivityPub.ObjectValidators.FollowValidator + alias Pleroma.Web.ActivityPub.ObjectValidators.GroupValidator alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator alias Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator @@ -37,6 +38,16 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do @impl true def validate(object, meta) + def validate(%{"type" => "Group"} = object, meta) do + with {:ok, object} <- + object + |> GroupValidator.cast_and_validate() + |> Ecto.Changeset.apply_action(:insert) do + object = stringify_keys(object) + {:ok, object, meta} + end + end + def validate(%{"type" => type} = object, meta) when type in ~w[Accept Reject] do with {:ok, object} <- diff --git a/lib/pleroma/web/activity_pub/object_validators/group_validator.ex b/lib/pleroma/web/activity_pub/object_validators/group_validator.ex new file mode 100644 index 000000000..cf7ae36c5 --- /dev/null +++ b/lib/pleroma/web/activity_pub/object_validators/group_validator.ex @@ -0,0 +1,40 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.ObjectValidators.GroupValidator do + use Ecto.Schema + + alias Pleroma.EctoType.ActivityPub.ObjectValidators + + import Ecto.Changeset + + @primary_key false + + embedded_schema do + field(:id, ObjectValidators.ObjectID, primary_key: true) + field(:type, :string) + end + + def cast_and_validate(data) do + data + |> cast_data() + |> validate_data() + end + + def cast_data(data) do + %__MODULE__{} + |> changeset(data) + end + + def changeset(struct, data) do + struct + |> cast(data, __schema__(:fields)) + end + + def validate_data(data_cng) do + data_cng + |> validate_inclusion(:type, ["Group"]) + |> validate_required([:id]) + end +end diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex index b003e30c7..400fe00c9 100644 --- a/lib/pleroma/web/common_api.ex +++ b/lib/pleroma/web/common_api.ex @@ -30,6 +30,13 @@ defmodule Pleroma.Web.CommonAPI do end end + def create_group(user, params) do + with {:ok, group_data, _} <- Builder.create_group(user, params), + {:ok, group, _} <- Pipeline.common_pipeline(group_data, local: true) do + {:ok, group} + end + end + def post_chat_message(%User{} = user, %User{} = recipient, content, opts \\ []) do with maybe_attachment <- opts[:media_id] && Object.get_by_id(opts[:media_id]), :ok <- validate_chat_content_length(content, !!maybe_attachment), |