Merge branch 'feature/761-add-users-filtration' into 'develop'
Feature/761 add users filtration Closes #761 See merge request pleroma/pleroma!1117
This commit is contained in:
commit
c2efc689d1
|
@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Pleroma API: Healthcheck endpoint
|
- Pleroma API: Healthcheck endpoint
|
||||||
- Admin API: Endpoints for listing/revoking invite tokens
|
- Admin API: Endpoints for listing/revoking invite tokens
|
||||||
- Admin API: Endpoints for making users follow/unfollow each other
|
- Admin API: Endpoints for making users follow/unfollow each other
|
||||||
|
- Admin API: added filters (role, tags, email, name) for users endpoint
|
||||||
- Mastodon API: [Scheduled statuses](https://docs.joinmastodon.org/api/rest/scheduled-statuses/)
|
- Mastodon API: [Scheduled statuses](https://docs.joinmastodon.org/api/rest/scheduled-statuses/)
|
||||||
- Mastodon API: `/api/v1/notifications/destroy_multiple` (glitch-soc extension)
|
- Mastodon API: `/api/v1/notifications/destroy_multiple` (glitch-soc extension)
|
||||||
- Mastodon API: `/api/v1/pleroma/accounts/:id/favourites` (API extension)
|
- Mastodon API: `/api/v1/pleroma/accounts/:id/favourites` (API extension)
|
||||||
|
|
|
@ -8,15 +8,20 @@ Authentication is required and the user must be an admin.
|
||||||
|
|
||||||
- Method `GET`
|
- Method `GET`
|
||||||
- Query Params:
|
- Query Params:
|
||||||
- *optional* `query`: **string** search term
|
- *optional* `query`: **string** search term (e.g. nickname, domain, nickname@domain)
|
||||||
- *optional* `filters`: **string** comma-separated string of filters:
|
- *optional* `filters`: **string** comma-separated string of filters:
|
||||||
- `local`: only local users
|
- `local`: only local users
|
||||||
- `external`: only external users
|
- `external`: only external users
|
||||||
- `active`: only active users
|
- `active`: only active users
|
||||||
- `deactivated`: only deactivated users
|
- `deactivated`: only deactivated users
|
||||||
|
- `is_admin`: users with admin role
|
||||||
|
- `is_moderator`: users with moderator role
|
||||||
- *optional* `page`: **integer** page number
|
- *optional* `page`: **integer** page number
|
||||||
- *optional* `page_size`: **integer** number of users per page (default is `50`)
|
- *optional* `page_size`: **integer** number of users per page (default is `50`)
|
||||||
- Example: `https://mypleroma.org/api/pleroma/admin/users?query=john&filters=local,active&page=1&page_size=10`
|
- *optional* `tags`: **[string]** tags list
|
||||||
|
- *optional* `name`: **string** user display name
|
||||||
|
- *optional* `email`: **string** user email
|
||||||
|
- Example: `https://mypleroma.org/api/pleroma/admin/users?query=john&filters=local,active&page=1&page_size=10&tags[]=some_tag&tags[]=another_tag&name=display_name&email=email@example.com`
|
||||||
- Response:
|
- Response:
|
||||||
|
|
||||||
```JSON
|
```JSON
|
||||||
|
|
|
@ -287,6 +287,29 @@ def all_by_actor_and_id(actor, status_ids) do
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def follow_requests_for_actor(%Pleroma.User{ap_id: ap_id}) do
|
||||||
|
from(
|
||||||
|
a in Activity,
|
||||||
|
where:
|
||||||
|
fragment(
|
||||||
|
"? ->> 'type' = 'Follow'",
|
||||||
|
a.data
|
||||||
|
),
|
||||||
|
where:
|
||||||
|
fragment(
|
||||||
|
"? ->> 'state' = 'pending'",
|
||||||
|
a.data
|
||||||
|
),
|
||||||
|
where:
|
||||||
|
fragment(
|
||||||
|
"coalesce((?)->'object'->>'id', (?)->>'object') = ?",
|
||||||
|
a.data,
|
||||||
|
a.data,
|
||||||
|
^ap_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
@spec query_by_actor(actor()) :: Ecto.Query.t()
|
@spec query_by_actor(actor()) :: Ecto.Query.t()
|
||||||
def query_by_actor(actor) do
|
def query_by_actor(actor) do
|
||||||
from(a in Activity, where: a.actor == ^actor)
|
from(a in Activity, where: a.actor == ^actor)
|
||||||
|
|
|
@ -34,7 +34,7 @@ def schedule_update do
|
||||||
def update_stats do
|
def update_stats do
|
||||||
peers =
|
peers =
|
||||||
from(
|
from(
|
||||||
u in Pleroma.User,
|
u in User,
|
||||||
select: fragment("distinct split_part(?, '@', 2)", u.nickname),
|
select: fragment("distinct split_part(?, '@', 2)", u.nickname),
|
||||||
where: u.local != ^true
|
where: u.local != ^true
|
||||||
)
|
)
|
||||||
|
@ -44,10 +44,13 @@ def update_stats do
|
||||||
domain_count = Enum.count(peers)
|
domain_count = Enum.count(peers)
|
||||||
|
|
||||||
status_query =
|
status_query =
|
||||||
from(u in User.local_user_query(), select: fragment("sum((?->>'note_count')::int)", u.info))
|
from(u in User.Query.build(%{local: true}),
|
||||||
|
select: fragment("sum((?->>'note_count')::int)", u.info)
|
||||||
|
)
|
||||||
|
|
||||||
status_count = Repo.one(status_query)
|
status_count = Repo.one(status_query)
|
||||||
user_count = Repo.aggregate(User.active_local_user_query(), :count, :id)
|
|
||||||
|
user_count = Repo.aggregate(User.Query.build(%{local: true, active: true}), :count, :id)
|
||||||
|
|
||||||
Agent.update(__MODULE__, fn _ ->
|
Agent.update(__MODULE__, fn _ ->
|
||||||
{peers, %{domain_count: domain_count, status_count: status_count, user_count: user_count}}
|
{peers, %{domain_count: domain_count, status_count: status_count, user_count: user_count}}
|
||||||
|
|
|
@ -254,10 +254,7 @@ defp autofollow_users(user) do
|
||||||
candidates = Pleroma.Config.get([:instance, :autofollowed_nicknames])
|
candidates = Pleroma.Config.get([:instance, :autofollowed_nicknames])
|
||||||
|
|
||||||
autofollowed_users =
|
autofollowed_users =
|
||||||
from(u in User,
|
User.Query.build(%{nickname: candidates, local: true})
|
||||||
where: u.local == true,
|
|
||||||
where: u.nickname in ^candidates
|
|
||||||
)
|
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
|
||||||
follow_all(user, autofollowed_users)
|
follow_all(user, autofollowed_users)
|
||||||
|
@ -576,19 +573,17 @@ def fetch_initial_posts(user) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_followers_query(%User{id: id, follower_address: follower_address}, nil) do
|
@spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
|
||||||
from(
|
def get_followers_query(%User{} = user, nil) do
|
||||||
u in User,
|
User.Query.build(%{followers: user})
|
||||||
where: fragment("? <@ ?", ^[follower_address], u.following),
|
|
||||||
where: u.id != ^id
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_followers_query(user, page) do
|
def get_followers_query(user, page) do
|
||||||
from(u in get_followers_query(user, nil))
|
from(u in get_followers_query(user, nil))
|
||||||
|> paginate(page, 20)
|
|> User.Query.paginate(page, 20)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_followers_query(User.t()) :: Ecto.Query.t()
|
||||||
def get_followers_query(user), do: get_followers_query(user, nil)
|
def get_followers_query(user), do: get_followers_query(user, nil)
|
||||||
|
|
||||||
def get_followers(user, page \\ nil) do
|
def get_followers(user, page \\ nil) do
|
||||||
|
@ -603,19 +598,17 @@ def get_followers_ids(user, page \\ nil) do
|
||||||
Repo.all(from(u in q, select: u.id))
|
Repo.all(from(u in q, select: u.id))
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_friends_query(%User{id: id, following: following}, nil) do
|
@spec get_friends_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
|
||||||
from(
|
def get_friends_query(%User{} = user, nil) do
|
||||||
u in User,
|
User.Query.build(%{friends: user})
|
||||||
where: u.follower_address in ^following,
|
|
||||||
where: u.id != ^id
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_friends_query(user, page) do
|
def get_friends_query(user, page) do
|
||||||
from(u in get_friends_query(user, nil))
|
from(u in get_friends_query(user, nil))
|
||||||
|> paginate(page, 20)
|
|> User.Query.paginate(page, 20)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_friends_query(User.t()) :: Ecto.Query.t()
|
||||||
def get_friends_query(user), do: get_friends_query(user, nil)
|
def get_friends_query(user), do: get_friends_query(user, nil)
|
||||||
|
|
||||||
def get_friends(user, page \\ nil) do
|
def get_friends(user, page \\ nil) do
|
||||||
|
@ -630,33 +623,10 @@ def get_friends_ids(user, page \\ nil) do
|
||||||
Repo.all(from(u in q, select: u.id))
|
Repo.all(from(u in q, select: u.id))
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_follow_requests_query(%User{} = user) do
|
@spec get_follow_requests(User.t()) :: {:ok, [User.t()]}
|
||||||
from(
|
|
||||||
a in Activity,
|
|
||||||
where:
|
|
||||||
fragment(
|
|
||||||
"? ->> 'type' = 'Follow'",
|
|
||||||
a.data
|
|
||||||
),
|
|
||||||
where:
|
|
||||||
fragment(
|
|
||||||
"? ->> 'state' = 'pending'",
|
|
||||||
a.data
|
|
||||||
),
|
|
||||||
where:
|
|
||||||
fragment(
|
|
||||||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?",
|
|
||||||
a.data,
|
|
||||||
a.data,
|
|
||||||
^user.ap_id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_follow_requests(%User{} = user) do
|
def get_follow_requests(%User{} = user) do
|
||||||
users =
|
users =
|
||||||
user
|
Activity.follow_requests_for_actor(user)
|
||||||
|> User.get_follow_requests_query()
|
|
||||||
|> join(:inner, [a], u in User, on: a.actor == u.ap_id)
|
|> join(:inner, [a], u in User, on: a.actor == u.ap_id)
|
||||||
|> where([a, u], not fragment("? @> ?", u.following, ^[user.follower_address]))
|
|> where([a, u], not fragment("? @> ?", u.following, ^[user.follower_address]))
|
||||||
|> group_by([a, u], u.id)
|
|> group_by([a, u], u.id)
|
||||||
|
@ -729,10 +699,7 @@ def update_note_count(%User{} = user) do
|
||||||
|
|
||||||
def update_follower_count(%User{} = user) do
|
def update_follower_count(%User{} = user) do
|
||||||
follower_count_query =
|
follower_count_query =
|
||||||
User
|
User.Query.build(%{followers: user}) |> select([u], %{count: count(u.id)})
|
||||||
|> where([u], ^user.follower_address in u.following)
|
|
||||||
|> where([u], u.id != ^user.id)
|
|
||||||
|> select([u], %{count: count(u.id)})
|
|
||||||
|
|
||||||
User
|
User
|
||||||
|> where(id: ^user.id)
|
|> where(id: ^user.id)
|
||||||
|
@ -755,38 +722,19 @@ def update_follower_count(%User{} = user) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_users_from_set_query(ap_ids, false) do
|
@spec get_users_from_set([String.t()], boolean()) :: [User.t()]
|
||||||
from(
|
|
||||||
u in User,
|
|
||||||
where: u.ap_id in ^ap_ids
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_users_from_set_query(ap_ids, true) do
|
|
||||||
query = get_users_from_set_query(ap_ids, false)
|
|
||||||
|
|
||||||
from(
|
|
||||||
u in query,
|
|
||||||
where: u.local == true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_users_from_set(ap_ids, local_only \\ true) do
|
def get_users_from_set(ap_ids, local_only \\ true) do
|
||||||
get_users_from_set_query(ap_ids, local_only)
|
criteria = %{ap_id: ap_ids}
|
||||||
|
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria
|
||||||
|
|
||||||
|
User.Query.build(criteria)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_recipients_from_activity(Activity.t()) :: [User.t()]
|
||||||
def get_recipients_from_activity(%Activity{recipients: to}) do
|
def get_recipients_from_activity(%Activity{recipients: to}) do
|
||||||
query =
|
User.Query.build(%{recipients_from_activity: to, local: true})
|
||||||
from(
|
|> Repo.all()
|
||||||
u in User,
|
|
||||||
where: u.ap_id in ^to,
|
|
||||||
or_where: fragment("? && ?", u.following, ^to)
|
|
||||||
)
|
|
||||||
|
|
||||||
query = from(u in query, where: u.local == true)
|
|
||||||
|
|
||||||
Repo.all(query)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def search(query, resolve \\ false, for_user \\ nil) do
|
def search(query, resolve \\ false, for_user \\ nil) do
|
||||||
|
@ -1048,14 +996,23 @@ def subscribed_to?(user, %{ap_id: ap_id}) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def muted_users(user),
|
@spec muted_users(User.t()) :: [User.t()]
|
||||||
do: Repo.all(from(u in User, where: u.ap_id in ^user.info.mutes))
|
def muted_users(user) do
|
||||||
|
User.Query.build(%{ap_id: user.info.mutes})
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
|
||||||
def blocked_users(user),
|
@spec blocked_users(User.t()) :: [User.t()]
|
||||||
do: Repo.all(from(u in User, where: u.ap_id in ^user.info.blocks))
|
def blocked_users(user) do
|
||||||
|
User.Query.build(%{ap_id: user.info.blocks})
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
|
||||||
def subscribers(user),
|
@spec subscribers(User.t()) :: [User.t()]
|
||||||
do: Repo.all(from(u in User, where: u.ap_id in ^user.info.subscribers))
|
def subscribers(user) do
|
||||||
|
User.Query.build(%{ap_id: user.info.subscribers})
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
|
||||||
def block_domain(user, domain) do
|
def block_domain(user, domain) do
|
||||||
info_cng =
|
info_cng =
|
||||||
|
@ -1081,69 +1038,6 @@ def unblock_domain(user, domain) do
|
||||||
update_and_set_cache(cng)
|
update_and_set_cache(cng)
|
||||||
end
|
end
|
||||||
|
|
||||||
def maybe_local_user_query(query, local) do
|
|
||||||
if local, do: local_user_query(query), else: query
|
|
||||||
end
|
|
||||||
|
|
||||||
def local_user_query(query \\ User) do
|
|
||||||
from(
|
|
||||||
u in query,
|
|
||||||
where: u.local == true,
|
|
||||||
where: not is_nil(u.nickname)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def maybe_external_user_query(query, external) do
|
|
||||||
if external, do: external_user_query(query), else: query
|
|
||||||
end
|
|
||||||
|
|
||||||
def external_user_query(query \\ User) do
|
|
||||||
from(
|
|
||||||
u in query,
|
|
||||||
where: u.local == false,
|
|
||||||
where: not is_nil(u.nickname)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def maybe_active_user_query(query, active) do
|
|
||||||
if active, do: active_user_query(query), else: query
|
|
||||||
end
|
|
||||||
|
|
||||||
def active_user_query(query \\ User) do
|
|
||||||
from(
|
|
||||||
u in query,
|
|
||||||
where: fragment("not (?->'deactivated' @> 'true')", u.info),
|
|
||||||
where: not is_nil(u.nickname)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def maybe_deactivated_user_query(query, deactivated) do
|
|
||||||
if deactivated, do: deactivated_user_query(query), else: query
|
|
||||||
end
|
|
||||||
|
|
||||||
def deactivated_user_query(query \\ User) do
|
|
||||||
from(
|
|
||||||
u in query,
|
|
||||||
where: fragment("(?->'deactivated' @> 'true')", u.info),
|
|
||||||
where: not is_nil(u.nickname)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def active_local_user_query do
|
|
||||||
from(
|
|
||||||
u in local_user_query(),
|
|
||||||
where: fragment("not (?->'deactivated' @> 'true')", u.info)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def moderator_user_query do
|
|
||||||
from(
|
|
||||||
u in User,
|
|
||||||
where: u.local == true,
|
|
||||||
where: fragment("?->'is_moderator' @> 'true'", u.info)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def deactivate(%User{} = user, status \\ true) do
|
def deactivate(%User{} = user, status \\ true) do
|
||||||
info_cng = User.Info.set_activation_status(user.info, status)
|
info_cng = User.Info.set_activation_status(user.info, status)
|
||||||
|
|
||||||
|
@ -1306,7 +1200,7 @@ def ap_enabled?(%User{info: info}), do: info.ap_enabled
|
||||||
def ap_enabled?(_), do: false
|
def ap_enabled?(_), do: false
|
||||||
|
|
||||||
@doc "Gets or fetch a user by uri or nickname."
|
@doc "Gets or fetch a user by uri or nickname."
|
||||||
@spec get_or_fetch(String.t()) :: User.t()
|
@spec get_or_fetch(String.t()) :: {:ok, User.t()} | {:error, String.t()}
|
||||||
def get_or_fetch("http" <> _host = uri), do: get_or_fetch_by_ap_id(uri)
|
def get_or_fetch("http" <> _host = uri), do: get_or_fetch_by_ap_id(uri)
|
||||||
def get_or_fetch(nickname), do: get_or_fetch_by_nickname(nickname)
|
def get_or_fetch(nickname), do: get_or_fetch_by_nickname(nickname)
|
||||||
|
|
||||||
|
@ -1423,22 +1317,12 @@ def error_user(ap_id) do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec all_superusers() :: [User.t()]
|
||||||
def all_superusers do
|
def all_superusers do
|
||||||
from(
|
User.Query.build(%{super_users: true, local: true})
|
||||||
u in User,
|
|
||||||
where: u.local == true,
|
|
||||||
where: fragment("?->'is_admin' @> 'true' OR ?->'is_moderator' @> 'true'", u.info, u.info)
|
|
||||||
)
|
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
defp paginate(query, page, page_size) do
|
|
||||||
from(u in query,
|
|
||||||
limit: ^page_size,
|
|
||||||
offset: ^((page - 1) * page_size)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def showing_reblogs?(%User{} = user, %User{} = target) do
|
def showing_reblogs?(%User{} = user, %User{} = target) do
|
||||||
target.ap_id not in user.info.muted_reblogs
|
target.ap_id not in user.info.muted_reblogs
|
||||||
end
|
end
|
||||||
|
|
150
lib/pleroma/user/query.ex
Normal file
150
lib/pleroma/user/query.ex
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.User.Query do
|
||||||
|
@moduledoc """
|
||||||
|
User query builder module. Builds query from new query or another user query.
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
query = Pleroma.User.Query(%{nickname: "nickname"})
|
||||||
|
another_query = Pleroma.User.Query.build(query, %{email: "email@example.com"})
|
||||||
|
Pleroma.Repo.all(query)
|
||||||
|
Pleroma.Repo.all(another_query)
|
||||||
|
|
||||||
|
Adding new rules:
|
||||||
|
- *ilike criteria*
|
||||||
|
- add field to @ilike_criteria list
|
||||||
|
- pass non empty string
|
||||||
|
- e.g. Pleroma.User.Query.build(%{nickname: "nickname"})
|
||||||
|
- *equal criteria*
|
||||||
|
- add field to @equal_criteria list
|
||||||
|
- pass non empty string
|
||||||
|
- e.g. Pleroma.User.Query.build(%{email: "email@example.com"})
|
||||||
|
- *contains criteria*
|
||||||
|
- add field to @containns_criteria list
|
||||||
|
- pass values list
|
||||||
|
- e.g. Pleroma.User.Query.build(%{ap_id: ["http://ap_id1", "http://ap_id2"]})
|
||||||
|
"""
|
||||||
|
import Ecto.Query
|
||||||
|
import Pleroma.Web.AdminAPI.Search, only: [not_empty_string: 1]
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
|
@type criteria ::
|
||||||
|
%{
|
||||||
|
query: String.t(),
|
||||||
|
tags: [String.t()],
|
||||||
|
name: String.t(),
|
||||||
|
email: String.t(),
|
||||||
|
local: boolean(),
|
||||||
|
external: boolean(),
|
||||||
|
active: boolean(),
|
||||||
|
deactivated: boolean(),
|
||||||
|
is_admin: boolean(),
|
||||||
|
is_moderator: boolean(),
|
||||||
|
super_users: boolean(),
|
||||||
|
followers: User.t(),
|
||||||
|
friends: User.t(),
|
||||||
|
recipients_from_activity: [String.t()],
|
||||||
|
nickname: [String.t()],
|
||||||
|
ap_id: [String.t()]
|
||||||
|
}
|
||||||
|
| %{}
|
||||||
|
|
||||||
|
@ilike_criteria [:nickname, :name, :query]
|
||||||
|
@equal_criteria [:email]
|
||||||
|
@role_criteria [:is_admin, :is_moderator]
|
||||||
|
@contains_criteria [:ap_id, :nickname]
|
||||||
|
|
||||||
|
@spec build(criteria()) :: Query.t()
|
||||||
|
def build(query \\ base_query(), criteria) do
|
||||||
|
prepare_query(query, criteria)
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec paginate(Ecto.Query.t(), pos_integer(), pos_integer()) :: Ecto.Query.t()
|
||||||
|
def paginate(query, page, page_size) do
|
||||||
|
from(u in query,
|
||||||
|
limit: ^page_size,
|
||||||
|
offset: ^((page - 1) * page_size)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp base_query do
|
||||||
|
from(u in User)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp prepare_query(query, criteria) do
|
||||||
|
Enum.reduce(criteria, query, &compose_query/2)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({key, value}, query)
|
||||||
|
when key in @ilike_criteria and not_empty_string(value) do
|
||||||
|
# hack for :query key
|
||||||
|
key = if key == :query, do: :nickname, else: key
|
||||||
|
where(query, [u], ilike(field(u, ^key), ^"%#{value}%"))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({key, value}, query)
|
||||||
|
when key in @equal_criteria and not_empty_string(value) do
|
||||||
|
where(query, [u], ^[{key, value}])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({key, values}, query) when key in @contains_criteria and is_list(values) do
|
||||||
|
where(query, [u], field(u, ^key) in ^values)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({:tags, tags}, query) when is_list(tags) and length(tags) > 0 do
|
||||||
|
Enum.reduce(tags, query, &prepare_tag_criteria/2)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({key, _}, query) when key in @role_criteria do
|
||||||
|
where(query, [u], fragment("(?->? @> 'true')", u.info, ^to_string(key)))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({:super_users, _}, query) do
|
||||||
|
where(
|
||||||
|
query,
|
||||||
|
[u],
|
||||||
|
fragment("?->'is_admin' @> 'true' OR ?->'is_moderator' @> 'true'", u.info, u.info)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({:local, _}, query), do: location_query(query, true)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|> where([u], not is_nil(u.nickname))
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({:deactivated, _}, query) do
|
||||||
|
where(query, [u], fragment("?->'deactivated' @> 'true'", u.info))
|
||||||
|
|> 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))
|
||||||
|
|> where([u], u.id != ^id)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({:friends, %User{id: id, following: following}}, query) do
|
||||||
|
where(query, [u], u.follower_address in ^following)
|
||||||
|
|> where([u], u.id != ^id)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp compose_query({:recipients_from_activity, to}, query) do
|
||||||
|
where(query, [u], u.ap_id in ^to or fragment("? && ?", u.following, ^to))
|
||||||
|
end
|
||||||
|
|
||||||
|
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))
|
||||||
|
end
|
||||||
|
end
|
|
@ -101,7 +101,10 @@ def list_users(conn, params) do
|
||||||
search_params = %{
|
search_params = %{
|
||||||
query: params["query"],
|
query: params["query"],
|
||||||
page: page,
|
page: page,
|
||||||
page_size: page_size
|
page_size: page_size,
|
||||||
|
tags: params["tags"],
|
||||||
|
name: params["name"],
|
||||||
|
email: params["email"]
|
||||||
}
|
}
|
||||||
|
|
||||||
with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
|
with {:ok, users, count} <- Search.user(Map.merge(search_params, filters)),
|
||||||
|
@ -116,11 +119,11 @@ def list_users(conn, params) do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@filters ~w(local external active deactivated)
|
@filters ~w(local external active deactivated is_admin is_moderator)
|
||||||
|
|
||||||
defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
|
|
||||||
|
|
||||||
@spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
|
@spec maybe_parse_filters(String.t()) :: %{required(String.t()) => true} | %{}
|
||||||
|
defp maybe_parse_filters(filters) when is_nil(filters) or filters == "", do: %{}
|
||||||
|
|
||||||
defp maybe_parse_filters(filters) do
|
defp maybe_parse_filters(filters) do
|
||||||
filters
|
filters
|
||||||
|> String.split(",")
|
|> String.split(",")
|
||||||
|
|
|
@ -10,45 +10,23 @@ defmodule Pleroma.Web.AdminAPI.Search do
|
||||||
|
|
||||||
@page_size 50
|
@page_size 50
|
||||||
|
|
||||||
def user(%{query: term} = params) when is_nil(term) or term == "" do
|
defmacro not_empty_string(string) do
|
||||||
query = maybe_filtered_query(params)
|
quote do
|
||||||
|
is_binary(unquote(string)) and unquote(string) != ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec user(map()) :: {:ok, [User.t()], pos_integer()}
|
||||||
|
def user(params \\ %{}) do
|
||||||
|
query = User.Query.build(params) |> order_by([u], u.nickname)
|
||||||
|
|
||||||
paginated_query =
|
paginated_query =
|
||||||
maybe_filtered_query(params)
|
User.Query.paginate(query, params[:page] || 1, params[:page_size] || @page_size)
|
||||||
|> paginate(params[:page] || 1, params[:page_size] || @page_size)
|
|
||||||
|
|
||||||
count = query |> Repo.aggregate(:count, :id)
|
count = Repo.aggregate(query, :count, :id)
|
||||||
|
|
||||||
results = Repo.all(paginated_query)
|
results = Repo.all(paginated_query)
|
||||||
|
|
||||||
{:ok, results, count}
|
{:ok, results, count}
|
||||||
end
|
end
|
||||||
|
|
||||||
def user(%{query: term} = params) when is_binary(term) do
|
|
||||||
search_query = from(u in maybe_filtered_query(params), where: ilike(u.nickname, ^"%#{term}%"))
|
|
||||||
|
|
||||||
count = search_query |> Repo.aggregate(:count, :id)
|
|
||||||
|
|
||||||
results =
|
|
||||||
search_query
|
|
||||||
|> paginate(params[:page] || 1, params[:page_size] || @page_size)
|
|
||||||
|> Repo.all()
|
|
||||||
|
|
||||||
{:ok, results, count}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp maybe_filtered_query(params) do
|
|
||||||
from(u in User, order_by: u.nickname)
|
|
||||||
|> User.maybe_local_user_query(params[:local])
|
|
||||||
|> User.maybe_external_user_query(params[:external])
|
|
||||||
|> User.maybe_active_user_query(params[:active])
|
|
||||||
|> User.maybe_deactivated_user_query(params[:deactivated])
|
|
||||||
end
|
|
||||||
|
|
||||||
defp paginate(query, page, page_size) do
|
|
||||||
from(u in query,
|
|
||||||
limit: ^page_size,
|
|
||||||
offset: ^((page - 1) * page_size)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -419,14 +419,19 @@ test "/api/pleroma/admin/password_reset" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/users" do
|
describe "GET /api/pleroma/admin/users" do
|
||||||
test "renders users array for the first page" do
|
setup do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
user = insert(:user, local: false, tags: ["foo", "bar"])
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, admin)
|
|> assign(:user, admin)
|
||||||
|> get("/api/pleroma/admin/users?page=1")
|
|
||||||
|
{:ok, conn: conn, admin: admin}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "renders users array for the first page", %{conn: conn, admin: admin} do
|
||||||
|
user = insert(:user, local: false, tags: ["foo", "bar"])
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?page=1")
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn, 200) == %{
|
||||||
"count" => 2,
|
"count" => 2,
|
||||||
|
@ -452,14 +457,10 @@ test "renders users array for the first page" do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "renders empty array for the second page" do
|
test "renders empty array for the second page", %{conn: conn} do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
|
||||||
insert(:user)
|
insert(:user)
|
||||||
|
|
||||||
conn =
|
conn = get(conn, "/api/pleroma/admin/users?page=2")
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/users?page=2")
|
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn, 200) == %{
|
||||||
"count" => 2,
|
"count" => 2,
|
||||||
|
@ -468,14 +469,10 @@ test "renders empty array for the second page" do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "regular search" do
|
test "regular search", %{conn: conn} do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
|
||||||
user = insert(:user, nickname: "bob")
|
user = insert(:user, nickname: "bob")
|
||||||
|
|
||||||
conn =
|
conn = get(conn, "/api/pleroma/admin/users?query=bo")
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/users?query=bo")
|
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn, 200) == %{
|
||||||
"count" => 1,
|
"count" => 1,
|
||||||
|
@ -493,17 +490,101 @@ test "regular search" do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "regular search with page size" do
|
test "search by domain", %{conn: conn} do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
user = insert(:user, nickname: "nickname@domain.com")
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{
|
||||||
|
"count" => 1,
|
||||||
|
"page_size" => 50,
|
||||||
|
"users" => [
|
||||||
|
%{
|
||||||
|
"deactivated" => user.info.deactivated,
|
||||||
|
"id" => user.id,
|
||||||
|
"nickname" => user.nickname,
|
||||||
|
"roles" => %{"admin" => false, "moderator" => false},
|
||||||
|
"local" => true,
|
||||||
|
"tags" => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "search by full nickname", %{conn: conn} do
|
||||||
|
user = insert(:user, nickname: "nickname@domain.com")
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{
|
||||||
|
"count" => 1,
|
||||||
|
"page_size" => 50,
|
||||||
|
"users" => [
|
||||||
|
%{
|
||||||
|
"deactivated" => user.info.deactivated,
|
||||||
|
"id" => user.id,
|
||||||
|
"nickname" => user.nickname,
|
||||||
|
"roles" => %{"admin" => false, "moderator" => false},
|
||||||
|
"local" => true,
|
||||||
|
"tags" => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "search by display name", %{conn: conn} do
|
||||||
|
user = insert(:user, name: "Display name")
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?name=display")
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{
|
||||||
|
"count" => 1,
|
||||||
|
"page_size" => 50,
|
||||||
|
"users" => [
|
||||||
|
%{
|
||||||
|
"deactivated" => user.info.deactivated,
|
||||||
|
"id" => user.id,
|
||||||
|
"nickname" => user.nickname,
|
||||||
|
"roles" => %{"admin" => false, "moderator" => false},
|
||||||
|
"local" => true,
|
||||||
|
"tags" => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "search by email", %{conn: conn} do
|
||||||
|
user = insert(:user, email: "email@example.com")
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{
|
||||||
|
"count" => 1,
|
||||||
|
"page_size" => 50,
|
||||||
|
"users" => [
|
||||||
|
%{
|
||||||
|
"deactivated" => user.info.deactivated,
|
||||||
|
"id" => user.id,
|
||||||
|
"nickname" => user.nickname,
|
||||||
|
"roles" => %{"admin" => false, "moderator" => false},
|
||||||
|
"local" => true,
|
||||||
|
"tags" => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "regular search with page size", %{conn: conn} do
|
||||||
user = insert(:user, nickname: "aalice")
|
user = insert(:user, nickname: "aalice")
|
||||||
user2 = insert(:user, nickname: "alice")
|
user2 = insert(:user, nickname: "alice")
|
||||||
|
|
||||||
conn =
|
conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/users?query=a&page_size=1&page=1")
|
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn1, 200) == %{
|
||||||
"count" => 2,
|
"count" => 2,
|
||||||
"page_size" => 1,
|
"page_size" => 1,
|
||||||
"users" => [
|
"users" => [
|
||||||
|
@ -518,12 +599,9 @@ test "regular search with page size" do
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
conn =
|
conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/users?query=a&page_size=1&page=2")
|
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn2, 200) == %{
|
||||||
"count" => 2,
|
"count" => 2,
|
||||||
"page_size" => 1,
|
"page_size" => 1,
|
||||||
"users" => [
|
"users" => [
|
||||||
|
@ -566,7 +644,7 @@ test "only local users" do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "only local users with no query" do
|
test "only local users with no query", %{admin: old_admin} do
|
||||||
admin = insert(:user, info: %{is_admin: true}, nickname: "john")
|
admin = insert(:user, info: %{is_admin: true}, nickname: "john")
|
||||||
user = insert(:user, nickname: "bob")
|
user = insert(:user, nickname: "bob")
|
||||||
|
|
||||||
|
@ -578,7 +656,7 @@ test "only local users with no query" do
|
||||||
|> get("/api/pleroma/admin/users?filters=local")
|
|> get("/api/pleroma/admin/users?filters=local")
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn, 200) == %{
|
||||||
"count" => 2,
|
"count" => 3,
|
||||||
"page_size" => 50,
|
"page_size" => 50,
|
||||||
"users" => [
|
"users" => [
|
||||||
%{
|
%{
|
||||||
|
@ -596,6 +674,100 @@ test "only local users with no query" do
|
||||||
"roles" => %{"admin" => true, "moderator" => false},
|
"roles" => %{"admin" => true, "moderator" => false},
|
||||||
"local" => true,
|
"local" => true,
|
||||||
"tags" => []
|
"tags" => []
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
"deactivated" => false,
|
||||||
|
"id" => old_admin.id,
|
||||||
|
"local" => true,
|
||||||
|
"nickname" => old_admin.nickname,
|
||||||
|
"roles" => %{"admin" => true, "moderator" => false},
|
||||||
|
"tags" => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "load only admins", %{conn: conn, admin: admin} do
|
||||||
|
second_admin = insert(:user, info: %{is_admin: true})
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{
|
||||||
|
"count" => 2,
|
||||||
|
"page_size" => 50,
|
||||||
|
"users" => [
|
||||||
|
%{
|
||||||
|
"deactivated" => false,
|
||||||
|
"id" => admin.id,
|
||||||
|
"nickname" => admin.nickname,
|
||||||
|
"roles" => %{"admin" => true, "moderator" => false},
|
||||||
|
"local" => admin.local,
|
||||||
|
"tags" => []
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
"deactivated" => false,
|
||||||
|
"id" => second_admin.id,
|
||||||
|
"nickname" => second_admin.nickname,
|
||||||
|
"roles" => %{"admin" => true, "moderator" => false},
|
||||||
|
"local" => second_admin.local,
|
||||||
|
"tags" => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "load only moderators", %{conn: conn} do
|
||||||
|
moderator = insert(:user, info: %{is_moderator: true})
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{
|
||||||
|
"count" => 1,
|
||||||
|
"page_size" => 50,
|
||||||
|
"users" => [
|
||||||
|
%{
|
||||||
|
"deactivated" => false,
|
||||||
|
"id" => moderator.id,
|
||||||
|
"nickname" => moderator.nickname,
|
||||||
|
"roles" => %{"admin" => false, "moderator" => true},
|
||||||
|
"local" => moderator.local,
|
||||||
|
"tags" => []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "load users with tags list", %{conn: conn} do
|
||||||
|
user1 = insert(:user, tags: ["first"])
|
||||||
|
user2 = insert(:user, tags: ["second"])
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
|
||||||
|
|
||||||
|
assert json_response(conn, 200) == %{
|
||||||
|
"count" => 2,
|
||||||
|
"page_size" => 50,
|
||||||
|
"users" => [
|
||||||
|
%{
|
||||||
|
"deactivated" => false,
|
||||||
|
"id" => user1.id,
|
||||||
|
"nickname" => user1.nickname,
|
||||||
|
"roles" => %{"admin" => false, "moderator" => false},
|
||||||
|
"local" => user1.local,
|
||||||
|
"tags" => ["first"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
"deactivated" => false,
|
||||||
|
"id" => user2.id,
|
||||||
|
"nickname" => user2.nickname,
|
||||||
|
"roles" => %{"admin" => false, "moderator" => false},
|
||||||
|
"local" => user2.local,
|
||||||
|
"tags" => ["second"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -651,13 +823,18 @@ test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/invite_token" do
|
describe "GET /api/pleroma/admin/invite_token" do
|
||||||
test "without options" do
|
setup do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, admin)
|
|> assign(:user, admin)
|
||||||
|> get("/api/pleroma/admin/invite_token")
|
|
||||||
|
{:ok, conn: conn}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "without options", %{conn: conn} do
|
||||||
|
conn = get(conn, "/api/pleroma/admin/invite_token")
|
||||||
|
|
||||||
token = json_response(conn, 200)
|
token = json_response(conn, 200)
|
||||||
invite = UserInviteToken.find_by_token!(token)
|
invite = UserInviteToken.find_by_token!(token)
|
||||||
|
@ -667,13 +844,9 @@ test "without options" do
|
||||||
assert invite.invite_type == "one_time"
|
assert invite.invite_type == "one_time"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with expires_at" do
|
test "with expires_at", %{conn: conn} do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
get(conn, "/api/pleroma/admin/invite_token", %{
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/invite_token", %{
|
|
||||||
"invite" => %{"expires_at" => Date.to_string(Date.utc_today())}
|
"invite" => %{"expires_at" => Date.to_string(Date.utc_today())}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -686,13 +859,9 @@ test "with expires_at" do
|
||||||
assert invite.invite_type == "date_limited"
|
assert invite.invite_type == "date_limited"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with max_use" do
|
test "with max_use", %{conn: conn} do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
get(conn, "/api/pleroma/admin/invite_token", %{
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/invite_token", %{
|
|
||||||
"invite" => %{"max_use" => 150}
|
"invite" => %{"max_use" => 150}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -704,13 +873,9 @@ test "with max_use" do
|
||||||
assert invite.invite_type == "reusable"
|
assert invite.invite_type == "reusable"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with max use and expires_at" do
|
test "with max use and expires_at", %{conn: conn} do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
get(conn, "/api/pleroma/admin/invite_token", %{
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/invite_token", %{
|
|
||||||
"invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())}
|
"invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -724,25 +889,26 @@ test "with max use and expires_at" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /api/pleroma/admin/invites" do
|
describe "GET /api/pleroma/admin/invites" do
|
||||||
test "no invites" do
|
setup do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> assign(:user, admin)
|
|> assign(:user, admin)
|
||||||
|> get("/api/pleroma/admin/invites")
|
|
||||||
|
{:ok, conn: conn}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "no invites", %{conn: conn} do
|
||||||
|
conn = get(conn, "/api/pleroma/admin/invites")
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{"invites" => []}
|
assert json_response(conn, 200) == %{"invites" => []}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "with invite" do
|
test "with invite", %{conn: conn} do
|
||||||
admin = insert(:user, info: %{is_admin: true})
|
|
||||||
{:ok, invite} = UserInviteToken.create_invite()
|
{:ok, invite} = UserInviteToken.create_invite()
|
||||||
|
|
||||||
conn =
|
conn = get(conn, "/api/pleroma/admin/invites")
|
||||||
build_conn()
|
|
||||||
|> assign(:user, admin)
|
|
||||||
|> get("/api/pleroma/admin/invites")
|
|
||||||
|
|
||||||
assert json_response(conn, 200) == %{
|
assert json_response(conn, 200) == %{
|
||||||
"invites" => [
|
"invites" => [
|
||||||
|
|
|
@ -70,11 +70,11 @@ test "it returns active/deactivated users" do
|
||||||
test "it returns specific user" do
|
test "it returns specific user" do
|
||||||
insert(:user)
|
insert(:user)
|
||||||
insert(:user)
|
insert(:user)
|
||||||
insert(:user, nickname: "bob", local: true, info: %{deactivated: false})
|
user = insert(:user, nickname: "bob", local: true, info: %{deactivated: false})
|
||||||
|
|
||||||
{:ok, _results, total_count} = Search.user(%{query: ""})
|
{:ok, _results, total_count} = Search.user(%{query: ""})
|
||||||
|
|
||||||
{:ok, _results, count} =
|
{:ok, [^user], count} =
|
||||||
Search.user(%{
|
Search.user(%{
|
||||||
query: "Bo",
|
query: "Bo",
|
||||||
active: true,
|
active: true,
|
||||||
|
@ -84,5 +84,87 @@ test "it returns specific user" do
|
||||||
assert total_count == 3
|
assert total_count == 3
|
||||||
assert count == 1
|
assert count == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it returns user by domain" do
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
user = insert(:user, nickname: "some@domain.com")
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
{:ok, [^user], count} = Search.user(%{query: "domain.com"})
|
||||||
|
assert total == 3
|
||||||
|
assert count == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it return user by full nickname" do
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
user = insert(:user, nickname: "some@domain.com")
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
{:ok, [^user], count} = Search.user(%{query: "some@domain.com"})
|
||||||
|
assert total == 3
|
||||||
|
assert count == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns admin user" do
|
||||||
|
admin = insert(:user, info: %{is_admin: true})
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
{:ok, [^admin], count} = Search.user(%{is_admin: true})
|
||||||
|
assert total == 3
|
||||||
|
assert count == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns moderator user" do
|
||||||
|
moderator = insert(:user, info: %{is_moderator: true})
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
{:ok, [^moderator], count} = Search.user(%{is_moderator: true})
|
||||||
|
assert total == 3
|
||||||
|
assert count == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns users with tags" do
|
||||||
|
user1 = insert(:user, tags: ["first"])
|
||||||
|
user2 = insert(:user, tags: ["second"])
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
{:ok, users, count} = Search.user(%{tags: ["first", "second"]})
|
||||||
|
assert total == 4
|
||||||
|
assert count == 2
|
||||||
|
assert user1 in users
|
||||||
|
assert user2 in users
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns user by display name" do
|
||||||
|
user = insert(:user, name: "Display name")
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
{:ok, [^user], count} = Search.user(%{name: "display"})
|
||||||
|
|
||||||
|
assert total == 3
|
||||||
|
assert count == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it returns user by email" do
|
||||||
|
user = insert(:user, email: "some@example.com")
|
||||||
|
insert(:user)
|
||||||
|
insert(:user)
|
||||||
|
|
||||||
|
{:ok, _results, total} = Search.user()
|
||||||
|
{:ok, [^user], count} = Search.user(%{email: "some@example.com"})
|
||||||
|
|
||||||
|
assert total == 3
|
||||||
|
assert count == 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue