Improve GraphQL documentation and cleanup API

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2020-11-19 17:06:28 +01:00
parent e8a3b6aa94
commit 3eacbb2ca3
87 changed files with 6542 additions and 6314 deletions

View File

@@ -26,9 +26,6 @@ defmodule Mobilizon.GraphQL.API.Groups do
else
{:existing_group, _} ->
{:error, "A group with this name already exists"}
{:is_owned, nil} ->
{:error, "Profile is not owned by authenticated user"}
end
end
@@ -42,9 +39,6 @@ defmodule Mobilizon.GraphQL.API.Groups do
else
{:existing_group, _} ->
{:error, "A group with this name already exists"}
{:is_owned, nil} ->
{:error, "Profile is not owned by authenticated user"}
end
end
end

View File

@@ -3,11 +3,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
Handles the comment-related GraphQL calls.
"""
alias Mobilizon.{Actors, Admin, Discussions, Events}
alias Mobilizon.{Actors, Admin, Discussions, Events, Users}
alias Mobilizon.Actors.Actor
alias Mobilizon.Discussions.Comment, as: CommentModel
alias Mobilizon.Events.{Event, EventOptions}
alias Mobilizon.Users
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
@@ -21,14 +20,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
def create_comment(
_parent,
%{actor_id: actor_id, event_id: event_id} = args,
%{event_id: event_id} = args,
%{
context: %{
current_user: %User{} = user
}
}
) do
with {:is_owned, %Actor{} = _organizer_actor} <- User.owns_actor(user, actor_id),
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
{:find_event,
{:ok,
%Event{
@@ -36,18 +35,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
organizer_actor_id: organizer_actor_id
}}} <-
{:find_event, Events.get_event(event_id)},
{actor_id, ""} <- Integer.parse(actor_id),
{:allowed, true} <-
{:allowed, comment_moderation != :closed || actor_id == organizer_actor_id},
args <- Map.put(args, :actor_id, actor_id),
{:ok, _, %CommentModel{} = comment} <-
Comments.create_comment(args) do
{:ok, comment}
else
{:allowed, false} ->
{:error, :unauthorized}
{:is_owned, nil} ->
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end
@@ -107,9 +103,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do
else
%CommentModel{deleted_at: deleted_at} when not is_nil(deleted_at) ->
{:error, dgettext("errors", "Comment is already deleted")}
{:is_owned, nil} ->
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end

View File

@@ -62,6 +62,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Discussion do
end
end
def get_discussion(_parent, _args, %{
context: %{
current_user: %User{} = _user
}
}),
do:
{:error,
dgettext("errors", "You must provide either an ID or a slug to access a discussion")}
def get_discussion(_parent, _args, _resolution),
do: {:error, dgettext("errors", "You need to be logged-in to access discussions")}

View File

@@ -3,7 +3,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
Handles the event-related GraphQL calls.
"""
alias Mobilizon.{Actors, Admin, Events}
alias Mobilizon.{Actors, Admin, Events, Users}
alias Mobilizon.Actors.Actor
alias Mobilizon.Config
alias Mobilizon.Events.{Event, EventParticipantStats}
@@ -74,10 +74,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
"""
def list_participants_for_event(
%Event{id: event_id},
%{page: page, limit: limit, roles: roles, actor_id: actor_id},
%{page: page, limit: limit, roles: roles},
%{context: %{current_user: %User{} = user}} = _resolution
) do
with {:is_owned, %Actor{} = _actor} <- User.owns_actor(user, actor_id),
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
# Check that moderator has right
{:actor_approve_permission, true} <-
{:actor_approve_permission, Events.moderator_for_event?(event_id, actor_id)} do
@@ -96,9 +96,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
participants = Events.list_participants_for_event(event_id, roles, page, limit)
{:ok, participants}
else
{:is_owned, nil} ->
{:error, dgettext("errors", "Moderator profile is not owned by authenticated user")}
{:actor_approve_permission, _} ->
{:error,
dgettext("errors", "Provided moderator profile doesn't have permission on this event")}
@@ -191,8 +188,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
%{context: %{current_user: user}} = _resolution
) do
# See https://github.com/absinthe-graphql/absinthe/issues/490
with args <- Map.put(args, :options, args[:options] || %{}),
{:is_owned, %Actor{} = organizer_actor} <- User.owns_actor(user, organizer_actor_id),
with {:is_owned, %Actor{} = organizer_actor} <- User.owns_actor(user, organizer_actor_id),
args <- Map.put(args, :options, args[:options] || %{}),
args_with_organizer <- Map.put(args, :organizer_actor, organizer_actor),
{:ok, %Activity{data: %{"object" => %{"type" => "Event"}}}, %Event{} = event} <-
API.Events.create_event(args_with_organizer) do
@@ -257,12 +254,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
"""
def delete_event(
_parent,
%{event_id: event_id, actor_id: actor_id},
%{event_id: event_id},
%{context: %{current_user: %User{role: role} = user}}
) do
with {:ok, %Event{local: is_local} = event} <- Events.get_event_with_preload(event_id),
{actor_id, ""} <- Integer.parse(actor_id),
{:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id) do
%Actor{id: actor_id} = actor <- Users.get_actor_for_user(user) do
cond do
{:event_can_be_managed, true} == Event.can_be_managed_by(event, actor_id) ->
do_delete_event(event, actor)
@@ -281,9 +277,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
else
{:error, :event_not_found} ->
{:error, dgettext("errors", "Event not found")}
{:is_owned, nil} ->
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
end
end

View File

@@ -121,10 +121,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
}
}
) do
with creator_actor_id <- Map.get(args, :creator_actor_id),
{:is_owned, %Actor{} = creator_actor} <- User.owns_actor(user, creator_actor_id),
with %Actor{id: creator_actor_id} = creator_actor <- Users.get_actor_for_user(user),
args <- Map.update(args, :preferred_username, "", &String.downcase/1),
args <- Map.put(args, :creator_actor, creator_actor),
args <- Map.put(args, :creator_actor_id, creator_actor_id),
args <- save_attached_pictures(args),
{:ok, _activity, %Actor{type: :Group} = group} <-
API.Groups.create_group(args) do
@@ -132,9 +132,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
else
{:error, err} when is_binary(err) ->
{:error, err}
{:is_owned, nil} ->
{:error, dgettext("errors", "Creator profile is not owned by the current user")}
end
end

View File

@@ -76,9 +76,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Member do
{:ok, _activity, %Member{} = member} <- ActivityPub.invite(group, actor, target_actor) do
{:ok, member}
else
{:is_owned, nil} ->
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:error, :group_not_found} ->
{:error, dgettext("errors", "Group not found")}

View File

@@ -2,7 +2,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
@moduledoc """
Handles the participation-related GraphQL calls.
"""
alias Mobilizon.{Actors, Config, Crypto, Events}
alias Mobilizon.{Actors, Config, Crypto, Events, Users}
alias Mobilizon.Actors.Actor
alias Mobilizon.Events.{Event, Participant}
alias Mobilizon.GraphQL.API.Participations
@@ -206,7 +206,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
def update_participation(
_parent,
%{id: participation_id, moderator_actor_id: moderator_actor_id, role: new_role},
%{id: participation_id, role: new_role},
%{
context: %{
current_user: user
@@ -214,7 +214,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
}
) do
# Check that moderator provided is rightly authenticated
with {:is_owned, moderator_actor} <- User.owns_actor(user, moderator_actor_id),
with %Actor{id: moderator_actor_id} = moderator_actor <- Users.get_actor_for_user(user),
# Check that participation already exists
{:has_participation, %Participant{role: old_role} = participation} <-
{:has_participation, Events.get_participant(participation_id)},
@@ -227,9 +227,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
Participations.update(participation, moderator_actor, new_role) do
{:ok, participation}
else
{:is_owned, nil} ->
{:error, dgettext("errors", "Moderator profile is not owned by authenticated user")}
{:has_participation, nil} ->
{:error, dgettext("errors", "Participant not found")}

View File

@@ -5,12 +5,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
import Mobilizon.Users.Guards
alias Mobilizon.Actors
alias Mobilizon.{Actors, Events, Users}
alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.Participant
alias Mobilizon.Storage.Page
alias Mobilizon.Users
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext

View File

@@ -4,9 +4,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Picture do
"""
alias Mobilizon.Actors.Actor
alias Mobilizon.Media
alias Mobilizon.{Media, Users}
alias Mobilizon.Media.Picture
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
@doc """
@@ -46,10 +45,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Picture do
@spec upload_picture(map, map, map) :: {:ok, Picture.t()} | {:error, any}
def upload_picture(
_parent,
%{file: %Plug.Upload{} = file, actor_id: actor_id} = args,
%{file: %Plug.Upload{} = file} = args,
%{context: %{current_user: user}}
) do
with {:is_owned, %Actor{}} <- User.owns_actor(user, actor_id),
with %Actor{id: actor_id} <- Users.get_actor_for_user(user),
{:ok, %{name: _name, url: url, content_type: content_type, size: size}} <-
Mobilizon.Web.Upload.store(file),
args <-
@@ -68,9 +67,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Picture do
size: picture.file.size
}}
else
{:is_owned, nil} ->
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:error, :mime_type_not_allowed} ->
{:error, dgettext("errors", "File doesn't have an allowed MIME type.")}

View File

@@ -5,10 +5,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
import Mobilizon.Users.Guards
alias Mobilizon.Actors
alias Mobilizon.{Actors, Config, Reports, Users}
alias Mobilizon.Actors.Actor
alias Mobilizon.Config
alias Mobilizon.Reports
alias Mobilizon.Reports.{Note, Report}
alias Mobilizon.Users.User
import Mobilizon.Web.Gettext
@@ -48,16 +46,14 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
"""
def create_report(
_parent,
%{reporter_id: reporter_id} = args,
args,
%{context: %{current_user: %User{} = user}} = _resolution
) do
with {:is_owned, %Actor{}} <- User.owns_actor(user, reporter_id),
{:ok, _, %Report{} = report} <- API.Reports.report(args) do
with %Actor{id: reporter_id} <- Users.get_actor_for_user(user),
{:ok, _, %Report{} = report} <-
args |> Map.put(:reporter_id, reporter_id) |> API.Reports.report() do
{:ok, report}
else
{:is_owned, nil} ->
{:error, dgettext("errors", "Reporter profile is not owned by authenticated user")}
_error ->
{:error, dgettext("errors", "Error while saving report")}
end
@@ -65,47 +61,37 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
def create_report(
_parent,
%{reporter_id: reporter_id} = args,
args,
_resolution
) do
with {:anonymous_reporting_allowed, true} <-
{:anonymous_reporting_allowed, Config.anonymous_reporting?()},
{:wrong_id, true} <- {:wrong_id, reporter_id == to_string(Config.anonymous_actor_id())},
{:ok, _, %Report{} = report} <- API.Reports.report(args) do
{:ok, _, %Report{} = report} <-
args |> Map.put(:reporter_id, Config.anonymous_actor_id()) |> API.Reports.report() do
{:ok, report}
else
{:anonymous_reporting_allowed, _} ->
{:error, dgettext("errors", "You need to be logged-in to create reports")}
{:wrong_id, _} ->
{:error, dgettext("errors", "Reporter ID does not match the anonymous profile id")}
_error ->
{:error, dgettext("errors", "Error while saving report")}
end
end
def create_report(_parent, _args, _resolution) do
{:error, dgettext("errors", "You need to be logged-in to create reports")}
end
@doc """
Update a report's status
"""
def update_report(
_parent,
%{report_id: report_id, moderator_id: moderator_id, status: status},
%{report_id: report_id, status: status},
%{context: %{current_user: %User{role: role} = user}}
)
when is_moderator(role) do
with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, moderator_id),
with %Actor{} = actor <- Users.get_actor_for_user(user),
%Report{} = report <- Mobilizon.Reports.get_report(report_id),
{:ok, %Report{} = report} <- API.Reports.update_report_status(actor, report, status) do
{:ok, report}
else
{:is_owned, nil} ->
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
_error ->
{:error, dgettext("errors", "Error while updating report")}
end
@@ -117,11 +103,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
def create_report_note(
_parent,
%{report_id: report_id, moderator_id: moderator_id, content: content},
%{report_id: report_id, content: content},
%{context: %{current_user: %User{role: role} = user}}
)
when is_moderator(role) do
with {:is_owned, %Actor{}} <- User.owns_actor(user, moderator_id),
with %Actor{id: moderator_id} <- Users.get_actor_for_user(user),
%Report{} = report <- Reports.get_report(report_id),
%Actor{} = moderator <- Actors.get_local_actor_with_preload(moderator_id),
{:ok, %Note{} = note} <- API.Reports.create_report_note(report, moderator, content) do
@@ -131,11 +117,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Report do
def delete_report_note(
_parent,
%{note_id: note_id, moderator_id: moderator_id},
%{note_id: note_id},
%{context: %{current_user: %User{role: role} = user}}
)
when is_moderator(role) do
with {:is_owned, %Actor{}} <- User.owns_actor(user, moderator_id),
with %Actor{id: moderator_id} <- Users.get_actor_for_user(user),
%Note{} = note <- Reports.get_note(note_id),
%Actor{} = moderator <- Actors.get_local_actor_with_preload(moderator_id),
{:ok, %Note{} = note} <- API.Reports.delete_report_note(note, moderator) do

View File

@@ -53,9 +53,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do
%Page{} = page <- Todos.get_todos_for_todo_list(todo_list) do
{:ok, page}
else
{:is_owned, nil} ->
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
{:member, _} ->
{:error, dgettext("errors", "Profile is not member of group")}
end

View File

@@ -62,18 +62,21 @@ defmodule Mobilizon.GraphQL.Schema.ActorInterface do
end
object :actor_mutations do
@desc "Suspend an actor"
field :suspend_profile, :deleted_object do
arg(:id, non_null(:id), description: "The profile ID to suspend")
arg(:id, non_null(:id), description: "The remote profile ID to suspend")
resolve(&ActorResolver.suspend_profile/3)
end
@desc "Unsuspend an actor"
field :unsuspend_profile, :actor do
arg(:id, non_null(:id), description: "The profile ID to unsuspend")
arg(:id, non_null(:id), description: "The remote profile ID to unsuspend")
resolve(&ActorResolver.unsuspend_profile/3)
end
@desc "Refresh a profile"
field :refresh_profile, :actor do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The remote profile ID to refresh")
resolve(&ActorResolver.refresh_profile/3)
end
end

View File

@@ -19,6 +19,9 @@ defmodule Mobilizon.GraphQL.Schema.Actors.FollowerType do
field(:updated_at, :datetime, description: "When the follow was updated")
end
@desc """
A paginated list of follower objects
"""
object :paginated_follower_list do
field(:elements, list_of(:follower), description: "A list of followers")
field(:total, :integer, description: "The total number of elements in the list")

View File

@@ -54,10 +54,18 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
# This one should have a privacy setting
field :organized_events, :paginated_event_list do
arg(:after_datetime, :datetime, default_value: nil)
arg(:before_datetime, :datetime, default_value: nil)
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:after_datetime, :datetime,
default_value: nil,
description: "Filter events that begin after this datetime"
)
arg(:before_datetime, :datetime,
default_value: nil,
description: "Filter events that begin before this datetime"
)
arg(:page, :integer, default_value: 1, description: "The page in the paginated event list")
arg(:limit, :integer, default_value: 10, description: "The limit of events per page")
resolve(&Group.find_events_for_group/3)
description("A list of the events this actor has organized")
end
@@ -74,23 +82,27 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
)
field :members, :paginated_member_list do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:roles, :string, default_value: "")
arg(:page, :integer, default_value: 1, description: "The page in the paginated member list")
arg(:limit, :integer, default_value: 10, description: "The limit of members per page")
arg(:roles, :string, default_value: "", description: "Filter members by their role")
resolve(&Member.find_members_for_group/3)
description("A paginated list of group members")
end
field :resources, :paginated_resource_list do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated resource list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of resources per page")
resolve(&Resource.find_resources_for_group/3)
description("A paginated list of the resources this group has")
end
field :posts, :paginated_post_list do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer, default_value: 1, description: "The page in the paginated post list")
arg(:limit, :integer, default_value: 10, description: "The limit of posts per page")
resolve(&Post.find_posts_for_group/3)
description("A paginated list of the posts this group has")
end
@@ -120,9 +132,12 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
value(:open, description: "The actor is open to followings")
end
@desc """
A paginated list of groups
"""
object :paginated_group_list do
field(:elements, list_of(:group), description: "A list of groups")
field(:total, :integer, description: "The total number of elements in the list")
field(:total, :integer, description: "The total number of groups in the list")
end
@desc "The list of visibility options for a group"
@@ -134,25 +149,33 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
object :group_queries do
@desc "Get all groups"
field :groups, :paginated_group_list do
arg(:preferred_username, :string, default_value: "")
arg(:name, :string, default_value: "")
arg(:domain, :string, default_value: "")
arg(:local, :boolean, default_value: true)
arg(:suspended, :boolean, default_value: false)
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:preferred_username, :string, default_value: "", description: "Filter by username")
arg(:name, :string, default_value: "", description: "Filter by name")
arg(:domain, :string, default_value: "", description: "Filter by domain")
arg(:local, :boolean,
default_value: true,
description: "Filter whether group is local or not"
)
arg(:suspended, :boolean, default_value: false, description: "Filter by suspended status")
arg(:page, :integer, default_value: 1, description: "The page in the paginated group list")
arg(:limit, :integer, default_value: 10, description: "The limit of groups per page")
resolve(&Group.list_groups/3)
end
@desc "Get a group by its ID"
field :get_group, :group do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The group ID")
resolve(&Group.get_group/3)
end
@desc "Get a group by its preferred username"
field :group, :group do
arg(:preferred_username, non_null(:string))
arg(:preferred_username, non_null(:string),
description: "The group preferred_username, eventually containing their domain if remote"
)
resolve(&Group.find_group/3)
end
end
@@ -162,8 +185,6 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
field :create_group, :group do
arg(:preferred_username, non_null(:string), description: "The name for the group")
arg(:creator_actor_id, non_null(:id), description: "The identity that creates the group")
arg(:name, :string, description: "The displayed name for the group")
arg(:summary, :string, description: "The summary for the group", default_value: "")
@@ -182,7 +203,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
"The banner for the group, either as an object or directly the ID of an existing Picture"
)
arg(:physical_address, :address_input)
arg(:physical_address, :address_input, description: "The physical address for the group")
resolve(&Group.create_group/3)
end
@@ -210,14 +231,14 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
"The banner for the group, either as an object or directly the ID of an existing Picture"
)
arg(:physical_address, :address_input)
arg(:physical_address, :address_input, description: "The physical address for the group")
resolve(&Group.update_group/3)
end
@desc "Delete a group"
field :delete_group, :deleted_object do
arg(:group_id, non_null(:id))
arg(:group_id, non_null(:id), description: "The group ID")
resolve(&Group.delete_group/3)
end

View File

@@ -19,16 +19,22 @@ defmodule Mobilizon.GraphQL.Schema.Actors.MemberType do
field(:updated_at, :naive_datetime, description: "When was this member updated")
end
@desc """
Values for a member role
"""
enum :member_role_enum do
value(:not_approved)
value(:invited)
value(:member)
value(:moderator)
value(:administrator)
value(:creator)
value(:rejected)
value(:not_approved, description: "The member needs to be approved by the group admins")
value(:invited, description: "The member has been invited")
value(:member, description: "Regular member")
value(:moderator, description: "The member is a moderator")
value(:administrator, description: "The member is an administrator")
value(:creator, description: "The member was the creator of the group. Shouldn't be used.")
value(:rejected, description: "The member has been rejected or excluded from the group")
end
@desc """
A paginated list of members
"""
object :paginated_member_list do
field(:elements, list_of(:member), description: "A list of members")
field(:total, :integer, description: "The total number of elements in the list")
@@ -37,51 +43,54 @@ defmodule Mobilizon.GraphQL.Schema.Actors.MemberType do
object :member_mutations do
@desc "Join a group"
field :join_group, :member do
arg(:group_id, non_null(:id))
arg(:group_id, non_null(:id), description: "The group ID")
resolve(&Group.join_group/3)
end
@desc "Leave a group"
field :leave_group, :deleted_object do
arg(:group_id, non_null(:id))
arg(:group_id, non_null(:id), description: "The group ID")
resolve(&Group.leave_group/3)
end
@desc "Invite an actor to join the group"
field :invite_member, :member do
arg(:group_id, non_null(:id))
arg(:target_actor_username, non_null(:string))
arg(:group_id, non_null(:id), description: "The group ID")
arg(:target_actor_username, non_null(:string),
description: "The targeted person's federated username"
)
resolve(&Member.invite_member/3)
end
@desc "Accept an invitation to a group"
field :accept_invitation, :member do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The member ID")
resolve(&Member.accept_invitation/3)
end
@desc "Reject an invitation to a group"
field :reject_invitation, :member do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The member ID")
resolve(&Member.reject_invitation/3)
end
field :update_member, :member do
arg(:member_id, non_null(:id))
arg(:role, non_null(:member_role_enum))
arg(:member_id, non_null(:id), description: "The member ID")
arg(:role, non_null(:member_role_enum), description: "The new member role")
resolve(&Member.update_member/3)
end
@desc "Remove a member from a group"
field :remove_member, :member do
arg(:group_id, non_null(:id))
arg(:member_id, non_null(:id))
arg(:group_id, non_null(:id), description: "The group ID")
arg(:member_id, non_null(:id), description: "The member ID")
resolve(&Member.remove_member/3)
end

View File

@@ -58,8 +58,8 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
field(:organized_events, :paginated_event_list,
description: "A list of the events this actor has organized"
) do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer, default_value: 1, description: "The page in the paginated event list")
arg(:limit, :integer, default_value: 10, description: "The limit of events per page")
resolve(&Person.organized_events_for_person/3)
end
@@ -68,8 +68,14 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
description: "The list of events this person goes to"
) do
arg(:event_id, :id)
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated participation list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of participations per page")
resolve(&Person.person_participations/3)
end
@@ -81,6 +87,14 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
end
end
@desc """
A paginated list of persons
"""
object :paginated_person_list do
field(:elements, list_of(:person), description: "A list of persons")
field(:total, :integer, description: "The total number of persons in the list")
end
object :person_queries do
@desc "Get the current actor for the logged-in user"
field :logged_person, :person do
@@ -89,13 +103,13 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
@desc "Get a person by its (federated) username"
field :fetch_person, :person do
arg(:preferred_username, non_null(:string))
arg(:preferred_username, non_null(:string), description: "The person's federated username")
resolve(&Person.fetch_person/3)
end
@desc "Get a person by its ID"
field :person, :person do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The person ID")
resolve(&Person.get_person/3)
end
@@ -104,14 +118,20 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
resolve(&Person.identities/3)
end
field :persons, :persons do
arg(:preferred_username, :string, default_value: "")
arg(:name, :string, default_value: "")
arg(:domain, :string, default_value: "")
arg(:local, :boolean, default_value: true)
arg(:suspended, :boolean, default_value: false)
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
@desc "List the profiles"
field :persons, :paginated_person_list do
arg(:preferred_username, :string, default_value: "", description: "Filter by username")
arg(:name, :string, default_value: "", description: "Filter by name")
arg(:domain, :string, default_value: "", description: "Filter by domain")
arg(:local, :boolean,
default_value: true,
description: "Filter by profile being local or not"
)
arg(:suspended, :boolean, default_value: false, description: "Filter by suspended status")
arg(:page, :integer, default_value: 1, description: "The page in the paginated person list")
arg(:limit, :integer, default_value: 10, description: "The limit of persons per page")
resolve(&Person.list_persons/3)
end
end
@@ -119,7 +139,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
object :person_mutations do
@desc "Create a new person for user"
field :create_person, :person do
arg(:preferred_username, non_null(:string))
arg(:preferred_username, non_null(:string), description: "The username for the profile")
arg(:name, :string, description: "The displayed name for the new profile", default_value: "")
@@ -140,7 +160,7 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
@desc "Update an identity"
field :update_person, :person do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The person's ID")
arg(:name, :string, description: "The displayed name for this profile")
@@ -161,14 +181,14 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
@desc "Delete an identity"
field :delete_person, :person do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The person's ID")
resolve(&Person.delete_person/3)
end
@desc "Register a first profile on registration"
field :register_person, :person do
arg(:preferred_username, non_null(:string))
arg(:preferred_username, non_null(:string), description: "The username for the profile")
arg(:name, :string, description: "The displayed name for the new profile", default_value: "")
@@ -190,16 +210,18 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
end
object :person_subscriptions do
@desc "Notify when a person's participation's status changed for an event"
field :event_person_participation_changed, :person do
arg(:person_id, non_null(:id))
arg(:person_id, non_null(:id), description: "The person's ID")
config(fn args, _ ->
{:ok, topic: args.person_id}
end)
end
@desc "Notify when a person's membership's status changed for a group"
field :group_membership_changed, :person do
arg(:person_id, non_null(:id))
arg(:person_id, non_null(:id), description: "The person's ID")
config(fn args, _ ->
{:ok, topic: args.person_id}

View File

@@ -10,19 +10,19 @@ defmodule Mobilizon.GraphQL.Schema.AddressType do
field(:geom, :point, description: "The geocoordinates for the point where this address is")
field(:street, :string, description: "The address's street name (with number)")
field(:locality, :string, description: "The address's locality")
field(:postal_code, :string)
field(:region, :string)
field(:country, :string)
field(:description, :string)
field(:type, :string)
field(:url, :string)
field(:id, :id)
field(:origin_id, :string)
field(:postal_code, :string, description: "The address's postal code")
field(:region, :string, description: "The address's region")
field(:country, :string, description: "The address's country")
field(:description, :string, description: "The address's description")
field(:type, :string, description: "The address's type")
field(:url, :string, description: "The address's URL")
field(:id, :id, description: "The address's ID")
field(:origin_id, :string, description: "The address's original ID from the provider")
end
object :phone_address do
field(:phone, :string)
field(:info, :string)
field(:phone, :string, description: "The phone number")
field(:info, :string, description: "Additional information about the phone number")
end
object :online_address do
@@ -35,33 +35,46 @@ defmodule Mobilizon.GraphQL.Schema.AddressType do
field(:geom, :point, description: "The geocoordinates for the point where this address is")
field(:street, :string, description: "The address's street name (with number)")
field(:locality, :string, description: "The address's locality")
field(:postal_code, :string)
field(:region, :string)
field(:country, :string)
field(:description, :string)
field(:url, :string)
field(:type, :string)
field(:id, :id)
field(:origin_id, :string)
field(:postal_code, :string, description: "The address's postal code")
field(:region, :string, description: "The address's region")
field(:country, :string, description: "The address's country")
field(:description, :string, description: "The address's description")
field(:type, :string, description: "The address's type")
field(:url, :string, description: "The address's URL")
field(:id, :id, description: "The address's ID")
field(:origin_id, :string, description: "The address's original ID from the provider")
end
object :address_queries do
@desc "Search for an address"
field :search_address, type: list_of(:address) do
arg(:query, non_null(:string))
arg(:locale, :string, default_value: "en")
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:locale, :string,
default_value: "en",
description: "The user's locale. Geocoding backends will make use of this value."
)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated search results list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of search results per page")
resolve(&Address.search/3)
end
@desc "Reverse geocode coordinates"
field :reverse_geocode, type: list_of(:address) do
arg(:longitude, non_null(:float))
arg(:latitude, non_null(:float))
arg(:zoom, :integer, default_value: 15)
arg(:locale, :string, default_value: "en")
arg(:longitude, non_null(:float), description: "Geographical longitude (using WGS 84)")
arg(:latitude, non_null(:float), description: "Geographical latitude (using WGS 84)")
arg(:zoom, :integer, default_value: 15, description: "Zoom level")
arg(:locale, :string,
default_value: "en",
description: "The user's locale. Geocoding backends will make use of this value."
)
resolve(&Address.reverse_geocode/3)
end

View File

@@ -22,18 +22,21 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
field(:inserted_at, :datetime, description: "The time when the action was performed")
end
@desc """
The different types of action log actions
"""
enum :action_log_action do
value(:report_update_closed)
value(:report_update_opened)
value(:report_update_resolved)
value(:note_creation)
value(:note_deletion)
value(:event_deletion)
value(:comment_deletion)
value(:event_update)
value(:actor_suspension)
value(:actor_unsuspension)
value(:user_deletion)
value(:report_update_closed, description: "The report was closed")
value(:report_update_opened, description: "The report was opened")
value(:report_update_resolved, description: "The report was resolved")
value(:note_creation, description: "A note was created on a report")
value(:note_deletion, description: "A note was deleted on a report")
value(:event_deletion, description: "An event was deleted")
value(:comment_deletion, description: "A comment was deleted")
value(:event_update, description: "An event was updated")
value(:actor_suspension, description: "An actor was suspended")
value(:actor_unsuspension, description: "An actor was unsuspended")
value(:user_deletion, description: "An user was deleted")
end
@desc "The objects that can be in an action log"
@@ -64,11 +67,17 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
end)
end
@desc """
Language information
"""
object :language do
field(:code, :string, description: "The iso-639-3 language code")
field(:name, :string, description: "The language name")
end
@desc """
Dashboard information
"""
object :dashboard do
field(:last_public_event_published, :event, description: "Last public event published")
field(:last_group_created, :group, description: "Last public group created")
@@ -85,33 +94,52 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
)
end
@desc """
Admin settings
"""
object :admin_settings do
field(:instance_name, :string)
field(:instance_description, :string)
field(:instance_long_description, :string)
field(:instance_slogan, :string)
field(:contact, :string)
field(:instance_terms, :string)
field(:instance_terms_type, :instance_terms_type)
field(:instance_terms_url, :string)
field(:instance_privacy_policy, :string)
field(:instance_privacy_policy_type, :instance_privacy_type)
field(:instance_privacy_policy_url, :string)
field(:instance_rules, :string)
field(:registrations_open, :boolean)
field(:instance_languages, list_of(:string))
field(:instance_name, :string, description: "The instance's name")
field(:instance_description, :string, description: "The instance's description")
field(:instance_long_description, :string, description: "The instance's long description")
field(:instance_slogan, :string, description: "The instance's slogan")
field(:contact, :string, description: "The instance's contact details")
field(:instance_terms, :string, description: "The instance's terms body text")
field(:instance_terms_type, :instance_terms_type, description: "The instance's terms type")
field(:instance_terms_url, :string, description: "The instance's terms URL")
field(:instance_privacy_policy, :string,
description: "The instance's privacy policy body text"
)
field(:instance_privacy_policy_type, :instance_privacy_type,
description: "The instance's privacy policy type"
)
field(:instance_privacy_policy_url, :string, description: "The instance's privacy policy URL")
field(:instance_rules, :string, description: "The instance's rules")
field(:registrations_open, :boolean, description: "Whether the registrations are opened")
field(:instance_languages, list_of(:string), description: "The instance's languages")
end
@desc "The acceptable values for the instance's terms type"
enum :instance_terms_type do
value(:url, as: "URL")
value(:default, as: "DEFAULT")
value(:custom, as: "CUSTOM")
value(:url, as: "URL", description: "An URL. Users will be redirected to this URL.")
value(:default, as: "DEFAULT", description: "Terms will be set to Mobilizon's default terms")
value(:custom, as: "CUSTOM", description: "Custom terms text")
end
@desc """
The acceptable values for the instance privacy policy type
"""
enum :instance_privacy_type do
value(:url, as: "URL")
value(:default, as: "DEFAULT")
value(:custom, as: "CUSTOM")
value(:url, as: "URL", description: "An URL. Users will be redirected to this URL.")
value(:default,
as: "DEFAULT",
description: "Privacy policy will be set to Mobilizon's default privacy policy"
)
value(:custom, as: "CUSTOM", description: "Custom privacy policy text")
end
object :admin_queries do
@@ -122,30 +150,69 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
resolve(&Admin.list_action_logs/3)
end
@desc """
List the instance's supported languages
"""
field :languages, type: list_of(:language) do
arg(:codes, list_of(:string))
arg(:codes, list_of(:string),
description:
"The user's locale. The list of languages will be translated with this locale"
)
resolve(&Admin.get_list_of_languages/3)
end
@desc """
Get dashboard information
"""
field :dashboard, type: :dashboard do
resolve(&Admin.get_dashboard/3)
end
@desc """
Get admin settings
"""
field :admin_settings, type: :admin_settings do
resolve(&Admin.get_settings/3)
end
@desc """
List the relay followers
"""
field :relay_followers, type: :paginated_follower_list do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated relay followers list"
)
arg(:limit, :integer,
default_value: 10,
description: "The limit of relay followers per page"
)
resolve(&Admin.list_relay_followers/3)
end
@desc """
List the relay followings
"""
field :relay_followings, type: :paginated_follower_list do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:order_by, :string, default_value: :updated_at)
arg(:direction, :string, default_value: :desc)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated relay followings list"
)
arg(:limit, :integer,
default_value: 10,
description: "The limit of relay followings per page"
)
arg(:order_by, :string,
default_value: :updated_at,
description: "The field to order by the list"
)
arg(:direction, :string, default_value: :desc, description: "The sorting direction")
resolve(&Admin.list_relay_followings/3)
end
end
@@ -153,47 +220,57 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
object :admin_mutations do
@desc "Add a relay subscription"
field :add_relay, type: :follower do
arg(:address, non_null(:string))
arg(:address, non_null(:string), description: "The relay hostname to add")
resolve(&Admin.create_relay/3)
end
@desc "Delete a relay subscription"
field :remove_relay, type: :follower do
arg(:address, non_null(:string))
arg(:address, non_null(:string), description: "The relay hostname to delete")
resolve(&Admin.remove_relay/3)
end
@desc "Accept a relay subscription"
field :accept_relay, type: :follower do
arg(:address, non_null(:string))
arg(:address, non_null(:string), description: "The accepted relay hostname")
resolve(&Admin.accept_subscription/3)
end
@desc "Reject a relay subscription"
field :reject_relay, type: :follower do
arg(:address, non_null(:string))
arg(:address, non_null(:string), description: "The rejected relay hostname")
resolve(&Admin.reject_subscription/3)
end
@desc """
Save admin settings
"""
field :save_admin_settings, type: :admin_settings do
arg(:instance_name, :string)
arg(:instance_description, :string)
arg(:instance_long_description, :string)
arg(:instance_slogan, :string)
arg(:contact, :string)
arg(:instance_terms, :string)
arg(:instance_terms_type, :instance_terms_type)
arg(:instance_terms_url, :string)
arg(:instance_privacy_policy, :string)
arg(:instance_privacy_policy_type, :instance_privacy_type)
arg(:instance_privacy_policy_url, :string)
arg(:instance_rules, :string)
arg(:registrations_open, :boolean)
arg(:instance_languages, list_of(:string))
arg(:instance_name, :string, description: "The instance's name")
arg(:instance_description, :string, description: "The instance's description")
arg(:instance_long_description, :string, description: "The instance's long description")
arg(:instance_slogan, :string, description: "The instance's slogan")
arg(:contact, :string, description: "The instance's contact details")
arg(:instance_terms, :string, description: "The instance's terms body text")
arg(:instance_terms_type, :instance_terms_type, description: "The instance's terms type")
arg(:instance_terms_url, :string, description: "The instance's terms URL")
arg(:instance_privacy_policy, :string,
description: "The instance's privacy policy body text"
)
arg(:instance_privacy_policy_type, :instance_privacy_type,
description: "The instance's privacy policy type"
)
arg(:instance_privacy_policy_url, :string, description: "The instance's privacy policy URL")
arg(:instance_rules, :string, description: "The instance's rules")
arg(:registrations_open, :boolean, description: "Whether the registrations are opened")
arg(:instance_languages, list_of(:string), description: "The instance's languages")
resolve(&Admin.save_settings/3)
end

View File

@@ -9,138 +9,262 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
@desc "A config object"
object :config do
# Instance name
field(:name, :string)
field(:description, :string)
field(:long_description, :string)
field(:slogan, :string)
field(:contact, :string)
field(:name, :string, description: "The instance's name")
field(:description, :string, description: "The instance's short description")
field(:long_description, :string, description: "The instance's long description")
field(:slogan, :string, description: "The instance's slogan")
field(:contact, :string, description: "The instance's contact details")
field(:languages, list_of(:string))
field(:registrations_open, :boolean)
field(:registrations_allowlist, :boolean)
field(:demo_mode, :boolean)
field(:country_code, :string)
field(:location, :lonlat)
field(:geocoding, :geocoding)
field(:maps, :maps)
field(:anonymous, :anonymous)
field(:resource_providers, list_of(:resource_provider))
field(:timezones, list_of(:string))
field(:features, :features)
field(:version, :string)
field(:federating, :boolean)
field(:languages, list_of(:string), description: "The instance's admins languages")
field(:registrations_open, :boolean, description: "Whether the registrations are opened")
field(:registrations_allowlist, :boolean,
description: "Whether the registration are on an allowlist"
)
field(:demo_mode, :boolean, description: "Whether the demo mode is enabled")
field(:country_code, :string, description: "The country code from the IP")
field(:location, :lonlat, description: "The IP's location")
field(:geocoding, :geocoding, description: "The instance's geocoding settings")
field(:maps, :maps, description: "The instance's maps settings")
field(:anonymous, :anonymous, description: "The instance's anonymous action settings")
field(:resource_providers, list_of(:resource_provider),
description: "The instance's enabled resource providers"
)
field(:timezones, list_of(:string), description: "The instance's available timezones")
field(:features, :features, description: "The instance's features")
field(:version, :string, description: "The instance's version")
field(:federating, :boolean, description: "Whether this instance is federation")
field(:terms, :terms, description: "The instance's terms") do
arg(:locale, :string, default_value: "en")
arg(:locale, :string,
default_value: "en",
description:
"The user's locale. The terms will be translated in their language, if available."
)
resolve(&Config.terms/3)
end
field(:privacy, :privacy, description: "The instance's privacy policy") do
arg(:locale, :string, default_value: "en")
arg(:locale, :string,
default_value: "en",
description:
"The user's locale. The privacy policy will be translated in their language, if available."
)
resolve(&Config.privacy/3)
end
field(:rules, :string, description: "The instance's rules")
field(:auth, :auth, description: "The instance auth methods")
end
@desc """
The instance's terms configuration
"""
object :terms do
field(:url, :string)
field(:type, :instance_terms_type)
field(:body_html, :string)
field(:url, :string, description: "The instance's terms URL.")
field(:type, :instance_terms_type, description: "The instance's terms type")
field(:body_html, :string, description: "The instance's terms body text")
end
@desc """
The instance's privacy policy configuration
"""
object :privacy do
field(:url, :string)
field(:type, :instance_privacy_type)
field(:body_html, :string)
field(:url, :string, description: "The instance's privacy policy URL")
field(:type, :instance_privacy_type, description: "The instance's privacy policy type")
field(:body_html, :string, description: "The instance's privacy policy body text")
end
@desc """
Geographic coordinates
"""
object :lonlat do
field(:longitude, :float)
field(:latitude, :float)
field(:longitude, :float, description: "The coordinates longitude")
field(:latitude, :float, description: "The coordinates latitude")
# field(:accuracy_radius, :integer)
end
@desc """
Instance geocoding configuration
"""
object :geocoding do
field(:autocomplete, :boolean)
field(:provider, :string)
field(:autocomplete, :boolean,
description: "Whether autocomplete in address fields can be enabled"
)
field(:provider, :string, description: "The geocoding provider")
end
@desc """
Instance maps configuration
"""
object :maps do
field(:tiles, :tiles)
field(:tiles, :tiles, description: "The instance's maps tiles configuration")
end
@desc """
Instance tiles configuration
"""
object :tiles do
field(:endpoint, :string)
field(:attribution, :string)
field(:endpoint, :string, description: "The instance's tiles endpoint")
field(:attribution, :string, description: "The instance's tiles attribution text")
end
@desc """
Instance anonymous configuration
"""
object :anonymous do
field(:participation, :anonymous_participation)
field(:event_creation, :anonymous_event_creation)
field(:reports, :anonymous_reports)
field(:actor_id, :id)
field(:participation, :anonymous_participation,
description: "The instance's anonymous participation settings"
)
field(:event_creation, :anonymous_event_creation,
description: "The instance's anonymous event creation settings"
)
field(:reports, :anonymous_reports, description: "The instance's anonymous reports setting")
field(:actor_id, :id,
description: "The actor ID that should be used to perform anonymous actions"
)
end
@desc """
Instance anonymous participation configuration
"""
object :anonymous_participation do
field(:allowed, :boolean)
field(:validation, :anonymous_participation_validation)
field(:allowed, :boolean, description: "Whether anonymous participations are allowed")
field(:validation, :anonymous_participation_validation,
description: "The ways to validate anonymous participations"
)
end
@desc """
Instance anonymous participation validation configuration
"""
object :anonymous_participation_validation do
field(:email, :anonymous_participation_validation_email)
field(:captcha, :anonymous_participation_validation_captcha)
field(:email, :anonymous_participation_validation_email,
description: "The policy to validate anonymous participations by email"
)
field(:captcha, :anonymous_participation_validation_captcha,
description: "The policy to validate anonymous participations by captcha"
)
end
@desc """
Instance anonymous participation with validation by email configuration
"""
object :anonymous_participation_validation_email do
field(:enabled, :boolean)
field(:confirmation_required, :boolean)
field(:enabled, :boolean,
description: "Whether anonymous participation validation by email is enabled"
)
field(:confirmation_required, :boolean,
description: "Whether anonymous participation validation by email is required"
)
end
@desc """
Instance anonymous participation with validation by captcha configuration
"""
object :anonymous_participation_validation_captcha do
field(:enabled, :boolean)
field(:enabled, :boolean,
description: "Whether anonymous participation validation by captcha is enabled"
)
end
@desc """
Instance anonymous event creation configuration
"""
object :anonymous_event_creation do
field(:allowed, :boolean)
field(:validation, :anonymous_event_creation_validation)
field(:allowed, :boolean, description: "Whether anonymous event creation is enabled")
field(:validation, :anonymous_event_creation_validation,
description: "The methods to validate events created anonymously"
)
end
@desc """
Instance anonymous event creation validation configuration
"""
object :anonymous_event_creation_validation do
field(:email, :anonymous_event_creation_validation_email)
field(:captcha, :anonymous_event_creation_validation_captcha)
field(:email, :anonymous_event_creation_validation_email,
description: "The policy to validate anonymous event creations by email"
)
field(:captcha, :anonymous_event_creation_validation_captcha,
description: "The policy to validate anonymous event creations by captcha"
)
end
@desc """
Instance anonymous event creation email validation configuration
"""
object :anonymous_event_creation_validation_email do
field(:enabled, :boolean)
field(:confirmation_required, :boolean)
field(:enabled, :boolean,
description: "Whether anonymous event creation with email validation is enabled"
)
field(:confirmation_required, :boolean,
description: "Whether anonymous event creation with email validation is required"
)
end
@desc """
Instance anonymous event creation captcha validation configuration
"""
object :anonymous_event_creation_validation_captcha do
field(:enabled, :boolean)
field(:enabled, :boolean,
description: "Whether anonymous event creation with validation by captcha is enabled"
)
end
@desc """
Instance anonymous reports
"""
object :anonymous_reports do
field(:allowed, :boolean)
field(:allowed, :boolean, description: "Whether anonymous reports are allowed")
end
@desc """
A resource provider details
"""
object :resource_provider do
field(:type, :string)
field(:endpoint, :string)
field(:software, :string)
field(:type, :string, description: "The resource provider's type")
field(:endpoint, :string, description: "The resource provider's endpoint")
field(:software, :string, description: "The resource provider's software")
end
@desc """
The instance's features
"""
object :features do
field(:groups, :boolean)
field(:event_creation, :boolean)
field(:groups, :boolean, description: "Whether groups are activated on this instance")
field(:event_creation, :boolean,
description: "Whether event creation is allowed on this instance"
)
end
@desc """
The instance's auth configuration
"""
object :auth do
field(:ldap, :boolean, description: "Whether or not LDAP auth is enabled")
field(:oauth_providers, list_of(:oauth_provider), description: "List of oauth providers")
end
@desc """
An oAuth Provider
"""
object :oauth_provider do
field(:id, :string, description: "The provider ID")
field(:label, :string, description: "The label for the auth provider")

View File

@@ -13,27 +13,43 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
object :comment do
interfaces([:action_log_object])
field(:id, :id, description: "Internal ID for this comment")
field(:uuid, :uuid)
field(:url, :string)
field(:local, :boolean)
field(:visibility, :comment_visibility)
field(:text, :string)
field(:primaryLanguage, :string)
field(:uuid, :uuid, description: "An UUID for this comment")
field(:url, :string, description: "Comment URL")
field(:local, :boolean, description: "Whether this comment is local or not")
field(:visibility, :comment_visibility, description: "The visibility for the comment")
field(:text, :string, description: "The comment body")
field(:primaryLanguage, :string, description: "The comment's primary language")
field(:replies, list_of(:comment)) do
description("A list of replies to the comment")
resolve(dataloader(Discussions))
end
field(:total_replies, :integer)
field(:in_reply_to_comment, :comment, resolve: dataloader(Discussions))
field(:event, :event, resolve: dataloader(Events))
field(:origin_comment, :comment, resolve: dataloader(Discussions))
field(:threadLanguages, non_null(list_of(:string)))
field(:actor, :person, resolve: dataloader(Actors))
field(:inserted_at, :datetime)
field(:updated_at, :datetime)
field(:deleted_at, :datetime)
field(:published_at, :datetime)
field(:total_replies, :integer,
description: "The number of total known replies to this comment"
)
field(:in_reply_to_comment, :comment,
resolve: dataloader(Discussions),
description: "The comment this comment directly replies to"
)
field(:event, :event,
resolve: dataloader(Events),
description: "The eventual event this comment is under"
)
field(:origin_comment, :comment,
resolve: dataloader(Discussions),
description: "The original comment that started the thread this comment is in"
)
field(:threadLanguages, non_null(list_of(:string)), description: "The thread languages")
field(:actor, :person, resolve: dataloader(Actors), description: "The comment's author")
field(:inserted_at, :datetime, description: "When was the comment inserted in database")
field(:updated_at, :datetime, description: "When was the comment updated")
field(:deleted_at, :datetime, description: "When was the comment deleted")
field(:published_at, :datetime, description: "When was the comment published")
end
@desc "The list of visibility options for a comment"
@@ -49,6 +65,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
value(:invite, description: "visible only to people invited")
end
@desc "A paginated list of comments"
object :paginated_comment_list do
field(:elements, list_of(:comment), description: "A list of comments")
field(:total, :integer, description: "The total number of comments in the list")
@@ -57,7 +74,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
object :comment_queries do
@desc "Get replies for thread"
field :thread, type: list_of(:comment) do
arg(:id, :id)
arg(:id, non_null(:id), description: "The comment ID")
resolve(&Comment.get_thread/3)
end
end
@@ -65,25 +82,24 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
object :comment_mutations do
@desc "Create a comment"
field :create_comment, type: :comment do
arg(:text, non_null(:string))
arg(:event_id, non_null(:id))
arg(:in_reply_to_comment_id, :id)
arg(:actor_id, non_null(:id))
arg(:text, non_null(:string), description: "The comment's body")
arg(:event_id, non_null(:id), description: "The event under which this comment is")
arg(:in_reply_to_comment_id, :id, description: "The comment ID this one replies to")
resolve(&Comment.create_comment/3)
end
@desc "Update a comment"
field :update_comment, type: :comment do
arg(:text, non_null(:string))
arg(:comment_id, non_null(:id))
arg(:text, non_null(:string), description: "The comment updated body")
arg(:comment_id, non_null(:id), description: "The comment ID")
resolve(&Comment.update_comment/3)
end
@desc "Delete a single comment"
field :delete_comment, type: :comment do
arg(:comment_id, non_null(:id))
arg(:comment_id, non_null(:id), description: "The comment ID")
resolve(&Comment.delete_comment/3)
end

View File

@@ -12,9 +12,9 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.DiscussionType do
@desc "A discussion"
object :discussion do
field(:id, :id, description: "Internal ID for this discussion")
field(:title, :string)
field(:slug, :string)
field(:last_comment, :comment)
field(:title, :string, description: "The title for this discussion")
field(:slug, :string, description: "The slug for the discussion")
field(:last_comment, :comment, description: "The last comment of the discussion")
field :comments, :paginated_comment_list do
arg(:page, :integer, default_value: 1)
@@ -23,22 +23,27 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.DiscussionType do
description("The comments for the discussion")
end
field(:creator, :person, resolve: dataloader(Actors))
field(:actor, :actor, resolve: dataloader(Actors))
field(:inserted_at, :datetime)
field(:updated_at, :datetime)
field(:creator, :person,
resolve: dataloader(Actors),
description: "This discussions's creator"
)
field(:actor, :actor, resolve: dataloader(Actors), description: "This discussion's group")
field(:inserted_at, :datetime, description: "When was this discussion's created")
field(:updated_at, :datetime, description: "When was this discussion's updated")
end
@desc "A paginated list of discussions"
object :paginated_discussion_list do
field(:elements, list_of(:discussion), description: "A list of discussion")
field(:total, :integer, description: "The total number of comments in the list")
field(:total, :integer, description: "The total number of discussions in the list")
end
object :discussion_queries do
@desc "Get a discussion"
field :discussion, type: :discussion do
arg(:id, :id)
arg(:slug, :string)
arg(:id, :id, description: "The discussion's ID")
arg(:slug, :string, description: "The discussion's slug")
resolve(&Discussion.get_discussion/3)
end
end
@@ -46,36 +51,39 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.DiscussionType do
object :discussion_mutations do
@desc "Create a discussion"
field :create_discussion, type: :discussion do
arg(:title, non_null(:string))
arg(:text, non_null(:string))
arg(:actor_id, non_null(:id))
arg(:creator_id, non_null(:id))
arg(:title, non_null(:string), description: "The discussion's title")
arg(:text, non_null(:string), description: "The discussion's first comment body")
arg(:actor_id, non_null(:id), description: "The discussion's group ID")
resolve(&Discussion.create_discussion/3)
end
@desc "Reply to a discussion"
field :reply_to_discussion, type: :discussion do
arg(:discussion_id, non_null(:id))
arg(:text, non_null(:string))
arg(:discussion_id, non_null(:id), description: "The discussion's ID")
arg(:text, non_null(:string), description: "The discussion's reply body")
resolve(&Discussion.reply_to_discussion/3)
end
@desc "Update a discussion"
field :update_discussion, type: :discussion do
arg(:title, non_null(:string))
arg(:discussion_id, non_null(:id))
arg(:title, non_null(:string), description: "The updated discussion's title")
arg(:discussion_id, non_null(:id), description: "The discussion's ID")
resolve(&Discussion.update_discussion/3)
end
@desc "Delete a discussion"
field :delete_discussion, type: :discussion do
arg(:discussion_id, non_null(:id))
arg(:discussion_id, non_null(:id), description: "The discussion's ID")
resolve(&Discussion.delete_discussion/3)
end
end
object :discussion_subscriptions do
@desc "Notify when a discussion changed"
field :discussion_comment_changed, :discussion do
arg(:slug, non_null(:string))
arg(:slug, non_null(:string), description: "The discussion's slug")
config(fn args, _ ->
{:ok, topic: args.slug}

View File

@@ -40,7 +40,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
field(:physical_address, :address,
resolve: dataloader(Addresses),
description: "The type of the event's address"
description: "The event's physical address"
)
field(:online_address, :string, description: "Online address of the event")
@@ -68,10 +68,13 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
)
field(:participants, :paginated_participant_list, description: "The event's participants") do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:roles, :string, default_value: "")
arg(:actor_id, :id)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated participants list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of participants per page")
arg(:roles, :string, default_value: "", description: "Filter by roles")
resolve(&Event.list_participants_for_event/3)
end
@@ -119,11 +122,13 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
value(:cancelled, description: "The event is cancelled")
end
@desc "A paginated list of events"
object :paginated_event_list do
field(:elements, list_of(:event), description: "A list of events")
field(:total, :integer, description: "The total number of events in the list")
end
@desc "Participation statistics"
object :participant_stats do
field(:going, :integer, description: "The number of approved participants")
field(:not_approved, :integer, description: "The number of not approved participants")
@@ -139,24 +144,36 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
field(:creator, :integer, description: "The number of creators")
end
@desc """
An event offer
"""
object :event_offer do
field(:price, :float, description: "The price amount for this offer")
field(:price_currency, :string, description: "The currency for this price offer")
field(:url, :string, description: "The URL to access to this offer")
end
@desc """
An event participation condition
"""
object :event_participation_condition do
field(:title, :string, description: "The title for this condition")
field(:content, :string, description: "The content for this condition")
field(:url, :string, description: "The URL to access this condition")
end
@desc """
An event offer
"""
input_object :event_offer_input do
field(:price, :float, description: "The price amount for this offer")
field(:price_currency, :string, description: "The currency for this price offer")
field(:url, :string, description: "The URL to access to this offer")
end
@desc """
An event participation condition
"""
input_object :event_participation_condition_input do
field(:title, :string, description: "The title for this condition")
field(:content, :string, description: "The content for this condition")
@@ -170,6 +187,9 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
value(:closed, description: "No one can comment except for the admin")
end
@desc """
Event options
"""
object :event_options do
field(:maximum_attendee_capacity, :integer,
description: "The maximum attendee capacity for this event"
@@ -213,6 +233,9 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
)
end
@desc """
Event options
"""
input_object :event_options_input do
field(:maximum_attendee_capacity, :integer,
description: "The maximum attendee capacity for this event"
@@ -259,6 +282,9 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
)
end
@desc """
A event contact
"""
input_object :contact do
field(:id, :string, description: "The Contact Actor ID")
end
@@ -266,14 +292,14 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
object :event_queries do
@desc "Get all events"
field :events, list_of(:event) do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer, default_value: 1, description: "The page in the paginated event list")
arg(:limit, :integer, default_value: 10, description: "The limit of events per page")
resolve(&Event.list_events/3)
end
@desc "Get an event by uuid"
field :event, :event do
arg(:uuid, non_null(:uuid))
arg(:uuid, non_null(:uuid), description: "The event's UUID")
resolve(&Event.find_event/3)
end
end
@@ -281,13 +307,21 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
object :event_mutations do
@desc "Create an event"
field :create_event, type: :event do
arg(:title, non_null(:string))
arg(:description, non_null(:string))
arg(:begins_on, non_null(:datetime))
arg(:ends_on, :datetime)
arg(:status, :event_status)
arg(:visibility, :event_visibility, default_value: :public)
arg(:join_options, :event_join_options, default_value: :free)
arg(:title, non_null(:string), description: "The event's title")
arg(:description, non_null(:string), description: "The event's description")
arg(:begins_on, non_null(:datetime), description: "Datetime for when the event begins")
arg(:ends_on, :datetime, description: "Datetime for when the event ends")
arg(:status, :event_status, description: "Status of the event")
arg(:visibility, :event_visibility,
default_value: :public,
description: "The event's visibility"
)
arg(:join_options, :event_join_options,
default_value: :free,
description: "The event's options to join"
)
arg(:tags, list_of(:string),
default_value: [],
@@ -299,31 +333,49 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
"The picture for the event, either as an object or directly the ID of an existing Picture"
)
arg(:publish_at, :datetime)
arg(:online_address, :string)
arg(:phone_address, :string)
arg(:organizer_actor_id, non_null(:id))
arg(:attributed_to_id, :id)
arg(:category, :string, default_value: "meeting")
arg(:physical_address, :address_input)
arg(:options, :event_options_input)
arg(:draft, :boolean, default_value: false)
arg(:contacts, list_of(:contact), default_value: [])
arg(:publish_at, :datetime, description: "Datetime when the event was published")
arg(:online_address, :string, description: "Online address of the event")
arg(:phone_address, :string, description: "Phone address for the event")
arg(:organizer_actor_id, non_null(:id),
description: "The event's organizer ID (as a person)"
)
arg(:attributed_to_id, :id, description: "Who the event is attributed to ID (often a group)")
arg(:category, :string, default_value: "meeting", description: "The event's category")
arg(:physical_address, :address_input, description: "The event's physical address")
arg(:options, :event_options_input, description: "The event options")
arg(:draft, :boolean,
default_value: false,
description: "Whether or not the event is a draft"
)
arg(:contacts, list_of(:contact), default_value: [], description: "The events contacts")
resolve(&Event.create_event/3)
end
@desc "Update an event"
field :update_event, type: :event do
arg(:event_id, non_null(:id))
arg(:event_id, non_null(:id), description: "The event's ID")
arg(:title, :string)
arg(:description, :string)
arg(:begins_on, :datetime)
arg(:ends_on, :datetime)
arg(:status, :event_status)
arg(:visibility, :event_visibility, default_value: :public)
arg(:join_options, :event_join_options, default_value: :free)
arg(:title, :string, description: "The event's title")
arg(:description, :string, description: "The event's description")
arg(:begins_on, :datetime, description: "Datetime for when the event begins")
arg(:ends_on, :datetime, description: "Datetime for when the event ends")
arg(:status, :event_status, description: "Status of the event")
arg(:visibility, :event_visibility,
default_value: :public,
description: "The event's visibility"
)
arg(:join_options, :event_join_options,
default_value: :free,
description: "The event's options to join"
)
arg(:tags, list_of(:string), description: "The list of tags associated to the event")
@@ -332,23 +384,24 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
"The picture for the event, either as an object or directly the ID of an existing Picture"
)
arg(:online_address, :string)
arg(:phone_address, :string)
arg(:organizer_actor_id, :id)
arg(:attributed_to_id, :id)
arg(:category, :string)
arg(:physical_address, :address_input)
arg(:options, :event_options_input)
arg(:draft, :boolean)
arg(:contacts, list_of(:contact), default_value: [])
arg(:online_address, :string, description: "Online address of the event")
arg(:phone_address, :string, description: "Phone address for the event")
arg(:organizer_actor_id, :id, description: "The event's organizer ID (as a person)")
arg(:attributed_to_id, :id, description: "Who the event is attributed to ID (often a group)")
arg(:category, :string, description: "The event's category")
arg(:physical_address, :address_input, description: "The event's physical address")
arg(:options, :event_options_input, description: "The event options")
arg(:draft, :boolean, description: "Whether or not the event is a draft")
arg(:contacts, list_of(:contact), default_value: [], description: "The events contacts")
resolve(&Event.update_event/3)
end
@desc "Delete an event"
field :delete_event, :deleted_object do
arg(:event_id, non_null(:id))
arg(:actor_id, non_null(:id))
arg(:event_id, non_null(:id), description: "The event ID to delete")
resolve(&Event.delete_event/3)
end

View File

@@ -10,7 +10,12 @@ defmodule Mobilizon.GraphQL.Schema.Events.FeedTokenType do
alias Mobilizon.{Actors, Users}
alias Mobilizon.GraphQL.Resolvers.FeedToken
@desc "Represents a participant to an event"
@desc """
Represents a feed token
Feed tokens are tokens that are used to provide access to private feeds such as WebCal feed for all of your user's events,
or an Atom feed for just a profile.
"""
object :feed_token do
field(
:actor,
@@ -31,21 +36,21 @@ defmodule Mobilizon.GraphQL.Schema.Events.FeedTokenType do
@desc "Represents a deleted feed_token"
object :deleted_feed_token do
field(:user, :deleted_object)
field(:actor, :deleted_object)
field(:user, :deleted_object, description: "The user that owned the deleted feed token")
field(:actor, :deleted_object, description: "The actor that owned the deleted feed token")
end
object :feed_token_mutations do
@desc "Create a Feed Token"
field :create_feed_token, :feed_token do
arg(:actor_id, :id)
arg(:actor_id, :id, description: "The actor ID for the feed token")
resolve(&FeedToken.create_feed_token/3)
end
@desc "Delete a feed token"
field :delete_feed_token, :deleted_feed_token do
arg(:token, non_null(:string))
arg(:token, non_null(:string), description: "The token to delete")
resolve(&FeedToken.delete_feed_token/3)
end

View File

@@ -37,6 +37,9 @@ defmodule Mobilizon.GraphQL.Schema.Events.ParticipantType do
field(:inserted_at, :datetime, description: "The datetime this participant was created")
end
@desc """
Metadata about a participant
"""
object :participant_metadata do
field(:cancellation_token, :string,
description: "The eventual token to leave an event when user is anonymous"
@@ -46,61 +49,66 @@ defmodule Mobilizon.GraphQL.Schema.Events.ParticipantType do
field(:locale, :string, description: "The participant's locale")
end
@desc """
A paginated list of participants
"""
object :paginated_participant_list do
field(:elements, list_of(:participant), description: "A list of participants")
field(:total, :integer, description: "The total number of participants in the list")
end
@desc """
The possible values for a participant role
"""
enum :participant_role_enum do
value(:not_approved)
value(:not_confirmed)
value(:participant)
value(:moderator)
value(:administrator)
value(:creator)
value(:rejected)
value(:not_approved, description: "The participant has not been approved")
value(:not_confirmed, description: "The participant has not confirmed their participation")
value(:participant, description: "The participant is a regular participant")
value(:moderator, description: "The participant is an event moderator")
value(:administrator, description: "The participant is an event administrator")
value(:creator, description: "The participant is an event creator")
value(:rejected, description: "The participant has been rejected from this event")
end
@desc "Represents a deleted participant"
object :deleted_participant do
field(:id, :id)
field(:event, :deleted_object)
field(:actor, :deleted_object)
field(:id, :id, description: "The participant ID")
field(:event, :deleted_object, description: "The participant's event")
field(:actor, :deleted_object, description: "The participant's actor")
end
object :participant_mutations do
@desc "Join an event"
field :join_event, :participant do
arg(:event_id, non_null(:id))
arg(:actor_id, non_null(:id))
arg(:email, :string)
arg(:message, :string)
arg(:locale, :string)
arg(:event_id, non_null(:id), description: "The event ID that is joined")
arg(:actor_id, non_null(:id), description: "The actor ID for the participant")
arg(:email, :string, description: "The anonymous participant's email")
arg(:message, :string, description: "The anonymous participant's message")
arg(:locale, :string, description: "The anonymous participant's locale")
resolve(&Participant.actor_join_event/3)
end
@desc "Leave an event"
field :leave_event, :deleted_participant do
arg(:event_id, non_null(:id))
arg(:actor_id, non_null(:id))
arg(:token, :string)
arg(:event_id, non_null(:id), description: "The event ID the participant left")
arg(:actor_id, non_null(:id), description: "The actor ID for the participant")
arg(:token, :string, description: "The anonymous participant participation token")
resolve(&Participant.actor_leave_event/3)
end
@desc "Accept a participation"
@desc "Update a participation"
field :update_participation, :participant do
arg(:id, non_null(:id))
arg(:role, non_null(:participant_role_enum))
arg(:moderator_actor_id, non_null(:id))
arg(:id, non_null(:id), description: "The participant ID")
arg(:role, non_null(:participant_role_enum), description: "The participant new role")
resolve(&Participant.update_participation/3)
end
@desc "Confirm a participation"
field :confirm_participation, :participant do
arg(:confirmation_token, non_null(:string))
arg(:confirmation_token, non_null(:string), description: "The participation token")
resolve(&Participant.confirm_participation_from_token/3)
end
end

View File

@@ -19,23 +19,23 @@ defmodule Mobilizon.GraphQL.Schema.PictureType do
@desc "An attached picture or a link to a picture"
input_object :picture_input do
# Either a full picture object
field(:picture, :picture_input_object)
field(:picture, :picture_input_object, description: "A full picture attached")
# Or directly the ID of an existing picture
field(:picture_id, :id)
field(:picture_id, :id, description: "The ID of an existing picture")
end
@desc "An attached picture"
input_object :picture_input_object do
field(:name, non_null(:string))
field(:alt, :string)
field(:file, non_null(:upload))
field(:actor_id, :id)
field(:name, non_null(:string), description: "The picture's name")
field(:alt, :string, description: "The picture's alternative text")
field(:file, non_null(:upload), description: "The picture file")
field(:actor_id, :id, description: "The picture owner")
end
object :picture_queries do
@desc "Get a picture"
field :picture, :picture do
arg(:id, non_null(:string))
arg(:id, non_null(:string), description: "The picture ID")
resolve(&Picture.picture/3)
end
end
@@ -43,10 +43,9 @@ defmodule Mobilizon.GraphQL.Schema.PictureType do
object :picture_mutations do
@desc "Upload a picture"
field :upload_picture, :picture do
arg(:name, non_null(:string))
arg(:alt, :string)
arg(:file, non_null(:upload))
arg(:actor_id, non_null(:id))
arg(:name, non_null(:string), description: "The picture's name")
arg(:alt, :string, description: "The picture's alternative text")
arg(:file, non_null(:upload), description: "The picture file")
resolve(&Picture.upload_picture/3)
end
end

View File

@@ -31,6 +31,9 @@ defmodule Mobilizon.GraphQL.Schema.PostType do
)
end
@desc """
A paginated list of posts
"""
object :paginated_post_list do
field(:elements, list_of(:post), description: "A list of posts")
field(:total, :integer, description: "The total number of posts in the list")
@@ -50,7 +53,7 @@ defmodule Mobilizon.GraphQL.Schema.PostType do
object :post_queries do
@desc "Get a post"
field :post, :post do
arg(:slug, non_null(:string))
arg(:slug, non_null(:string), description: "The post's slug")
resolve(&Post.get_post/3)
end
end
@@ -58,12 +61,15 @@ defmodule Mobilizon.GraphQL.Schema.PostType do
object :post_mutations do
@desc "Create a post"
field :create_post, :post do
arg(:attributed_to_id, non_null(:id))
arg(:title, non_null(:string))
arg(:body, non_null(:string))
arg(:draft, :boolean, default_value: false)
arg(:visibility, :post_visibility)
arg(:publish_at, :datetime)
arg(:attributed_to_id, non_null(:id),
description: "The ID from the group whose post is attributed to"
)
arg(:title, non_null(:string), description: "The post's title")
arg(:body, non_null(:string), description: "The post's body")
arg(:draft, :boolean, default_value: false, description: "Whether the post is a draft")
arg(:visibility, :post_visibility, description: "The post's visibility")
arg(:publish_at, :datetime, description: "The post's publish date")
arg(:tags, list_of(:string),
default_value: [],
@@ -80,13 +86,17 @@ defmodule Mobilizon.GraphQL.Schema.PostType do
@desc "Update a post"
field :update_post, :post do
arg(:id, non_null(:id))
arg(:title, :string)
arg(:body, :string)
arg(:attributed_to_id, :id)
arg(:draft, :boolean)
arg(:visibility, :post_visibility)
arg(:publish_at, :datetime)
arg(:id, non_null(:id), description: "The post's ID")
arg(:title, :string, description: "The post's new title")
arg(:body, :string, description: "The post's new body")
arg(:attributed_to_id, :id, description: "The group the post is attributed to")
arg(:draft, :boolean, description: "Whether the post is a draft")
arg(:visibility, :post_visibility, description: "The post's visibility")
arg(:publish_at, :datetime,
description: "The time when the posts is going to be or has been published"
)
arg(:tags, list_of(:string), description: "The list of tags associated to the post")
arg(:picture, :picture_input,
@@ -99,7 +109,7 @@ defmodule Mobilizon.GraphQL.Schema.PostType do
@desc "Delete a post"
field :delete_post, :deleted_object do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The post's ID")
resolve(&Post.delete_post/3)
end
end

View File

@@ -55,15 +55,19 @@ defmodule Mobilizon.GraphQL.Schema.ReportType do
object :report_queries do
@desc "Get all reports"
field :reports, list_of(:report) do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:status, :report_status, default_value: :open)
arg(:page, :integer,
default_value: 1,
description: "The page in the reports participations list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of reports per page")
arg(:status, :report_status, default_value: :open, description: "Filter reports by status")
resolve(&Report.list_reports/3)
end
@desc "Get a report by id"
field :report, :report do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The report ID")
resolve(&Report.get_report/3)
end
end
@@ -71,34 +75,41 @@ defmodule Mobilizon.GraphQL.Schema.ReportType do
object :report_mutations do
@desc "Create a report"
field :create_report, type: :report do
arg(:content, :string)
arg(:reporter_id, non_null(:id))
arg(:reported_id, non_null(:id))
arg(:event_id, :id, default_value: nil)
arg(:comments_ids, list_of(:id), default_value: [])
arg(:forward, :boolean, default_value: false)
arg(:content, :string, description: "The message sent with the report")
arg(:reported_id, non_null(:id), description: "The actor's ID that is being reported")
arg(:event_id, :id, default_value: nil, description: "The event ID that is being reported")
arg(:comments_ids, list_of(:id),
default_value: [],
description: "The comment ID that is being reported"
)
arg(:forward, :boolean,
default_value: false,
description:
"Whether to forward the report to the original instance if the content is remote"
)
resolve(&Report.create_report/3)
end
@desc "Update a report"
field :update_report_status, type: :report do
arg(:report_id, non_null(:id))
arg(:moderator_id, non_null(:id))
arg(:status, non_null(:report_status))
arg(:report_id, non_null(:id), description: "The report's ID")
arg(:status, non_null(:report_status), description: "The report's new status")
resolve(&Report.update_report/3)
end
@desc "Create a note on a report"
field :create_report_note, type: :report_note do
arg(:content, :string)
arg(:moderator_id, non_null(:id))
arg(:report_id, non_null(:id))
arg(:content, :string, description: "The note's content")
arg(:report_id, non_null(:id), description: "The report's ID")
resolve(&Report.create_report_note/3)
end
@desc "Delete a note on a report"
field :delete_report_note, type: :deleted_object do
arg(:note_id, non_null(:id))
arg(:moderator_id, non_null(:id))
arg(:note_id, non_null(:id), description: "The note's ID")
resolve(&Report.delete_report_note/3)
end
end

View File

@@ -30,31 +30,41 @@ defmodule Mobilizon.GraphQL.Schema.ResourceType do
end
end
@desc """
A paginated list of resources
"""
object :paginated_resource_list do
field(:elements, list_of(:resource), description: "A list of resources")
field(:total, :integer, description: "The total number of resources in the list")
end
@desc """
The metadata associated to the resource
"""
object :resource_metadata do
field(:type, :string, description: "The type of the resource")
field(:title, :string, description: "The resource's metadata title")
field(:description, :string, description: "The resource's metadata description")
field(:image_remote_url, :string, description: "The resource's metadata image")
field(:width, :integer)
field(:height, :integer)
field(:author_name, :string)
field(:author_url, :string)
field(:provider_name, :string)
field(:provider_url, :string)
field(:html, :string)
field(:favicon_url, :string)
field(:width, :integer, description: "The resource's metadata image width")
field(:height, :integer, description: "The resource's metadata image height")
field(:author_name, :string, description: "The resource's author name")
field(:author_url, :string, description: "The resource's author URL")
field(:provider_name, :string, description: "The resource's provider name")
field(:provider_url, :string, description: "The resource's provider URL")
field(:html, :string, description: "The resource's author name")
field(:favicon_url, :string, description: "The resource's favicon URL")
end
object :resource_queries do
@desc "Get a resource"
field :resource, :resource do
arg(:path, non_null(:string))
arg(:username, non_null(:string))
arg(:path, non_null(:string), description: "The path for the resource")
arg(:username, non_null(:string),
description: "The federated username for the group resource"
)
resolve(&Resource.get_resource/3)
end
end
@@ -62,36 +72,39 @@ defmodule Mobilizon.GraphQL.Schema.ResourceType do
object :resource_mutations do
@desc "Create a resource"
field :create_resource, :resource do
arg(:parent_id, :id)
arg(:actor_id, non_null(:id))
arg(:title, non_null(:string))
arg(:summary, :string)
arg(:resource_url, :string)
arg(:type, :string, default_value: "link")
arg(:parent_id, :id,
description: "The ID from the parent resource (folder) this resource is in"
)
arg(:actor_id, non_null(:id), description: "The group this resource belongs to")
arg(:title, non_null(:string), description: "This resource's title")
arg(:summary, :string, description: "This resource summary")
arg(:resource_url, :string, description: "This resource's own original URL")
arg(:type, :string, default_value: "link", description: "The type for this resource")
resolve(&Resource.create_resource/3)
end
@desc "Update a resource"
field :update_resource, :resource do
arg(:id, non_null(:id))
arg(:title, :string)
arg(:summary, :string)
arg(:parent_id, :id)
arg(:resource_url, :string)
arg(:id, non_null(:id), description: "The resource ID")
arg(:title, :string, description: "The new resource title")
arg(:summary, :string, description: "The new resource summary")
arg(:parent_id, :id, description: "The new resource parent ID (if the resource is moved)")
arg(:resource_url, :string, description: "The new resource URL")
resolve(&Resource.update_resource/3)
end
@desc "Delete a resource"
field :delete_resource, :deleted_object do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The resource ID")
resolve(&Resource.delete_resource/3)
end
@desc "Get a preview for a resource link"
field :preview_resource_link, :resource_metadata do
arg(:resource_url, non_null(:string))
arg(:resource_url, non_null(:string), description: "The link to crawl to get of preview of")
resolve(&Resource.preview_resource_link/3)
end
end

View File

@@ -26,6 +26,9 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do
field(:elements, non_null(list_of(:event)), description: "Event elements")
end
@desc """
A entity that can be interacted with from a remote instance
"""
interface :interactable do
field(:url, :string, description: "A public URL for the entity")
@@ -44,20 +47,25 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do
object :search_queries do
@desc "Search persons"
field :search_persons, :persons do
arg(:term, :string, default_value: "")
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:term, :string, default_value: "", description: "Search term")
arg(:page, :integer, default_value: 1, description: "Result page")
arg(:limit, :integer, default_value: 10, description: "Results limit per page")
resolve(&Search.search_persons/3)
end
@desc "Search groups"
field :search_groups, :groups do
arg(:term, :string, default_value: "")
arg(:term, :string, default_value: "", description: "Search term")
arg(:location, :string, description: "A geohash for coordinates")
arg(:radius, :float, default_value: 50)
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:radius, :float,
default_value: 50,
description: "Radius around the location to search in"
)
arg(:page, :integer, default_value: 1, description: "Result page")
arg(:limit, :integer, default_value: 10, description: "Results limit per page")
resolve(&Search.search_groups/3)
end
@@ -67,11 +75,16 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do
arg(:term, :string, default_value: "")
arg(:tags, :string, description: "A comma-separated string listing the tags")
arg(:location, :string, description: "A geohash for coordinates")
arg(:radius, :float, default_value: 50)
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:begins_on, :datetime)
arg(:ends_on, :datetime)
arg(:radius, :float,
default_value: 50,
description: "Radius around the location to search in"
)
arg(:page, :integer, default_value: 1, description: "Result page")
arg(:limit, :integer, default_value: 10, description: "Results limit per page")
arg(:begins_on, :datetime, description: "Filter events by their start date")
arg(:ends_on, :datetime, description: "Filter events by their end date")
resolve(&Search.search_events/3)
end

View File

@@ -6,7 +6,7 @@ defmodule Mobilizon.GraphQL.Schema.SortType do
@desc "Available sort directions"
enum :sort_direction do
value(:asc)
value(:desc)
value(:asc, description: "Ascending order")
value(:desc, description: "Descending order")
end
end

View File

@@ -23,8 +23,8 @@ defmodule Mobilizon.GraphQL.Schema.TagType do
object :tag_queries do
@desc "Get the list of tags"
field :tags, non_null(list_of(:tag)) do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer, default_value: 1, description: "The page in the paginated tags list")
arg(:limit, :integer, default_value: 10, description: "The limit of tags per page")
resolve(&Tag.list_tags/3)
end
end

View File

@@ -26,6 +26,9 @@ defmodule Mobilizon.GraphQL.Schema.Todos.TodoType do
)
end
@desc """
A paginated list of todos
"""
object :paginated_todo_list do
field(:elements, list_of(:todo), description: "A list of todos")
field(:total, :integer, description: "The total number of todos in the list")
@@ -34,7 +37,7 @@ defmodule Mobilizon.GraphQL.Schema.Todos.TodoType do
object :todo_queries do
@desc "Get a todo"
field :todo, :todo do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The todo ID")
resolve(&TodoResolver.get_todo/3)
end
end
@@ -42,23 +45,23 @@ defmodule Mobilizon.GraphQL.Schema.Todos.TodoType do
object :todo_mutations do
@desc "Create a todo"
field :create_todo, :todo do
arg(:todo_list_id, non_null(:id))
arg(:title, non_null(:string))
arg(:status, :boolean)
arg(:due_date, :datetime)
arg(:assigned_to_id, :id)
arg(:todo_list_id, non_null(:id), description: "The todo-list ID this todo is in")
arg(:title, non_null(:string), description: "The todo title")
arg(:status, :boolean, description: "The todo status")
arg(:due_date, :datetime, description: "The todo due date")
arg(:assigned_to_id, :id, description: "The actor this todo is assigned to")
resolve(&TodoResolver.create_todo/3)
end
@desc "Update a todo"
field :update_todo, :todo do
arg(:id, non_null(:id))
arg(:todo_list_id, :id)
arg(:title, :string)
arg(:status, :boolean)
arg(:due_date, :datetime)
arg(:assigned_to_id, :id)
arg(:id, non_null(:id), description: "The todo ID")
arg(:todo_list_id, :id, description: "The new todo-list ID")
arg(:title, :string, description: "The new todo title")
arg(:status, :boolean, description: "The new todo status")
arg(:due_date, :datetime, description: "The new todo due date")
arg(:assigned_to_id, :id, description: "The new id of the actor this todo is assigned to")
resolve(&TodoResolver.update_todo/3)
end

View File

@@ -23,6 +23,9 @@ defmodule Mobilizon.GraphQL.Schema.Todos.TodoListType do
)
end
@desc """
A paginated list of todo-lists
"""
object :paginated_todo_list_list do
field(:elements, list_of(:todo_list), description: "A list of todo lists")
field(:total, :integer, description: "The total number of todo lists in the list")
@@ -31,7 +34,7 @@ defmodule Mobilizon.GraphQL.Schema.Todos.TodoListType do
object :todo_list_queries do
@desc "Get a todo list"
field :todo_list, :todo_list do
arg(:id, non_null(:id))
arg(:id, non_null(:id), description: "The todo-list ID")
resolve(&Todos.get_todo_list/3)
end
end
@@ -39,8 +42,8 @@ defmodule Mobilizon.GraphQL.Schema.Todos.TodoListType do
object :todo_list_mutations do
@desc "Create a todo list"
field :create_todo_list, :todo_list do
arg(:title, non_null(:string))
arg(:group_id, non_null(:id))
arg(:title, non_null(:string), description: "The todo list title")
arg(:group_id, non_null(:id), description: "The group ID")
resolve(&Todos.create_todo_list/3)
end
end

View File

@@ -58,24 +58,42 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
field(:participations, :paginated_participant_list,
description: "The list of participations this user has"
) do
arg(:after_datetime, :datetime)
arg(:before_datetime, :datetime)
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:after_datetime, :datetime, description: "Filter participations by event start datetime")
arg(:before_datetime, :datetime, description: "Filter participations by event end datetime")
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated participations list"
)
arg(:limit, :integer,
default_value: 10,
description: "The limit of participations per page"
)
resolve(&User.user_participations/3)
end
field(:memberships, :paginated_member_list,
description: "The list of memberships for this user"
) do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated memberships list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of memberships per page")
resolve(&User.user_memberships/3)
end
field(:drafts, list_of(:event), description: "The list of draft events this user has created") do
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:page, :integer,
default_value: 1,
description: "The page in the paginated drafts events list"
)
arg(:limit, :integer, default_value: 10, description: "The limit of drafts events per page")
resolve(&User.user_drafted_events/3)
end
@@ -94,10 +112,11 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
)
end
@desc "The list of roles an user can have"
enum :user_role do
value(:administrator)
value(:moderator)
value(:user)
value(:administrator, description: "Administrator role")
value(:moderator, description: "Moderator role")
value(:user, description: "User role")
end
@desc "Token"
@@ -112,9 +131,9 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
field(:elements, non_null(list_of(:user)), description: "User elements")
end
@desc "The list of possible options for the event's status"
@desc "The list of sortable fields for an user list"
enum :sortable_user_field do
value(:id)
value(:id, description: "The user's ID")
end
object :user_settings do
@@ -142,11 +161,24 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
)
end
@desc "The list of values the for pending notification settings"
enum :notification_pending_enum do
value(:none, as: :none)
value(:direct, as: :direct)
value(:one_hour, as: :one_hour)
value(:one_day, as: :one_day)
value(:none, as: :none, description: "None. The notification won't be sent.")
value(:direct,
as: :direct,
description: "Direct. The notification will be sent right away each time."
)
value(:one_hour,
as: :one_hour,
description: "One hour. Notifications will be sent at most each hour"
)
value(:one_day,
as: :one_day,
description: "One day. Notifications will be sent at most each day"
)
end
object :user_queries do
@@ -163,12 +195,12 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
@desc "List instance users"
field :users, :users do
arg(:email, :string, default_value: "")
arg(:page, :integer, default_value: 1)
arg(:limit, :integer, default_value: 10)
arg(:email, :string, default_value: "", description: "Filter users by email")
arg(:page, :integer, default_value: 1, description: "The page in the paginated users list")
arg(:limit, :integer, default_value: 10, description: "The limit of users per page")
arg(:sort, :sortable_user_field, default_value: :id)
arg(:direction, :sort_direction, default_value: :desc)
arg(:sort, :sortable_user_field, default_value: :id, description: "Sort column")
arg(:direction, :sort_direction, default_value: :desc, description: "Sort direction")
resolve(&User.list_users/3)
end
@@ -177,99 +209,128 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
object :user_mutations do
@desc "Create an user"
field :create_user, type: :user do
arg(:email, non_null(:string))
arg(:password, non_null(:string))
arg(:locale, :string)
arg(:email, non_null(:string), description: "The new user's email")
arg(:password, non_null(:string), description: "The new user's password")
arg(:locale, :string, description: "The new user's locale")
resolve(&User.create_user/3)
end
@desc "Validate an user after registration"
field :validate_user, type: :login do
arg(:token, non_null(:string))
arg(:token, non_null(:string),
description: "The token that will be used to validate the user"
)
resolve(&User.validate_user/3)
end
@desc "Resend registration confirmation token"
field :resend_confirmation_email, type: :string do
arg(:email, non_null(:string))
arg(:locale, :string)
arg(:email, non_null(:string), description: "The email used to register")
arg(:locale, :string, description: "The user's locale")
resolve(&User.resend_confirmation_email/3)
end
@desc "Send a link through email to reset user password"
field :send_reset_password, type: :string do
arg(:email, non_null(:string))
arg(:locale, :string)
arg(:email, non_null(:string), description: "The user's email")
arg(:locale, :string, description: "The user's locale")
resolve(&User.send_reset_password/3)
end
@desc "Reset user password"
field :reset_password, type: :login do
arg(:token, non_null(:string))
arg(:password, non_null(:string))
arg(:locale, :string, default_value: "en")
arg(:token, non_null(:string),
description: "The user's token that will be used to reset the password"
)
arg(:password, non_null(:string), description: "The new password")
arg(:locale, :string, default_value: "en", description: "The user's locale")
resolve(&User.reset_password/3)
end
@desc "Login an user"
field :login, type: :login do
arg(:email, non_null(:string))
arg(:password, non_null(:string))
arg(:email, non_null(:string), description: "The user's email")
arg(:password, non_null(:string), description: "The user's password")
resolve(&User.login_user/3)
end
@desc "Refresh a token"
field :refresh_token, type: :refreshed_token do
arg(:refresh_token, non_null(:string))
arg(:refresh_token, non_null(:string), description: "A refresh token")
resolve(&User.refresh_token/3)
end
@desc "Change default actor for user"
field :change_default_actor, :user do
arg(:preferred_username, non_null(:string))
arg(:preferred_username, non_null(:string), description: "The actor preferred_username")
resolve(&User.change_default_actor/3)
end
@desc "Change an user password"
field :change_password, :user do
arg(:old_password, non_null(:string))
arg(:new_password, non_null(:string))
arg(:old_password, non_null(:string), description: "The user's current password")
arg(:new_password, non_null(:string), description: "The user's new password")
resolve(&User.change_password/3)
end
@desc "Change an user email"
field :change_email, :user do
arg(:email, non_null(:string))
arg(:password, non_null(:string))
arg(:email, non_null(:string), description: "The user's new email")
arg(:password, non_null(:string), description: "The user's current password")
resolve(&User.change_email/3)
end
@desc "Validate an user email"
field :validate_email, :user do
arg(:token, non_null(:string))
arg(:token, non_null(:string),
description: "The token that will be used to validate the email change"
)
resolve(&User.validate_email/3)
end
@desc "Delete an account"
field :delete_account, :deleted_object do
arg(:password, :string)
arg(:user_id, :id)
arg(:password, :string, description: "The user's password")
arg(:user_id, :id, description: "The user's ID")
resolve(&User.delete_account/3)
end
@desc "Set user settings"
field :set_user_settings, :user_settings do
arg(:timezone, :string)
arg(:notification_on_day, :boolean)
arg(:notification_each_week, :boolean)
arg(:notification_before_event, :boolean)
arg(:notification_pending_participation, :notification_pending_enum)
arg(:notification_pending_membership, :notification_pending_enum)
arg(:timezone, :string, description: "The timezone for this user")
arg(:notification_on_day, :boolean,
description:
"Whether this user will receive an email at the start of the day of an event."
)
arg(:notification_each_week, :boolean,
description: "Whether this user will receive an weekly event recap"
)
arg(:notification_before_event, :boolean,
description: "Whether this user will receive a notification right before event"
)
arg(:notification_pending_participation, :notification_pending_enum,
description: "When does the user receives a notification about new pending participations"
)
arg(:notification_pending_membership, :notification_pending_enum,
description:
"When does the user receives a notification about a new pending membership in one of the group they're admin for"
)
resolve(&User.set_user_setting/3)
end
@desc "Update the user's locale"
field :update_locale, :user do
arg(:locale, :string)
arg(:locale, :string, description: "The user's new locale")
resolve(&User.update_locale/3)
end
end