X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=inline;f=lib%2Fpleroma%2Fuser%2Fquery.ex;h=3a3b047934d98e872ae4eb008a78e5237135048d;hb=8b97b6f5baa7e0593414fa794ce8059a8e5b95e3;hp=2baf016cfd3f3ecb7f269eb8f6e7faa0e92b63da;hpb=f95a2b2cda236f7c0e5ced2a4698e2b10d99fa53;p=akkoma
diff --git a/lib/pleroma/user/query.ex b/lib/pleroma/user/query.ex
index 2baf016cf..3a3b04793 100644
--- a/lib/pleroma/user/query.ex
+++ b/lib/pleroma/user/query.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors
+# Copyright © 2017-2020 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.Query do
@@ -28,6 +28,8 @@ defmodule Pleroma.User.Query do
"""
import Ecto.Query
import Pleroma.Web.AdminAPI.Search, only: [not_empty_string: 1]
+
+ alias Pleroma.FollowingRelationship
alias Pleroma.User
@type criteria ::
@@ -43,23 +45,23 @@ defmodule Pleroma.User.Query do
is_admin: boolean(),
is_moderator: boolean(),
super_users: boolean(),
+ exclude_service_users: boolean(),
followers: User.t(),
friends: User.t(),
recipients_from_activity: [String.t()],
- nickname: [String.t()],
+ nickname: [String.t()] | String.t(),
ap_id: [String.t()],
order_by: term(),
select: term(),
limit: pos_integer()
}
- | %{}
+ | map()
@ilike_criteria [:nickname, :name, :query]
@equal_criteria [:email]
- @role_criteria [:is_admin, :is_moderator]
@contains_criteria [:ap_id, :nickname]
- @spec build(criteria()) :: Query.t()
+ @spec build(Query.t(), criteria()) :: Query.t()
def build(query \\ base_query(), criteria) do
prepare_query(query, criteria)
end
@@ -87,6 +89,10 @@ defmodule Pleroma.User.Query do
where(query, [u], ilike(field(u, ^key), ^"%#{value}%"))
end
+ defp compose_query({:exclude_service_users, _}, query) do
+ where(query, [u], not like(u.ap_id, "%/relay") and not like(u.ap_id, "%/internal/fetch"))
+ end
+
defp compose_query({key, value}, query)
when key in @equal_criteria and not_empty_string(value) do
where(query, [u], ^[{key, value}])
@@ -97,18 +103,22 @@ defmodule Pleroma.User.Query do
end
defp compose_query({:tags, tags}, query) when is_list(tags) and length(tags) > 0 do
- Enum.reduce(tags, query, &prepare_tag_criteria/2)
+ where(query, [u], fragment("? && ?", u.tags, ^tags))
+ end
+
+ defp compose_query({:is_admin, _}, query) do
+ where(query, [u], u.is_admin)
end
- defp compose_query({key, _}, query) when key in @role_criteria do
- where(query, [u], fragment("(?->? @> 'true')", u.info, ^to_string(key)))
+ defp compose_query({:is_moderator, _}, query) do
+ where(query, [u], u.is_moderator)
end
defp compose_query({:super_users, _}, query) do
where(
query,
[u],
- fragment("?->'is_admin' @> 'true' OR ?->'is_moderator' @> 'true'", u.info, u.info)
+ u.is_admin or u.is_moderator
)
end
@@ -117,7 +127,13 @@ defmodule Pleroma.User.Query do
defp compose_query({:external, _}, query), do: location_query(query, false)
defp compose_query({:active, _}, query) do
- where(query, [u], fragment("not (?->'deactivated' @> 'true')", u.info))
+ User.restrict_deactivated(query)
+ |> where([u], not is_nil(u.nickname))
+ end
+
+ defp compose_query({:legacy_active, _}, query) do
+ query
+ |> where([u], fragment("not (?->'deactivated' @> 'true')", u.info))
|> where([u], not is_nil(u.nickname))
end
@@ -126,22 +142,45 @@ defmodule Pleroma.User.Query do
end
defp compose_query({:deactivated, true}, query) do
- where(query, [u], fragment("?->'deactivated' @> 'true'", u.info))
+ where(query, [u], u.deactivated == ^true)
|> where([u], not is_nil(u.nickname))
end
- defp compose_query({:followers, %User{id: id, follower_address: follower_address}}, query) do
- where(query, [u], fragment("? <@ ?", ^[follower_address], u.following))
+ defp compose_query({:followers, %User{id: id}}, query) do
+ query
|> where([u], u.id != ^id)
+ |> join(:inner, [u], r in FollowingRelationship,
+ as: :relationships,
+ on: r.following_id == ^id and r.follower_id == u.id
+ )
+ |> where([relationships: r], r.state == ^:follow_accept)
end
- defp compose_query({:friends, %User{id: id, following: following}}, query) do
- where(query, [u], u.follower_address in ^following)
+ defp compose_query({:friends, %User{id: id}}, query) do
+ query
|> where([u], u.id != ^id)
+ |> join(:inner, [u], r in FollowingRelationship,
+ as: :relationships,
+ on: r.following_id == u.id and r.follower_id == ^id
+ )
+ |> where([relationships: r], r.state == ^:follow_accept)
end
defp compose_query({:recipients_from_activity, to}, query) do
- where(query, [u], u.ap_id in ^to or fragment("? && ?", u.following, ^to))
+ query
+ |> join(:left, [u], r in FollowingRelationship,
+ as: :relationships,
+ on: r.follower_id == u.id
+ )
+ |> join(:left, [relationships: r], f in User,
+ as: :following,
+ on: f.id == r.following_id
+ )
+ |> where(
+ [u, following: f, relationships: r],
+ u.ap_id in ^to or (f.follower_address in ^to and r.state == ^:follow_accept)
+ )
+ |> distinct(true)
end
defp compose_query({:order_by, key}, query) do
@@ -158,10 +197,6 @@ defmodule Pleroma.User.Query do
defp compose_query(_unsupported_param, query), do: query
- defp prepare_tag_criteria(tag, query) do
- or_where(query, [u], fragment("? = any(?)", ^tag, u.tags))
- end
-
defp location_query(query, local) do
where(query, [u], u.local == ^local)
|> where([u], not is_nil(u.nickname))