Allow group members to access group drafts

Closes #843

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-11-13 18:43:44 +01:00
parent 6a63ece91f
commit 6d599441a9
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
5 changed files with 68 additions and 5 deletions

View file

@ -214,6 +214,9 @@ export const LOGGED_USER_DRAFTS = gql`
} }
beginsOn beginsOn
visibility visibility
attributedTo {
...ActorFragment
}
organizerActor { organizerActor {
...ActorFragment ...ActorFragment
} }

View file

@ -391,12 +391,15 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
} = params } = params
) )
when object_type in ["Person", "Group", "Application", "Service", "Organization"] do when object_type in ["Person", "Group", "Application", "Service", "Organization"] do
with {:ok, %Actor{suspended: false} = old_actor} <- with author_url <- Utils.get_actor(params),
{:ok, %Actor{suspended: false} = author} <-
ActivityPubActor.get_or_fetch_actor_by_url(author_url),
{:ok, %Actor{suspended: false} = old_actor} <-
ActivityPubActor.get_or_fetch_actor_by_url(object["id"]), ActivityPubActor.get_or_fetch_actor_by_url(object["id"]),
object_data <- object_data <-
object |> Converter.Actor.as_to_model_data(), object |> Converter.Actor.as_to_model_data(),
{:ok, %Activity{} = activity, %Actor{} = new_actor} <- {:ok, %Activity{} = activity, %Actor{} = new_actor} <-
Actions.Update.update(old_actor, object_data, false) do Actions.Update.update(old_actor, object_data, false, %{updater_actor: author}) do
{:ok, activity, new_actor} {:ok, activity, new_actor}
else else
e -> e ->

View file

@ -43,18 +43,22 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
@spec update(Actor.t(), map, map) :: @spec update(Actor.t(), map, map) ::
{:ok, Actor.t(), ActivityStream.t()} | {:error, Ecto.Changeset.t()} {:ok, Actor.t(), ActivityStream.t()} | {:error, Ecto.Changeset.t()}
def update(%Actor{} = old_actor, args, additional) do def update(%Actor{} = old_actor, args, additional) do
updater_actor = Map.get(args, :updater_actor) || Map.get(additional, :updater_actor)
case Actors.update_actor(old_actor, args) do case Actors.update_actor(old_actor, args) do
{:ok, %Actor{} = new_actor} -> {:ok, %Actor{} = new_actor} ->
GroupActivity.insert_activity(new_actor, GroupActivity.insert_activity(new_actor,
subject: "group_updated", subject: "group_updated",
old_group: old_actor, old_group: old_actor,
updater_actor: Map.get(args, :updater_actor) updater_actor: updater_actor
) )
actor_as_data = Convertible.model_to_as(new_actor) actor_as_data = Convertible.model_to_as(new_actor)
Cachex.del(:activity_pub, "actor_#{new_actor.preferred_username}") Cachex.del(:activity_pub, "actor_#{new_actor.preferred_username}")
audience = Audience.get_audience(new_actor) audience = Audience.get_audience(new_actor)
additional = Map.merge(additional, %{"actor" => old_actor.url})
additional = Map.merge(additional, %{"actor" => (updater_actor || old_actor).url})
update_data = make_update_data(actor_as_data, Map.merge(audience, additional)) update_data = make_update_data(actor_as_data, Map.merge(audience, additional))
{:ok, new_actor, update_data} {:ok, new_actor, update_data}

View file

@ -129,7 +129,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
@spec permissions(Event.t()) :: Permission.t() @spec permissions(Event.t()) :: Permission.t()
def permissions(%Event{draft: draft, attributed_to_id: _attributed_to_id}) do def permissions(%Event{draft: draft, attributed_to_id: _attributed_to_id}) do
%Permission{ %Permission{
access: if(draft, do: nil, else: :member), access: if(draft, do: :moderator, else: :member),
create: :moderator, create: :moderator,
update: :moderator, update: :moderator,
delete: :moderator delete: :moderator

View file

@ -112,6 +112,9 @@ defmodule Mobilizon.Web.Resolvers.EventTest do
organizer_actor { organizer_actor {
id id
}, },
attributed_to {
id
},
online_address, online_address,
phone_address, phone_address,
category, category,
@ -320,6 +323,56 @@ defmodule Mobilizon.Web.Resolvers.EventTest do
assert res["data"]["person"]["participations"]["elements"] == [] assert res["data"]["person"]["participations"]["elements"] == []
end end
test "create_event/3 creates an event as a draft for a group", %{
conn: conn,
actor: actor,
user: user
} do
%Actor{id: group_id} = group = insert(:group)
insert(:member, parent: group, actor: actor, role: :moderator)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @create_event_mutation,
variables: %{
title: "come to my event",
description: "it will be fine",
begins_on: "#{DateTime.utc_now()}",
organizer_actor_id: "#{actor.id}",
attributed_to_id: group_id,
draft: true
}
)
assert res["data"]["createEvent"]["title"] == "come to my event"
assert res["data"]["createEvent"]["draft"] == true
assert res["data"]["createEvent"]["attributed_to"]["id"] == to_string(group_id)
event_uuid = res["data"]["createEvent"]["uuid"]
event_id = res["data"]["createEvent"]["id"]
refute_enqueued(
worker: Workers.BuildSearch,
args: %{event_id: String.to_integer(event_id), op: :insert_search_event}
)
res =
conn
|> AbsintheHelpers.graphql_query(query: @find_event_query, variables: %{uuid: event_uuid})
assert hd(res["errors"])["message"] =~ "not found"
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(query: @find_event_query, variables: %{uuid: event_uuid})
assert res["errors"] == nil
assert res["data"]["event"]["draft"] == true
end
test "create_event/3 creates an event with options", %{conn: conn, actor: actor, user: user} do test "create_event/3 creates an event with options", %{conn: conn, actor: actor, user: user} do
begins_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601() begins_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
ends_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601() ends_on = DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()