Merge develop
authorRoman Chvanikov <chvanikoff@pm.me>
Tue, 9 Jul 2019 18:21:09 +0000 (21:21 +0300)
committerRoman Chvanikov <chvanikoff@pm.me>
Tue, 9 Jul 2019 18:21:09 +0000 (21:21 +0300)
13 files changed:
1  2 
CHANGELOG.md
config/config.exs
config/test.exs
docs/config.md
lib/mix/tasks/pleroma/instance.ex
lib/pleroma/application.ex
lib/pleroma/user.ex
lib/pleroma/web/router.ex
mix.exs
mix.lock
priv/templates/sample_config.eex
test/user_search_test.exs
test/user_test.exs

diff --cc CHANGELOG.md
Simple merge
Simple merge
diff --cc config/test.exs
index 1838cffc8eb15302b02bd05e8870e274e5fd343f,63443dde0115a1127df6133a645b329a01810be4..1635a5d92feaf8c5b114ba62dc478457af2a315a
@@@ -74,8 -75,8 +75,10 @@@ rum_enabled = System.get_env("RUM_ENABL
  config :pleroma, :database, rum_enabled: rum_enabled
  IO.puts("RUM enabled: #{rum_enabled}")
  
 +config :joken, default_signer: "yU8uHKq+yyAkZ11Hx//jcdacWc8yQ1bxAAGrplzB0Zwwjkp35v0RK9SO8WTPr6QZ"
 +
+ config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock
  try do
    import_config "test.secret.exs"
  rescue
diff --cc docs/config.md
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc mix.exs
Simple merge
diff --cc mix.lock
index 02932b2c067cc673ff88d31fb64d6e7e39354a97,e711be635b801af7690f4ba9b4a181bae9aee6ca..addd72e4bf6498400206e54ec55ca844cbb376b6
+++ b/mix.lock
    "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
    "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
    "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
 -  "mochiweb": {:hex, :mochiweb, "2.15.0", "e1daac474df07651e5d17cc1e642c4069c7850dc4508d3db7263a0651330aacc", [:rebar3], [], "hexpm"},
 +  "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
    "mock": {:hex, :mock, "0.3.3", "42a433794b1291a9cf1525c6d26b38e039e0d3a360732b5e467bfc77ef26c914", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
    "mogrify": {:hex, :mogrify, "0.6.1", "de1b527514f2d95a7bbe9642eb556061afb337e220cf97adbf3a4e6438ed70af", [:mix], [], "hexpm"},
+   "mox": {:hex, :mox, "0.5.1", "f86bb36026aac1e6f924a4b6d024b05e9adbed5c63e8daa069bd66fb3292165b", [:mix], [], "hexpm"},
    "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"},
    "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
    "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "0.12.3", "6706a148809a29c306062862c803406e88f048277f6e85b68faf73291e820b84", [:mix], [], "hexpm"},
@@@ -78,9 -72,7 +78,8 @@@
    "prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"},
    "prometheus_phoenix": {:hex, :prometheus_phoenix, "1.2.1", "964a74dfbc055f781d3a75631e06ce3816a2913976d1df7830283aa3118a797a", [:mix], [{:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm"},
    "prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm"},
-   "prometheus_process_collector": {:hex, :prometheus_process_collector, "1.4.3", "657386e8f142fc817347d95c1f3a05ab08710f7df9e7f86db6facaed107ed929", [:rebar3], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"},
    "quack": {:hex, :quack, "0.1.1", "cca7b4da1a233757fdb44b3334fce80c94785b3ad5a602053b7a002b5a8967bf", [:mix], [{:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: false]}, {:tesla, "~> 1.2.0", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm"},
 +  "quantum": {:hex, :quantum, "2.3.4", "72a0e8855e2adc101459eac8454787cb74ab4169de6ca50f670e72142d4960e9", [:mix], [{:calendar, "~> 0.17", [hex: :calendar, repo: "hexpm", optional: true]}, {:crontab, "~> 1.1", [hex: :crontab, repo: "hexpm", optional: false]}, {:gen_stage, "~> 0.12", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:swarm, "~> 3.3", [hex: :swarm, repo: "hexpm", optional: false]}, {:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: true]}], "hexpm"},
    "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},
    "recon": {:git, "https://github.com/ferd/recon.git", "75d70c7c08926d2f24f1ee6de14ee50fe8a52763", [tag: "2.4.0"]},
    "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
index 7f275279e710d15e1d139db06184b7e2bdff87f9,5cc31c604b1eb8079ca2a0676b3183d8df36547d..5b4dad648aa8a1d08c7ec89c51c134939587b04b
@@@ -67,22 -67,3 +67,5 @@@ config :pleroma, Pleroma.Uploaders.Loca
  # For using third-party S3 clones like wasabi, also do:
  # config :ex_aws, :s3,
  #   host: "s3.wasabisys.com"
- # Configure Openstack Swift support if desired.
- #
- # Many openstack deployments are different, so config is left very open with
- # no assumptions made on which provider you're using. This should allow very
- # wide support without needing separate handlers for OVH, Rackspace, etc.
- #
- # config :pleroma, Pleroma.Uploaders.Swift,
- #  container: "some-container",
- #  username: "api-username-yyyy",
- #  password: "api-key-xxxx",
- #  tenant_id: "<openstack-project/tenant-id>",
- #  auth_url: "https://keystone-endpoint.provider.com",
- #  storage_url: "https://swift-endpoint.prodider.com/v1/AUTH_<tenant>/<container>",
- #  object_url: "https://cdn-endpoint.provider.com/<container>"
- #
 +
 +config :joken, default_signer: "<%= jwt_secret %>"
index 0000000000000000000000000000000000000000,1f0162486034104fa43568cebb9eff09e565b1e2..3c13d8b0f018a884227d5da18aadb9ae9b3cacd1
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,252 +1,259 @@@
 -      assert user == result |> Map.put(:search_rank, nil) |> Map.put(:search_type, nil)
+ # Pleroma: A lightweight social networking server
+ # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+ # SPDX-License-Identifier: AGPL-3.0-only
+ defmodule Pleroma.UserSearchTest do
+   alias Pleroma.Repo
+   alias Pleroma.User
+   use Pleroma.DataCase
+   import Pleroma.Factory
+   setup_all do
+     Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
+     :ok
+   end
+   describe "User.search" do
+     test "accepts limit parameter" do
+       Enum.each(0..4, &insert(:user, %{nickname: "john#{&1}"}))
+       assert length(User.search("john", limit: 3)) == 3
+       assert length(User.search("john")) == 5
+     end
+     test "accepts offset parameter" do
+       Enum.each(0..4, &insert(:user, %{nickname: "john#{&1}"}))
+       assert length(User.search("john", limit: 3)) == 3
+       assert length(User.search("john", limit: 3, offset: 3)) == 2
+     end
+     test "finds a user by full or partial nickname" do
+       user = insert(:user, %{nickname: "john"})
+       Enum.each(["john", "jo", "j"], fn query ->
+         assert user ==
+                  User.search(query)
+                  |> List.first()
+                  |> Map.put(:search_rank, nil)
+                  |> Map.put(:search_type, nil)
+       end)
+     end
+     test "finds a user by full or partial name" do
+       user = insert(:user, %{name: "John Doe"})
+       Enum.each(["John Doe", "JOHN", "doe", "j d", "j", "d"], fn query ->
+         assert user ==
+                  User.search(query)
+                  |> List.first()
+                  |> Map.put(:search_rank, nil)
+                  |> Map.put(:search_type, nil)
+       end)
+     end
+     test "finds users, preferring nickname matches over name matches" do
+       u1 = insert(:user, %{name: "lain", nickname: "nick1"})
+       u2 = insert(:user, %{nickname: "lain", name: "nick1"})
+       assert [u2.id, u1.id] == Enum.map(User.search("lain"), & &1.id)
+     end
+     test "finds users, considering density of matched tokens" do
+       u1 = insert(:user, %{name: "Bar Bar plus Word Word"})
+       u2 = insert(:user, %{name: "Word Word Bar Bar Bar"})
+       assert [u2.id, u1.id] == Enum.map(User.search("bar word"), & &1.id)
+     end
+     test "finds users, ranking by similarity" do
+       u1 = insert(:user, %{name: "lain"})
+       _u2 = insert(:user, %{name: "ean"})
+       u3 = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social"})
+       u4 = insert(:user, %{nickname: "lain@pleroma.soykaf.com"})
+       assert [u4.id, u3.id, u1.id] == Enum.map(User.search("lain@ple", for_user: u1), & &1.id)
+     end
+     test "finds users, handling misspelled requests" do
+       u1 = insert(:user, %{name: "lain"})
+       assert [u1.id] == Enum.map(User.search("laiin"), & &1.id)
+     end
+     test "finds users, boosting ranks of friends and followers" do
+       u1 = insert(:user)
+       u2 = insert(:user, %{name: "Doe"})
+       follower = insert(:user, %{name: "Doe"})
+       friend = insert(:user, %{name: "Doe"})
+       {:ok, follower} = User.follow(follower, u1)
+       {:ok, u1} = User.follow(u1, friend)
+       assert [friend.id, follower.id, u2.id] --
+                Enum.map(User.search("doe", resolve: false, for_user: u1), & &1.id) == []
+     end
+     test "finds followers of user by partial name" do
+       u1 = insert(:user)
+       u2 = insert(:user, %{name: "Jimi"})
+       follower_jimi = insert(:user, %{name: "Jimi Hendrix"})
+       follower_lizz = insert(:user, %{name: "Lizz Wright"})
+       friend = insert(:user, %{name: "Jimi"})
+       {:ok, follower_jimi} = User.follow(follower_jimi, u1)
+       {:ok, _follower_lizz} = User.follow(follower_lizz, u2)
+       {:ok, u1} = User.follow(u1, friend)
+       assert Enum.map(User.search("jimi", following: true, for_user: u1), & &1.id) == [
+                follower_jimi.id
+              ]
+       assert User.search("lizz", following: true, for_user: u1) == []
+     end
+     test "find local and remote users for authenticated users" do
+       u1 = insert(:user, %{name: "lain"})
+       u2 = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social", local: false})
+       u3 = insert(:user, %{nickname: "lain@pleroma.soykaf.com", local: false})
+       results =
+         "lain"
+         |> User.search(for_user: u1)
+         |> Enum.map(& &1.id)
+         |> Enum.sort()
+       assert [u1.id, u2.id, u3.id] == results
+     end
+     test "find only local users for unauthenticated users" do
+       %{id: id} = insert(:user, %{name: "lain"})
+       insert(:user, %{name: "ebn", nickname: "lain@mastodon.social", local: false})
+       insert(:user, %{nickname: "lain@pleroma.soykaf.com", local: false})
+       assert [%{id: ^id}] = User.search("lain")
+     end
+     test "find only local users for authenticated users when `limit_to_local_content` is `:all`" do
+       Pleroma.Config.put([:instance, :limit_to_local_content], :all)
+       %{id: id} = insert(:user, %{name: "lain"})
+       insert(:user, %{name: "ebn", nickname: "lain@mastodon.social", local: false})
+       insert(:user, %{nickname: "lain@pleroma.soykaf.com", local: false})
+       assert [%{id: ^id}] = User.search("lain")
+       Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+     end
+     test "find all users for unauthenticated users when `limit_to_local_content` is `false`" do
+       Pleroma.Config.put([:instance, :limit_to_local_content], false)
+       u1 = insert(:user, %{name: "lain"})
+       u2 = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social", local: false})
+       u3 = insert(:user, %{nickname: "lain@pleroma.soykaf.com", local: false})
+       results =
+         "lain"
+         |> User.search()
+         |> Enum.map(& &1.id)
+         |> Enum.sort()
+       assert [u1.id, u2.id, u3.id] == results
+       Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+     end
+     test "finds a user whose name is nil" do
+       _user = insert(:user, %{name: "notamatch", nickname: "testuser@pleroma.amplifie.red"})
+       user_two = insert(:user, %{name: nil, nickname: "lain@pleroma.soykaf.com"})
+       assert user_two ==
+                User.search("lain@pleroma.soykaf.com")
+                |> List.first()
+                |> Map.put(:search_rank, nil)
+                |> Map.put(:search_type, nil)
+     end
+     test "does not yield false-positive matches" do
+       insert(:user, %{name: "John Doe"})
+       Enum.each(["mary", "a", ""], fn query ->
+         assert [] == User.search(query)
+       end)
+     end
+     test "works with URIs" do
+       user = insert(:user)
+       results =
+         User.search("http://mastodon.example.org/users/admin", resolve: true, for_user: user)
+       result = results |> List.first()
+       user = User.get_cached_by_ap_id("http://mastodon.example.org/users/admin")
+       assert length(results) == 1
++
++      expected =
++        result
++        |> Map.put(:search_rank, nil)
++        |> Map.put(:search_type, nil)
++        |> Map.put(:last_digest_emailed_at, nil)
++
++      assert user == expected
+     end
+     test "excludes a blocked users from search result" do
+       user = insert(:user, %{nickname: "Bill"})
+       [blocked_user | users] = Enum.map(0..3, &insert(:user, %{nickname: "john#{&1}"}))
+       blocked_user2 =
+         insert(
+           :user,
+           %{nickname: "john awful", ap_id: "https://awful-and-rude-instance.com/user/bully"}
+         )
+       User.block_domain(user, "awful-and-rude-instance.com")
+       User.block(user, blocked_user)
+       account_ids = User.search("john", for_user: refresh_record(user)) |> collect_ids
+       assert account_ids == collect_ids(users)
+       refute Enum.member?(account_ids, blocked_user.id)
+       refute Enum.member?(account_ids, blocked_user2.id)
+       assert length(account_ids) == 3
+     end
+     test "local user has the same search_rank as for users with the same nickname, but another domain" do
+       user = insert(:user)
+       insert(:user, nickname: "lain@mastodon.social")
+       insert(:user, nickname: "lain")
+       insert(:user, nickname: "lain@pleroma.social")
+       assert User.search("lain@localhost", resolve: true, for_user: user)
+              |> Enum.each(fn u -> u.search_rank == 0.5 end)
+     end
+     test "localhost is the part of the domain" do
+       user = insert(:user)
+       insert(:user, nickname: "another@somedomain")
+       insert(:user, nickname: "lain")
+       insert(:user, nickname: "lain@examplelocalhost")
+       result = User.search("lain@examplelocalhost", resolve: true, for_user: user)
+       assert Enum.each(result, fn u -> u.search_rank == 0.5 end)
+       assert length(result) == 2
+     end
+     test "local user search with users" do
+       user = insert(:user)
+       local_user = insert(:user, nickname: "lain")
+       insert(:user, nickname: "another@localhost.com")
+       insert(:user, nickname: "localhost@localhost.com")
+       [result] = User.search("lain@localhost", resolve: true, for_user: user)
+       assert Map.put(result, :search_rank, nil) |> Map.put(:search_type, nil) == local_user
+     end
+   end
+ end
Simple merge