Merge branch 'fixes' into 'main'
Fix various instance view stuff and legacy cleaning Closes #1393 See merge request framasoft/mobilizon!1520
This commit is contained in:
commit
b317fe6163
|
@ -33,7 +33,7 @@
|
|||
# If you want to enforce a style guide and need a more traditional linting
|
||||
# experience, you can change `strict` to `true` below:
|
||||
#
|
||||
strict: false,
|
||||
strict: true,
|
||||
#
|
||||
# If you want to use uncolored output by default, you can change `color`
|
||||
# to `false` below:
|
||||
|
@ -160,6 +160,7 @@
|
|||
#
|
||||
{Credo.Check.Warning.LazyLogging, false},
|
||||
{Credo.Check.Refactor.MapInto, false},
|
||||
{Credo.Check.Warning.MissedMetadataKeyInLoggerConfig, false}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -25,7 +25,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Invite do
|
|||
) do
|
||||
Logger.debug("Handling #{actor_url} invite to #{group_url} sent to #{target_actor_url}")
|
||||
|
||||
if is_able_to_invite?(actor, group) do
|
||||
if able_to_invite?(actor, group) do
|
||||
with {:ok, %Member{url: member_url} = member} <-
|
||||
Actors.create_member(%{
|
||||
parent_id: group_id,
|
||||
|
@ -64,8 +64,8 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Invite do
|
|||
end
|
||||
end
|
||||
|
||||
@spec is_able_to_invite?(Actor.t(), Actor.t()) :: boolean
|
||||
defp is_able_to_invite?(%Actor{domain: actor_domain, id: actor_id}, %Actor{
|
||||
@spec able_to_invite?(Actor.t(), Actor.t()) :: boolean
|
||||
defp able_to_invite?(%Actor{domain: actor_domain, id: actor_id}, %Actor{
|
||||
domain: group_domain,
|
||||
id: group_id
|
||||
}) do
|
||||
|
@ -76,7 +76,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Invite do
|
|||
# If local group, we'll send the invite
|
||||
case Actors.get_member(actor_id, group_id) do
|
||||
{:ok, %Member{} = admin_member} ->
|
||||
Member.is_administrator(admin_member)
|
||||
Member.administrator?(admin_member)
|
||||
|
||||
_ ->
|
||||
false
|
||||
|
|
|
@ -34,7 +34,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Leave do
|
|||
local,
|
||||
additional
|
||||
) do
|
||||
if Participant.is_not_only_organizer(event_id, actor_id) do
|
||||
if Participant.not_only_organizer?(event_id, actor_id) do
|
||||
{:error, :is_only_organizer}
|
||||
else
|
||||
case Mobilizon.Events.get_participant(
|
||||
|
@ -83,7 +83,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Leave do
|
|||
case Actors.get_member(actor_id, group_id) do
|
||||
{:ok, %Member{id: member_id} = member} ->
|
||||
if Map.get(additional, :force_member_removal, false) || group_domain != actor_domain ||
|
||||
!Actors.is_only_administrator?(member_id, group_id) do
|
||||
!Actors.only_administrator?(member_id, group_id) do
|
||||
with {:ok, %Member{} = member} <- Actors.delete_member(member) do
|
||||
Mobilizon.Service.Activity.Member.insert_activity(member, subject: "member_quit")
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@ defmodule Mobilizon.Federation.ActivityPub.Permission do
|
|||
) do
|
||||
case object |> Ownable.permissions() |> get_in([:create]) do
|
||||
:member ->
|
||||
Actors.is_member?(actor_id, group_id)
|
||||
Actors.member?(actor_id, group_id)
|
||||
|
||||
:moderator ->
|
||||
Actors.is_moderator?(actor_id, group_id)
|
||||
Actors.moderator?(actor_id, group_id)
|
||||
|
||||
:administrator ->
|
||||
Actors.is_administrator?(actor_id, group_id)
|
||||
Actors.administrator?(actor_id, group_id)
|
||||
|
||||
_ ->
|
||||
false
|
||||
|
@ -122,21 +122,21 @@ defmodule Mobilizon.Federation.ActivityPub.Permission do
|
|||
"Checking if activity actor #{actor_url} is a moderator from group from #{object.url}"
|
||||
)
|
||||
|
||||
Actors.is_moderator?(actor_id, group_id)
|
||||
Actors.moderator?(actor_id, group_id)
|
||||
|
||||
:administrator ->
|
||||
Logger.debug(
|
||||
"Checking if activity actor #{actor_url} is an administrator from group from #{object.url}"
|
||||
)
|
||||
|
||||
Actors.is_administrator?(actor_id, group_id)
|
||||
Actors.administrator?(actor_id, group_id)
|
||||
|
||||
_ ->
|
||||
Logger.debug(
|
||||
"Checking if activity actor #{actor_url} is a member from group from #{object.url}"
|
||||
)
|
||||
|
||||
Actors.is_member?(actor_id, group_id)
|
||||
Actors.member?(actor_id, group_id)
|
||||
end
|
||||
|
||||
_ ->
|
||||
|
|
|
@ -21,10 +21,10 @@ defmodule Mobilizon.Federation.ActivityPub.Publisher do
|
|||
Logger.debug("Publishing an activity")
|
||||
Logger.debug(inspect(activity, pretty: true))
|
||||
|
||||
public = Visibility.is_public?(activity)
|
||||
public = Visibility.public?(activity)
|
||||
Logger.debug("is public ? #{public}")
|
||||
|
||||
if public && is_create_activity?(activity) && Config.get([:instance, :allow_relay]) do
|
||||
if public && create_activity?(activity) && Config.get([:instance, :allow_relay]) do
|
||||
Logger.info(fn -> "Relaying #{activity.data["id"]} out" end)
|
||||
|
||||
Relay.publish(activity)
|
||||
|
@ -125,9 +125,9 @@ defmodule Mobilizon.Federation.ActivityPub.Publisher do
|
|||
end)
|
||||
end
|
||||
|
||||
@spec is_create_activity?(Activity.t()) :: boolean
|
||||
defp is_create_activity?(%Activity{data: %{"type" => "Create"}}), do: true
|
||||
defp is_create_activity?(_), do: false
|
||||
@spec create_activity?(Activity.t()) :: boolean
|
||||
defp create_activity?(%Activity{data: %{"type" => "Create"}}), do: true
|
||||
defp create_activity?(_), do: false
|
||||
|
||||
@spec convert_members_in_recipients(list(String.t())) :: {list(String.t()), list(Actor.t())}
|
||||
defp convert_members_in_recipients(recipients) do
|
||||
|
|
|
@ -285,7 +285,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
object_data when is_map(object_data) <-
|
||||
object |> Converter.Resource.as_to_model_data(),
|
||||
{:member, true} <-
|
||||
{:member, Actors.is_member?(object_data.creator_id, object_data.actor_id)},
|
||||
{:member, Actors.member?(object_data.creator_id, object_data.actor_id)},
|
||||
{:ok, %Activity{} = activity, %Resource{} = resource} <-
|
||||
Actions.Create.create(:resource, object_data, false) do
|
||||
{:ok, activity, resource}
|
||||
|
@ -1005,14 +1005,14 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
end
|
||||
|
||||
# Comment initiates a whole discussion only if it has full title
|
||||
@spec is_data_for_comment_or_discussion?(map()) :: boolean()
|
||||
defp is_data_for_comment_or_discussion?(object_data) do
|
||||
is_data_a_discussion_initialization?(object_data) and
|
||||
@spec data_for_comment_or_discussion?(map()) :: boolean()
|
||||
defp data_for_comment_or_discussion?(object_data) do
|
||||
data_a_discussion_initialization?(object_data) and
|
||||
is_nil(object_data.discussion_id)
|
||||
end
|
||||
|
||||
# Comment initiates a whole discussion only if it has full title
|
||||
defp is_data_a_discussion_initialization?(object_data) do
|
||||
defp data_a_discussion_initialization?(object_data) do
|
||||
not Map.has_key?(object_data, :title) or
|
||||
is_nil(object_data.title) or object_data.title == ""
|
||||
end
|
||||
|
@ -1034,7 +1034,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
@spec transform_object_data_for_discussion(map()) :: map()
|
||||
defp transform_object_data_for_discussion(object_data) do
|
||||
# Basic comment
|
||||
if is_data_a_discussion_initialization?(object_data) do
|
||||
if data_a_discussion_initialization?(object_data) do
|
||||
object_data
|
||||
else
|
||||
# Conversation
|
||||
|
@ -1138,8 +1138,8 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
end
|
||||
end
|
||||
|
||||
defp is_group_object_gone(object_id) do
|
||||
Logger.debug("is_group_object_gone #{object_id}")
|
||||
defp group_object_gone_check(object_id) do
|
||||
Logger.debug("Checking if group object #{object_id} is gone")
|
||||
|
||||
case ActivityPub.fetch_object_from_url(object_id, force: true) do
|
||||
# comments are just emptied
|
||||
|
@ -1163,14 +1163,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
end
|
||||
end
|
||||
|
||||
# Before 1.0.4 the object of a "Remove" activity was an actor's URL
|
||||
# instead of the member's URL.
|
||||
# TODO: Remove in 1.2
|
||||
@spec get_remove_object(map() | String.t()) :: {:ok, integer()}
|
||||
defp get_remove_object(object) do
|
||||
case object |> Utils.get_url() |> ActivityPub.fetch_object_from_url() do
|
||||
{:ok, %Member{actor: %Actor{id: person_id}}} -> {:ok, person_id}
|
||||
{:ok, %Actor{id: person_id}} -> {:ok, person_id}
|
||||
_ -> {:error, :remove_object_not_found}
|
||||
end
|
||||
end
|
||||
|
@ -1196,7 +1192,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
@spec create_comment_or_discussion(map()) ::
|
||||
{:ok, Activity.t(), struct()} | {:error, atom() | Ecto.Changeset.t()}
|
||||
defp create_comment_or_discussion(object_data) do
|
||||
if is_data_for_comment_or_discussion?(object_data) do
|
||||
if data_for_comment_or_discussion?(object_data) do
|
||||
Logger.debug("Chosing to create a regular comment")
|
||||
Actions.Create.create(:comment, object_data, false)
|
||||
else
|
||||
|
@ -1248,7 +1244,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
end
|
||||
|
||||
defp handle_group_being_gone(actor, actor_url, object_id) do
|
||||
case is_group_object_gone(object_id) do
|
||||
case group_object_gone_check(object_id) do
|
||||
# The group object is no longer there, we can remove the element
|
||||
{:ok, entity} ->
|
||||
if Utils.origin_check_from_id?(actor_url, object_id) ||
|
||||
|
|
|
@ -93,7 +93,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Members do
|
|||
atom()
|
||||
) :: boolean
|
||||
defp check_admins_left?(member_id, group_id, current_role, updated_role) do
|
||||
Actors.is_only_administrator?(member_id, group_id) && current_role == :administrator &&
|
||||
Actors.only_administrator?(member_id, group_id) && current_role == :administrator &&
|
||||
updated_role != :administrator
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,17 +14,17 @@ defmodule Mobilizon.Federation.ActivityPub.Visibility do
|
|||
|
||||
@public "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
@spec is_public?(Activity.t() | map()) :: boolean()
|
||||
def is_public?(%{data: %{"type" => "Tombstone"}}), do: false
|
||||
def is_public?(%{data: data}), do: is_public?(data)
|
||||
def is_public?(%Activity{data: data}), do: is_public?(data)
|
||||
@spec public?(Activity.t() | map()) :: boolean()
|
||||
def public?(%{data: %{"type" => "Tombstone"}}), do: false
|
||||
def public?(%{data: data}), do: public?(data)
|
||||
def public?(%Activity{data: data}), do: public?(data)
|
||||
|
||||
def is_public?(data) when is_map(data) do
|
||||
def public?(data) when is_map(data) do
|
||||
@public in make_list(Map.get(data, "to", []))
|
||||
end
|
||||
|
||||
def is_public?(%Comment{deleted_at: deleted_at}), do: !is_nil(deleted_at)
|
||||
def is_public?(err), do: raise(ArgumentError, message: "Invalid argument #{inspect(err)}")
|
||||
def public?(%Comment{deleted_at: deleted_at}), do: !is_nil(deleted_at)
|
||||
def public?(err), do: raise(ArgumentError, message: "Invalid argument #{inspect(err)}")
|
||||
|
||||
defp make_list(data) when is_list(data), do: data
|
||||
defp make_list(data), do: [data]
|
||||
|
|
|
@ -76,14 +76,13 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Actor do
|
|||
def as_to_model_data(_), do: {:error, :actor_not_allowed_type}
|
||||
|
||||
defp add_endpoints_to_model(actor, data) do
|
||||
# TODO: Remove fallbacks in 3.0
|
||||
endpoints = %{
|
||||
members_url: get_in(data, ["endpoints", "members"]) || data["members"],
|
||||
resources_url: get_in(data, ["endpoints", "resources"]) || data["resources"],
|
||||
todos_url: get_in(data, ["endpoints", "todos"]) || data["todos"],
|
||||
events_url: get_in(data, ["endpoints", "events"]) || data["events"],
|
||||
posts_url: get_in(data, ["endpoints", "posts"]) || data["posts"],
|
||||
discussions_url: get_in(data, ["endpoints", "discussions"]) || data["discussions"],
|
||||
members_url: get_in(data, ["endpoints", "members"]),
|
||||
resources_url: get_in(data, ["endpoints", "resources"]),
|
||||
todos_url: get_in(data, ["endpoints", "todos"]),
|
||||
events_url: get_in(data, ["endpoints", "events"]),
|
||||
posts_url: get_in(data, ["endpoints", "posts"]),
|
||||
discussions_url: get_in(data, ["endpoints", "discussions"]),
|
||||
shared_inbox_url: data["endpoints"]["sharedInbox"]
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Comment do
|
|||
tags: fetch_tags(tag_object),
|
||||
mentions: fetch_mentions(tag_object),
|
||||
local: is_nil(actor_domain),
|
||||
visibility: if(Visibility.is_public?(object), do: :public, else: :private),
|
||||
visibility: if(Visibility.public?(object), do: :public, else: :private),
|
||||
published_at: object["published"],
|
||||
is_announcement: Map.get(object, "isAnnouncement", false)
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
category: Categories.get_category(object["category"]),
|
||||
visibility: visibility,
|
||||
join_options: Map.get(object, "joinMode", "free"),
|
||||
local: is_local?(object["id"]),
|
||||
local: local?(object["id"]),
|
||||
external_participation_url: object["externalParticipationUrl"],
|
||||
options: options,
|
||||
metadata: metadata,
|
||||
|
@ -305,8 +305,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
)
|
||||
end
|
||||
|
||||
@spec is_local?(String.t()) :: boolean()
|
||||
defp is_local?(url) do
|
||||
@spec local?(String.t()) :: boolean()
|
||||
defp local?(url) do
|
||||
%URI{host: url_domain} = URI.parse(url)
|
||||
%URI{host: local_domain} = URI.parse(Endpoint.url())
|
||||
url_domain == local_domain
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule Mobilizon.Federation.NodeInfo do
|
|||
|
||||
alias Mobilizon.Service.HTTP.WebfingerClient
|
||||
require Logger
|
||||
import Mobilizon.Service.HTTP.Utils, only: [is_content_type?: 2]
|
||||
import Mobilizon.Service.HTTP.Utils, only: [content_type_matches?: 2]
|
||||
|
||||
@application_uri "https://www.w3.org/ns/activitystreams#Application"
|
||||
@nodeinfo_rel_2_0 "http://nodeinfo.diaspora.software/ns/schema/2.0"
|
||||
|
@ -110,7 +110,7 @@ defmodule Mobilizon.Federation.NodeInfo do
|
|||
{:ok, String.t()} | {:error, :bad_content_type | :body_not_json}
|
||||
defp validate_json_response(body, headers) do
|
||||
cond do
|
||||
!is_content_type?(headers, "application/json") ->
|
||||
!content_type_matches?(headers, "application/json") ->
|
||||
{:error, :bad_content_type}
|
||||
|
||||
!is_map(body) ->
|
||||
|
|
|
@ -25,8 +25,8 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||
|
||||
cond do
|
||||
# Some URLs could be domain.tld/@username, so keep this condition above
|
||||
# the `is_handle` function
|
||||
is_url(term) ->
|
||||
# the `handle?` function
|
||||
url?(term) ->
|
||||
# skip, if it's not an actor
|
||||
case process_from_url(term) do
|
||||
%Page{total: _total, elements: [%Actor{} = _actor]} = page ->
|
||||
|
@ -36,11 +36,11 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||
{:ok, %{total: 0, elements: []}}
|
||||
end
|
||||
|
||||
is_handle(term) ->
|
||||
handle?(term) ->
|
||||
{:ok, process_from_username(term)}
|
||||
|
||||
true ->
|
||||
if is_global_search(args) do
|
||||
if global_search?(args) do
|
||||
service = GlobalSearch.service()
|
||||
|
||||
{:ok, service.search_groups(Keyword.new(args, fn {k, v} -> {k, v} end))}
|
||||
|
@ -75,7 +75,7 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||
def search_events(%{term: term} = args, page \\ 1, limit \\ 10) do
|
||||
term = String.trim(term)
|
||||
|
||||
if is_url(term) do
|
||||
if url?(term) do
|
||||
# skip, if it's not an event
|
||||
case process_from_url(term) do
|
||||
%Page{total: _total, elements: [%Event{} = event]} = page ->
|
||||
|
@ -89,7 +89,7 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||
{:ok, %{total: 0, elements: []}}
|
||||
end
|
||||
else
|
||||
if is_global_search(args) do
|
||||
if global_search?(args) do
|
||||
service = GlobalSearch.service()
|
||||
|
||||
{:ok, service.search_events(Keyword.new(args, fn {k, v} -> {k, v} end))}
|
||||
|
@ -140,17 +140,17 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||
end
|
||||
end
|
||||
|
||||
@spec is_url(String.t()) :: boolean
|
||||
defp is_url(search), do: String.starts_with?(search, ["http://", "https://"])
|
||||
@spec url?(String.t()) :: boolean
|
||||
defp url?(search), do: String.starts_with?(search, ["http://", "https://"])
|
||||
|
||||
@spec is_handle(String.t()) :: boolean
|
||||
defp is_handle(search), do: String.match?(search, ~r/@/)
|
||||
@spec handle?(String.t()) :: boolean
|
||||
defp handle?(search), do: String.match?(search, ~r/@/)
|
||||
|
||||
defp is_global_search(%{search_target: :global}) do
|
||||
defp global_search?(%{search_target: :global}) do
|
||||
global_search_enabled?()
|
||||
end
|
||||
|
||||
defp is_global_search(_), do: global_search_enabled?() && global_search_default?()
|
||||
defp global_search?(_), do: global_search_enabled?() && global_search_default?()
|
||||
|
||||
defp global_search_enabled? do
|
||||
Application.get_env(:mobilizon, :search) |> get_in([:global]) |> get_in([:is_enabled])
|
||||
|
|
|
@ -68,6 +68,6 @@ defmodule Mobilizon.GraphQL.API.Utils do
|
|||
|
||||
@spec check_actor_owns_media?(integer() | String.t(), integer() | String.t()) :: boolean()
|
||||
defp check_actor_owns_media?(actor_id, media_actor_id) do
|
||||
actor_id == media_actor_id || Mobilizon.Actors.is_member?(media_actor_id, actor_id)
|
||||
actor_id == media_actor_id || Mobilizon.Actors.member?(media_actor_id, actor_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,8 +5,8 @@ defmodule Mobilizon.GraphQL.Error do
|
|||
|
||||
require Logger
|
||||
alias __MODULE__
|
||||
alias Mobilizon.Web.Gettext, as: GettextBackend
|
||||
import Mobilizon.Web.Gettext, only: [dgettext: 2]
|
||||
import Mobilizon.Storage.Ecto, only: [convert_ecto_errors: 1]
|
||||
|
||||
@type t :: %{code: atom(), message: String.t(), status_code: pos_integer(), field: atom()}
|
||||
|
||||
|
@ -64,7 +64,7 @@ defmodule Mobilizon.GraphQL.Error do
|
|||
|
||||
defp handle(%Ecto.Changeset{} = changeset) do
|
||||
changeset
|
||||
|> Ecto.Changeset.traverse_errors(&translate_error/1)
|
||||
|> convert_ecto_errors()
|
||||
|> Enum.map(fn {k, v} ->
|
||||
%Error{
|
||||
code: :validation,
|
||||
|
@ -126,27 +126,4 @@ defmodule Mobilizon.GraphQL.Error do
|
|||
Logger.warning("Unhandled error code: #{inspect(code)}")
|
||||
{422, to_string(code)}
|
||||
end
|
||||
|
||||
# Translates an error message using gettext.
|
||||
defp translate_error({msg, opts}) do
|
||||
# Because error messages were defined within Ecto, we must
|
||||
# call the Gettext module passing our Gettext backend. We
|
||||
# also use the "errors" domain as translations are placed
|
||||
# in the errors.po file.
|
||||
# Ecto will pass the :count keyword if the error message is
|
||||
# meant to be pluralized.
|
||||
# On your own code and templates, depending on whether you
|
||||
# need the message to be pluralized or not, this could be
|
||||
# written simply as:
|
||||
#
|
||||
# dngettext "errors", "1 file", "%{count} files", count
|
||||
# dgettext "errors", "is invalid"
|
||||
#
|
||||
|
||||
if count = opts[:count] do
|
||||
Gettext.dngettext(GettextBackend, "errors", msg, msg, count, opts)
|
||||
else
|
||||
Gettext.dgettext(GettextBackend, "errors", msg, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
|
|||
def group_activity(%Actor{type: :Group, id: group_id}, %{page: page, limit: limit} = args, %{
|
||||
context: %{current_user: %User{role: role}, current_actor: %Actor{id: actor_id}}
|
||||
}) do
|
||||
if Actors.is_member?(actor_id, group_id) or is_moderator(role) do
|
||||
if Actors.member?(actor_id, group_id) or is_moderator(role) do
|
||||
%Page{total: total, elements: elements} =
|
||||
Activities.list_group_activities_for_member(
|
||||
group_id,
|
||||
|
|
|
@ -26,7 +26,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Conversation do
|
|||
}
|
||||
)
|
||||
when not is_nil(attributed_to_id) do
|
||||
if Actors.is_member?(actor_id, attributed_to_id) do
|
||||
if Actors.member?(actor_id, attributed_to_id) do
|
||||
{:ok,
|
||||
event_id
|
||||
|> Conversations.find_conversations_for_event(attributed_to_id, page, limit)
|
||||
|
@ -103,7 +103,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Conversation do
|
|||
{:error, :not_found}
|
||||
|
||||
%ConversationParticipant{actor_id: actor_id} = conversation_participant ->
|
||||
if actor_id == performing_actor_id or Actors.is_member?(performing_actor_id, actor_id) do
|
||||
if actor_id == performing_actor_id or Actors.member?(performing_actor_id, actor_id) do
|
||||
{:ok, conversation_participant_to_view(conversation_participant)}
|
||||
else
|
||||
{:error, :not_found}
|
||||
|
@ -121,7 +121,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Conversation do
|
|||
}
|
||||
) do
|
||||
if conversation_actor_id == performing_actor_id or
|
||||
Actors.is_member?(performing_actor_id, conversation_actor_id) do
|
||||
Actors.member?(performing_actor_id, conversation_actor_id) do
|
||||
{:ok,
|
||||
Mobilizon.Discussions.get_comments_in_reply_to_comment_id(origin_comment_id, page, limit)}
|
||||
else
|
||||
|
@ -184,7 +184,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Conversation do
|
|||
{:valid_actor, true} <-
|
||||
{:valid_actor,
|
||||
actor_id == current_actor_id or
|
||||
Actors.is_member?(current_actor_id, actor_id)},
|
||||
Actors.member?(current_actor_id, actor_id)},
|
||||
{:ok, %ConversationParticipant{} = conversation_participant} <-
|
||||
Conversations.update_conversation_participant(conversation_participant, %{
|
||||
unread: !read
|
||||
|
@ -269,7 +269,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Conversation do
|
|||
|
||||
to_string(current_actor_id) in participant_ids or
|
||||
Enum.any?(participant_ids, fn participant_id ->
|
||||
Actors.is_member?(current_actor_id, participant_id) and
|
||||
Actors.member?(current_actor_id, participant_id) and
|
||||
attributed_to_id == participant_id
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
|||
}
|
||||
}
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
with {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:ok, %Actor{type: :Group} = group} <- Actors.get_group_by_actor_id(group_id) do
|
||||
{:ok, Discussions.find_discussions_for_actor(group, page, limit)}
|
||||
else
|
||||
|
@ -45,7 +45,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
|||
}) do
|
||||
case Discussions.get_discussion(id) do
|
||||
%Discussion{actor_id: actor_id} = discussion ->
|
||||
if Actors.is_member?(creator_id, actor_id) do
|
||||
if Actors.member?(creator_id, actor_id) do
|
||||
{:ok, discussion}
|
||||
else
|
||||
{:error, :unauthorized}
|
||||
|
@ -63,7 +63,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
|||
}) do
|
||||
with %Discussion{actor_id: actor_id} = discussion <-
|
||||
Discussions.get_discussion_by_slug(slug),
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)} do
|
||||
{:member, true} <- {:member, Actors.member?(creator_id, actor_id)} do
|
||||
{:ok, discussion}
|
||||
else
|
||||
nil -> {:error, dgettext("errors", "Discussion not found")}
|
||||
|
@ -105,7 +105,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
|||
}
|
||||
}
|
||||
) do
|
||||
if Actors.is_member?(creator_id, group_id) do
|
||||
if Actors.member?(creator_id, group_id) do
|
||||
case Comments.create_discussion(%{
|
||||
title: title,
|
||||
text: text,
|
||||
|
@ -150,7 +150,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
|||
}
|
||||
} = _discussion} <-
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:member, true} <- {:member, Actors.member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
Comments.create_discussion(%{
|
||||
text: text,
|
||||
|
@ -183,7 +183,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
|||
) do
|
||||
with {:no_discussion, %Discussion{actor_id: actor_id} = discussion} <-
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:member, true} <- {:member, Actors.member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
Actions.Update.update(
|
||||
discussion,
|
||||
|
@ -213,7 +213,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
|
|||
}) do
|
||||
with {:no_discussion, %Discussion{actor_id: actor_id} = discussion} <-
|
||||
{:no_discussion, Discussions.get_discussion(discussion_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)},
|
||||
{:member, true} <- {:member, Actors.member?(creator_id, actor_id)},
|
||||
{:ok, _activity, %Discussion{} = discussion} <-
|
||||
Actions.Delete.delete(discussion, actor) do
|
||||
{:ok, discussion}
|
||||
|
|
|
@ -36,7 +36,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
|||
when not is_nil(attributed_to_id) do
|
||||
with %Actor{id: group_id} <- Actors.get_actor(attributed_to_id),
|
||||
{:member, true} <-
|
||||
{:member, Actors.is_member?(actor_id, group_id) or is_moderator(user_role)},
|
||||
{:member, Actors.member?(actor_id, group_id) or is_moderator(user_role)},
|
||||
%Actor{} = actor <- Actors.get_actor(organizer_actor_id) do
|
||||
{:ok, actor}
|
||||
else
|
||||
|
@ -176,7 +176,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
|||
_args,
|
||||
%{context: %{current_user: %User{id: user_id} = _user}} = _resolution
|
||||
) do
|
||||
if Events.is_user_moderator_for_event?(user_id, event_id) do
|
||||
if Events.user_moderator_for_event?(user_id, event_id) do
|
||||
{:ok,
|
||||
Map.put(
|
||||
stats,
|
||||
|
@ -256,7 +256,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
|||
{:can_create_event, true} <- can_create_event(args),
|
||||
{:event_external, true} <- edit_event_external_checker(args),
|
||||
{:organizer_group_member, true} <-
|
||||
{:organizer_group_member, is_organizer_group_member?(args)},
|
||||
{:organizer_group_member, organizer_group_member?(args)},
|
||||
args_with_organizer <-
|
||||
args |> Map.put(:organizer_actor, organizer_actor) |> extract_timezone(user.id),
|
||||
{:askismet, :ham} <-
|
||||
|
@ -447,17 +447,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
|||
end
|
||||
end
|
||||
|
||||
@spec is_organizer_group_member?(map()) :: boolean()
|
||||
defp is_organizer_group_member?(%{
|
||||
@spec organizer_group_member?(map()) :: boolean()
|
||||
defp organizer_group_member?(%{
|
||||
attributed_to_id: attributed_to_id,
|
||||
organizer_actor_id: organizer_actor_id
|
||||
})
|
||||
when not is_nil(attributed_to_id) do
|
||||
Actors.is_member?(organizer_actor_id, attributed_to_id) &&
|
||||
Actors.member?(organizer_actor_id, attributed_to_id) &&
|
||||
Permission.can_create_group_object?(organizer_actor_id, attributed_to_id, %Event{})
|
||||
end
|
||||
|
||||
defp is_organizer_group_member?(_), do: true
|
||||
defp organizer_group_member?(_), do: true
|
||||
|
||||
@spec verify_profile_change(map(), Event.t(), User.t(), Actor.t()) :: {:ok, map()}
|
||||
defp verify_profile_change(
|
||||
|
|
|
@ -23,7 +23,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Followers do
|
|||
) do
|
||||
followers = group_followers(group, args)
|
||||
|
||||
if Actors.is_moderator?(actor_id, group_id) or is_moderator(user_role) do
|
||||
if Actors.moderator?(actor_id, group_id) or is_moderator(user_role) do
|
||||
{:ok, followers}
|
||||
else
|
||||
{:ok, %Page{followers | elements: []}}
|
||||
|
@ -48,7 +48,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Followers do
|
|||
with %Follower{target_actor: %Actor{type: :Group, id: group_id}} = follower <-
|
||||
Actors.get_follower(follower_id),
|
||||
{:member, true} <-
|
||||
{:member, Actors.is_moderator?(actor_id, group_id)},
|
||||
{:member, Actors.moderator?(actor_id, group_id)},
|
||||
{:ok, _activity, %Follower{} = follower} <-
|
||||
(if approved do
|
||||
Actions.Accept.accept(:follow, follower)
|
||||
|
|
|
@ -36,7 +36,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||
) do
|
||||
case ActivityPubActor.find_or_make_group_from_nickname(name) do
|
||||
{:ok, %Actor{id: group_id, suspended: false} = group} ->
|
||||
if Actors.is_member?(actor_id, group_id) do
|
||||
if Actors.member?(actor_id, group_id) do
|
||||
{:ok, group}
|
||||
else
|
||||
find_group(parent, args, nil)
|
||||
|
@ -72,7 +72,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||
}
|
||||
}) do
|
||||
with %Actor{suspended: false, id: group_id} = group <- Actors.get_actor_with_preload(id),
|
||||
true <- Actors.is_member?(actor_id, group_id) do
|
||||
true <- Actors.member?(actor_id, group_id) do
|
||||
{:ok, group}
|
||||
else
|
||||
_ ->
|
||||
|
@ -215,7 +215,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||
}
|
||||
}
|
||||
) do
|
||||
if Actors.is_administrator?(updater_actor.id, group_id) do
|
||||
if Actors.administrator?(updater_actor.id, group_id) do
|
||||
args = Map.put(args, :updater_actor, updater_actor)
|
||||
|
||||
case save_attached_pictures(args) do
|
||||
|
@ -265,7 +265,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||
) do
|
||||
with {:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
|
||||
{:ok, %Member{} = member} <- Actors.get_member(actor_id, group.id),
|
||||
{:is_admin, true} <- {:is_admin, Member.is_administrator(member)},
|
||||
{:is_admin, true} <- {:is_admin, Member.administrator?(member)},
|
||||
{:ok, _activity, group} <- Actions.Delete.delete(group, actor, true) do
|
||||
{:ok, %{id: group.id}}
|
||||
else
|
||||
|
@ -448,7 +448,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||
}
|
||||
}
|
||||
) do
|
||||
if Actors.is_member?(actor_id, group_id) do
|
||||
if Actors.member?(actor_id, group_id) do
|
||||
{:ok,
|
||||
Events.list_organized_events_for_group(
|
||||
group,
|
||||
|
|
|
@ -26,7 +26,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
|
|||
context: %{current_user: %User{role: user_role}, current_actor: %Actor{id: actor_id}}
|
||||
} = _resolution
|
||||
) do
|
||||
if Actors.is_member?(actor_id, group_id) or is_moderator(user_role) do
|
||||
if Actors.member?(actor_id, group_id) or is_moderator(user_role) do
|
||||
roles =
|
||||
case roles do
|
||||
"" ->
|
||||
|
|
|
@ -384,7 +384,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
|
|||
with {:member, true} <-
|
||||
{:member,
|
||||
to_string(current_actor_id) == to_string(actor_id) or
|
||||
Actors.is_member?(current_actor_id, actor_id)},
|
||||
Actors.member?(current_actor_id, actor_id)},
|
||||
{:ok, _activity, %Conversation{} = conversation} <- Comments.create_conversation(args) do
|
||||
{:ok, conversation_to_view(conversation, Actors.get_actor(actor_id))}
|
||||
else
|
||||
|
|
|
@ -32,7 +32,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
|||
}
|
||||
} = _resolution
|
||||
) do
|
||||
if Actors.is_member?(actor_id, group_id) or is_moderator(user_role) do
|
||||
if Actors.member?(actor_id, group_id) or is_moderator(user_role) do
|
||||
%Page{} = page = Posts.get_posts_for_group(group, page, limit)
|
||||
{:ok, page}
|
||||
else
|
||||
|
@ -111,7 +111,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
|||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
with {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
%Actor{} = group <- Actors.get_actor(group_id),
|
||||
args <-
|
||||
Map.update(args, :picture, nil, fn picture ->
|
||||
|
@ -160,7 +160,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
|||
process_picture(picture, group)
|
||||
end),
|
||||
args <- extract_pictures_from_post_body(args, actor_id),
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:ok, _, %Post{} = post} <-
|
||||
Actions.Update.update(post, args, true, %{"actor" => actor_url}) do
|
||||
{:ok, post}
|
||||
|
@ -194,7 +194,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
|
|||
with {:uuid, {:ok, _uuid}} <- {:uuid, Ecto.UUID.cast(post_id)},
|
||||
{:post, %Post{attributed_to: %Actor{id: group_id}} = post} <-
|
||||
{:post, Posts.get_post_with_preloads(post_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:ok, _, %Post{} = post} <-
|
||||
Actions.Delete.delete(post, actor) do
|
||||
{:ok, post}
|
||||
|
|
|
@ -32,7 +32,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
with {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
%Page{} = page <- Resources.get_resources_for_group(group, page, limit) do
|
||||
{:ok, page}
|
||||
else
|
||||
|
@ -60,7 +60,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
with {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
%Page{} = page <- Resources.get_resources_for_folder(parent, page, limit) do
|
||||
{:ok, page}
|
||||
end
|
||||
|
@ -83,7 +83,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
Logger.debug("Getting resource for group with username #{username}")
|
||||
|
||||
with {:group, %Actor{id: group_id}} <- {:group, Actors.get_actor_by_name(username, :Group)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:resource, %Resource{} = resource} <-
|
||||
{:resource, Resources.get_resource_by_group_and_path_with_preloads(group_id, path)} do
|
||||
{:ok, resource}
|
||||
|
@ -109,7 +109,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
}
|
||||
} = _resolution
|
||||
) do
|
||||
if Actors.is_member?(actor_id, group_id) do
|
||||
if Actors.member?(actor_id, group_id) do
|
||||
parent = get_eventual_parent(args)
|
||||
|
||||
if check_resource_owned_by_group(parent, group_id) do
|
||||
|
@ -155,7 +155,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
) do
|
||||
case Resources.get_resource_with_preloads(resource_id) do
|
||||
%Resource{actor_id: group_id} = resource ->
|
||||
if Actors.is_member?(actor_id, group_id) do
|
||||
if Actors.member?(actor_id, group_id) do
|
||||
case Actions.Update.update(resource, args, true, %{"actor" => actor_url}) do
|
||||
{:ok, _, %Resource{} = resource} ->
|
||||
{:ok, resource}
|
||||
|
@ -192,7 +192,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
|
|||
) do
|
||||
with {:resource, %Resource{parent_id: _parent_id, actor_id: group_id} = resource} <-
|
||||
{:resource, Resources.get_resource_with_preloads(resource_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:ok, _, %Resource{} = resource} <-
|
||||
Actions.Delete.delete(resource, actor) do
|
||||
{:ok, resource}
|
||||
|
|
|
@ -26,7 +26,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
context: %{current_actor: %Actor{id: actor_id}}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
with {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
%Page{} = page <- Todos.get_todo_lists_for_group(group, page, limit) do
|
||||
{:ok, page}
|
||||
else
|
||||
|
@ -50,7 +50,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
context: %{current_actor: %Actor{id: actor_id}}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
with {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
%Page{} = page <- Todos.get_todos_for_todo_list(todo_list, page, limit) do
|
||||
{:ok, page}
|
||||
else
|
||||
|
@ -70,7 +70,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
) do
|
||||
with {:todo, %TodoList{actor_id: group_id} = todo} <-
|
||||
{:todo, Todos.get_todo_list(todo_list_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)} do
|
||||
{:ok, todo}
|
||||
else
|
||||
{:todo, nil} ->
|
||||
|
@ -93,7 +93,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
context: %{current_actor: %Actor{id: actor_id}}
|
||||
} = _resolution
|
||||
) do
|
||||
with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
with {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:ok, _, %TodoList{} = todo_list} <-
|
||||
Actions.Create.create(
|
||||
:todo_list,
|
||||
|
@ -121,7 +121,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
# with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
|
||||
# {:todo_list, %TodoList{actor_id: group_id} = todo_list} <-
|
||||
# {:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
# {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
# {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
# {:ok, _, %TodoList{} = todo} <-
|
||||
# Actions.Update.update_todo_list(todo_list, actor, true, %{}) do
|
||||
# {:ok, todo}
|
||||
|
@ -144,7 +144,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
# with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
|
||||
# {:todo_list, %TodoList{actor_id: group_id} = todo_list} <-
|
||||
# {:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
# {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
# {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
# {:ok, _, %TodoList{} = todo} <-
|
||||
# Actions.Delete.delete_todo_list(todo_list, actor, true, %{}) do
|
||||
# {:ok, todo}
|
||||
|
@ -169,7 +169,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
{:todo, Todos.get_todo(todo_id)},
|
||||
{:todo_list, %TodoList{actor_id: group_id}} <-
|
||||
{:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)} do
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)} do
|
||||
{:ok, todo}
|
||||
else
|
||||
{:todo, nil} ->
|
||||
|
@ -194,7 +194,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
) do
|
||||
with {:todo_list, %TodoList{actor_id: group_id} = _todo_list} <-
|
||||
{:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:ok, _, %Todo{} = todo} <-
|
||||
Actions.Create.create(
|
||||
:todo,
|
||||
|
@ -228,7 +228,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
{:todo, Todos.get_todo(todo_id)},
|
||||
{:todo_list, %TodoList{actor_id: group_id}} <-
|
||||
{:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
{:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
{:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
{:ok, _, %Todo{} = todo} <-
|
||||
Actions.Update.update(todo, args, true, %{}) do
|
||||
{:ok, todo}
|
||||
|
@ -259,7 +259,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
|
|||
# {:todo, Todos.get_todo(todo_id)},
|
||||
# {:todo_list, %TodoList{actor_id: group_id}} <-
|
||||
# {:todo_list, Todos.get_todo_list(todo_list_id)},
|
||||
# {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)},
|
||||
# {:member, true} <- {:member, Actors.member?(actor_id, group_id)},
|
||||
# {:ok, _, %Todo{} = todo} <-
|
||||
# Actions.Delete.delete_todo(todo, actor, true, %{}) do
|
||||
# {:ok, todo}
|
||||
|
|
|
@ -209,8 +209,8 @@ defmodule Mobilizon.Actors.Actor do
|
|||
@doc """
|
||||
Checks whether actor visibility is public.
|
||||
"""
|
||||
@spec is_public_visibility?(t) :: boolean
|
||||
def is_public_visibility?(%__MODULE__{visibility: visibility}) do
|
||||
@spec public_visibility?(t) :: boolean
|
||||
def public_visibility?(%__MODULE__{visibility: visibility}) do
|
||||
visibility in [:public, :unlisted]
|
||||
end
|
||||
|
||||
|
|
|
@ -710,8 +710,8 @@ defmodule Mobilizon.Actors do
|
|||
@doc """
|
||||
Returns whether the `actor_id` is a confirmed member for the group `parent_id`
|
||||
"""
|
||||
@spec is_member?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def is_member?(actor_id, parent_id) do
|
||||
@spec member?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def member?(actor_id, parent_id) do
|
||||
match?(
|
||||
{:ok, %Member{}},
|
||||
get_member(actor_id, parent_id, @member_roles)
|
||||
|
@ -721,8 +721,8 @@ defmodule Mobilizon.Actors do
|
|||
@doc """
|
||||
Returns whether the `actor_id` is a moderator for the group `parent_id`
|
||||
"""
|
||||
@spec is_moderator?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def is_moderator?(actor_id, parent_id) do
|
||||
@spec moderator?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def moderator?(actor_id, parent_id) do
|
||||
match?(
|
||||
{:ok, %Member{}},
|
||||
get_member(actor_id, parent_id, @moderator_roles)
|
||||
|
@ -732,8 +732,8 @@ defmodule Mobilizon.Actors do
|
|||
@doc """
|
||||
Returns whether the `actor_id` is an administrator for the group `parent_id`
|
||||
"""
|
||||
@spec is_administrator?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def is_administrator?(actor_id, parent_id) do
|
||||
@spec administrator?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def administrator?(actor_id, parent_id) do
|
||||
match?(
|
||||
{:ok, %Member{}},
|
||||
get_member(actor_id, parent_id, @administrator_roles)
|
||||
|
@ -922,8 +922,8 @@ defmodule Mobilizon.Actors do
|
|||
@doc """
|
||||
Returns whether the member is the last administrator for a group
|
||||
"""
|
||||
@spec is_only_administrator?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def is_only_administrator?(member_id, group_id) do
|
||||
@spec only_administrator?(integer | String.t(), integer | String.t()) :: boolean()
|
||||
def only_administrator?(member_id, group_id) do
|
||||
Member
|
||||
|> where(
|
||||
[m],
|
||||
|
|
|
@ -55,9 +55,10 @@ defmodule Mobilizon.Actors.Member do
|
|||
@doc """
|
||||
Checks whether the member is an administrator (admin or creator) of the group.
|
||||
"""
|
||||
def is_administrator(%__MODULE__{role: :administrator}), do: true
|
||||
def is_administrator(%__MODULE__{role: :creator}), do: true
|
||||
def is_administrator(%__MODULE__{}), do: false
|
||||
@spec administrator?(t()) :: boolean()
|
||||
def administrator?(%__MODULE__{role: :administrator}), do: true
|
||||
def administrator?(%__MODULE__{role: :creator}), do: true
|
||||
def administrator?(%__MODULE__{}), do: false
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
|
|
|
@ -77,7 +77,7 @@ defmodule Mobilizon.Discussions do
|
|||
|> join(:left, [c], r in Comment, on: r.origin_comment_id == c.id)
|
||||
|> where([c, _], is_nil(c.in_reply_to_comment_id))
|
||||
|> where([c], c.visibility in ^@public_visibility)
|
||||
# TODO: This was added because we don't want to count deleted comments in total_replies.
|
||||
# This was added because we don't want to count deleted comments in total_replies.
|
||||
# However, it also excludes all top-level comments with deleted replies from being selected
|
||||
# |> where([_, r], is_nil(r.deleted_at))
|
||||
|> group_by([c], c.id)
|
||||
|
|
|
@ -515,8 +515,8 @@ defmodule Mobilizon.Events do
|
|||
|> Page.build_page(page, limit)
|
||||
end
|
||||
|
||||
@spec is_user_moderator_for_event?(integer | String.t(), integer | String.t()) :: boolean
|
||||
def is_user_moderator_for_event?(user_id, event_id) do
|
||||
@spec user_moderator_for_event?(integer | String.t(), integer | String.t()) :: boolean
|
||||
def user_moderator_for_event?(user_id, event_id) do
|
||||
Participant
|
||||
|> join(:inner, [p], a in Actor, on: p.actor_id == a.id)
|
||||
|> where([p, _a], p.event_id == ^event_id)
|
||||
|
@ -1492,14 +1492,14 @@ defmodule Mobilizon.Events do
|
|||
end
|
||||
|
||||
@spec filter_online(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
||||
defp filter_online(query, %{type: :online}), do: is_online_fragment(query, true)
|
||||
defp filter_online(query, %{type: :online}), do: online_fragment_check(query, true)
|
||||
|
||||
defp filter_online(query, %{type: :in_person}), do: is_online_fragment(query, false)
|
||||
defp filter_online(query, %{type: :in_person}), do: online_fragment_check(query, false)
|
||||
|
||||
defp filter_online(query, _), do: query
|
||||
|
||||
@spec is_online_fragment(Ecto.Query.t(), boolean()) :: Ecto.Query.t()
|
||||
defp is_online_fragment(query, value) do
|
||||
@spec online_fragment_check(Ecto.Query.t(), boolean()) :: Ecto.Query.t()
|
||||
defp online_fragment_check(query, value) do
|
||||
where(query, [q], fragment("(?->>'is_online')::bool = ?", q.options, ^value))
|
||||
end
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ defmodule Mobilizon.Events.Participant do
|
|||
We start by fetching the list of organizers and if there's only one of them
|
||||
and that it's the actor requesting leaving the event we return true.
|
||||
"""
|
||||
@spec is_not_only_organizer(integer | String.t(), integer | String.t()) :: boolean
|
||||
def is_not_only_organizer(event_id, actor_id) do
|
||||
@spec not_only_organizer?(integer | String.t(), integer | String.t()) :: boolean
|
||||
def not_only_organizer?(event_id, actor_id) do
|
||||
case Events.list_organizers_participants_for_event(event_id) do
|
||||
[%__MODULE__{actor: %Actor{id: participant_actor_id}}] ->
|
||||
participant_actor_id == actor_id
|
||||
|
|
|
@ -34,6 +34,10 @@ defmodule Mobilizon.Instances.InstanceActor do
|
|||
instance_actor
|
||||
|> cast(attrs, @attrs)
|
||||
|> validate_required(@required_attrs)
|
||||
|> validate_length(:domain, max: 254)
|
||||
|> validate_length(:instance_name, max: 254)
|
||||
|> validate_length(:software, max: 254)
|
||||
|> validate_length(:software_version, max: 254)
|
||||
|> unique_constraint(:domain)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,7 @@ defmodule Mobilizon.Instances do
|
|||
"""
|
||||
alias Ecto.Adapters.SQL
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
alias Mobilizon.Instances.{Instance, InstanceActor}
|
||||
alias Mobilizon.Storage.{Page, Repo}
|
||||
import Ecto.Query
|
||||
|
@ -22,11 +23,15 @@ defmodule Mobilizon.Instances do
|
|||
|
||||
order_by_options = Keyword.new([{direction, order_by}])
|
||||
|
||||
%Actor{id: relay_id} = Relay.get_actor()
|
||||
|
||||
query =
|
||||
Instance
|
||||
|> join(:left, [i], ia in InstanceActor, on: i.domain == ia.domain)
|
||||
|> join(:left, [_i, ia], a in Actor, on: ia.actor_id == a.id)
|
||||
# following
|
||||
|> join(:left, [_i, _ia, a], f1 in Follower, on: f1.target_actor_id == a.id)
|
||||
# followed
|
||||
|> join(:left, [_i, _ia, a], f2 in Follower, on: f2.actor_id == a.id)
|
||||
|> select([i, ia, a, f1, f2], %{
|
||||
instance: i,
|
||||
|
@ -45,14 +50,27 @@ defmodule Mobilizon.Instances do
|
|||
if is_nil(filter_domain) or filter_domain == "" do
|
||||
query
|
||||
else
|
||||
where(query, [i], like(i.domain, ^"%#{filter_domain}%"))
|
||||
where(
|
||||
query,
|
||||
[i, ia],
|
||||
like(i.domain, ^"%#{filter_domain}%") or like(ia.instance_name, ^"%#{filter_domain}%")
|
||||
)
|
||||
end
|
||||
|
||||
query =
|
||||
case follow_status do
|
||||
:following -> where(query, [i, s], s.following == true)
|
||||
:followed -> where(query, [i, s], s.follower == true)
|
||||
:all -> query
|
||||
:following ->
|
||||
where(query, [_i, _ia, _a, f1], f1.actor_id == ^relay_id and f1.approved == true)
|
||||
|
||||
:followed ->
|
||||
where(
|
||||
query,
|
||||
[_i, _ia, _a, _f1, f2],
|
||||
f2.target_actor_id == ^relay_id and f2.approved == true
|
||||
)
|
||||
|
||||
:all ->
|
||||
query
|
||||
end
|
||||
|
||||
%Page{elements: elements} = paged_instances = Page.build_page(query, page, limit, :domain)
|
||||
|
|
|
@ -214,7 +214,7 @@ defmodule Mobilizon.Medias do
|
|||
query
|
||||
|> Repo.all(timeout: :infinity)
|
||||
|> Enum.filter(fn %Media{file: %File{url: url}} ->
|
||||
!url_is_also_a_profile_file?(url) && is_all_media_orphan?(url, expiration_date)
|
||||
!url_is_also_a_profile_file?(url) && all_media_orphan?(url, expiration_date)
|
||||
end)
|
||||
|> Enum.chunk_by(fn %Media{file: %File{url: url}} ->
|
||||
url
|
||||
|
@ -223,14 +223,14 @@ defmodule Mobilizon.Medias do
|
|||
end)
|
||||
end
|
||||
|
||||
defp is_all_media_orphan?(url, expiration_date) do
|
||||
defp all_media_orphan?(url, expiration_date) do
|
||||
url
|
||||
|> get_all_media_by_url()
|
||||
|> Enum.all?(&is_media_orphan?(&1, expiration_date))
|
||||
|> Enum.all?(&media_orphan?(&1, expiration_date))
|
||||
end
|
||||
|
||||
@spec is_media_orphan?(Media.t(), DateTime.t()) :: boolean()
|
||||
defp is_media_orphan?(%Media{id: media_id}, expiration_date) do
|
||||
@spec media_orphan?(Media.t(), DateTime.t()) :: boolean()
|
||||
defp media_orphan?(%Media{id: media_id}, expiration_date) do
|
||||
media_query =
|
||||
from(m in Media,
|
||||
as: :media,
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule Mobilizon.Storage.Ecto do
|
|||
import Ecto.Changeset, only: [fetch_change: 2, put_change: 3, get_field: 2]
|
||||
alias Ecto.{Changeset, Query}
|
||||
alias Mobilizon.Web.Endpoint
|
||||
alias Mobilizon.Web.Gettext, as: GettextBackend
|
||||
alias Mobilizon.Web.Router.Helpers, as: Routes
|
||||
|
||||
@doc """
|
||||
|
@ -56,4 +57,30 @@ defmodule Mobilizon.Storage.Ecto do
|
|||
changeset
|
||||
end
|
||||
end
|
||||
|
||||
def convert_ecto_errors(%Ecto.Changeset{} = changeset),
|
||||
do: Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
|
||||
|
||||
# Translates an error message using gettext.
|
||||
defp translate_error({msg, opts}) do
|
||||
# Because error messages were defined within Ecto, we must
|
||||
# call the Gettext module passing our Gettext backend. We
|
||||
# also use the "errors" domain as translations are placed
|
||||
# in the errors.po file.
|
||||
# Ecto will pass the :count keyword if the error message is
|
||||
# meant to be pluralized.
|
||||
# On your own code and templates, depending on whether you
|
||||
# need the message to be pluralized or not, this could be
|
||||
# written simply as:
|
||||
#
|
||||
# dngettext "errors", "1 file", "%{count} files", count
|
||||
# dgettext "errors", "is invalid"
|
||||
#
|
||||
|
||||
if count = opts[:count] do
|
||||
Gettext.dngettext(GettextBackend, "errors", msg, msg, count, opts)
|
||||
else
|
||||
Gettext.dgettext(GettextBackend, "errors", msg, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -55,14 +55,14 @@ defmodule Mobilizon.Service.DateTime do
|
|||
)
|
||||
end
|
||||
|
||||
@spec is_first_day_of_week(Date.t(), String.t()) :: boolean()
|
||||
defp is_first_day_of_week(%Date{} = date, locale) do
|
||||
@spec first_day_of_week?(Date.t(), String.t()) :: boolean()
|
||||
defp first_day_of_week?(%Date{} = date, locale) do
|
||||
Date.day_of_week(date) == Cldr.Calendar.first_day_for_locale(locale)
|
||||
end
|
||||
|
||||
@spec calculate_first_day_of_week(Date.t(), String.t()) :: Date.t()
|
||||
def calculate_first_day_of_week(%Date{} = date, locale \\ "en") do
|
||||
if is_first_day_of_week(date, locale),
|
||||
if first_day_of_week?(date, locale),
|
||||
do: date,
|
||||
else: calculate_first_day_of_week(Date.add(date, -1), locale)
|
||||
end
|
||||
|
@ -204,11 +204,11 @@ defmodule Mobilizon.Service.DateTime do
|
|||
compare_to_day = Keyword.get(options, :compare_to_day, Date.utc_today())
|
||||
locale = Keyword.get(options, :locale, "en")
|
||||
|
||||
is_first_day_of_week(compare_to_day, locale) && is_between_hours?(options)
|
||||
first_day_of_week?(compare_to_day, locale) && is_between_hours?(options)
|
||||
end
|
||||
|
||||
@spec is_delay_ok_since_last_notification_sent?(DateTime.t(), pos_integer()) :: boolean()
|
||||
def is_delay_ok_since_last_notification_sent?(
|
||||
@spec delay_ok_since_last_notification_sent?(DateTime.t(), pos_integer()) :: boolean()
|
||||
def delay_ok_since_last_notification_sent?(
|
||||
%DateTime{} = last_notification_sent,
|
||||
delay \\ 3_600
|
||||
) do
|
||||
|
@ -216,8 +216,8 @@ defmodule Mobilizon.Service.DateTime do
|
|||
:lt
|
||||
end
|
||||
|
||||
@spec is_same_day?(DateTime.t(), DateTime.t()) :: boolean()
|
||||
def is_same_day?(%DateTime{} = one, %DateTime{} = two) do
|
||||
@spec same_day?(DateTime.t(), DateTime.t()) :: boolean()
|
||||
def same_day?(%DateTime{} = one, %DateTime{} = two) do
|
||||
DateTime.to_date(one) == DateTime.to_date(two)
|
||||
end
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ defmodule Mobilizon.Service.Export.Common do
|
|||
def fetch_actor_event_feed(name, limit) do
|
||||
case Actors.get_actor_by_name(name) do
|
||||
%Actor{} = actor ->
|
||||
if Actor.is_public_visibility?(actor) do
|
||||
if Actor.public_visibility?(actor) do
|
||||
%Page{elements: events} = Events.list_public_upcoming_events_for_actor(actor, 1, limit)
|
||||
%Page{elements: posts} = Posts.get_public_posts_for_group(actor, 1, limit)
|
||||
{:ok, actor, events, posts}
|
||||
|
|
|
@ -265,7 +265,7 @@ defmodule Mobilizon.Service.Export.Feed do
|
|||
end
|
||||
|
||||
defp clear_actor_feed(%Actor{preferred_username: preferred_username} = actor) do
|
||||
if Actor.is_public_visibility?(actor) do
|
||||
if Actor.public_visibility?(actor) do
|
||||
Cachex.del(:feed, "actor_#{preferred_username}")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -216,7 +216,7 @@ defmodule Mobilizon.Service.Export.ICalendar do
|
|||
end
|
||||
|
||||
defp clear_actor_feed(%Actor{preferred_username: preferred_username} = actor) do
|
||||
if Actor.is_public_visibility?(actor) do
|
||||
if Actor.public_visibility?(actor) do
|
||||
Cachex.del(:ics, "actor_#{preferred_username}")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,8 +13,8 @@ defmodule Mobilizon.Service.HTTP.Utils do
|
|||
end
|
||||
end
|
||||
|
||||
@spec is_content_type?(Enum.t(), String.t() | list(String.t())) :: boolean
|
||||
def is_content_type?(headers, content_type) do
|
||||
@spec content_type_matches?(Enum.t(), String.t() | list(String.t())) :: boolean
|
||||
def content_type_matches?(headers, content_type) do
|
||||
headers
|
||||
|> get_header("Content-Type")
|
||||
|> content_type_header_matches(content_type)
|
||||
|
|
|
@ -12,8 +12,8 @@ defmodule Mobilizon.Service.Notifier.Email do
|
|||
|
||||
import Mobilizon.Service.DateTime,
|
||||
only: [
|
||||
is_delay_ok_since_last_notification_sent?: 1,
|
||||
is_delay_ok_since_last_notification_sent?: 2
|
||||
delay_ok_since_last_notification_sent?: 1,
|
||||
delay_ok_since_last_notification_sent?: 2
|
||||
]
|
||||
|
||||
require Logger
|
||||
|
@ -129,7 +129,7 @@ defmodule Mobilizon.Service.Notifier.Email do
|
|||
|
||||
# Delay ok since last notification
|
||||
defp match_group_notifications_setting(:one_hour, _, %DateTime{} = last_notification_sent, _) do
|
||||
is_delay_ok_since_last_notification_sent?(last_notification_sent)
|
||||
delay_ok_since_last_notification_sent?(last_notification_sent)
|
||||
end
|
||||
|
||||
# Delay ok since last notification
|
||||
|
@ -139,7 +139,7 @@ defmodule Mobilizon.Service.Notifier.Email do
|
|||
%DateTime{} = last_notification_sent,
|
||||
options
|
||||
) do
|
||||
is_delay_ok_since_last_notification_sent?(last_notification_sent, 3_600 * 23) and
|
||||
delay_ok_since_last_notification_sent?(last_notification_sent, 3_600 * 23) and
|
||||
Keyword.get(options, :recap, false) != false
|
||||
end
|
||||
|
||||
|
@ -149,7 +149,7 @@ defmodule Mobilizon.Service.Notifier.Email do
|
|||
%DateTime{} = last_notification_sent,
|
||||
options
|
||||
) do
|
||||
is_delay_ok_since_last_notification_sent?(last_notification_sent, 3_600 * 24 * 6) and
|
||||
delay_ok_since_last_notification_sent?(last_notification_sent, 3_600 * 24 * 6) and
|
||||
Keyword.get(options, :recap, false) != false
|
||||
end
|
||||
|
||||
|
|
|
@ -11,9 +11,7 @@ defmodule Mobilizon.Service.RichMedia.Parser do
|
|||
max_body: 2_000_000,
|
||||
timeout: 10_000,
|
||||
recv_timeout: 20_000,
|
||||
follow_redirect: true,
|
||||
# TODO: Remove me once Hackney/HTTPoison fixes their issue with TLS1.3 and OTP 23
|
||||
ssl: [{:versions, [:"tlsv1.2"]}]
|
||||
follow_redirect: true
|
||||
]
|
||||
|
||||
alias Mobilizon.Config
|
||||
|
@ -75,7 +73,7 @@ defmodule Mobilizon.Service.RichMedia.Parser do
|
|||
opts: @options
|
||||
)},
|
||||
{:is_html, _response_headers, true} <-
|
||||
{:is_html, response_headers, is_html?(response_headers)} do
|
||||
{:is_html, response_headers, html?(response_headers)} do
|
||||
body
|
||||
|> convert_utf8(response_headers)
|
||||
|> maybe_parse()
|
||||
|
@ -108,21 +106,21 @@ defmodule Mobilizon.Service.RichMedia.Parser do
|
|||
defp get_data_for_media(response_headers, url) do
|
||||
data = %{title: get_filename_from_headers(response_headers) || get_filename_from_url(url)}
|
||||
|
||||
if is_image?(response_headers) do
|
||||
if image?(response_headers) do
|
||||
Map.put(data, :image_remote_url, url)
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
@spec is_html?(Enum.t()) :: boolean
|
||||
defp is_html?(headers) do
|
||||
is_content_type?(headers, ["text/html", "application/xhtml"])
|
||||
@spec html?(Enum.t()) :: boolean
|
||||
defp html?(headers) do
|
||||
content_type_matches?(headers, ["text/html", "application/xhtml"])
|
||||
end
|
||||
|
||||
@spec is_image?(Enum.t()) :: boolean
|
||||
defp is_image?(headers) do
|
||||
is_content_type?(headers, ["image/"])
|
||||
@spec image?(Enum.t()) :: boolean
|
||||
defp image?(headers) do
|
||||
content_type_matches?(headers, ["image/"])
|
||||
end
|
||||
|
||||
@spec get_filename_from_headers(Enum.t()) :: String.t() | nil
|
||||
|
|
|
@ -81,7 +81,7 @@ defmodule Mobilizon.Service.Workers.LegacyNotifierBuilder do
|
|||
options
|
||||
) do
|
||||
mentionned_actor_ids
|
||||
|> Enum.filter(&Actors.is_member?(&1, Keyword.fetch!(options, :group_id)))
|
||||
|> Enum.filter(&Actors.member?(&1, Keyword.fetch!(options, :group_id)))
|
||||
|> users_from_actor_ids(Keyword.fetch!(options, :author_id))
|
||||
end
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ defmodule Mobilizon.Service.Workers.RefreshInstances do
|
|||
alias Mobilizon.Instances.{Instance, InstanceActor}
|
||||
alias Oban.Job
|
||||
require Logger
|
||||
import Mobilizon.Storage.Ecto, only: [convert_ecto_errors: 1]
|
||||
|
||||
@impl Oban.Worker
|
||||
@spec perform(Oban.Job.t()) :: :ok
|
||||
|
@ -56,6 +57,10 @@ defmodule Mobilizon.Service.Workers.RefreshInstances do
|
|||
Instances.create_instance_actor(args) do
|
||||
Logger.info("Saved instance actor details for domain #{host}")
|
||||
else
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
Logger.error("Unable to save instance \"#{domain}\" metadata")
|
||||
Logger.debug(convert_ecto_errors(changeset))
|
||||
|
||||
err ->
|
||||
Logger.error(inspect(err))
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ defmodule Mobilizon.Service.Workers.SendActivityRecapWorker do
|
|||
only: [
|
||||
is_between_hours?: 1,
|
||||
is_between_hours_on_first_day?: 1,
|
||||
is_delay_ok_since_last_notification_sent?: 1
|
||||
delay_ok_since_last_notification_sent?: 1
|
||||
]
|
||||
|
||||
@impl Oban.Worker
|
||||
|
@ -108,7 +108,7 @@ defmodule Mobilizon.Service.Workers.SendActivityRecapWorker do
|
|||
"Testing if it's less than an hour since the last time we sent an activity recap"
|
||||
)
|
||||
|
||||
is_delay_ok_since_last_notification_sent?(last_notification_sent)
|
||||
delay_ok_since_last_notification_sent?(last_notification_sent)
|
||||
end
|
||||
|
||||
# If we're between notification hours
|
||||
|
|
|
@ -173,26 +173,26 @@ defmodule Mobilizon.Web.PageController do
|
|||
end
|
||||
end
|
||||
|
||||
@spec is_visible?(map) :: boolean()
|
||||
defp is_visible?(%{visibility: v}), do: v in [:public, :unlisted]
|
||||
defp is_visible?(%Tombstone{}), do: true
|
||||
defp is_visible?(_), do: true
|
||||
@spec visible?(map) :: boolean()
|
||||
defp visible?(%{visibility: v}), do: v in [:public, :unlisted]
|
||||
defp visible?(%Tombstone{}), do: true
|
||||
defp visible?(_), do: true
|
||||
|
||||
@spec ok_status?(cache_status) :: boolean()
|
||||
defp ok_status?(status), do: status in [:ok, :commit]
|
||||
|
||||
@typep cache_status :: :ok | :commit | :ignore
|
||||
|
||||
@spec ok_status_and_is_visible?(Plug.Conn.t(), cache_status, map()) :: boolean()
|
||||
defp ok_status_and_is_visible?(_conn, status, o),
|
||||
do: ok_status?(status) and is_visible?(o)
|
||||
@spec ok_status_and_visible?(Plug.Conn.t(), cache_status, map()) :: boolean()
|
||||
defp ok_status_and_visible?(_conn, status, o),
|
||||
do: ok_status?(status) and visible?(o)
|
||||
|
||||
defp checks?(conn, status, o) do
|
||||
cond do
|
||||
ok_status_and_is_visible?(conn, status, o) ->
|
||||
if is_local?(o) == :remote && get_format(conn) == "activity-json", do: :remote, else: true
|
||||
ok_status_and_visible?(conn, status, o) ->
|
||||
if local?(o) == :remote && get_format(conn) == "activity-json", do: :remote, else: true
|
||||
|
||||
is_person?(o) && get_format(conn) == "activity-json" ->
|
||||
person?(o) && get_format(conn) == "activity-json" ->
|
||||
true
|
||||
|
||||
true ->
|
||||
|
@ -200,9 +200,9 @@ defmodule Mobilizon.Web.PageController do
|
|||
end
|
||||
end
|
||||
|
||||
@spec is_local?(map()) :: boolean | :remote
|
||||
defp is_local?(%{local: local}), do: if(local, do: true, else: :remote)
|
||||
defp is_local?(_), do: false
|
||||
@spec local?(map()) :: boolean | :remote
|
||||
defp local?(%{local: local}), do: if(local, do: true, else: :remote)
|
||||
defp local?(_), do: false
|
||||
|
||||
@spec maybe_add_noindex_header(Plug.Conn.t(), map()) :: Plug.Conn.t()
|
||||
defp maybe_add_noindex_header(conn, %{visibility: visibility})
|
||||
|
@ -212,9 +212,9 @@ defmodule Mobilizon.Web.PageController do
|
|||
|
||||
defp maybe_add_noindex_header(conn, _), do: conn
|
||||
|
||||
@spec is_person?(Actor.t()) :: boolean()
|
||||
defp is_person?(%Actor{type: :Person}), do: true
|
||||
defp is_person?(_), do: false
|
||||
@spec person?(Actor.t()) :: boolean()
|
||||
defp person?(%Actor{type: :Person}), do: true
|
||||
defp person?(_), do: false
|
||||
|
||||
defp maybe_add_content_type_header(conn) do
|
||||
case get_format(conn) do
|
||||
|
|
|
@ -87,8 +87,6 @@ defmodule Mobilizon.Web.Email.Group do
|
|||
end
|
||||
end
|
||||
|
||||
# TODO : def send_confirmation_to_inviter()
|
||||
|
||||
@member_roles [:administrator, :moderator, :member]
|
||||
@spec send_group_suspension_notification(Member.t()) :: :ok
|
||||
def send_group_suspension_notification(%Member{actor: %Actor{user_id: nil}}), do: :ok
|
||||
|
|
|
@ -124,6 +124,4 @@ defmodule Mobilizon.Web.Email.Member do
|
|||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
# TODO : def send_confirmation_to_inviter()
|
||||
end
|
||||
|
|
|
@ -71,13 +71,7 @@ defmodule Mobilizon.Web.MediaProxy do
|
|||
@compile {:no_warn_undefined, {:crypto, :mac, 4}}
|
||||
@compile {:no_warn_undefined, {:crypto, :hmac, 3}}
|
||||
defp sha_hmac(key, url) do
|
||||
# :crypto.hmac was removed in OTP24, but :crypto.mac was added in OTP 22.1
|
||||
# TODO: Remove me when we don't support OTP 21/22 anymore
|
||||
if function_exported?(:crypto, :mac, 4) do
|
||||
:crypto.mac(:hmac, :sha, key, url)
|
||||
else
|
||||
:crypto.hmac(:sha, key, url)
|
||||
end
|
||||
:crypto.mac(:hmac, :sha, key, url)
|
||||
end
|
||||
|
||||
@spec filename(String.t()) :: String.t() | nil
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
timezone: @timezone,
|
||||
locale: @locale
|
||||
) %>
|
||||
<% is_same_day?(@start_date, @end_date) -> %>
|
||||
<% same_day?(@start_date, @end_date) -> %>
|
||||
<strong>
|
||||
<%= gettext("On %{date} from %{start_time} to %{end_time}",
|
||||
date: datetime_to_date_string(@start_date, @locale),
|
||||
|
|
|
@ -1 +1 @@
|
|||
<%= cond do %><% @end_date == nil -> %><%= render("date/event_tz_date.text", date: @start_date, event: @event, timezone: @timezone, locale: @locale) %><% is_same_day?(@start_date, @end_date) -> %><%= gettext "On %{date} from %{start_time} to %{end_time}", date: datetime_to_date_string(@start_date, @locale), start_time: datetime_to_time_string(@start_date, @locale), end_time: datetime_to_time_string(@end_date, @locale) %><%= if @event.options.timezone != @timezone do %> <%= gettext "🌐 %{timezone} %{offset}", timezone: @event.options.timezone, offset: Cldr.DateTime.Formatter.zone_gmt(@start_date) %><% end %><% true -> %><%= gettext "From the %{start} to the %{end}", start: datetime_to_string(@start_date, @locale, :short), end: datetime_to_string(@end_date, @locale, :short) %><%= if @event.options.timezone != @timezone do %> <%= gettext "🌐 %{timezone} %{offset}", timezone: @event.options.timezone, offset: Cldr.DateTime.Formatter.zone_gmt(@start_date) %><% end %><% end %>
|
||||
<%= cond do %><% @end_date == nil -> %><%= render("date/event_tz_date.text", date: @start_date, event: @event, timezone: @timezone, locale: @locale) %><% same_day?(@start_date, @end_date) -> %><%= gettext "On %{date} from %{start_time} to %{end_time}", date: datetime_to_date_string(@start_date, @locale), start_time: datetime_to_time_string(@start_date, @locale), end_time: datetime_to_time_string(@end_date, @locale) %><%= if @event.options.timezone != @timezone do %> <%= gettext "🌐 %{timezone} %{offset}", timezone: @event.options.timezone, offset: Cldr.DateTime.Formatter.zone_gmt(@start_date) %><% end %><% true -> %><%= gettext "From the %{start} to the %{end}", start: datetime_to_string(@start_date, @locale, :short), end: datetime_to_string(@end_date, @locale, :short) %><%= if @event.options.timezone != @timezone do %> <%= gettext "🌐 %{timezone} %{offset}", timezone: @event.options.timezone, offset: Cldr.DateTime.Formatter.zone_gmt(@start_date) %><% end %><% end %>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
</script>
|
||||
<%= if is_root(assigns) do %>
|
||||
<%= if root?(assigns) do %>
|
||||
<link rel="preload" href="/img/shape-1.svg" as="image" />
|
||||
<link rel="preload" href="/img/shape-2.svg" as="image" />
|
||||
<link rel="preload" href="/img/shape-3.svg" as="image" />
|
||||
|
|
|
@ -25,7 +25,7 @@ defmodule Mobilizon.Web.EmailView do
|
|||
defdelegate datetime_tz_convert(datetime, timezone), to: DateTimeRenderer
|
||||
defdelegate datetime_relative(datetime, locale \\ "en"), to: DateTimeRenderer
|
||||
defdelegate render_address(address), to: Address
|
||||
defdelegate is_same_day?(one, two), to: DateTimeRenderer
|
||||
defdelegate same_day?(one, two), to: DateTimeRenderer
|
||||
defdelegate display_name(actor), to: Actor
|
||||
defdelegate preferred_username_and_domain(actor), to: Actor
|
||||
|
||||
|
|
|
@ -87,8 +87,8 @@ defmodule Mobilizon.Web.PageView do
|
|||
assigns |> Map.get(:locale, "en") |> get_language_direction()
|
||||
end
|
||||
|
||||
@spec is_root(map()) :: boolean()
|
||||
def is_root(assigns) do
|
||||
@spec root?(map()) :: boolean()
|
||||
def root?(assigns) do
|
||||
assigns |> Map.get(:conn, %{request_path: "/"}) |> Map.get(:request_path, "/") == "/"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
"**/*.{js,ts,vue}": [
|
||||
"eslint --fix",
|
||||
"prettier --write"
|
||||
],
|
||||
"**/*.{ex,exs,eex,heex}": [
|
||||
"mix format",
|
||||
"mix credo"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
defmodule Mobilizon.Storage.Repo.Migrations.ChangeActorInstanceDescriptionTypeToText do
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
alter table(:instance_actors) do
|
||||
modify(:instance_description, :text)
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
alter table(:instance_actors) do
|
||||
modify(:instance_description, :string)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1641,5 +1641,6 @@
|
|||
"Announcements for {eventTitle}": "Announcements for {eventTitle}",
|
||||
"Visit {instance_domain}": "Visit {instance_domain}",
|
||||
"Software details: {software_details}": "Software details: {software_details}",
|
||||
"Only instances with an application actor can be followed": "Only instances with an application actor can be followed"
|
||||
"Only instances with an application actor can be followed": "Only instances with an application actor can be followed",
|
||||
"Domain or instance name": "Domain or instance name"
|
||||
}
|
|
@ -1635,5 +1635,6 @@
|
|||
"Announcements for {eventTitle}": "Annonces pour {eventTitle}",
|
||||
"Visit {instance_domain}": "Visiter {instance_domain}",
|
||||
"Software details: {software_details}": "Détails du logiciel : {software_details}",
|
||||
"Only instances with an application actor can be followed": "Seules les instances avec un acteur application peuvent être suivies"
|
||||
"Only instances with an application actor can be followed": "Seules les instances avec un acteur application peuvent être suivies",
|
||||
"Domain or instance name": "Domaine ou nom de l'instance"
|
||||
}
|
||||
|
|
|
@ -54,15 +54,14 @@
|
|||
>
|
||||
</o-field>
|
||||
<o-field
|
||||
:label="t('Domain')"
|
||||
:label="t('Domain or instance name')"
|
||||
label-for="domain-filter"
|
||||
class="flex-auto"
|
||||
>
|
||||
<o-input
|
||||
id="domain-filter"
|
||||
:placeholder="t('mobilizon-instance.tld')"
|
||||
:value="filterDomain"
|
||||
@input="debouncedUpdateDomainFilter"
|
||||
v-model="filterDomain"
|
||||
/>
|
||||
</o-field>
|
||||
</div>
|
||||
|
@ -223,7 +222,6 @@ import { Paginate } from "@/types/paginate";
|
|||
import RouteName from "../../router/name";
|
||||
import { IInstance } from "@/types/instance.model";
|
||||
import EmptyContent from "@/components/Utils/EmptyContent.vue";
|
||||
import debounce from "lodash/debounce";
|
||||
import {
|
||||
InstanceFilterFollowStatus,
|
||||
InstanceFollowStatus,
|
||||
|
@ -254,12 +252,16 @@ const followStatus = useRouteQuery(
|
|||
|
||||
const { result: instancesResult } = useQuery<{
|
||||
instances: Paginate<IInstance>;
|
||||
}>(INSTANCES, () => ({
|
||||
page: instancePage.value,
|
||||
limit: INSTANCES_PAGE_LIMIT,
|
||||
filterDomain: filterDomain.value,
|
||||
filterFollowStatus: followStatus.value,
|
||||
}));
|
||||
}>(
|
||||
INSTANCES,
|
||||
() => ({
|
||||
page: instancePage.value,
|
||||
limit: INSTANCES_PAGE_LIMIT,
|
||||
filterDomain: filterDomain.value,
|
||||
filterFollowStatus: followStatus.value,
|
||||
}),
|
||||
{ debounce: 500 }
|
||||
);
|
||||
|
||||
const instances = computed(() => instancesResult.value?.instances);
|
||||
|
||||
|
@ -276,13 +278,6 @@ const newRelayAddress = ref("");
|
|||
|
||||
// relayFollowers: Paginate<IFollower> = { elements: [], total: 0 };
|
||||
|
||||
const updateDomainFilter = (event: InputEvent) => {
|
||||
const newValue = (event.target as HTMLInputElement).value;
|
||||
filterDomain.value = newValue;
|
||||
};
|
||||
|
||||
const debouncedUpdateDomainFilter = debounce(updateDomainFilter, 500);
|
||||
|
||||
const hasFilter = computed((): boolean => {
|
||||
return (
|
||||
followStatus.value !== InstanceFilterFollowStatus.ALL ||
|
||||
|
|
|
@ -179,7 +179,7 @@ defmodule Mix.Tasks.Mobilizon.Actors.NewTest do
|
|||
assert %Actor{name: @group_name, preferred_username: @group_username, id: group_id} =
|
||||
Actors.get_group_by_title(@group_username)
|
||||
|
||||
assert Actors.is_administrator?(admin_id, group_id)
|
||||
assert Actors.administrator?(admin_id, group_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue