Improve and activate groups

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2020-09-29 09:53:48 +02:00
parent 1ca46a6863
commit 49a5725da3
131 changed files with 16440 additions and 1929 deletions

View File

@@ -196,8 +196,9 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
end
)
args = Map.put(args, :options, options)
Map.update(args, :tags, [], &ConverterUtils.fetch_tags/1)
args
|> Map.put(:options, options)
|> Map.update(:tags, [], &ConverterUtils.fetch_tags/1)
|> Map.update(:contacts, [], &ConverterUtils.fetch_actors/1)
end
end

View File

@@ -3,8 +3,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
Various utils for converters.
"""
alias Mobilizon.{Actors, Events}
alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.Tag
alias Mobilizon.Mention
alias Mobilizon.Storage.Repo
@@ -42,6 +42,13 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
address
end
def fetch_actors(actors) when is_list(actors) do
Logger.debug("fetching contacts")
actors |> Enum.map(& &1.id) |> Enum.filter(& &1) |> Enum.map(&Actors.get_actor/1)
end
def fetch_actors(_), do: []
@spec build_tags([Tag.t()]) :: [map()]
def build_tags(tags) do
Enum.map(tags, fn %Tag{} = tag ->

View File

@@ -28,7 +28,7 @@ defmodule Mobilizon.GraphQL.API.Groups do
{:error, "A group with this name already exists"}
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, "Profile is not owned by authenticated user"}
end
end
@@ -44,7 +44,7 @@ defmodule Mobilizon.GraphQL.API.Groups do
{:error, "A group with this name already exists"}
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, "Profile is not owned by authenticated user"}
end
end
end

View File

@@ -9,6 +9,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Federation.ActivityPub.Refresher
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
require Logger
@@ -20,10 +21,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
{:ok, actor}
%Actor{} ->
{:error, "Only remote actors may be refreshed"}
{:error, dgettext("errors", "Only remote profiles may be refreshed")}
_ ->
{:error, "No actor found with this ID"}
{:error, dgettext("errors", "No profile found with this ID")}
end
end
@@ -50,22 +51,22 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
{:ok, actor}
%Actor{domain: nil} ->
{:error, "No remote profile found with this ID"}
{:error, dgettext("errors", "No remote profile found with this ID")}
end
else
{:moderator_actor, nil} ->
{:error, "No actor found for the moderator user"}
{:error, dgettext("errors", "No profile found for the moderator user")}
%Actor{suspended: true} ->
{:error, "Actor already suspended"}
{:error, dgettext("errors", "Profile already suspended")}
{:error, _} ->
{:error, "Error while performing background task"}
{:error, dgettext("errors", "Error while performing background task")}
end
end
def suspend_profile(_parent, _args, _resolution) do
{:error, "Only moderators and administrators can suspend a profile"}
{:error, dgettext("errors", "Only moderators and administrators can suspend a profile")}
end
def unsuspend_profile(_parent, %{id: id}, %{
@@ -84,18 +85,18 @@ defmodule Mobilizon.GraphQL.Resolvers.Actor do
{:ok, actor}
else
{:moderator_actor, nil} ->
{:error, "No actor found for the moderator user"}
{:error, dgettext("errors", "No profile found for the moderator user")}
nil ->
{:error, "No remote profile found with this ID"}
{:error, dgettext("errors", "No remote profile found with this ID")}
{:error, _} ->
{:error, "Error while performing background task"}
{:error, dgettext("errors", "Error while performing background task")}
end
end
def unsuspend_profile(_parent, _args, _resolution) do
{:error, "Only moderators and administrators can unsuspend a profile"}
{:error, dgettext("errors", "Only moderators and administrators can unsuspend a profile")}
end
@spec refresh_if_remote(Actor.t()) :: {:ok, Actor.t()}

View File

@@ -17,6 +17,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
alias Mobilizon.Service.Statistics
alias Mobilizon.Storage.Page
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
require Logger
def list_action_logs(
@@ -47,7 +48,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
end
def list_action_logs(_parent, _args, _resolution) do
{:error, "You need to be logged-in and a moderator to list action logs"}
{:error, dgettext("errors", "You need to be logged-in and a moderator to list action logs")}
end
defp transform_action_log(
@@ -174,7 +175,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
end
def get_dashboard(_parent, _args, _resolution) do
{:error, "You need to be logged-in and an administrator to access dashboard statistics"}
{:error,
dgettext(
"errors",
"You need to be logged-in and an administrator to access dashboard statistics"
)}
end
def get_settings(_parent, _args, %{
@@ -185,7 +190,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
end
def get_settings(_parent, _args, _resolution) do
{:error, "You need to be logged-in and an administrator to access admin settings"}
{:error,
dgettext("errors", "You need to be logged-in and an administrator to access admin settings")}
end
def save_settings(_parent, args, %{
@@ -212,7 +218,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
end
def save_settings(_parent, _args, _resolution) do
{:error, "You need to be logged-in and an administrator to save admin settings"}
{:error,
dgettext("errors", "You need to be logged-in and an administrator to save admin settings")}
end
def list_relay_followers(

View File

@@ -8,6 +8,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
alias Mobilizon.Discussions.Comment, as: CommentModel
alias Mobilizon.Users
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
alias Mobilizon.GraphQL.API.Comments
@@ -32,12 +33,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
{:ok, comment}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
def create_comment(_parent, _args, _context) do
{:error, "You are not allowed to create a comment if not connected"}
{:error, dgettext("errors", "You are not allowed to create a comment if not connected")}
end
def update_comment(
@@ -59,7 +60,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
end
def edit_comment(_parent, _args, _context) do
{:error, "You are not allowed to update a comment if not connected"}
{:error, dgettext("errors", "You are not allowed to update a comment if not connected")}
end
def delete_comment(
@@ -87,19 +88,19 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
end
true ->
{:error, "You cannot delete this comment"}
{:error, dgettext("errors", "You cannot delete this comment")}
end
else
%CommentModel{deleted_at: deleted_at} when not is_nil(deleted_at) ->
{:error, "Comment is already deleted"}
{:error, dgettext("errors", "Comment is already deleted")}
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
def delete_comment(_parent, _args, %{}) do
{:error, "You are not allowed to delete a comment if not connected"}
{:error, dgettext("errors", "You are not allowed to delete a comment if not connected")}
end
defp do_delete_comment(%CommentModel{} = comment, %Actor{} = actor) do

View File

@@ -70,7 +70,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
%{
name: Config.instance_name(),
registrations_open: Config.instance_registrations_open?(),
registrations_whitelist: Config.instance_registrations_whitelist?(),
registrations_allowlist: Config.instance_registrations_allowlist?(),
contact: Config.contact(),
demo_mode: Config.instance_demo_mode?(),
description: Config.instance_description(),

View File

@@ -9,6 +9,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
alias Mobilizon.Federation.ActivityPub
alias Mobilizon.Storage.Page
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
def find_discussions_for_actor(
%Actor{id: group_id},
@@ -57,12 +58,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
{:member, true} <- {:member, Actors.is_member?(creator_id, actor_id)} do
{:ok, discussion}
else
nil -> {:error, "No such discussion"}
nil -> {:error, dgettext("errors", "Discussion not found")}
end
end
def get_discussion(_parent, _args, _resolution),
do: {:error, "You need to be logged-in to access discussions"}
do: {:error, dgettext("errors", "You need to be logged-in to access discussions")}
def get_comments_for_discussion(
%Discussion{id: discussion_id},
@@ -177,10 +178,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
{:ok, discussion}
else
{:no_discussion, _} ->
{:error, "No discussion with ID #{discussion_id}"}
{:error, dgettext("errors", "No discussion with ID %{id}", id: discussion_id)}
{:member, _} ->
{:error, "You are not a member of the group the discussion belongs to"}
{:error,
dgettext("errors", "You are not a member of the group the discussion belongs to")}
end
end
end

View File

@@ -13,6 +13,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
alias Mobilizon.GraphQL.Resolvers.Person
alias Mobilizon.Federation.ActivityPub.Activity
import Mobilizon.Web.Gettext
# We limit the max number of events that can be retrieved
@event_max_limit 100
@@ -37,12 +38,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
{:ok, Map.put(event, :organizer_actor, Person.proxify_pictures(event.organizer_actor))}
{:has_event, _} ->
{:error, "Event with UUID #{uuid} not found"}
{:error, dgettext("errors", "Event with UUID %{uuid} not found", uuid: uuid)}
end
end
defp find_private_event(_parent, %{uuid: uuid}, _resolution) do
{:error, "Event with UUID #{uuid} not found"}
{:error, dgettext("errors", "Event with UUID %{uuid} not found", uuid: uuid)}
end
def find_event(parent, %{uuid: uuid} = args, %{context: context} = resolution) do
@@ -56,7 +57,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
find_private_event(parent, args, resolution)
{:access_valid, _} ->
{:error, "Event with UUID #{uuid} not found"}
{:error, dgettext("errors", "Event with UUID %{uuid} not found", uuid)}
end
end
@@ -96,10 +97,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
{:ok, participants}
else
{:is_owned, nil} ->
{:error, "Moderator Actor ID is not owned by authenticated user"}
{:error, dgettext("errors", "Moderator profile is not owned by authenticated user")}
{:actor_approve_permission, _} ->
{:error, "Provided moderator actor ID doesn't have permission on this event"}
{:error,
dgettext("errors", "Provided moderator profile doesn't have permission on this event")}
end
end
@@ -197,7 +199,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
{:ok, event}
else
{:is_owned, nil} ->
{:error, "Organizer actor id is not owned by the user"}
{:error, dgettext("errors", "Organizer profile is not owned by the user")}
{:error, _, %Ecto.Changeset{} = error, _} ->
{:error, error}
@@ -208,7 +210,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
end
def create_event(_parent, _args, _resolution) do
{:error, "You need to be logged-in to create events"}
{:error, dgettext("errors", "You need to be logged-in to create events")}
end
@doc """
@@ -231,10 +233,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
{:ok, event}
else
{:error, :event_not_found} ->
{:error, "Event not found"}
{:error, dgettext("errors", "Event not found")}
{:is_owned, nil} ->
{:error, "User doesn't own actor"}
{:error, dgettext("errors", "User doesn't own profile")}
{:error, _, %Ecto.Changeset{} = error, _} ->
{:error, error}
@@ -242,7 +244,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
end
def update_event(_parent, _args, _resolution) do
{:error, "You need to be logged-in to update an event"}
{:error, dgettext("errors", "You need to be logged-in to update an event")}
end
@doc """
@@ -269,19 +271,19 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
end
true ->
{:error, "You cannot delete this event"}
{:error, dgettext("errors", "You cannot delete this event")}
end
else
{:error, :event_not_found} ->
{:error, "Event not found"}
{:error, dgettext("errors", "Event not found")}
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
def delete_event(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete an event"}
{:error, dgettext("errors", "You need to be logged-in to delete an event")}
end
defp do_delete_event(%Event{} = event, %Actor{} = actor, federate \\ true)

View File

@@ -7,6 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
alias Mobilizon.Events
alias Mobilizon.Events.FeedToken
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
require Logger
@@ -24,7 +25,7 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
{:ok, feed_token}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
@@ -40,7 +41,7 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
@spec create_feed_token(any, map, map) :: {:error, String.t()}
def create_feed_token(_parent, _args, %{}) do
{:error, "You are not allowed to create a feed token if not connected"}
{:error, dgettext("errors", "You are not allowed to create a feed token if not connected")}
end
@doc """
@@ -62,21 +63,21 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
{:ok, res}
else
{:error, nil} ->
{:error, "No such feed token"}
{:error, dgettext("errors", "No such feed token")}
:error ->
{:error, "Token is not a valid UUID"}
{:error, dgettext("errors", "Token is not a valid UUID")}
{:no_token, _} ->
{:error, "Token does not exist"}
{:error, dgettext("errors", "Token does not exist")}
{:token_from_user, false} ->
{:error, "You don't have permission to delete this token"}
{:error, dgettext("errors", "You don't have permission to delete this token")}
end
end
@spec delete_feed_token(any, map, map) :: {:error, String.t()}
def delete_feed_token(_parent, _args, %{}) do
{:error, "You are not allowed to delete a feed token if not connected"}
{:error, dgettext("errors", "You are not allowed to delete a feed token if not connected")}
end
end

View File

@@ -10,6 +10,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
alias Mobilizon.GraphQL.API
alias Mobilizon.GraphQL.Resolvers.Person
alias Mobilizon.Users.User
alias Mobilizon.Web.Upload
import Mobilizon.Web.Gettext
require Logger
@@ -36,7 +38,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
find_group(parent, args, nil)
_ ->
{:error, "Group with name #{name} not found"}
{:error, dgettext("errors", "Group with name %{name} not found", name: name)}
end
end
@@ -50,7 +52,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
{:ok, actor}
else
_ ->
{:error, "Group with name #{name} not found"}
{:error, dgettext("errors", "Group with name %{name} not found", name: name)}
end
end
@@ -64,7 +66,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
{:ok, actor}
else
_ ->
{:error, "Group with ID #{id} not found"}
{:error, dgettext("errors", "Group with ID %{id} not found", id: id)}
end
end
@@ -92,7 +94,23 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
end
def list_groups(_parent, _args, _resolution),
do: {:error, "You may not list groups unless moderator."}
do: {:error, dgettext("errors", "You may not list groups unless moderator.")}
# TODO Move me to somewhere cleaner
defp save_attached_pictures(args) do
Enum.reduce([:avatar, :banner], args, fn key, args ->
if Map.has_key?(args, key) && !is_nil(args[key][:picture]) do
pic = args[key][:picture]
with {:ok, %{name: name, url: url, content_type: content_type, size: _size}} <-
Upload.store(pic.file, type: key, description: pic.alt) do
Map.put(args, key, %{"name" => name, "url" => url, "mediaType" => content_type})
end
else
args
end
end)
end
@doc """
Create a new group. The creator is automatically added as admin
@@ -109,6 +127,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
with creator_actor_id <- Map.get(args, :creator_actor_id),
{:is_owned, %Actor{} = creator_actor} <- User.owns_actor(user, creator_actor_id),
args <- Map.put(args, :creator_actor, creator_actor),
args <- save_attached_pictures(args),
{:ok, _activity, %Actor{type: :Group} = group} <-
API.Groups.create_group(args) do
{:ok, group}
@@ -117,7 +136,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
{:error, err}
{:is_owned, nil} ->
{:error, "Creator actor id is not owned by the current user"}
{:error, dgettext("errors", "Creator profile is not owned by the current user")}
end
end
@@ -139,6 +158,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
) do
with %Actor{} = updater_actor <- Users.get_actor_for_user(user),
args <- Map.put(args, :updater_actor, updater_actor),
args <- save_attached_pictures(args),
{:ok, _activity, %Actor{type: :Group} = group} <-
API.Groups.update_group(args) do
{:ok, group}
@@ -147,12 +167,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
{:error, err}
{:is_owned, nil} ->
{:error, "Creator actor id is not owned by the current user"}
{:error, dgettext("errors", "Creator profile is not owned by the current user")}
end
end
def update_group(_parent, _args, _resolution) do
{:error, "You need to be logged-in to update a group"}
{:error, dgettext("errors", "You need to be logged-in to update a group")}
end
@doc """
@@ -175,18 +195,19 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
{:ok, %{id: group.id}}
else
{:error, :group_not_found} ->
{:error, "Group not found"}
{:error, dgettext("errors", "Group not found")}
{:error, :member_not_found} ->
{:error, "Actor id is not a member of this group"}
{:error, dgettext("errors", "Current profile is not a member of this group")}
{:is_admin, false} ->
{:error, "Actor id is not an administrator of the selected group"}
{:error,
dgettext("errors", "Current profile is not an administrator of the selected group")}
end
end
def delete_group(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete a group"}
{:error, dgettext("errors", "You need to be logged-in to delete a group")}
end
@doc """
@@ -219,21 +240,21 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:error, :group_not_found} ->
{:error, "Group id not found"}
{:error, dgettext("errors", "Group not found")}
{:is_able_to_join, false} ->
{:error, "You cannot join this group"}
{:error, dgettext("errors", "You cannot join this group")}
{:ok, %Member{}} ->
{:error, "You are already a member of this group"}
{:error, dgettext("errors", "You are already a member of this group")}
end
end
def join_group(_parent, _args, _resolution) do
{:error, "You need to be logged-in to join a group"}
{:error, dgettext("errors", "You need to be logged-in to join a group")}
end
@doc """
@@ -254,18 +275,19 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
{:ok, member}
else
{:error, :member_not_found} ->
{:error, "Member not found"}
{:error, dgettext("errors", "Member not found")}
{:group, nil} ->
{:error, "Group not found"}
{:error, dgettext("errors", "Group not found")}
{:is_not_only_admin, false} ->
{:error, "You can't leave this group because you are the only administrator"}
{:error,
dgettext("errors", "You can't leave this group because you are the only administrator")}
end
end
def leave_group(_parent, _args, _resolution) do
{:error, "You need to be logged-in to leave a group"}
{:error, dgettext("errors", "You need to be logged-in to leave a group")}
end
def find_events_for_group(

View File

@@ -10,6 +10,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
alias Mobilizon.Federation.ActivityPub.Refresher
alias Mobilizon.Storage.Page
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
@doc """
Find members for group.
@@ -73,22 +74,22 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
{:ok, member}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:error, :group_not_found} ->
{:error, "Group id not found"}
{:error, dgettext("errors", "Group not found")}
{:target_actor_username, _} ->
{:error, "Actor invited doesn't exist"}
{:error, dgettext("errors", "Profile invited doesn't exist")}
{:has_rights_to_invite, {:error, :member_not_found}} ->
{:error, "You are not a member of this group"}
{:error, dgettext("errors", "You are not a member of this group")}
{:has_rights_to_invite, _} ->
{:error, "You cannot invite to this group"}
{:error, dgettext("errors", "You cannot invite to this group")}
{:ok, %Member{}} ->
{:error, "Actor is already a member of this group"}
{:error, dgettext("errors", "Profile is already a member of this group")}
end
end
@@ -133,11 +134,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
{:ok, member}
else
{:has_rights_to_update_role, {:error, :member_not_found}} ->
{:error, "You are not a moderator or admin for this group"}
{:error, dgettext("errors", "You are not a moderator or admin for this group")}
{:is_only_admin, true} ->
{:error,
"You can't set yourself to a lower member role for this group because you are the only administrator"}
dgettext(
"errors",
"You can't set yourself to a lower member role for this group because you are the only administrator"
)}
end
end

View File

@@ -11,6 +11,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
alias Mobilizon.Web.Email
alias Mobilizon.Web.Email.Checker
require Logger
import Mobilizon.Web.Gettext
@doc """
Join an event for an regular actor
@@ -25,7 +26,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
do_actor_join_event(actor, event_id, args)
_ ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
@@ -82,28 +83,29 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
{:error, err}
{:has_event, _} ->
{:error, "Event with this ID #{inspect(event_id)} doesn't exist"}
{:error,
dgettext("errors", "Event with this ID %{id} doesn't exist", id: inspect(event_id))}
{:anonymous_participation_enabled, false} ->
{:error, "Anonymous participation is not enabled"}
{:error, dgettext("errors", "Anonymous participation is not enabled")}
{:anonymous_actor_id, false} ->
{:error, "Actor ID provided is not the anonymous actor one"}
{:error, dgettext("errors", "Profile ID provided is not the anonymous profile one")}
{:email_required, _} ->
{:error, "A valid email is required by your instance"}
{:error, dgettext("errors", "A valid email is required by your instance")}
{:actor_not_found, _} ->
Logger.error(
"The actor ID \"#{actor_id}\" provided by configuration doesn't match any actor in database"
)
{:error, "Internal Error"}
{:error, dgettext("errors", "Internal Error")}
end
end
def actor_join_event(_parent, _args, _resolution) do
{:error, "You need to be logged-in to join an event"}
{:error, dgettext("errors", "You need to be logged-in to join an event")}
end
@spec do_actor_join_event(Actor.t(), integer | String.t(), map()) ::
@@ -119,16 +121,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
{:ok, participant}
else
{:maximum_attendee_capacity, _} ->
{:error, "The event has already reached its maximum capacity"}
{:error, dgettext("errors", "The event has already reached its maximum capacity")}
{:has_event, _} ->
{:error, "Event with this ID #{inspect(event_id)} doesn't exist"}
{:error,
dgettext("errors", "Event with this ID %{id} doesn't exist", id: inspect(event_id))}
{:error, :event_not_found} ->
{:error, "Event id not found"}
{:error, dgettext("errors", "Event id not found")}
{:ok, %Participant{}} ->
{:error, "You are already a participant of this event"}
{:error, dgettext("errors", "You are already a participant of this event")}
end
end
@@ -153,16 +156,21 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
{:ok, %{event: %{id: event_id}, actor: %{id: actor_id}, id: participant_id}}
else
{:has_event, _} ->
{:error, "Event with this ID #{inspect(event_id)} doesn't exist"}
{:error,
dgettext("errors", "Event with this ID %{id} doesn't exist", id: inspect(event_id))}
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:only_organizer, true} ->
{:error, "You can't leave event because you're the only event creator participant"}
{:error,
dgettext(
"errors",
"You can't leave event because you're the only event creator participant"
)}
{:error, :participant_not_found} ->
{:error, "Participant not found"}
{:error, dgettext("errors", "Participant not found")}
end
end
@@ -181,18 +189,22 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
{:error, "Event with this ID #{inspect(event_id)} doesn't exist"}
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:only_organizer, true} ->
{:error, "You can't leave event because you're the only event creator participant"}
{:error,
dgettext(
"errors",
"You can't leave event because you're the only event creator participant"
)}
{:error, :participant_not_found} ->
{:error, "Participant not found"}
{:error, dgettext("errors", "Participant not found")}
end
end
def actor_leave_event(_parent, _args, _resolution) do
{:error, "You need to be logged-in to leave an event"}
{:error, dgettext("errors", "You need to be logged-in to leave an event")}
end
def update_participation(
@@ -219,19 +231,20 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
{:ok, participation}
else
{:is_owned, nil} ->
{:error, "Moderator Actor ID is not owned by authenticated user"}
{:error, dgettext("errors", "Moderator profile is not owned by authenticated user")}
{:has_participation, nil} ->
{:error, "Participant not found"}
{:error, dgettext("errors", "Participant not found")}
{:actor_approve_permission, _} ->
{:error, "Provided moderator actor ID doesn't have permission on this event"}
{:error,
dgettext("errors", "Provided moderator profile doesn't have permission on this event")}
{:same_role, true} ->
{:error, "Participant already has role #{new_role}"}
{:error, dgettext("errors", "Participant already has role %{role}", role: new_role)}
{:error, :participant_not_found} ->
{:error, "Participant not found"}
{:error, dgettext("errors", "Participant not found")}
end
end
@@ -251,7 +264,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
{:ok, participant}
else
{:has_participant, _} ->
{:error, "This token is invalid"}
{:error, dgettext("errors", "This token is invalid")}
end
end

View File

@@ -12,6 +12,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
alias Mobilizon.Storage.Page
alias Mobilizon.Users
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
alias Mobilizon.Federation.ActivityPub
@@ -27,7 +28,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, actor}
else
_ ->
{:error, "Person with ID #{id} not found"}
{:error, dgettext("errors", "Person with ID %{id} not found", id: id)}
end
end
@@ -41,7 +42,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, actor}
else
_ ->
{:error, "Person with username #{preferred_username} not found"}
{:error,
dgettext("errors", "Person with username %{username} not found",
username: preferred_username
)}
end
end
@@ -66,7 +70,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
end
def list_persons(_parent, _args, _resolution) do
{:error, "You need to be logged-in and a moderator to list persons"}
{:error, dgettext("errors", "You need to be logged-in and a moderator to list persons")}
end
@doc """
@@ -77,7 +81,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
end
def get_current_person(_parent, _args, _resolution) do
{:error, "You need to be logged-in to view current person"}
{:error, dgettext("errors", "You need to be logged-in to view current person")}
end
@doc """
@@ -88,7 +92,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
end
def identities(_parent, _args, _resolution) do
{:error, "You need to be logged-in to view your list of identities"}
{:error, dgettext("errors", "You need to be logged-in to view your list of identities")}
end
@doc """
@@ -111,7 +115,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
This function is used to create more identities from an existing user
"""
def create_person(_parent, _args, _resolution) do
{:error, "You need to be logged-in to create a new identity"}
{:error, dgettext("errors", "You need to be logged-in to create a new identity")}
end
@doc """
@@ -132,15 +136,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, actor}
else
{:find_actor, nil} ->
{:error, "Actor not found"}
{:error, dgettext("errors", "Profile not found")}
{:is_owned, nil} ->
{:error, "Actor is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
def update_person(_parent, _args, _resolution) do
{:error, "You need to be logged-in to update an identity"}
{:error, dgettext("errors", "You need to be logged-in to update an identity")}
end
@doc """
@@ -160,21 +164,21 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, actor}
else
{:find_actor, nil} ->
{:error, "Actor not found"}
{:error, dgettext("errors", "Profile not found")}
{:last_identity, true} ->
{:error, "Cannot remove the last identity of a user"}
{:error, dgettext("errors", "Cannot remove the last identity of a user")}
{:last_admin, true} ->
{:error, "Cannot remove the last administrator of a group"}
{:error, dgettext("errors", "Cannot remove the last administrator of a group")}
{:is_owned, nil} ->
{:error, "Actor is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
def delete_person(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete an identity"}
{:error, dgettext("errors", "You need to be logged-in to delete an identity")}
end
defp last_identity?(user) do
@@ -210,10 +214,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, new_person}
else
{:error, :user_not_found} ->
{:error, "No user with this email was found"}
{:error, dgettext("errors", "No user with this email was found")}
{:no_actor, _} ->
{:error, "You already have a profile for this user"}
{:error, dgettext("errors", "You already have a profile for this user")}
{:error, %Ecto.Changeset{} = e} ->
{:error, e}
@@ -234,7 +238,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, %Page{elements: [participant], total: 1}}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:no_participant, _} ->
{:ok, %Page{elements: [], total: 0}}
@@ -266,7 +270,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, page}
else
{:is_owned, false} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
@@ -279,7 +283,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, participations}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
@@ -301,7 +305,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
{:ok, nil}
_ ->
{:error, "User not found"}
{:error, dgettext("errors", "User not found")}
end
end

View File

@@ -7,6 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Picture do
alias Mobilizon.Media
alias Mobilizon.Media.Picture
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
@doc """
Get picture for an event's pic
@@ -41,7 +42,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Picture do
}}
_error ->
{:error, "Picture with ID #{picture_id} was not found"}
{:error, dgettext("errors", "Picture with ID %{id} was not found", id: picture_id)}
end
end
@@ -71,7 +72,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Picture do
}}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
error ->
{:error, error}
@@ -79,6 +80,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Picture do
end
def upload_picture(_parent, _args, _resolution) do
{:error, "You need to login to upload a picture"}
{:error, dgettext("errors", "You need to login to upload a picture")}
end
end

View File

@@ -10,6 +10,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
alias Mobilizon.Posts.Post
alias Mobilizon.Storage.Page
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
require Logger
@@ -75,7 +76,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
{:ok, post}
else
{:member, false} -> get_post(parent, %{slug: slug}, nil)
{:post, _} -> {:error, "No such post"}
{:post, _} -> {:error, dgettext("errors", "No such post")}
end
end
@@ -90,12 +91,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
{:ok, post}
{:post, _} ->
{:error, "No such post"}
{:error, dgettext("errors", "No such post")}
end
end
def get_post(_parent, _args, _resolution) do
{:error, "No such post"}
{:error, dgettext("errors", "No such post")}
end
def create_post(
@@ -120,16 +121,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
) do
{:ok, post}
else
{:own_check, _} ->
{:error, "Parent post doesn't match this group"}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
def create_post(_parent, _args, _resolution) do
{:error, "You need to be logged-in to create posts"}
{:error, dgettext("errors", "You need to be logged-in to create posts")}
end
def update_post(
@@ -151,18 +149,18 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
{:ok, post}
else
{:uuid, :error} ->
{:error, "Post ID is not a valid ID"}
{:error, dgettext("errors", "Post ID is not a valid ID")}
{:post, _} ->
{:error, "Post doesn't exist"}
{:error, dgettext("errors", "Post doesn't exist")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
def update_post(_parent, _args, _resolution) do
{:error, "You need to be logged-in to update posts"}
{:error, dgettext("errors", "You need to be logged-in to update posts")}
end
def delete_post(
@@ -184,17 +182,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Post do
{:ok, post}
else
{:uuid, :error} ->
{:error, "Post ID is not a valid ID"}
{:error, dgettext("errors", "Post ID is not a valid ID")}
{:post, _} ->
{:error, "Post doesn't exist"}
{:error, dgettext("errors", "Post doesn't exist")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
def delete_post(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete posts"}
{:error, dgettext("errors", "You need to be logged-in to delete posts")}
end
end

View File

@@ -11,6 +11,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
alias Mobilizon.Reports
alias Mobilizon.Reports.{Note, Report}
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
alias Mobilizon.GraphQL.API
@@ -24,7 +25,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
end
def list_reports(_parent, _args, _resolution) do
{:error, "You need to be logged-in and a moderator to list reports"}
{:error, dgettext("errors", "You need to be logged-in and a moderator to list reports")}
end
def get_report(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
@@ -34,12 +35,12 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
{:ok, report}
nil ->
{:error, "Report not found"}
{:error, dgettext("errors", "Report not found")}
end
end
def get_report(_parent, _args, _resolution) do
{:error, "You need to be logged-in and a moderator to view a report"}
{:error, dgettext("errors", "You need to be logged-in and a moderator to view a report")}
end
@doc """
@@ -55,10 +56,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
{:ok, report}
else
{:is_owned, nil} ->
{:error, "Reporter actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Reporter profile is not owned by authenticated user")}
_error ->
{:error, "Error while saving report"}
{:error, dgettext("errors", "Error while saving report")}
end
end
@@ -77,18 +78,18 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
{:ok, report}
else
{:anonymous_reporting_allowed, _} ->
{:error, "You need to be logged-in to create reports"}
{:error, dgettext("errors", "You need to be logged-in to create reports")}
{:wrong_id, _} ->
{:error, "Reporter ID is not the anonymous actor id"}
{:error, dgettext("errors", "Reporter ID does not match the anonymous profile id")}
_error ->
{:error, "Error while saving report"}
{:error, dgettext("errors", "Error while saving report")}
end
end
def create_report(_parent, _args, _resolution) do
{:error, "You need to be logged-in to create reports"}
{:error, dgettext("errors", "You need to be logged-in to create reports")}
end
@doc """
@@ -106,15 +107,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
{:ok, report}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
_error ->
{:error, "Error while updating report"}
{:error, dgettext("errors", "Error while updating report")}
end
end
def update_report(_parent, _args, _resolution) do
{:error, "You need to be logged-in and a moderator to update a report"}
{:error, dgettext("errors", "You need to be logged-in and a moderator to update a report")}
end
def create_report_note(

View File

@@ -11,6 +11,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
alias Mobilizon.Service.RichMedia.Parser
alias Mobilizon.Storage.Page
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
require Logger
@@ -82,13 +83,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
{:resource, Resources.get_resource_by_group_and_path_with_preloads(group_id, path)} do
{:ok, resource}
else
{:member, false} -> {:error, "Actor is not member of group"}
{:resource, _} -> {:error, "No such resource"}
{:member, false} -> {:error, dgettext("errors", "Profile is not member of group")}
{:resource, _} -> {:error, dgettext("errors", "No such resource")}
end
end
def get_resource(_parent, _args, _resolution) do
{:error, "You need to be logged-in to access resources"}
{:error, dgettext("errors", "You need to be logged-in to access resources")}
end
def create_resource(
@@ -116,15 +117,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
{:ok, resource}
else
{:own_check, _} ->
{:error, "Parent resource doesn't match this group"}
{:error, dgettext("errors", "Parent resource doesn't belong to this group")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
def create_resource(_parent, _args, _resolution) do
{:error, "You need to be logged-in to create resources"}
{:error, dgettext("errors", "You need to be logged-in to create resources")}
end
def update_resource(
@@ -145,15 +146,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
{:ok, resource}
else
{:resource, _} ->
{:error, "Resource doesn't exist"}
{:error, dgettext("errors", "Resource doesn't exist")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
def update_resource(_parent, _args, _resolution) do
{:error, "You need to be logged-in to update resources"}
{:error, dgettext("errors", "You need to be logged-in to update resources")}
end
def delete_resource(
@@ -174,15 +175,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
{:ok, resource}
else
{:resource, _} ->
{:error, "Resource doesn't exist"}
{:error, dgettext("errors", "Resource doesn't exist")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
def delete_resource(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete resources"}
{:error, dgettext("errors", "You need to be logged-in to delete resources")}
end
def preview_resource_link(
@@ -200,7 +201,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Resource do
end
def preview_resource_link(_parent, _args, _resolution) do
{:error, "You need to be logged-in to view a resource preview"}
{:error, dgettext("errors", "You need to be logged-in to view a resource preview")}
end
@spec get_eventual_parent(map()) :: Resource.t() | nil

View File

@@ -9,6 +9,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
alias Mobilizon.Storage.Page
alias Mobilizon.Todos.{Todo, TodoList}
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
require Logger
@@ -53,10 +54,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
{:ok, page}
else
{:is_owned, nil} ->
{:error, "Actor id is not owned by authenticated user"}
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
@@ -74,13 +75,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
{:ok, todo}
else
{:todo, nil} ->
{:error, "Todo list doesn't exist"}
{:error, dgettext("errors", "Todo list doesn't exist")}
{:actor, nil} ->
{:error, "No actor found for user"}
{:error, dgettext("errors", "No profile found for user")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
@@ -98,7 +99,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
{:ok, todo_list}
else
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
@@ -118,10 +119,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
# {:ok, todo}
# else
# {:todo_list, _} ->
# {:error, "TodoList doesn't exist"}
# {:error, "Todo list doesn't exist"}
# {:member, _} ->
# {:error, "Actor id is not member of group"}
# {:error, "Profile is not member of group"}
# end
# end
@@ -141,10 +142,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
# {:ok, todo}
# else
# {:todo_list, _} ->
# {:error, "TodoList doesn't exist"}
# {:error, "Todo list doesn't exist"}
# {:member, _} ->
# {:error, "Actor id is not member of group"}
# {:error, "Profile is not member of group"}
# end
# end
@@ -164,13 +165,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
{:ok, todo}
else
{:todo, nil} ->
{:error, "Todo doesn't exist"}
{:error, dgettext("errors", "Todo doesn't exist")}
{:actor, nil} ->
{:error, "No actor found for user"}
{:error, dgettext("errors", "No profile found for user")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
@@ -190,10 +191,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
{:ok, todo}
else
{:todo_list, _} ->
{:error, "TodoList doesn't exist"}
{:error, dgettext("errors", "Todo list doesn't exist")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
@@ -215,13 +216,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
{:ok, todo}
else
{:todo_list, _} ->
{:error, "TodoList doesn't exist"}
{:error, dgettext("errors", "Todo list doesn't exist")}
{:todo, _} ->
{:error, "Todo doesn't exist"}
{:error, dgettext("errors", "Todo doesn't exist")}
{:member, _} ->
{:error, "Actor id is not member of group"}
{:error, dgettext("errors", "Profile is not member of group")}
end
end
@@ -243,13 +244,13 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
# {:ok, todo}
# else
# {:todo_list, _} ->
# {:error, "TodoList doesn't exist"}
# {:error, "Todo list doesn't exist"}
# {:todo, _} ->
# {:error, "Todo doesn't exist"}
# {:member, _} ->
# {:error, "Actor id is not member of group"}
# {:error, "Profile is not member of group"}
# end
# end
end

View File

@@ -15,6 +15,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
alias Mobilizon.Users.{Setting, User}
alias Mobilizon.Web.{Auth, Email}
import Mobilizon.Web.Gettext
require Logger
@@ -54,7 +55,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
end
def list_users(_parent, _args, _resolution) do
{:error, "You need to have admin access to list users"}
{:error, dgettext("errors", "You need to have admin access to list users")}
end
@doc """
@@ -72,13 +73,17 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, user_and_tokens}
else
{:error, :user_not_found} ->
{:error, "No user with this email was found"}
{:error, dgettext("errors", "No user with this email was found")}
{:error, :disabled_user} ->
{:error, "This user has been disabled"}
{:error, dgettext("errors", "This user has been disabled")}
{:error, _error} ->
{:error, "Impossible to authenticate, either your email or password are invalid."}
{:error,
dgettext(
"errors",
"Impossible to authenticate, either your email or password are invalid."
)}
end
end
@@ -95,12 +100,12 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
else
{:error, message} ->
Logger.debug("Cannot refresh user token: #{inspect(message)}")
{:error, "Cannot refresh the token"}
{:error, dgettext("errors", "Cannot refresh the token")}
end
end
def refresh_token(_parent, _params, _context) do
{:error, "You need to have an existing token to get a refresh token"}
{:error, dgettext("errors", "You need to have an existing token to get a refresh token")}
end
@doc """
@@ -117,10 +122,10 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, user}
else
:registration_closed ->
{:error, "Registrations are not enabled"}
{:error, dgettext("errors", "Registrations are not open")}
:not_whitelisted ->
{:error, "Your email is not on the whitelist"}
:not_allowlisted ->
{:error, dgettext("errors", "Your email is not on the allowlist")}
error ->
error
@@ -133,22 +138,22 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
Config.instance_registrations_open?() ->
:registration_ok
Config.instance_registrations_whitelist?() ->
check_white_listed_email?(email)
Config.instance_registrations_allowlist?() ->
check_allow_listed_email?(email)
true ->
:registration_closed
end
end
@spec check_white_listed_email?(String.t()) :: :registration_ok | :not_whitelisted
defp check_white_listed_email?(email) do
@spec check_allow_listed_email?(String.t()) :: :registration_ok | :not_allowlisted
defp check_allow_listed_email?(email) do
[_, domain] = String.split(email, "@", parts: 2, trim: true)
if domain in Config.instance_registrations_whitelist() or
email in Config.instance_registrations_whitelist(),
if domain in Config.instance_registrations_allowlist() or
email in Config.instance_registrations_allowlist(),
do: :registration_ok,
else: :not_whitelisted
else: :not_allowlisted
end
@doc """
@@ -171,7 +176,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
Logger.info("Unable to validate user with token #{token}")
Logger.debug(inspect(error))
{:error, "Unable to validate user"}
{:error, dgettext("errors", "Unable to validate user")}
end
end
@@ -187,10 +192,10 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, email}
else
{:error, :user_not_found} ->
{:error, "No user to validate with this email was found"}
{:error, dgettext("errors", "No user to validate with this email was found")}
{:error, :email_too_soon} ->
{:error, "You requested again a confirmation email too soon"}
{:error, dgettext("errors", "You requested again a confirmation email too soon")}
end
end
@@ -207,14 +212,14 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, email}
else
{:can_reset_password, false} ->
{:error, "This user can't reset their password"}
{:error, dgettext("errors", "This user can't reset their password")}
{:error, :user_not_found} ->
# TODO : implement rate limits for this endpoint
{:error, "No user with this email was found"}
{:error, dgettext("errors", "No user with this email was found")}
{:error, :email_too_soon} ->
{:error, "You requested again a confirmation email too soon"}
{:error, dgettext("errors", "You requested again a confirmation email too soon")}
end
end
@@ -322,19 +327,22 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, user}
else
{:current_password, _} ->
{:error, "The current password is invalid"}
{:error, dgettext("errors", "The current password is invalid")}
{:same_password, true} ->
{:error, "The new password must be different"}
{:error, dgettext("errors", "The new password must be different")}
{:error, %Ecto.Changeset{errors: [password: {"registration.error.password_too_short", _}]}} ->
{:error,
"The password you have chosen is too short. Please make sure your password contains at least 6 characters."}
dgettext(
"errors",
"The password you have chosen is too short. Please make sure your password contains at least 6 characters."
)}
end
end
def change_password(_parent, _args, _resolution) do
{:error, "You need to be logged-in to change your password"}
{:error, dgettext("errors", "You need to be logged-in to change your password")}
end
def change_email(_parent, %{email: new_email, password: password}, %{
@@ -365,18 +373,18 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, user}
else
{:current_password, _} ->
{:error, "The password provided is invalid"}
{:error, dgettext("errors", "The password provided is invalid")}
{:same_email, true} ->
{:error, "The new email must be different"}
{:error, dgettext("errors", "The new email must be different")}
{:email_valid, _} ->
{:error, "The new email doesn't seem to be valid"}
{:error, dgettext("errors", "The new email doesn't seem to be valid")}
end
end
def change_email(_parent, _args, _resolution) do
{:error, "You need to be logged-in to change your email"}
{:error, dgettext("errors", "You need to be logged-in to change your email")}
end
def validate_email(_parent, %{token: token}, _resolution) do
@@ -406,10 +414,10 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
Admin.log_action(moderator_actor, "delete", user)
else
{:moderator_actor, nil} ->
{:error, "No actor found for the moderator user"}
{:error, dgettext("errors", "No profile found for the moderator user")}
%User{disabled: true} ->
{:error, "User already disabled"}
{:error, dgettext("errors", "User already disabled")}
end
end
@@ -428,15 +436,15 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
do_delete_account(user)
{:confirmation_password, nil} ->
{:error, "The password provided is invalid"}
{:error, dgettext("errors", "The password provided is invalid")}
{:current_password, _} ->
{:error, "The password provided is invalid"}
{:error, dgettext("errors", "The password provided is invalid")}
end
end
def delete_account(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete your account"}
{:error, dgettext("errors", "You need to be logged-in to delete your account")}
end
defp do_delete_account(%User{} = user, actor_performing \\ nil) do
@@ -478,7 +486,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:ok, settings}
else
{:same_user, _} ->
{:error, "User requested is not logged-in"}
{:error, dgettext("errors", "User requested is not logged-in")}
end
end
@@ -503,7 +511,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
{:error, changeset} ->
Logger.debug(inspect(changeset))
{:error, "Error while saving user setting"}
{:error, dgettext("errors", "Error while saving user settings")}
end
end

View File

@@ -15,7 +15,7 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
field(:contact, :string)
field(:registrations_open, :boolean)
field(:registrations_whitelist, :boolean)
field(:registrations_allowlist, :boolean)
field(:demo_mode, :boolean)
field(:country_code, :string)
field(:location, :lonlat)

View File

@@ -76,6 +76,8 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
resolve(&Event.list_participants_for_event/3)
end
field(:contacts, list_of(:actor), description: "The events contacts")
field(:related_events, list_of(:event),
resolve: &Event.list_related_events/3,
description: "Events related to this one"
@@ -258,6 +260,10 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
)
end
input_object :contact do
field(:id, :string, description: "The Contact Actor ID")
end
object :event_queries do
@desc "Get all events"
field :events, list_of(:event) do
@@ -303,6 +309,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
arg(:physical_address, :address_input)
arg(:options, :event_options_input)
arg(:draft, :boolean, default_value: false)
arg(:contacts, list_of(:contact), default_value: [])
resolve(handle_errors(&Event.create_event/3))
end
@@ -334,6 +341,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
arg(:physical_address, :address_input)
arg(:options, :event_options_input)
arg(:draft, :boolean)
arg(:contacts, list_of(:contact), default_value: [])
resolve(handle_errors(&Event.update_event/3))
end

View File

@@ -1579,7 +1579,8 @@ defmodule Mobilizon.Actors do
:comments,
:attributed_to,
:tags,
:physical_address
:physical_address,
:contacts
])
ActivityPub.delete(event, actor, false)

View File

@@ -99,11 +99,11 @@ defmodule Mobilizon.Config do
)
)
@spec instance_registrations_whitelist :: list(String.t())
def instance_registrations_whitelist, do: instance_config()[:registration_email_whitelist]
@spec instance_registrations_allowlist :: list(String.t())
def instance_registrations_allowlist, do: instance_config()[:registration_email_allowlist]
@spec instance_registrations_whitelist? :: boolean
def instance_registrations_whitelist?, do: length(instance_registrations_whitelist()) > 0
@spec instance_registrations_allowlist? :: boolean
def instance_registrations_allowlist?, do: length(instance_registrations_allowlist()) > 0
@spec instance_demo_mode? :: boolean
def instance_demo_mode?, do: to_boolean(instance_config()[:demo])

View File

@@ -59,7 +59,8 @@ defmodule Mobilizon.Events.Event do
sessions: [Session.t()],
mentions: [Mention.t()],
tags: [Tag.t()],
participants: [Actor.t()]
participants: [Actor.t()],
contacts: [Actor.t()]
}
@update_required_attrs [:title, :begins_on, :organizer_actor_id]
@@ -114,6 +115,7 @@ defmodule Mobilizon.Events.Event do
has_many(:sessions, Session)
has_many(:mentions, Mention)
has_many(:comments, Comment)
many_to_many(:contacts, Actor, join_through: "event_contacts", on_replace: :delete)
many_to_many(:tags, Tag, join_through: "events_tags", on_replace: :delete)
many_to_many(:participants, Actor, join_through: Participant)
@@ -147,6 +149,7 @@ defmodule Mobilizon.Events.Event do
defp common_changeset(%Changeset{} = changeset, attrs) do
changeset
|> cast_embed(:options)
|> put_assoc(:contacts, Map.get(attrs, :contacts, []))
|> put_tags(attrs)
|> put_address(attrs)
|> put_picture(attrs)

View File

@@ -83,7 +83,8 @@ defmodule Mobilizon.Events do
:comments,
:participants,
:physical_address,
:picture
:picture,
:contacts
]
@doc """
@@ -1019,7 +1020,7 @@ defmodule Mobilizon.Events do
) do
with {:update_event_participation_stats, true} <-
{:update_event_participation_stats, update_event_participation_stats},
{:ok, %Event{} = event} <- get_event(event_id),
{:ok, %Event{} = event} <- get_event_with_preload(event_id),
%EventParticipantStats{} = participant_stats <-
Map.get(event, :participant_stats),
%EventParticipantStats{} = participant_stats <-

View File

@@ -12,6 +12,7 @@ defmodule Mobilizon.Users.User do
alias Mobilizon.Events.FeedToken
alias Mobilizon.Users.{Setting, UserRole}
alias Mobilizon.Web.Email.Checker
import Mobilizon.Web.Gettext
@type t :: %__MODULE__{
email: String.t(),
@@ -100,9 +101,13 @@ defmodule Mobilizon.Users.User do
user
|> cast(attrs, @attrs)
|> validate_required(@required_attrs)
|> unique_constraint(:email, message: "This email is already used.")
|> unique_constraint(:email, message: dgettext("errors", "This email is already used."))
|> Checker.validate_changeset()
|> validate_length(:password, min: 6, max: 200, message: "The chosen password is too short.")
|> validate_length(:password,
min: 6,
max: 200,
message: dgettext("errors", "The chosen password is too short.")
)
if Map.has_key?(attrs, :default_actor) do
put_assoc(changeset, :default_actor, attrs.default_actor)
@@ -129,7 +134,11 @@ defmodule Mobilizon.Users.User do
|> save_confirmation_token()
|> unique_constraint(
:confirmation_token,
message: "The registration token is already in use, this looks like an issue on our side."
message:
dgettext(
"errors",
"The registration token is already in use, this looks like an issue on our side."
)
)
end

View File

@@ -5,6 +5,8 @@ defmodule Mobilizon.Web.Endpoint do
use Phoenix.Endpoint, otp_app: :mobilizon
use Absinthe.Phoenix.Endpoint
plug(Mobilizon.Web.Plugs.SetLocalePlug)
# For e2e tests
if Application.get_env(:mobilizon, :sql_sandbox) do
plug(Phoenix.Ecto.SQL.Sandbox,

View File

@@ -0,0 +1,67 @@
# Portions of this file are derived from Pleroma:
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
# NOTE: this module is based on https://github.com/smeevil/set_locale
defmodule Mobilizon.Web.Plugs.SetLocalePlug do
@moduledoc """
Plug to set locale for Gettext
"""
import Plug.Conn, only: [get_req_header: 2, assign: 3]
def init(_), do: nil
def call(conn, _) do
locale = get_locale_from_header(conn) || Gettext.get_locale()
Gettext.put_locale(locale)
assign(conn, :locale, locale)
end
defp get_locale_from_header(conn) do
conn
|> extract_accept_language()
|> Enum.find(&supported_locale?/1)
end
defp extract_accept_language(conn) do
case get_req_header(conn, "accept-language") do
[value | _] ->
value
|> String.split(",")
|> Enum.map(&parse_language_option/1)
|> Enum.sort(&(&1.quality > &2.quality))
|> Enum.map(& &1.tag)
|> Enum.reject(&is_nil/1)
|> ensure_language_fallbacks()
_ ->
[]
end
end
defp supported_locale?(locale) do
Mobilizon.Web.Gettext
|> Gettext.known_locales()
|> Enum.member?(locale)
end
defp parse_language_option(string) do
captures = Regex.named_captures(~r/^\s?(?<tag>[\w\-]+)(?:;q=(?<quality>[\d\.]+))?$/i, string)
quality =
case Float.parse(captures["quality"] || "1.0") do
{val, _} -> val
:error -> 1.0
end
%{tag: captures["tag"], quality: quality}
end
defp ensure_language_fallbacks(tags) do
Enum.flat_map(tags, fn tag ->
[language | _] = String.split(tag, "-")
if Enum.member?(tags, language), do: [tag], else: [tag, language]
end)
end
end

View File

@@ -53,7 +53,7 @@ defmodule Mobilizon.Web.ReverseProxy do
* `inline_content_types`:
* `true` will not alter `content-disposition` (up to the upstream),
* `false` will add `content-disposition: attachment` to any request,
* a list of whitelisted content types
* a list of allowlisted content types
* `keep_user_agent` will forward the client's user-agent to the upstream.
This may be useful if the upstream is doing content transformation