forked from potsda.mn/mobilizon
Refactor Mobilizon.Federation.ActivityPub.Permission to handle
permissions Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
1ceb976f4e
commit
20ff0a7f6c
|
@ -8,12 +8,42 @@ defmodule Mobilizon.Federation.ActivityPub.Permission do
|
|||
alias Mobilizon.Federation.ActivityPub.Types.{Entity, Ownable}
|
||||
require Logger
|
||||
|
||||
use StructAccess
|
||||
defstruct [:access, :create, :update, :delete]
|
||||
|
||||
@member_roles [:member, :moderator, :administrator]
|
||||
|
||||
@doc """
|
||||
Check that actor can access the object
|
||||
"""
|
||||
@spec can_access_group_object?(Actor.t(), Entity.t()) :: boolean()
|
||||
def can_access_group_object?(%Actor{} = actor, object) do
|
||||
can_manage_group_object?(:role_needed_to_access, actor, object)
|
||||
can_manage_group_object?(:access, actor, object)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Check that actor can create such an object
|
||||
"""
|
||||
@spec can_create_group_object?(String.t() | integer(), String.t() | integer(), Entity.t()) ::
|
||||
boolean()
|
||||
def can_create_group_object?(
|
||||
actor_id,
|
||||
group_id,
|
||||
object
|
||||
) do
|
||||
case object |> Ownable.permissions() |> get_in([:create]) do
|
||||
:member ->
|
||||
Actors.is_member?(actor_id, group_id)
|
||||
|
||||
:moderator ->
|
||||
Actors.is_moderator?(actor_id, group_id)
|
||||
|
||||
:administrator ->
|
||||
Actors.is_administrator?(actor_id, group_id)
|
||||
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -21,7 +51,7 @@ defmodule Mobilizon.Federation.ActivityPub.Permission do
|
|||
"""
|
||||
@spec can_update_group_object?(Actor.t(), Entity.t()) :: boolean()
|
||||
def can_update_group_object?(%Actor{} = actor, object) do
|
||||
can_manage_group_object?(:role_needed_to_update, actor, object)
|
||||
can_manage_group_object?(:update, actor, object)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -29,29 +59,31 @@ defmodule Mobilizon.Federation.ActivityPub.Permission do
|
|||
"""
|
||||
@spec can_delete_group_object?(Actor.t(), Entity.t()) :: boolean()
|
||||
def can_delete_group_object?(%Actor{} = actor, object) do
|
||||
can_manage_group_object?(:role_needed_to_delete, actor, object)
|
||||
can_manage_group_object?(:delete, actor, object)
|
||||
end
|
||||
|
||||
@type existing_object_permissions :: :access | :update | :delete
|
||||
|
||||
@spec can_manage_group_object?(
|
||||
:role_needed_to_access | :role_needed_to_update | :role_needed_to_delete,
|
||||
existing_object_permissions(),
|
||||
Actor.t(),
|
||||
any()
|
||||
) :: boolean()
|
||||
defp can_manage_group_object?(action_function, %Actor{url: actor_url} = actor, object) do
|
||||
defp can_manage_group_object?(permission, %Actor{url: actor_url} = actor, object) do
|
||||
if Ownable.group_actor(object) != nil do
|
||||
case apply(Ownable, action_function, [object]) do
|
||||
role when role in [:member, :moderator, :administrator] ->
|
||||
case object |> Ownable.permissions() |> get_in([permission]) do
|
||||
role when role in @member_roles ->
|
||||
activity_actor_is_group_member?(actor, object, role)
|
||||
|
||||
_ ->
|
||||
case action_function do
|
||||
:role_needed_to_access ->
|
||||
case permission do
|
||||
:access ->
|
||||
Logger.warn("Actor #{actor_url} can't access #{object.url}")
|
||||
|
||||
:role_needed_to_update ->
|
||||
:update ->
|
||||
Logger.warn("Actor #{actor_url} can't update #{object.url}")
|
||||
|
||||
:role_needed_to_delete ->
|
||||
:delete ->
|
||||
Logger.warn("Actor #{actor_url} can't delete #{object.url}")
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
|
|||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Follower, Member}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.{Audience, Relay}
|
||||
alias Mobilizon.Federation.ActivityPub.{Audience, Permission, Relay}
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
|
||||
|
@ -104,9 +104,14 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
|
|||
|
||||
def group_actor(%Actor{} = actor), do: actor
|
||||
|
||||
def role_needed_to_access(%Actor{} = _group), do: :member
|
||||
def role_needed_to_update(%Actor{} = _group), do: :administrator
|
||||
def role_needed_to_delete(%Actor{} = _group), do: :administrator
|
||||
def permissions(%Actor{} = _group) do
|
||||
%Permission{
|
||||
access: :member,
|
||||
create: nil,
|
||||
update: :administrator,
|
||||
delete: :administrator
|
||||
}
|
||||
end
|
||||
|
||||
@spec join(Actor.t(), Actor.t(), boolean(), map()) :: {:ok, map(), Member.t()}
|
||||
def join(%Actor{type: :Group} = group, %Actor{} = actor, _local, additional) do
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
|||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Events.{Event, EventOptions}
|
||||
alias Mobilizon.Federation.ActivityPub.Audience
|
||||
alias Mobilizon.Federation.ActivityPub.{Audience, Permission}
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
|
@ -104,9 +104,13 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
|||
|
||||
def group_actor(_), do: nil
|
||||
|
||||
def role_needed_to_access(%Comment{}), do: :member
|
||||
def role_needed_to_update(%Comment{attributed_to: %Actor{} = _group}), do: :administrator
|
||||
def role_needed_to_delete(%Comment{attributed_to_id: _attributed_to_id}), do: :administrator
|
||||
def permissions(%Comment{}),
|
||||
do: %Permission{
|
||||
access: :member,
|
||||
create: :member,
|
||||
update: :administrator,
|
||||
delete: :administrator
|
||||
}
|
||||
|
||||
# Prepare and sanitize arguments for comments
|
||||
defp prepare_args_for_comment(args) do
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
|
|||
alias Mobilizon.{Actors, Discussions}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Federation.ActivityPub.Audience
|
||||
alias Mobilizon.Federation.ActivityPub.{Audience, Permission}
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
|
||||
|
@ -110,9 +110,9 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
|
|||
|
||||
def group_actor(%Discussion{actor_id: actor_id}), do: Actors.get_actor(actor_id)
|
||||
|
||||
def role_needed_to_access(%Discussion{}), do: :member
|
||||
def role_needed_to_update(%Discussion{}), do: :moderator
|
||||
def role_needed_to_delete(%Discussion{}), do: :moderator
|
||||
def permissions(%Discussion{}) do
|
||||
%Permission{access: :member, create: :member, update: :moderator, delete: :moderator}
|
||||
end
|
||||
|
||||
@spec maybe_publish_graphql_subscription(Discussion.t()) :: :ok
|
||||
defp maybe_publish_graphql_subscription(%Discussion{} = discussion) do
|
||||
|
|
|
@ -17,6 +17,7 @@ alias Mobilizon.Federation.ActivityPub.Types.{
|
|||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Federation.ActivityPub.Permission
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Resources.Resource
|
||||
alias Mobilizon.Todos.{Todo, TodoList}
|
||||
|
@ -67,14 +68,8 @@ defprotocol Mobilizon.Federation.ActivityPub.Types.Ownable do
|
|||
@doc "Returns the actor for the entity"
|
||||
def actor(entity)
|
||||
|
||||
@spec role_needed_to_access(Entity.t()) :: group_role()
|
||||
def role_needed_to_access(entity)
|
||||
|
||||
@spec role_needed_to_update(Entity.t()) :: group_role()
|
||||
def role_needed_to_update(entity)
|
||||
|
||||
@spec role_needed_to_delete(Entity.t()) :: group_role()
|
||||
def role_needed_to_delete(entity)
|
||||
@spec permissions(Entity.t()) :: Permission.t()
|
||||
def permissions(entity)
|
||||
end
|
||||
|
||||
defimpl Managable, for: Event do
|
||||
|
@ -85,9 +80,7 @@ end
|
|||
defimpl Ownable, for: Event do
|
||||
defdelegate group_actor(entity), to: Events
|
||||
defdelegate actor(entity), to: Events
|
||||
defdelegate role_needed_to_access(entity), to: Events
|
||||
defdelegate role_needed_to_update(entity), to: Events
|
||||
defdelegate role_needed_to_delete(entity), to: Events
|
||||
defdelegate permissions(entity), to: Events
|
||||
end
|
||||
|
||||
defimpl Managable, for: Comment do
|
||||
|
@ -98,9 +91,7 @@ end
|
|||
defimpl Ownable, for: Comment do
|
||||
defdelegate group_actor(entity), to: Comments
|
||||
defdelegate actor(entity), to: Comments
|
||||
defdelegate role_needed_to_access(entity), to: Comments
|
||||
defdelegate role_needed_to_update(entity), to: Comments
|
||||
defdelegate role_needed_to_delete(entity), to: Comments
|
||||
defdelegate permissions(entity), to: Comments
|
||||
end
|
||||
|
||||
defimpl Managable, for: Post do
|
||||
|
@ -111,9 +102,7 @@ end
|
|||
defimpl Ownable, for: Post do
|
||||
defdelegate group_actor(entity), to: Posts
|
||||
defdelegate actor(entity), to: Posts
|
||||
defdelegate role_needed_to_access(entity), to: Posts
|
||||
defdelegate role_needed_to_update(entity), to: Posts
|
||||
defdelegate role_needed_to_delete(entity), to: Posts
|
||||
defdelegate permissions(entity), to: Posts
|
||||
end
|
||||
|
||||
defimpl Managable, for: Actor do
|
||||
|
@ -124,9 +113,7 @@ end
|
|||
defimpl Ownable, for: Actor do
|
||||
defdelegate group_actor(entity), to: Actors
|
||||
defdelegate actor(entity), to: Actors
|
||||
defdelegate role_needed_to_access(entity), to: Actors
|
||||
defdelegate role_needed_to_update(entity), to: Actors
|
||||
defdelegate role_needed_to_delete(entity), to: Actors
|
||||
defdelegate permissions(entity), to: Actors
|
||||
end
|
||||
|
||||
defimpl Managable, for: TodoList do
|
||||
|
@ -137,9 +124,7 @@ end
|
|||
defimpl Ownable, for: TodoList do
|
||||
defdelegate group_actor(entity), to: TodoLists
|
||||
defdelegate actor(entity), to: TodoLists
|
||||
defdelegate role_needed_to_access(entity), to: TodoLists
|
||||
defdelegate role_needed_to_update(entity), to: TodoLists
|
||||
defdelegate role_needed_to_delete(entity), to: TodoLists
|
||||
defdelegate permissions(entity), to: TodoLists
|
||||
end
|
||||
|
||||
defimpl Managable, for: Todo do
|
||||
|
@ -150,9 +135,7 @@ end
|
|||
defimpl Ownable, for: Todo do
|
||||
defdelegate group_actor(entity), to: Todos
|
||||
defdelegate actor(entity), to: Todos
|
||||
defdelegate role_needed_to_access(entity), to: Todos
|
||||
defdelegate role_needed_to_update(entity), to: Todos
|
||||
defdelegate role_needed_to_delete(entity), to: Todos
|
||||
defdelegate permissions(entity), to: Todos
|
||||
end
|
||||
|
||||
defimpl Managable, for: Resource do
|
||||
|
@ -163,9 +146,7 @@ end
|
|||
defimpl Ownable, for: Resource do
|
||||
defdelegate group_actor(entity), to: Resources
|
||||
defdelegate actor(entity), to: Resources
|
||||
defdelegate role_needed_to_access(entity), to: Resources
|
||||
defdelegate role_needed_to_update(entity), to: Resources
|
||||
defdelegate role_needed_to_delete(entity), to: Resources
|
||||
defdelegate permissions(entity), to: Resources
|
||||
end
|
||||
|
||||
defimpl Managable, for: Discussion do
|
||||
|
@ -176,17 +157,13 @@ end
|
|||
defimpl Ownable, for: Discussion do
|
||||
defdelegate group_actor(entity), to: Discussions
|
||||
defdelegate actor(entity), to: Discussions
|
||||
defdelegate role_needed_to_access(entity), to: Discussions
|
||||
defdelegate role_needed_to_update(entity), to: Discussions
|
||||
defdelegate role_needed_to_delete(entity), to: Discussions
|
||||
defdelegate permissions(entity), to: Discussions
|
||||
end
|
||||
|
||||
defimpl Ownable, for: Tombstone do
|
||||
defdelegate group_actor(entity), to: Tombstones
|
||||
defdelegate actor(entity), to: Tombstones
|
||||
defdelegate role_needed_to_access(entity), to: Tombstones
|
||||
defdelegate role_needed_to_update(entity), to: Tombstones
|
||||
defdelegate role_needed_to_delete(entity), to: Tombstones
|
||||
defdelegate permissions(entity), to: Tombstones
|
||||
end
|
||||
|
||||
defimpl Managable, for: Member do
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
|||
alias Mobilizon.Events, as: EventsManager
|
||||
alias Mobilizon.Events.{Event, Participant}
|
||||
alias Mobilizon.Federation.ActivityPub
|
||||
alias Mobilizon.Federation.ActivityPub.Audience
|
||||
alias Mobilizon.Federation.ActivityPub.{Audience, Permission}
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
|
@ -95,11 +95,14 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
|||
|
||||
def group_actor(_), do: nil
|
||||
|
||||
def role_needed_to_access(%Event{draft: false}), do: :member
|
||||
def role_needed_to_access(%Event{}), do: :moderator
|
||||
def role_needed_to_update(%Event{attributed_to: %Actor{} = _group}), do: :moderator
|
||||
def role_needed_to_delete(%Event{attributed_to_id: _attributed_to_id}), do: :moderator
|
||||
def role_needed_to_delete(_), do: nil
|
||||
def permissions(%Event{draft: draft, attributed_to_id: _attributed_to_id}) do
|
||||
%Permission{
|
||||
access: if(draft, do: nil, else: :member),
|
||||
create: :moderator,
|
||||
update: :moderator,
|
||||
delete: :moderator
|
||||
}
|
||||
end
|
||||
|
||||
def join(%Event{} = event, %Actor{} = actor, _local, additional) do
|
||||
with {:maximum_attendee_capacity, true} <-
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
|
|||
@moduledoc false
|
||||
alias Mobilizon.{Actors, Posts, Tombstone}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub.Audience
|
||||
alias Mobilizon.Federation.ActivityPub.{Audience, Permission}
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
|
@ -91,8 +91,12 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
|
|||
def group_actor(%Post{attributed_to_id: attributed_to_id}),
|
||||
do: Actors.get_actor(attributed_to_id)
|
||||
|
||||
def role_needed_to_access(%Post{draft: false}), do: :member
|
||||
def role_needed_to_access(%Post{}), do: :moderator
|
||||
def role_needed_to_update(%Post{}), do: :moderator
|
||||
def role_needed_to_delete(%Post{}), do: :moderator
|
||||
def permissions(%Post{draft: draft}) do
|
||||
%Permission{
|
||||
access: if(draft, do: nil, else: :member),
|
||||
create: :moderator,
|
||||
update: :moderator,
|
||||
delete: :moderator
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
|
|||
@moduledoc false
|
||||
alias Mobilizon.{Actors, Resources}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub.Permission
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
alias Mobilizon.Resources.Resource
|
||||
|
@ -170,7 +171,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Resources do
|
|||
|
||||
def group_actor(%Resource{actor_id: actor_id}), do: Actors.get_actor(actor_id)
|
||||
|
||||
def role_needed_to_access(%Resource{}), do: :member
|
||||
def role_needed_to_update(%Resource{}), do: :member
|
||||
def role_needed_to_delete(%Resource{}), do: :member
|
||||
def permissions(%Resource{}) do
|
||||
%Permission{access: :member, create: :member, update: :member, delete: :member}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.TodoLists do
|
|||
@moduledoc false
|
||||
alias Mobilizon.{Actors, Todos}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub.Permission
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
|
@ -68,7 +69,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.TodoLists do
|
|||
|
||||
def group_actor(%TodoList{actor_id: actor_id}), do: Actors.get_actor(actor_id)
|
||||
|
||||
def role_needed_to_access(%TodoList{}), do: :member
|
||||
def role_needed_to_update(%TodoList{}), do: :member
|
||||
def role_needed_to_delete(%TodoList{}), do: :member
|
||||
def permissions(%TodoList{}) do
|
||||
%Permission{access: :member, create: :member, update: :member, delete: :member}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Todos do
|
|||
@moduledoc false
|
||||
alias Mobilizon.{Actors, Todos}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub.Permission
|
||||
alias Mobilizon.Federation.ActivityPub.Types.Entity
|
||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||
alias Mobilizon.Todos.{Todo, TodoList}
|
||||
|
@ -80,7 +81,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Todos do
|
|||
end
|
||||
end
|
||||
|
||||
def role_needed_to_access(%Todo{}), do: :member
|
||||
def role_needed_to_update(%Todo{}), do: :member
|
||||
def role_needed_to_delete(%Todo{}), do: :member
|
||||
def permissions(%Todo{}) do
|
||||
%Permission{access: :member, create: :member, update: :member, delete: :member}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Tombstones do
|
|||
@moduledoc false
|
||||
alias Mobilizon.{Actors, Tombstone}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Federation.ActivityPub.Permission
|
||||
|
||||
def actor(%Tombstone{actor: %Actor{id: actor_id}}), do: Actors.get_actor(actor_id)
|
||||
|
||||
|
@ -12,7 +13,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Tombstones do
|
|||
|
||||
def group_actor(_), do: nil
|
||||
|
||||
def role_needed_to_access(%Actor{}), do: nil
|
||||
def role_needed_to_update(%Actor{}), do: nil
|
||||
def role_needed_to_delete(%Actor{}), do: nil
|
||||
def permissions(_) do
|
||||
%Permission{access: nil, create: nil, update: nil, delete: nil}
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue