Introduce the group activity section

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2021-02-24 19:06:48 +01:00
parent d0567f783d
commit 3fe64a4389
70 changed files with 3224 additions and 70 deletions

View File

@@ -459,6 +459,7 @@ defmodule Mobilizon.Federation.ActivityPub do
Map.get(additional, :force_member_removal, false) ||
!Actors.is_only_administrator?(member_id, group_id)},
{:delete, {:ok, %Member{} = member}} <- {:delete, Actors.delete_member(member)},
Mobilizon.Service.Activity.Member.insert_activity(member, subject: "member_quit"),
leave_data <- %{
"to" => [group_members_url],
"cc" => [group_url],
@@ -477,12 +478,17 @@ defmodule Mobilizon.Federation.ActivityPub do
def remove(
%Member{} = member,
%Actor{type: :Group, url: group_url, members_url: group_members_url},
%Actor{url: moderator_url},
%Actor{url: moderator_url} = moderator,
local,
_additional \\ %{}
) do
with {:ok, %Member{id: member_id}} <- Actors.update_member(member, %{role: :rejected}),
%Member{} = member <- Actors.get_member(member_id),
{:ok, _} <-
Mobilizon.Service.Activity.Member.insert_activity(member,
moderator: moderator,
subject: "member_removed"
),
:ok <- Group.send_notification_to_removed_member(member),
remove_data <- %{
"to" => [group_members_url],
@@ -518,6 +524,11 @@ defmodule Mobilizon.Federation.ActivityPub do
invited_by_id: actor_id,
url: Map.get(additional, :url)
}),
{:ok, _} <-
Mobilizon.Service.Activity.Member.insert_activity(member,
moderator: actor,
subject: "member_invited"
),
invite_data <- %{
"type" => "Invite",
"attributedTo" => group_url,
@@ -914,6 +925,10 @@ defmodule Mobilizon.Federation.ActivityPub do
defp accept_join(%Member{} = member, additional) do
with {:ok, %Member{} = member} <-
Actors.update_member(member, %{role: :member}),
{:ok, _} <-
Mobilizon.Service.Activity.Member.insert_activity(member,
subject: "member_approved"
),
_ <-
unless(is_nil(member.parent.domain),
do: Refresher.fetch_group(member.parent.url, member.actor)
@@ -949,6 +964,10 @@ defmodule Mobilizon.Federation.ActivityPub do
%Actor{url: actor_url} <- Actors.get_actor(actor_id),
{:ok, %Member{id: member_id} = member} <-
Actors.update_member(member, %{role: :member}),
{:ok, _} <-
Mobilizon.Service.Activity.Member.insert_activity(member,
subject: "member_accepted_invitation"
),
accept_data <- %{
"type" => "Accept",
"attributedTo" => member.parent.url,
@@ -1029,6 +1048,9 @@ defmodule Mobilizon.Federation.ActivityPub do
%Actor{url: actor_url} <- Actors.get_actor(actor_id),
{:ok, %Member{url: member_url, id: member_id} = member} <-
Actors.delete_member(member),
Mobilizon.Service.Activity.Member.insert_activity(member,
subject: "member_rejected_invitation"
),
accept_data <- %{
"type" => "Reject",
"actor" => actor_url,

View File

@@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
alias Mobilizon.Federation.ActivityPub.Types.Entity
alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
alias Mobilizon.Service.Activity.Group, as: GroupActivity
alias Mobilizon.Service.Formatter.HTML
alias Mobilizon.Service.Notifications.Scheduler
alias Mobilizon.Web.Email.Follow, as: FollowMailer
@@ -20,6 +21,11 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
def create(args, additional) do
with args <- prepare_args_for_actor(args),
{:ok, %Actor{} = actor} <- Actors.create_actor(args),
{:ok, _} <-
GroupActivity.insert_activity(actor,
subject: "group_created",
actor_id: args.creator_actor_id
),
actor_as_data <- Convertible.model_to_as(actor),
audience <- %{"to" => ["https://www.w3.org/ns/activitystreams#Public"], "cc" => []},
create_data <-
@@ -32,6 +38,12 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
@spec update(Actor.t(), map, map) :: {:ok, Actor.t(), Activity.t()} | any
def update(%Actor{} = old_actor, args, additional) do
with {:ok, %Actor{} = new_actor} <- Actors.update_actor(old_actor, args),
{:ok, _} <-
GroupActivity.insert_activity(new_actor,
subject: "group_updated",
old_group: old_actor,
updater_actor: Map.get(args, :updater_actor)
),
actor_as_data <- Convertible.model_to_as(new_actor),
{:ok, true} <- Cachex.del(:activity_pub, "actor_#{new_actor.preferred_username}"),
audience <-
@@ -112,6 +124,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
|> Map.get(:metadata, %{})
|> Map.update(:message, nil, &String.trim(HTML.strip_tags(&1)))
}),
{:ok, _} <-
Mobilizon.Service.Activity.Member.insert_activity(member, subject: "member_joined"),
Absinthe.Subscription.publish(Endpoint, actor, group_membership_changed: actor.id),
join_data <- %{
"type" => "Join",

View File

@@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
alias Mobilizon.Federation.ActivityPub.Audience
alias Mobilizon.Federation.ActivityPub.Types.Entity
alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.Service.Activity.Discussion, as: DiscussionActivity
alias Mobilizon.Web.Endpoint
import Mobilizon.Federation.ActivityPub.Utils, only: [make_create_data: 2, make_update_data: 2]
require Logger
@@ -19,6 +20,11 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
with %Discussion{} = discussion <- Discussions.get_discussion(discussion_id),
{:ok, %Discussion{last_comment_id: last_comment_id} = discussion} <-
Discussions.reply_to_discussion(discussion, args),
{:ok, _} <-
DiscussionActivity.insert_activity(discussion,
subject: "discussion_replied",
actor_id: Map.get(args, :creator_id, args.actor_id)
),
%Comment{} = last_comment <- Discussions.get_comment_with_preload(last_comment_id),
:ok <- maybe_publish_graphql_subscription(discussion),
comment_as_data <- Convertible.model_to_as(last_comment),
@@ -35,6 +41,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
def create(args, additional) do
with {:ok, %Discussion{} = discussion} <-
Discussions.create_discussion(args),
{:ok, _} <-
DiscussionActivity.insert_activity(discussion, subject: "discussion_created"),
discussion_as_data <- Convertible.model_to_as(discussion),
audience <-
Audience.calculate_to_and_cc_from_mentions(discussion),
@@ -49,6 +57,11 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
def update(%Discussion{} = old_discussion, args, additional) do
with {:ok, %Discussion{} = new_discussion} <-
Discussions.update_discussion(old_discussion, args),
{:ok, _} <-
DiscussionActivity.insert_activity(new_discussion,
subject: "discussion_renamed",
old_discussion: old_discussion
),
{:ok, true} <- Cachex.del(:activity_pub, "discussion_#{new_discussion.slug}"),
discussion_as_data <- Convertible.model_to_as(new_discussion),
audience <-
@@ -71,7 +84,12 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
_local,
_additionnal
) do
with {:ok, _} <- Discussions.delete_discussion(discussion) do
with {:ok, _} <- Discussions.delete_discussion(discussion),
{:ok, _} <-
DiscussionActivity.insert_activity(discussion,
subject: "discussion_deleted",
moderator: actor
) do
# This is just fake
activity_data = %{
"type" => "Delete",

View File

@@ -10,6 +10,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
alias Mobilizon.Service.Activity.Event, as: EventActivity
alias Mobilizon.Service.Formatter.HTML
alias Mobilizon.Service.Notifications.Scheduler
alias Mobilizon.Share
@@ -24,6 +25,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
def create(args, additional) do
with args <- prepare_args_for_event(args),
{:ok, %Event{} = event} <- EventsManager.create_event(args),
{:ok, _} <-
EventActivity.insert_activity(event, subject: "event_created"),
event_as_data <- Convertible.model_to_as(event),
audience <-
Audience.calculate_to_and_cc_from_mentions(event),
@@ -38,6 +41,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
def update(%Event{} = old_event, args, additional) do
with args <- prepare_args_for_event(args),
{:ok, %Event{} = new_event} <- EventsManager.update_event(old_event, args),
{:ok, _} <-
EventActivity.insert_activity(new_event, subject: "event_updated"),
{:ok, true} <- Cachex.del(:activity_pub, "event_#{new_event.uuid}"),
event_as_data <- Convertible.model_to_as(new_event),
audience <-
@@ -66,6 +71,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
with audience <-
Audience.calculate_to_and_cc_from_mentions(event),
{:ok, %Event{} = event} <- EventsManager.delete_event(event),
{:ok, _} <-
EventActivity.insert_activity(event, subject: "event_deleted"),
{:ok, true} <- Cachex.del(:activity_pub, "event_#{event.uuid}"),
{:ok, %Tombstone{} = _tombstone} <-
Tombstone.create_tombstone(%{uri: event.url, actor_id: actor.id}) do

View File

@@ -4,13 +4,14 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Members do
alias Mobilizon.Actors.{Actor, Member}
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.Service.Activity.Member, as: MemberActivity
require Logger
import Mobilizon.Federation.ActivityPub.Utils, only: [make_update_data: 2]
def update(
%Member{parent: %Actor{id: group_id}, id: member_id, role: current_role} = member,
%Member{parent: %Actor{id: group_id}, id: member_id, role: current_role} = old_member,
%{role: updated_role} = args,
%{moderator: %Actor{url: moderator_url, id: moderator_id}} = additional
%{moderator: %Actor{url: moderator_url, id: moderator_id} = moderator} = additional
) do
with additional <- Map.delete(additional, :moderator),
{:has_rights_to_update_role, {:ok, %Member{role: moderator_role}}}
@@ -19,7 +20,13 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Members do
{:is_only_admin, false} <-
{:is_only_admin, check_admins_left(member_id, group_id, current_role, updated_role)},
{:ok, %Member{} = member} <-
Actors.update_member(member, args),
Actors.update_member(old_member, args),
{:ok, _} <-
MemberActivity.insert_activity(member,
old_member: old_member,
moderator: moderator,
subject: "member_updated"
),
{:ok, true} <- Cachex.del(:activity_pub, "member_#{member_id}"),
member_as_data <-
Convertible.model_to_as(member),

View File

@@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.Posts.Post
alias Mobilizon.Service.Activity.Post, as: PostsActivity
require Logger
import Mobilizon.Federation.ActivityPub.Utils, only: [make_create_data: 2, make_update_data: 2]
@@ -19,6 +20,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
with args <- Map.update(args, :tags, [], &ConverterUtils.fetch_tags/1),
{:ok, %Post{attributed_to_id: group_id, author_id: creator_id} = post} <-
Posts.create_post(args),
{:ok, _} <- PostsActivity.insert_activity(post, subject: "post_created"),
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
%Actor{} = creator <- Actors.get_actor(creator_id),
post_as_data <-
@@ -40,6 +42,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
with args <- Map.update(args, :tags, [], &ConverterUtils.fetch_tags/1),
{:ok, %Post{attributed_to_id: group_id, author_id: creator_id} = post} <-
Posts.update_post(post, args),
{:ok, _} <- PostsActivity.insert_activity(post, subject: "post_updated"),
{:ok, true} <- Cachex.del(:activity_pub, "post_#{post.slug}"),
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
%Actor{} = creator <- Actors.get_actor(creator_id),
@@ -76,6 +79,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
}
with {:ok, %Post{} = post} <- Posts.delete_post(post),
{:ok, _} <- PostsActivity.insert_activity(post, subject: "post_deleted"),
{:ok, true} <- Cachex.del(:activity_pub, "post_#{post.slug}"),
{:ok, %Tombstone{} = _tombstone} <-
Tombstone.create_tombstone(%{uri: post.url, actor_id: actor.id}) do

View File

@@ -5,6 +5,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
alias Mobilizon.Federation.ActivityPub.Types.Entity
alias Mobilizon.Federation.ActivityStream.Convertible
alias Mobilizon.Resources.Resource
alias Mobilizon.Service.Activity.Resource, as: ResourceActivity
alias Mobilizon.Service.RichMedia.Parser
require Logger
@@ -33,6 +34,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
with {:ok,
%Resource{actor_id: group_id, creator_id: creator_id, parent_id: parent_id} = resource} <-
Resources.create_resource(args),
{:ok, _} <- ResourceActivity.insert_activity(resource, subject: "resource_created"),
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
%Actor{url: creator_url} = creator <- Actors.get_actor(creator_id),
resource_as_data <-
@@ -63,7 +65,12 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
end
@impl Entity
def update(%Resource{} = old_resource, %{parent_id: _parent_id} = args, additional) do
def update(
%Resource{parent_id: old_parent_id} = old_resource,
%{parent_id: parent_id} = args,
additional
)
when old_parent_id != parent_id do
move(old_resource, args, additional)
end
@@ -71,6 +78,11 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
def update(%Resource{} = old_resource, %{title: title} = _args, additional) do
with {:ok, %Resource{actor_id: group_id, creator_id: creator_id} = resource} <-
Resources.update_resource(old_resource, %{title: title}),
{:ok, _} <-
ResourceActivity.insert_activity(resource,
subject: "resource_renamed",
old_resource: old_resource
),
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
%Actor{url: creator_url} <- Actors.get_actor(creator_id),
resource_as_data <-
@@ -100,6 +112,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
%Resource{actor_id: group_id, creator_id: creator_id, parent_id: new_parent_id} =
resource} <-
Resources.update_resource(old_resource, args),
{:ok, _} <- ResourceActivity.insert_activity(resource, subject: "resource_moved"),
old_parent <- Resources.get_resource(old_parent_id),
new_parent <- Resources.get_resource(new_parent_id),
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
@@ -146,6 +159,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
}
with {:ok, _resource} <- Resources.delete_resource(resource),
{:ok, _} <- ResourceActivity.insert_activity(resource, subject: "resource_deleted"),
{:ok, true} <- Cachex.del(:activity_pub, "resource_#{resource.id}") do
{:ok, activity_data, actor, resource}
end