aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma
diff options
context:
space:
mode:
authorLain Soykaf <lain@soykaf.club>2021-01-28 09:33:30 +0100
committerLain Soykaf <lain@soykaf.club>2021-01-28 09:33:30 +0100
commitd18ba133b2db3d6af05cce191c5ea0c200b57346 (patch)
treeaac2e5fa108474fc8b2e369647075ab1a506b9b4 /lib/pleroma
parent633d0286b3cecc5140490b3a27e2732f98e012c5 (diff)
downloadpleroma-groups.tar.gz
Groups: Basic group validation.groups
Diffstat (limited to 'lib/pleroma')
-rw-r--r--lib/pleroma/group.ex11
-rw-r--r--lib/pleroma/user.ex4
-rw-r--r--lib/pleroma/web/activity_pub/builder.ex25
-rw-r--r--lib/pleroma/web/activity_pub/object_validator.ex11
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/group_validator.ex40
-rw-r--r--lib/pleroma/web/common_api.ex7
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),