From d2864a22d92963febcc2568165d2d274d0fcda2d Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Fri, 1 Apr 2022 16:48:46 +0200 Subject: [PATCH 1/7] Allow to exclude stale actors from group search (one week without refreshment) Signed-off-by: Thomas Citharel --- config/config.exs | 3 ++- lib/graphql/api/search.ex | 3 ++- lib/mobilizon/actors/actors.ex | 12 ++++++++++++ test/graphql/api/search_test.exs | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/config/config.exs b/config/config.exs index 44d0666c2..f15398df7 100644 --- a/config/config.exs +++ b/config/config.exs @@ -212,7 +212,8 @@ config :mobilizon, :activitypub, # One day actor_stale_period: 3_600 * 48, actor_key_rotation_delay: 3_600 * 48, - sign_object_fetches: true + sign_object_fetches: true, + stale_actor_search_exclusion_after: 3_600 * 24 * 7 config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim diff --git a/lib/graphql/api/search.ex b/lib/graphql/api/search.ex index 799f1234d..3b002b6f6 100644 --- a/lib/graphql/api/search.ex +++ b/lib/graphql/api/search.ex @@ -49,7 +49,8 @@ defmodule Mobilizon.GraphQL.API.Search do location: Map.get(args, :location), minimum_visibility: Map.get(args, :minimum_visibility, :public), current_actor_id: Map.get(args, :current_actor_id), - exclude_my_groups: Map.get(args, :exclude_my_groups, false) + exclude_my_groups: Map.get(args, :exclude_my_groups, false), + exclude_stale_actors: true ], page, limit diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 9058ec482..cbf854ff6 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -461,6 +461,7 @@ defmodule Mobilizon.Actors do ) do term |> build_actors_by_username_or_name_page_query(options) + |> maybe_exclude_stale_actors(Keyword.get(options, :exclude_stale_actors, false)) |> maybe_exclude_my_groups( Keyword.get(options, :exclude_my_groups, false), Keyword.get(options, :current_actor_id) @@ -477,6 +478,17 @@ defmodule Mobilizon.Actors do defp maybe_exclude_my_groups(query, _, _), do: query + @spec maybe_exclude_stale_actors(Ecto.Queryable.t(), boolean()) :: Ecto.Query.t() + defp maybe_exclude_stale_actors(query, true) do + actor_stale_period = + Application.get_env(:mobilizon, :activitypub)[:stale_actor_search_exclusion_after] + + stale_date = DateTime.utc_now() |> DateTime.add(-actor_stale_period) + where(query, [a], is_nil(a.domain) or a.last_refreshed_at >= ^stale_date) + end + + defp maybe_exclude_stale_actors(query, false), do: query + @spec build_actors_by_username_or_name_page_query( String.t(), Keyword.t() diff --git a/test/graphql/api/search_test.exs b/test/graphql/api/search_test.exs index 62016294c..7ef116467 100644 --- a/test/graphql/api/search_test.exs +++ b/test/graphql/api/search_test.exs @@ -53,7 +53,8 @@ defmodule Mobilizon.GraphQL.API.SearchTest do location: nil, minimum_visibility: :public, current_actor_id: nil, - exclude_my_groups: false + exclude_my_groups: false, + exclude_stale_actors: true ], 1, 10 From 7fcaa4a15129a259522a7e56581e1f13b4f7aca6 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 3 Apr 2022 17:39:57 +0200 Subject: [PATCH 2/7] [GraphQL] Allow to get group by ID in person memberships Signed-off-by: Thomas Citharel --- lib/graphql/resolvers/person.ex | 49 ++++++++++++++++++----------- lib/graphql/schema/actors/person.ex | 3 +- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/lib/graphql/resolvers/person.ex b/lib/graphql/resolvers/person.ex index 31a296d61..060ae2d42 100644 --- a/lib/graphql/resolvers/person.ex +++ b/lib/graphql/resolvers/person.ex @@ -358,11 +358,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do Returns this person's group memberships """ @spec person_memberships(Actor.t(), map(), map()) :: {:ok, Page.t()} | {:error, String.t()} - def person_memberships(%Actor{id: actor_id} = person, %{group: group}, %{ + def person_memberships(%Actor{id: actor_id} = person, args, %{ context: %{current_user: %User{} = user} }) do if user_can_access_person_details?(person, user) do - with {:group, %Actor{id: group_id}} <- {:group, Actors.get_actor_by_name(group, :Group)}, + with {:group, %Actor{id: group_id}} <- {:group, group_from_args(args)}, {:ok, %Member{} = membership} <- Actors.get_member(actor_id, group_id) do {:ok, %Page{ @@ -373,6 +373,21 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do {:error, :member_not_found} -> {:ok, %Page{total: 0, elements: []}} + {:group, :none} -> + with {:can_get_memberships, true} <- + {:can_get_memberships, user_can_access_person_details?(person, user)}, + memberships <- + Actors.list_members_for_actor( + person, + Map.get(args, :page, 1), + Map.get(args, :limit, 10) + ) do + {:ok, memberships} + else + {:can_get_memberships, _} -> + {:error, dgettext("errors", "Profile is not owned by authenticated user")} + end + {:group, nil} -> {:error, :group_not_found} end @@ -381,23 +396,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do end end - def person_memberships( - %Actor{} = person, - %{page: page, limit: limit}, - %{ - context: %{current_user: %User{} = user} - } - ) do - with {:can_get_memberships, true} <- - {:can_get_memberships, user_can_access_person_details?(person, user)}, - memberships <- Actors.list_members_for_actor(person, page, limit) do - {:ok, memberships} - else - {:can_get_memberships, _} -> - {:error, dgettext("errors", "Profile is not owned by authenticated user")} - end - end - @doc """ Returns this person's group follows """ @@ -498,4 +496,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do do: actor_user_id == user_id defp user_can_access_person_details?(_, _), do: false + + @spec group_from_args(map()) :: Actor.t() | nil + defp group_from_args(%{group: group}) do + Actors.get_actor_by_name(group, :Group) + end + + defp group_from_args(%{group_id: group_id}) do + Actors.get_actor(group_id) + end + + defp group_from_args(_) do + :none + end end diff --git a/lib/graphql/schema/actors/person.ex b/lib/graphql/schema/actors/person.ex index 65fd6c54a..a7d773c71 100644 --- a/lib/graphql/schema/actors/person.ex +++ b/lib/graphql/schema/actors/person.ex @@ -88,11 +88,12 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do resolve(&Person.person_participations/3) end - @desc "The list of group this person is member of" + @desc "The list of groups this person is member of" field(:memberships, :paginated_member_list, description: "The list of group this person is member of" ) do arg(:group, :string, description: "Filter by group federated username") + arg(:group_id, :id, description: "Filter by group ID") arg(:page, :integer, default_value: 1, From 4e3eb33d01fb6f07e90063b577e21eda741a1495 Mon Sep 17 00:00:00 2001 From: Thomas Citharel Date: Sun, 3 Apr 2022 17:41:16 +0200 Subject: [PATCH 3/7] Don't offer to confirm already confirmed user Signed-off-by: Thomas Citharel --- js/src/views/Admin/AdminUserProfile.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/views/Admin/AdminUserProfile.vue b/js/src/views/Admin/AdminUserProfile.vue index a2bd191ef..d6a6da772 100644 --- a/js/src/views/Admin/AdminUserProfile.vue +++ b/js/src/views/Admin/AdminUserProfile.vue @@ -95,7 +95,7 @@ > Date: Sun, 3 Apr 2022 22:13:06 +0200 Subject: [PATCH 4/7] Redesign organizer picker with tailwind Signed-off-by: Thomas Citharel --- js/src/components/Event/OrganizerPicker.vue | 65 ++++++++++++------- .../Event/OrganizerPickerWrapper.vue | 5 +- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/js/src/components/Event/OrganizerPicker.vue b/js/src/components/Event/OrganizerPicker.vue index d9c2b1d13..2aba5a8ec 100644 --- a/js/src/components/Event/OrganizerPicker.vue +++ b/js/src/components/Event/OrganizerPicker.vue @@ -5,33 +5,48 @@ :placeholder="$t('Filter by profile or group name')" v-model="actorFilter" /> - -
-
- -
- + -
-

{{ availableActor.name }}

- {{ `@${availableActor.preferredUsername}` }} -
-
-
+ + +